Version 2.0.0-dev.56.0

Merge commit '0ff6c20c6660bd123c49fb09d09994577e3de097' into dev
diff --git a/BUILD.gn b/BUILD.gn
index fe6513a..f4f9bec 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -13,7 +13,7 @@
     testonly = true
   }
   deps = [
-    ":runtime",
+    ":runtime_kernel",
   ]
 }
 
diff --git a/CHANGELOG.md b/CHANGELOG.md
index a13f6d2..563a2fb 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,50 @@
+## 2.0.0-dev.56.0
+
+### Language
+
+* Invocations of noSuchMethod receive default values for optional args.
+  * The following program used to print "No arguments passed", and now prints
+    "First argument is 3".
+
+```dart
+abstract class B {
+  void m([int x = 3]);
+}
+
+class A implements B {
+  noSuchMethod(Invocation i) {
+    if (i.positionalArguments.length == 0) {
+      print("No arguments passed");
+    } else {
+      print("First argument is ${i.positionalArguments[0]}");
+    }
+  }
+}
+
+void main() {
+  A().m();
+}
+```
+
+### Core library changes
+
+* `dart:core`
+  * Deprecated the `NoSuchMethodError` constructor.
+
+* `dart:mirrors`
+  * Marked `MirrorsUsed` as deprecated. The mirrors library is no longer
+    supported by dart2js, and `MirrorsUsed` only affected dart2js.
+
+* `dart:io`
+  * Added `X509Certificate.der`, `X509Certificate.pem`, and
+    `X509Certificate.sha1`.
+
+### Tool Changes
+
+#### dartfmt
+
+  * Support metadata annotations on enum cases.
+
 ## 2.0.0-dev.55.0
 
 ### Language
diff --git a/DEPS b/DEPS
index 6e0ad81..204088f 100644
--- a/DEPS
+++ b/DEPS
@@ -47,15 +47,11 @@
   # Scripts that make 'git cl format' work.
   "clang_format_scripts_rev": "c09c8deeac31f05bd801995c475e7c8070f9ecda",
 
-  "gperftools_revision": "02eeed29df112728564a5dde6417fa4622b57a06",
+  "gperftools_revision": "9608fa3bcf8020d35f59fbf70cd3cbe4b015b972",
 
   # Revisions of /third_party/* dependencies.
   "args_tag": "1.4.1",
-  "async_tag": "2.0.6",
-  "barback-0.13.0_rev": "34853",
-  "barback-0.14.0_rev": "36398",
-  "barback-0.14.1_rev": "38525",
-  "barback_tag" : "0.15.2+14",
+  "async_tag": "2.0.7",
   "bazel_worker_tag": "v0.1.9",
   "boolean_selector_tag" : "1.0.3",
   "boringssl_gen_rev": "344f455fd13d46f054726638e76026156ea73aa9",
@@ -63,7 +59,7 @@
   "charcode_tag": "v1.1.1",
   "chrome_rev" : "19997",
   "cli_util_tag" : "0.1.2+1",
-  "collection_tag": "1.14.6",
+  "collection_tag": "1.14.9",
   "convert_tag": "2.0.1",
   "crypto_tag" : "2.0.2+1",
   "csslib_tag" : "0.14.1",
@@ -81,7 +77,7 @@
   #     minutes later.
   #
   # For more details, see https://github.com/dart-lang/sdk/issues/30164
-  "dart_style_tag": "1.0.12",  # Please see the note above before updating.
+  "dart_style_tag": "1.0.14",  # Please see the note above before updating.
 
   "dartdoc_tag" : "v0.19.0",
   "fixnum_tag": "0.10.5",
@@ -93,12 +89,12 @@
   "http_parser_tag" : "3.1.1",
   "http_retry_tag": "0.1.1",
   "http_tag" : "0.11.3+16",
-  "http_throttle_tag" : "1.0.1",
+  "http_throttle_tag" : "1.0.2",
   "idl_parser_rev": "5fb1ebf49d235b5a70c9f49047e83b0654031eb7",
   "intl_tag": "0.15.2",
   "jinja2_rev": "2222b31554f03e62600cd7e383376a7c187967a1",
   "json_rpc_2_tag": "2.0.6",
-  "linter_tag": "0.1.50",
+  "linter_tag": "0.1.51",
   "logging_tag": "0.11.3+1",
   "markdown_tag": "1.1.1",
   "matcher_tag": "0.12.1+4",
@@ -135,7 +131,7 @@
   "test_process_tag": "1.0.1",
   "term_glyph_tag": "1.0.0",
   "test_reflective_loader_tag": "0.1.4",
-  "test_tag": "0.12.30+1",
+  "test_tag": "0.12.38",
   "tuple_tag": "v1.0.1",
   "typed_data_tag": "1.1.3",
   "usage_tag": "3.3.0",
@@ -200,8 +196,6 @@
       Var("dart_git") + "args.git" + "@" + Var("args_tag"),
   Var("dart_root") + "/third_party/pkg/async":
       Var("dart_git") + "async.git" + "@" + Var("async_tag"),
-  Var("dart_root") + "/third_party/pkg/barback":
-      Var("dart_git") + "barback.git" + "@" + Var("barback_tag"),
   Var("dart_root") + "/third_party/pkg/bazel_worker":
       Var("dart_git") + "bazel_worker.git" + "@" + Var("bazel_worker_tag"),
   Var("dart_root") + "/third_party/pkg/boolean_selector":
diff --git a/build/dart/dart_action.gni b/build/dart/dart_action.gni
index f5bf967..6bd19d7 100644
--- a/build/dart/dart_action.gni
+++ b/build/dart/dart_action.gni
@@ -6,6 +6,12 @@
 import("dart_host_sdk_toolchain.gni")
 import("prebuilt_dart_sdk.gni")
 
+_is_fuchsia = defined(is_fuchsia_tree) && is_fuchsia_tree
+
+if (_is_fuchsia) {
+  import("//build/dart/dart.gni")
+}
+
 # This file defines templates for running and compiling Dart code during
 # Dart's build.
 #
@@ -90,6 +96,87 @@
   }
 }
 
+template("_prebuilt_tool_action") {
+  assert(defined(invoker.binary),
+      "The path to where the prebuilt binary lives must be defined")
+  assert(defined(invoker.target),
+      "The target to use if the prebuilt doesn't exist must be defined")
+
+  vm_args = []
+  if (defined(invoker.vm_args)) {
+    vm_args += invoker.vm_args
+  }
+
+  if (_is_fuchsia || prebuilt_dart_exe_works) {
+    not_needed(invoker, ["target"])
+    action(target_name) {
+      forward_variables_from(invoker, [
+          "outputs",
+          "deps",
+          "visibility",
+          "depfile",
+      ])
+      script = "$_dart_root/build/gn_run_binary.py"
+
+      inputs = []
+      if (defined(invoker.inputs)) {
+        inputs += invoker.inputs
+      }
+
+      if (defined(invoker.script)) {
+        inputs += [ invoker.script ]
+      }
+      if (defined(invoker.packages)) {
+        inputs += [ invoker.packages ]
+      }
+
+      args = [
+        "compiled_action",
+        rebase_path(invoker.binary),
+      ] + vm_args
+      if (defined(invoker.packages)) {
+        args += [
+          "--packages=" + rebase_path(invoker.packages),
+        ]
+      }
+      if (defined(invoker.script)) {
+        args += [ rebase_path(invoker.script) ]
+      }
+      args += invoker.args
+    }
+  } else {
+    not_needed(invoker, ["binary"])
+    _compiled_action(target_name) {
+      forward_variables_from(invoker, [
+          "inputs",
+          "outputs",
+          "deps",
+          "visibility",
+          "depfile",
+      ])
+
+      if (defined(invoker.script)) {
+        inputs += [ invoker.script ]
+      }
+      if (defined(invoker.packages)) {
+        inputs += [ invoker.packages ]
+      }
+
+      tool = invoker.target
+      args = vm_args
+      if (defined(invoker.packages)) {
+        args += [
+          "--packages=" + rebase_path(invoker.packages),
+        ]
+      }
+      if (defined(invoker.script)) {
+        args += [ rebase_path(invoker.script) ]
+      }
+      args += invoker.args
+    }
+  }
+}
+
 # A template for running Dart scripts during the build using the prebuilt Dart
 # SDK. This should *not* be used for generating snapshots. It uses the dart
 # binary from the prebuilt Dart SDK if one is available, and dart_bootstrap
@@ -121,67 +208,28 @@
   assert(!defined(invoker.sources),
          "prebuilt_dart_action doesn't take a sources arg. Use inputs instead.")
 
-  vm_args = []
-  if (defined(invoker.vm_args)) {
-    vm_args += invoker.vm_args
-  }
-
-  if (prebuilt_dart_exe_works) {
-    action(target_name) {
-      forward_variables_from(invoker, [
-          "inputs",
-          "outputs",
-          "deps",
-          "visibility",
-          "depfile",
-      ])
-      script = "$_dart_root/build/gn_run_binary.py"
-      prebuilt_dart_binary =
+  _prebuilt_tool_action(target_name) {
+    forward_variables_from(invoker, "*")
+    if (_is_fuchsia) {
+      binary = prebuilt_dart
+    } else {
+      binary =
           "$_dart_root/tools/sdks/$host_os/dart-sdk/bin/dart$executable_suffix"
-
-      inputs += [ invoker.script ]
-      if (defined(invoker.packages)) {
-        inputs += [ invoker.packages ]
-      }
-
-      args = [
-        "compiled_action",
-        rebase_path(prebuilt_dart_binary),
-      ] + vm_args
-      if (defined(invoker.packages)) {
-        args += [
-          "--packages=" + rebase_path(invoker.packages),
-        ]
-      }
-      args += [ rebase_path(invoker.script) ] + invoker.args
     }
-  } else {
-    _compiled_action(target_name) {
-      forward_variables_from(invoker, [
-          "inputs",
-          "outputs",
-          "deps",
-          "visibility",
-          "depfile",
-      ])
-
-      inputs += [ invoker.script ]
-      if (defined(invoker.packages)) {
-        inputs += [ invoker.packages ]
-      }
-
-      tool = "$_dart_root/runtime/bin:dart_bootstrap"
-      args = vm_args
-      if (defined(invoker.packages)) {
-        args += [
-          "--packages=" + rebase_path(invoker.packages),
-        ]
-      }
-      args += [ rebase_path(invoker.script) ] + invoker.args
-    }
+    target = "$_dart_root/runtime/bin:dart_bootstrap"
   }
 }
 
+if (_is_fuchsia) {
+template("_prebuilt_gen_snapshot_action") {
+  _prebuilt_tool_action(target_name) {
+    forward_variables_from(invoker, "*")
+    binary = prebuilt_gen_snapshot
+    target = "error"
+  }
+}
+}
+
 # This template runs the specified tool produced by the in-progress build.
 #
 # Parameters:
@@ -272,20 +320,26 @@
 #    visibility
 template("dart_action") {
   assert(defined(invoker.script), "script must be defined for $target_name")
-  _built_tool_action(target_name) {
-    tool = "$_dart_root/runtime/bin:dart"
-    forward_variables_from(invoker, [
-      "args",
-      "depfile",
-      "deps",
-      "inputs",
-      "outputs",
-      "packages",
-      "script",
-      "tool",
-      "visibility",
-      "vm_args",
-    ])
+  if (!_is_fuchsia || !use_prebuilt_dart_sdk) {
+    _built_tool_action(target_name) {
+      tool = "$_dart_root/runtime/bin:dart"
+      forward_variables_from(invoker, [
+        "args",
+        "depfile",
+        "deps",
+        "inputs",
+        "outputs",
+        "packages",
+        "script",
+        "tool",
+        "visibility",
+        "vm_args",
+      ])
+    }
+  } else {
+    prebuilt_dart_action(target_name) {
+      forward_variables_from(invoker, "*")
+    }
   }
 }
 
@@ -312,20 +366,28 @@
 #    visibility
 template("dart_bootstrap_action") {
   assert(defined(invoker.script), "script must be defined for $target_name")
-  _built_tool_action(target_name) {
-    tool = "$_dart_root/runtime/bin:dart_bootstrap"
-    forward_variables_from(invoker, [
-      "args",
-      "depfile",
-      "deps",
-      "inputs",
-      "outputs",
-      "packages",
-      "script",
-      "tool",
-      "visibility",
-      "vm_args",
-    ])
+  if (!_is_fuchsia || !use_prebuilt_dart_sdk) {
+    _built_tool_action(target_name) {
+      tool = "$_dart_root/runtime/bin:dart_bootstrap"
+      forward_variables_from(invoker, [
+        "args",
+        "depfile",
+        "deps",
+        "inputs",
+        "outputs",
+        "packages",
+        "script",
+        "tool",
+        "visibility",
+        "vm_args",
+      ])
+    }
+  } else {
+    # We already have a prebuilt dart at the right version, so there is no
+    # reason to use dart_bootstrap.
+    prebuilt_dart_action(target_name) {
+      forward_variables_from(invoker, "*")
+    }
   }
 }
 
@@ -350,18 +412,24 @@
 template("gen_snapshot_action") {
   assert(!defined(invoker.script),
       "script must not be defined for $target_name. If there is a script use args instead.")
-  _built_tool_action(target_name) {
-    tool = "$_dart_root/runtime/bin:gen_snapshot"
-    forward_variables_from(invoker, [
-      "args",
-      "depfile",
-      "deps",
-      "inputs",
-      "outputs",
-      "packages",
-      "tool",
-      "visibility",
-      "vm_args",
-    ])
+  if (!_is_fuchsia || !use_prebuilt_dart_sdk) {
+    _built_tool_action(target_name) {
+      tool = "$_dart_root/runtime/bin:gen_snapshot"
+      forward_variables_from(invoker, [
+        "args",
+        "depfile",
+        "deps",
+        "inputs",
+        "outputs",
+        "packages",
+        "tool",
+        "visibility",
+        "vm_args",
+      ])
+    }
+  } else {
+    _prebuilt_gen_snapshot_action(target_name) {
+      forward_variables_from(invoker, "*")
+    }
   }
 }
diff --git a/build/dart/prebuilt_dart_sdk.gni b/build/dart/prebuilt_dart_sdk.gni
index 59e519c..2a5be7b 100644
--- a/build/dart/prebuilt_dart_sdk.gni
+++ b/build/dart/prebuilt_dart_sdk.gni
@@ -6,7 +6,8 @@
 
 _dart_root = rebase_path("../..")
 
-_prebuilt_dart_exe = "$_dart_root/tools/sdks/$host_os/dart-sdk/bin/dart$executable_suffix"
+_prebuilt_dart_exe =
+    "$_dart_root/tools/sdks/$host_os/dart-sdk/bin/dart$executable_suffix"
 
 # When the first argument is "exec_script", gn_run_binary.py always exits with
 # status 0, but gives non-empty output when the command it is given fails.
diff --git a/docs/language/dart.sty b/docs/language/dart.sty
index 6f5a870..468a8e8 100644
--- a/docs/language/dart.sty
+++ b/docs/language/dart.sty
@@ -21,7 +21,9 @@
 \def\GET{\builtinId{get}}
 \def\IMPLEMENTS{\builtinId{implements}}
 \def\IMPORT{\builtinId{import}}
+\def\INTERFACE{\builtinId{interface}}
 \def\LIBRARY{\builtinId{library}}
+\def\MIXIN{\builtinId{mixin}}
 \def\OPERATOR{\builtinId{operator}}
 \def\PART{\builtinId{part}}
 \def\SET{\builtinId{set}}
diff --git a/docs/language/dartLangSpec.tex b/docs/language/dartLangSpec.tex
index 3d99fb8..4ad9e1d 100644
--- a/docs/language/dartLangSpec.tex
+++ b/docs/language/dartLangSpec.tex
@@ -45,6 +45,8 @@
 % - Specify `call` for Dart 2 (no function type given to enclosing class).
 % - Clarify that an identifier reference denoting a top-level, static, or
 %   local function evaluates to the closurization of that declaration.
+% - Make `mixin` and `interface` built-in identifiers.
+% - Make `async` *not* a reserved word inside async functions.
 %
 % 1.15
 % - Change how language specification describes control flow.
@@ -6847,8 +6849,10 @@
   \GET{};
   \IMPLEMENTS{};
   \IMPORT{};
+  \INTERFACE{};
   \LIBRARY{};
   \OPERATOR{};
+  \MIXIN{};
   \PART{};
   \SET{};
   \STATIC{};
@@ -6891,7 +6895,7 @@
 }
 
 \LMHash{}
-It is a compile-time error if any of the identifiers \ASYNC, \AWAIT{} or \YIELD{} is used as an identifier in a function body marked with either \ASYNC{}, \ASYNC* or \SYNC*.
+It is a compile-time error if either of the identifiers \AWAIT{} or \YIELD{} is used as an identifier in a function body marked with either \ASYNC{}, \ASYNC* or \SYNC*.
 
 \rationale{
 For compatibility reasons, new constructs cannot rely upon new reserved words or even built-in identifiers.
diff --git a/pkg/analysis_server/benchmark/integration/main.dart b/pkg/analysis_server/benchmark/integration/main.dart
index a04fb4a..2182796 100644
--- a/pkg/analysis_server/benchmark/integration/main.dart
+++ b/pkg/analysis_server/benchmark/integration/main.dart
@@ -121,7 +121,7 @@
   }
   logger.log(Level.INFO, 'tmpSrcDir: ${args.tmpSrcDirPath}');
   return inputRaw
-      .transform(SYSTEM_ENCODING.decoder)
+      .transform(systemEncoding.decoder)
       .transform(new LineSplitter())
       .transform(new InputConverter(args.tmpSrcDirPath, args.srcPathMap));
 }
diff --git a/pkg/analysis_server/doc/api.html b/pkg/analysis_server/doc/api.html
index 453a520..3e2656a 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.20.2
+  1.20.3
 </h1>
 <p>
   This document contains a specification of the API provided by the
@@ -276,6 +276,7 @@
 
 <p><a href="#domain_execution">Execution</a></p><ul><li><a href="#request_execution.createContext">execution.createContext</a></li>
 <li><a href="#request_execution.deleteContext">execution.deleteContext</a></li>
+<li><a href="#request_execution.getSuggestions">execution.getSuggestions</a></li>
 <li><a href="#request_execution.mapUri">execution.mapUri</a></li>
 <li><a class="deprecated" href="#request_execution.setSubscriptions">execution.setSubscriptions</a></li>
 </ul>
@@ -2263,6 +2264,7 @@
   
   
   
+  
 <h3>Requests</h3><dl><dt class="request"><a name="request_execution.createContext">execution.createContext</a></dt><dd><div class="box"><pre>request: {
   "id": String
   "method": "execution.createContext"
@@ -2317,6 +2319,110 @@
         <p>
           The identifier of the execution context that is to be deleted.
         </p>
+      </dd></dl></dd><dt class="request"><a name="request_execution.getSuggestions">execution.getSuggestions</a></dt><dd><div class="box"><pre>request: {
+  "id": String
+  "method": "execution.getSuggestions"
+  "params": {
+    "<b>code</b>": String
+    "<b>offset</b>": int
+    "<b>contextFile</b>": <a href="#type_FilePath">FilePath</a>
+    "<b>contextOffset</b>": int
+    "<b>variables</b>": List&lt;<a href="#type_RuntimeCompletionVariable">RuntimeCompletionVariable</a>&gt;
+    "<b>expressions</b>": <span style="color:#999999">optional</span> List&lt;<a href="#type_RuntimeCompletionExpression">RuntimeCompletionExpression</a>&gt;
+  }
+}</pre><br><pre>response: {
+  "id": String
+  "error": <span style="color:#999999">optional</span> <a href="#type_RequestError">RequestError</a>
+  "result": {
+    "<b>suggestions</b>": <span style="color:#999999">optional</span> List&lt;<a href="#type_CompletionSuggestion">CompletionSuggestion</a>&gt;
+    "<b>expressions</b>": <span style="color:#999999">optional</span> List&lt;<a href="#type_RuntimeCompletionExpression">RuntimeCompletionExpression</a>&gt;
+  }
+}</pre></div>
+    <p>
+      Request completion suggestions for the given runtime context.
+    </p>
+    <p>
+      It might take one or two requests of this type to get completion
+      suggestions. The first request should have only "code", "offset",
+      and "variables", but not "expressions". If there are sub-expressions that
+      can have different runtime types, and are considered to be safe to
+      evaluate at runtime (e.g. getters), so using their actual runtime types
+      can improve completion results, the server will not include the
+      "suggestions" field in the response, and instead will return the
+      "expressions" field. The client will use debug API to get current runtime
+      types for these sub-expressions and send another request, this time with
+      "expressions". If there are no interesting sub-expressions to get
+      runtime types for, or when the "expressions" field is provided by the
+      client, the server will return "suggestions" in the response.
+    </p>
+    
+    
+  <h4>parameters:</h4><dl><dt class="field"><b>code: String</b></dt><dd>
+        
+        <p>
+          The code to get suggestions in.
+        </p>
+      </dd><dt class="field"><b>offset: int</b></dt><dd>
+        
+        <p>
+          The offset within the code to get suggestions at.
+        </p>
+      </dd><dt class="field"><b>contextFile: <a href="#type_FilePath">FilePath</a></b></dt><dd>
+        
+        <p>
+          The path of the context file, e.g. the file of the current debugger
+          frame. The combination of the context file and context offset can
+          be used to ensure that all variables of the context are available
+          for completion (with their static types).
+        </p>
+      </dd><dt class="field"><b>contextOffset: int</b></dt><dd>
+        
+        <p>
+          The offset in the context file, e.g. the line offset in the current
+          debugger frame.
+        </p>
+      </dd><dt class="field"><b>variables: List&lt;<a href="#type_RuntimeCompletionVariable">RuntimeCompletionVariable</a>&gt;</b></dt><dd>
+        
+        <p>
+          The runtime context variables that are potentially referenced in the
+          code.
+        </p>
+      </dd><dt class="field"><b>expressions: List&lt;<a href="#type_RuntimeCompletionExpression">RuntimeCompletionExpression</a>&gt;<span style="color:#999999"> (optional)</span></b></dt><dd>
+        
+        <p>
+          The list of sub-expressions in the code for which the client wants
+          to provide runtime types. It does not have to be the full list of
+          expressions requested by the server, for missing expressions their
+          static types will be used.
+        </p>
+        <p>
+          When this field is omitted, the server will return completion
+          suggestions only when there are no interesting sub-expressions in the
+          given code. The client may provide an empty list, in this case the
+          server will return completion suggestions.
+        </p>
+      </dd></dl><h4>returns:</h4><dl><dt class="field"><b>suggestions: List&lt;<a href="#type_CompletionSuggestion">CompletionSuggestion</a>&gt;<span style="color:#999999"> (optional)</span></b></dt><dd>
+        
+        <p>
+          The completion suggestions. In contrast to usual completion request,
+          suggestions for private elements also will be provided.
+        </p>
+        <p>
+          If there are sub-expressions that can have different runtime types,
+          and are considered to be safe to evaluate at runtime (e.g. getters),
+          so using their actual runtime types can improve completion results,
+          the server omits this field in the response, and instead will return
+          the "expressions" field.
+        </p>
+      </dd><dt class="field"><b>expressions: List&lt;<a href="#type_RuntimeCompletionExpression">RuntimeCompletionExpression</a>&gt;<span style="color:#999999"> (optional)</span></b></dt><dd>
+        
+        <p>
+          The list of sub-expressions in the code for which the server would
+          like to know runtime types to provide better completion suggestions.
+        </p>
+        <p>
+          This field is omitted the field "suggestions" is returned.
+        </p>
       </dd></dl></dd><dt class="request"><a name="request_execution.mapUri">execution.mapUri</a></dt><dd><div class="box"><pre>request: {
   "<b>id</b>": String
   "method": "execution.mapUri"
@@ -2543,6 +2649,10 @@
   
   
   
+  
+  
+  
+  
 <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
@@ -3199,7 +3309,7 @@
       An enumeration of the kinds of folding regions.
     </p>
     
-  <dl><dt class="value">COMMENT</dt><dt class="value">CLASS_MEMBER</dt><dt class="value">DIRECTIVES</dt><dt class="value">DOCUMENTATION_COMMENT</dt><dt class="value">TOP_LEVEL_DECLARATION</dt></dl></dd><dt class="typeDefinition"><a name="type_FoldingRegion">FoldingRegion: object</a></dt><dd>
+  <dl><dt class="value">ANNOTATIONS</dt><dt class="value">CLASS_BODY</dt><dt class="value">DIRECTIVES</dt><dt class="value">DOCUMENTATION_COMMENT</dt><dt class="value">FILE_HEADER</dt><dt class="value">FUNCTION_BODY</dt></dl></dd><dt class="typeDefinition"><a name="type_FoldingRegion">FoldingRegion: object</a></dt><dd>
     <p>
       A description of a region that can be folded.
     </p>
@@ -4250,6 +4360,103 @@
           API reaches version 1.0.
         </p>
         
+      </dd></dl></dd><dt class="typeDefinition"><a name="type_RuntimeCompletionExpression">RuntimeCompletionExpression: object</a></dt><dd>
+    <p>
+      An expression for which we want to know its runtime type.
+      In expressions like `a.b.c.where((e) =&gt; e.^)` we want to know the
+      runtime type of `a.b.c` to enforce it statically at the time when we
+      compute completion suggestions, and get better type for `e`.
+    </p>
+    
+  <dl><dt class="field"><b>offset: int</b></dt><dd>
+        
+        <p>
+          The offset of the expression in the code for completion.
+        </p>
+      </dd><dt class="field"><b>length: int</b></dt><dd>
+        
+        <p>
+          The length of the expression in the code for completion.
+        </p>
+      </dd><dt class="field"><b>type: <a href="#type_RuntimeCompletionExpressionType">RuntimeCompletionExpressionType</a><span style="color:#999999"> (optional)</span></b></dt><dd>
+        
+        <p>
+          When the expression is sent from the server to the client, the
+          type is omitted. The client should fill the type when it sends the
+          request to the server again.
+        </p>
+      </dd></dl></dd><dt class="typeDefinition"><a name="type_RuntimeCompletionExpressionType">RuntimeCompletionExpressionType: object</a></dt><dd>
+    <p>
+      A type at runtime.
+    </p>
+    
+  <dl><dt class="field"><b>libraryPath: <a href="#type_FilePath">FilePath</a><span style="color:#999999"> (optional)</span></b></dt><dd>
+        
+        <p>
+          The path of the library that has this type.
+          Omitted if the type is not declared in any library, e.g. "dynamic",
+          or "void".
+        </p>
+      </dd><dt class="field"><b>kind: <a href="#type_RuntimeCompletionExpressionTypeKind">RuntimeCompletionExpressionTypeKind</a></b></dt><dd>
+        
+        <p>
+          The kind of the type.
+        </p>
+      </dd><dt class="field"><b>name: String<span style="color:#999999"> (optional)</span></b></dt><dd>
+        
+        <p>
+          The name of the type. Omitted if the type does not have a name, e.g.
+          an inline function type.
+        </p>
+      </dd><dt class="field"><b>typeArguments: List&lt;<a href="#type_RuntimeCompletionExpressionType">RuntimeCompletionExpressionType</a>&gt;<span style="color:#999999"> (optional)</span></b></dt><dd>
+        
+        <p>
+          The type arguments of the type.
+          Omitted if the type does not have type parameters.
+        </p>
+      </dd><dt class="field"><b>returnType: <a href="#type_RuntimeCompletionExpressionType">RuntimeCompletionExpressionType</a><span style="color:#999999"> (optional)</span></b></dt><dd>
+        
+        <p>
+          If the type is a function type, the return type of the function.
+          Omitted if the type is not a function type.
+        </p>
+      </dd><dt class="field"><b>parameterTypes: List&lt;<a href="#type_RuntimeCompletionExpressionType">RuntimeCompletionExpressionType</a>&gt;<span style="color:#999999"> (optional)</span></b></dt><dd>
+        
+        <p>
+          If the type is a function type, the types of the function parameters
+          of all kinds - required, optional positional, and optional named.
+          Omitted if the type is not a function type.
+        </p>
+      </dd><dt class="field"><b>parameterNames: List&lt;String&gt;<span style="color:#999999"> (optional)</span></b></dt><dd>
+        
+        <p>
+          If the type is a function type, the names of the function parameters
+          of all kinds - required, optional positional, and optional named.
+          The names of positional parameters are empty strings.
+          Omitted if the type is not a function type.
+        </p>
+      </dd></dl></dd><dt class="typeDefinition"><a name="type_RuntimeCompletionExpressionTypeKind">RuntimeCompletionExpressionTypeKind: String</a></dt><dd>
+    <p>
+      An enumeration of the kinds of runtime expression types.
+    </p>
+    
+  <dl><dt class="value">DYNAMIC</dt><dt class="value">FUNCTION</dt><dt class="value">INTERFACE</dt></dl></dd><dt class="typeDefinition"><a name="type_RuntimeCompletionVariable">RuntimeCompletionVariable: object</a></dt><dd>
+    <p>
+      A variable in a runtime context.
+    </p>
+    
+  <dl><dt class="field"><b>name: String</b></dt><dd>
+        
+        <p>
+          The name of the variable.
+          The name "this" has a special meaning and is used as an implicit
+          target for runtime completion, and in explicit "this" references.
+        </p>
+      </dd><dt class="field"><b>type: <a href="#type_RuntimeCompletionExpressionType">RuntimeCompletionExpressionType</a></b></dt><dd>
+        
+        <p>
+          The type of the variable.
+        </p>
       </dd></dl></dd><dt class="typeDefinition"><a name="type_SearchId">SearchId: String</a></dt><dd>
     
     <p>
@@ -4832,7 +5039,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.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_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></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>
 
 
 </body></html>
\ No newline at end of file
diff --git a/pkg/analysis_server/lib/protocol/protocol.dart b/pkg/analysis_server/lib/protocol/protocol.dart
index 9e77ed7..730887e 100644
--- a/pkg/analysis_server/lib/protocol/protocol.dart
+++ b/pkg/analysis_server/lib/protocol/protocol.dart
@@ -14,26 +14,6 @@
 export 'package:analyzer_plugin/protocol/protocol.dart' show Enum;
 
 /**
- * A [RequestHandler] that supports [startup] and [shutdown] methods.
- *
- * Clients may not extend, implement or mix-in this class.
- */
-abstract class DomainHandler implements RequestHandler {
-  /**
-   * Perform any operations associated with the shutdown of the domain. It is
-   * not guaranteed that this method will be called. If it is, it will be
-   * called after the last [Request] has been made.
-   */
-  void shutdown() {}
-
-  /**
-   * Perform any operations associated with the startup of the domain. This
-   * will be called before the first [Request].
-   */
-  void startup() {}
-}
-
-/**
  * A notification that can be sent from the server about an event that occurred.
  *
  * Clients may not extend, implement or mix-in this class.
diff --git a/pkg/analysis_server/lib/protocol/protocol_constants.dart b/pkg/analysis_server/lib/protocol/protocol_constants.dart
index 148fc49..fcd4300 100644
--- a/pkg/analysis_server/lib/protocol/protocol_constants.dart
+++ b/pkg/analysis_server/lib/protocol/protocol_constants.dart
@@ -196,6 +196,13 @@
 const String EXECUTION_REQUEST_CREATE_CONTEXT_CONTEXT_ROOT = 'contextRoot';
 const String EXECUTION_REQUEST_DELETE_CONTEXT = 'execution.deleteContext';
 const String EXECUTION_REQUEST_DELETE_CONTEXT_ID = 'id';
+const String EXECUTION_REQUEST_GET_SUGGESTIONS = 'execution.getSuggestions';
+const String EXECUTION_REQUEST_GET_SUGGESTIONS_CODE = 'code';
+const String EXECUTION_REQUEST_GET_SUGGESTIONS_CONTEXT_FILE = 'contextFile';
+const String EXECUTION_REQUEST_GET_SUGGESTIONS_CONTEXT_OFFSET = 'contextOffset';
+const String EXECUTION_REQUEST_GET_SUGGESTIONS_EXPRESSIONS = 'expressions';
+const String EXECUTION_REQUEST_GET_SUGGESTIONS_OFFSET = 'offset';
+const String EXECUTION_REQUEST_GET_SUGGESTIONS_VARIABLES = 'variables';
 const String EXECUTION_REQUEST_MAP_URI = 'execution.mapUri';
 const String EXECUTION_REQUEST_MAP_URI_FILE = 'file';
 const String EXECUTION_REQUEST_MAP_URI_ID = 'id';
@@ -204,6 +211,8 @@
 const String EXECUTION_REQUEST_SET_SUBSCRIPTIONS_SUBSCRIPTIONS =
     'subscriptions';
 const String EXECUTION_RESPONSE_CREATE_CONTEXT_ID = 'id';
+const String EXECUTION_RESPONSE_GET_SUGGESTIONS_EXPRESSIONS = 'expressions';
+const String EXECUTION_RESPONSE_GET_SUGGESTIONS_SUGGESTIONS = 'suggestions';
 const String EXECUTION_RESPONSE_MAP_URI_FILE = 'file';
 const String EXECUTION_RESPONSE_MAP_URI_URI = 'uri';
 const String FLUTTER_NOTIFICATION_OUTLINE = 'flutter.outline';
diff --git a/pkg/analysis_server/lib/protocol/protocol_generated.dart b/pkg/analysis_server/lib/protocol/protocol_generated.dart
index cd60f28..7175c14 100644
--- a/pkg/analysis_server/lib/protocol/protocol_generated.dart
+++ b/pkg/analysis_server/lib/protocol/protocol_generated.dart
@@ -9504,6 +9504,422 @@
 }
 
 /**
+ * execution.getSuggestions params
+ *
+ * {
+ *   "code": String
+ *   "offset": int
+ *   "contextFile": FilePath
+ *   "contextOffset": int
+ *   "variables": List<RuntimeCompletionVariable>
+ *   "expressions": optional List<RuntimeCompletionExpression>
+ * }
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+class ExecutionGetSuggestionsParams implements RequestParams {
+  String _code;
+
+  int _offset;
+
+  String _contextFile;
+
+  int _contextOffset;
+
+  List<RuntimeCompletionVariable> _variables;
+
+  List<RuntimeCompletionExpression> _expressions;
+
+  /**
+   * The code to get suggestions in.
+   */
+  String get code => _code;
+
+  /**
+   * The code to get suggestions in.
+   */
+  void set code(String value) {
+    assert(value != null);
+    this._code = value;
+  }
+
+  /**
+   * The offset within the code to get suggestions at.
+   */
+  int get offset => _offset;
+
+  /**
+   * The offset within the code to get suggestions at.
+   */
+  void set offset(int value) {
+    assert(value != null);
+    this._offset = value;
+  }
+
+  /**
+   * The path of the context file, e.g. the file of the current debugger frame.
+   * The combination of the context file and context offset can be used to
+   * ensure that all variables of the context are available for completion
+   * (with their static types).
+   */
+  String get contextFile => _contextFile;
+
+  /**
+   * The path of the context file, e.g. the file of the current debugger frame.
+   * The combination of the context file and context offset can be used to
+   * ensure that all variables of the context are available for completion
+   * (with their static types).
+   */
+  void set contextFile(String value) {
+    assert(value != null);
+    this._contextFile = value;
+  }
+
+  /**
+   * The offset in the context file, e.g. the line offset in the current
+   * debugger frame.
+   */
+  int get contextOffset => _contextOffset;
+
+  /**
+   * The offset in the context file, e.g. the line offset in the current
+   * debugger frame.
+   */
+  void set contextOffset(int value) {
+    assert(value != null);
+    this._contextOffset = value;
+  }
+
+  /**
+   * The runtime context variables that are potentially referenced in the code.
+   */
+  List<RuntimeCompletionVariable> get variables => _variables;
+
+  /**
+   * The runtime context variables that are potentially referenced in the code.
+   */
+  void set variables(List<RuntimeCompletionVariable> value) {
+    assert(value != null);
+    this._variables = value;
+  }
+
+  /**
+   * The list of sub-expressions in the code for which the client wants to
+   * provide runtime types. It does not have to be the full list of expressions
+   * requested by the server, for missing expressions their static types will
+   * be used.
+   *
+   * When this field is omitted, the server will return completion suggestions
+   * only when there are no interesting sub-expressions in the given code. The
+   * client may provide an empty list, in this case the server will return
+   * completion suggestions.
+   */
+  List<RuntimeCompletionExpression> get expressions => _expressions;
+
+  /**
+   * The list of sub-expressions in the code for which the client wants to
+   * provide runtime types. It does not have to be the full list of expressions
+   * requested by the server, for missing expressions their static types will
+   * be used.
+   *
+   * When this field is omitted, the server will return completion suggestions
+   * only when there are no interesting sub-expressions in the given code. The
+   * client may provide an empty list, in this case the server will return
+   * completion suggestions.
+   */
+  void set expressions(List<RuntimeCompletionExpression> value) {
+    this._expressions = value;
+  }
+
+  ExecutionGetSuggestionsParams(String code, int offset, String contextFile,
+      int contextOffset, List<RuntimeCompletionVariable> variables,
+      {List<RuntimeCompletionExpression> expressions}) {
+    this.code = code;
+    this.offset = offset;
+    this.contextFile = contextFile;
+    this.contextOffset = contextOffset;
+    this.variables = variables;
+    this.expressions = expressions;
+  }
+
+  factory ExecutionGetSuggestionsParams.fromJson(
+      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+    if (json == null) {
+      json = {};
+    }
+    if (json is Map) {
+      String code;
+      if (json.containsKey("code")) {
+        code = jsonDecoder.decodeString(jsonPath + ".code", json["code"]);
+      } else {
+        throw jsonDecoder.mismatch(jsonPath, "code");
+      }
+      int offset;
+      if (json.containsKey("offset")) {
+        offset = jsonDecoder.decodeInt(jsonPath + ".offset", json["offset"]);
+      } else {
+        throw jsonDecoder.mismatch(jsonPath, "offset");
+      }
+      String contextFile;
+      if (json.containsKey("contextFile")) {
+        contextFile = jsonDecoder.decodeString(
+            jsonPath + ".contextFile", json["contextFile"]);
+      } else {
+        throw jsonDecoder.mismatch(jsonPath, "contextFile");
+      }
+      int contextOffset;
+      if (json.containsKey("contextOffset")) {
+        contextOffset = jsonDecoder.decodeInt(
+            jsonPath + ".contextOffset", json["contextOffset"]);
+      } else {
+        throw jsonDecoder.mismatch(jsonPath, "contextOffset");
+      }
+      List<RuntimeCompletionVariable> variables;
+      if (json.containsKey("variables")) {
+        variables = jsonDecoder.decodeList(
+            jsonPath + ".variables",
+            json["variables"],
+            (String jsonPath, Object json) =>
+                new RuntimeCompletionVariable.fromJson(
+                    jsonDecoder, jsonPath, json));
+      } else {
+        throw jsonDecoder.mismatch(jsonPath, "variables");
+      }
+      List<RuntimeCompletionExpression> expressions;
+      if (json.containsKey("expressions")) {
+        expressions = jsonDecoder.decodeList(
+            jsonPath + ".expressions",
+            json["expressions"],
+            (String jsonPath, Object json) =>
+                new RuntimeCompletionExpression.fromJson(
+                    jsonDecoder, jsonPath, json));
+      }
+      return new ExecutionGetSuggestionsParams(
+          code, offset, contextFile, contextOffset, variables,
+          expressions: expressions);
+    } else {
+      throw jsonDecoder.mismatch(
+          jsonPath, "execution.getSuggestions params", json);
+    }
+  }
+
+  factory ExecutionGetSuggestionsParams.fromRequest(Request request) {
+    return new ExecutionGetSuggestionsParams.fromJson(
+        new RequestDecoder(request), "params", request.params);
+  }
+
+  @override
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> result = {};
+    result["code"] = code;
+    result["offset"] = offset;
+    result["contextFile"] = contextFile;
+    result["contextOffset"] = contextOffset;
+    result["variables"] = variables
+        .map((RuntimeCompletionVariable value) => value.toJson())
+        .toList();
+    if (expressions != null) {
+      result["expressions"] = expressions
+          .map((RuntimeCompletionExpression value) => value.toJson())
+          .toList();
+    }
+    return result;
+  }
+
+  @override
+  Request toRequest(String id) {
+    return new Request(id, "execution.getSuggestions", toJson());
+  }
+
+  @override
+  String toString() => json.encode(toJson());
+
+  @override
+  bool operator ==(other) {
+    if (other is ExecutionGetSuggestionsParams) {
+      return code == other.code &&
+          offset == other.offset &&
+          contextFile == other.contextFile &&
+          contextOffset == other.contextOffset &&
+          listEqual(
+              variables,
+              other.variables,
+              (RuntimeCompletionVariable a, RuntimeCompletionVariable b) =>
+                  a == b) &&
+          listEqual(
+              expressions,
+              other.expressions,
+              (RuntimeCompletionExpression a, RuntimeCompletionExpression b) =>
+                  a == b);
+    }
+    return false;
+  }
+
+  @override
+  int get hashCode {
+    int hash = 0;
+    hash = JenkinsSmiHash.combine(hash, code.hashCode);
+    hash = JenkinsSmiHash.combine(hash, offset.hashCode);
+    hash = JenkinsSmiHash.combine(hash, contextFile.hashCode);
+    hash = JenkinsSmiHash.combine(hash, contextOffset.hashCode);
+    hash = JenkinsSmiHash.combine(hash, variables.hashCode);
+    hash = JenkinsSmiHash.combine(hash, expressions.hashCode);
+    return JenkinsSmiHash.finish(hash);
+  }
+}
+
+/**
+ * execution.getSuggestions result
+ *
+ * {
+ *   "suggestions": optional List<CompletionSuggestion>
+ *   "expressions": optional List<RuntimeCompletionExpression>
+ * }
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+class ExecutionGetSuggestionsResult implements ResponseResult {
+  List<CompletionSuggestion> _suggestions;
+
+  List<RuntimeCompletionExpression> _expressions;
+
+  /**
+   * The completion suggestions. In contrast to usual completion request,
+   * suggestions for private elements also will be provided.
+   *
+   * If there are sub-expressions that can have different runtime types, and
+   * are considered to be safe to evaluate at runtime (e.g. getters), so using
+   * their actual runtime types can improve completion results, the server
+   * omits this field in the response, and instead will return the
+   * "expressions" field.
+   */
+  List<CompletionSuggestion> get suggestions => _suggestions;
+
+  /**
+   * The completion suggestions. In contrast to usual completion request,
+   * suggestions for private elements also will be provided.
+   *
+   * If there are sub-expressions that can have different runtime types, and
+   * are considered to be safe to evaluate at runtime (e.g. getters), so using
+   * their actual runtime types can improve completion results, the server
+   * omits this field in the response, and instead will return the
+   * "expressions" field.
+   */
+  void set suggestions(List<CompletionSuggestion> value) {
+    this._suggestions = value;
+  }
+
+  /**
+   * The list of sub-expressions in the code for which the server would like to
+   * know runtime types to provide better completion suggestions.
+   *
+   * This field is omitted the field "suggestions" is returned.
+   */
+  List<RuntimeCompletionExpression> get expressions => _expressions;
+
+  /**
+   * The list of sub-expressions in the code for which the server would like to
+   * know runtime types to provide better completion suggestions.
+   *
+   * This field is omitted the field "suggestions" is returned.
+   */
+  void set expressions(List<RuntimeCompletionExpression> value) {
+    this._expressions = value;
+  }
+
+  ExecutionGetSuggestionsResult(
+      {List<CompletionSuggestion> suggestions,
+      List<RuntimeCompletionExpression> expressions}) {
+    this.suggestions = suggestions;
+    this.expressions = expressions;
+  }
+
+  factory ExecutionGetSuggestionsResult.fromJson(
+      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+    if (json == null) {
+      json = {};
+    }
+    if (json is Map) {
+      List<CompletionSuggestion> suggestions;
+      if (json.containsKey("suggestions")) {
+        suggestions = jsonDecoder.decodeList(
+            jsonPath + ".suggestions",
+            json["suggestions"],
+            (String jsonPath, Object json) =>
+                new CompletionSuggestion.fromJson(jsonDecoder, jsonPath, json));
+      }
+      List<RuntimeCompletionExpression> expressions;
+      if (json.containsKey("expressions")) {
+        expressions = jsonDecoder.decodeList(
+            jsonPath + ".expressions",
+            json["expressions"],
+            (String jsonPath, Object json) =>
+                new RuntimeCompletionExpression.fromJson(
+                    jsonDecoder, jsonPath, json));
+      }
+      return new ExecutionGetSuggestionsResult(
+          suggestions: suggestions, expressions: expressions);
+    } else {
+      throw jsonDecoder.mismatch(
+          jsonPath, "execution.getSuggestions result", json);
+    }
+  }
+
+  factory ExecutionGetSuggestionsResult.fromResponse(Response response) {
+    return new ExecutionGetSuggestionsResult.fromJson(
+        new ResponseDecoder(REQUEST_ID_REFACTORING_KINDS.remove(response.id)),
+        "result",
+        response.result);
+  }
+
+  @override
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> result = {};
+    if (suggestions != null) {
+      result["suggestions"] = suggestions
+          .map((CompletionSuggestion value) => value.toJson())
+          .toList();
+    }
+    if (expressions != null) {
+      result["expressions"] = expressions
+          .map((RuntimeCompletionExpression 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 ExecutionGetSuggestionsResult) {
+      return listEqual(suggestions, other.suggestions,
+              (CompletionSuggestion a, CompletionSuggestion b) => a == b) &&
+          listEqual(
+              expressions,
+              other.expressions,
+              (RuntimeCompletionExpression a, RuntimeCompletionExpression b) =>
+                  a == b);
+    }
+    return false;
+  }
+
+  @override
+  int get hashCode {
+    int hash = 0;
+    hash = JenkinsSmiHash.combine(hash, suggestions.hashCode);
+    hash = JenkinsSmiHash.combine(hash, expressions.hashCode);
+    return JenkinsSmiHash.finish(hash);
+  }
+}
+
+/**
  * execution.launchData params
  *
  * {
@@ -15227,6 +15643,585 @@
 }
 
 /**
+ * RuntimeCompletionExpression
+ *
+ * {
+ *   "offset": int
+ *   "length": int
+ *   "type": optional RuntimeCompletionExpressionType
+ * }
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+class RuntimeCompletionExpression implements HasToJson {
+  int _offset;
+
+  int _length;
+
+  RuntimeCompletionExpressionType _type;
+
+  /**
+   * The offset of the expression in the code for completion.
+   */
+  int get offset => _offset;
+
+  /**
+   * The offset of the expression in the code for completion.
+   */
+  void set offset(int value) {
+    assert(value != null);
+    this._offset = value;
+  }
+
+  /**
+   * The length of the expression in the code for completion.
+   */
+  int get length => _length;
+
+  /**
+   * The length of the expression in the code for completion.
+   */
+  void set length(int value) {
+    assert(value != null);
+    this._length = value;
+  }
+
+  /**
+   * When the expression is sent from the server to the client, the type is
+   * omitted. The client should fill the type when it sends the request to the
+   * server again.
+   */
+  RuntimeCompletionExpressionType get type => _type;
+
+  /**
+   * When the expression is sent from the server to the client, the type is
+   * omitted. The client should fill the type when it sends the request to the
+   * server again.
+   */
+  void set type(RuntimeCompletionExpressionType value) {
+    this._type = value;
+  }
+
+  RuntimeCompletionExpression(int offset, int length,
+      {RuntimeCompletionExpressionType type}) {
+    this.offset = offset;
+    this.length = length;
+    this.type = type;
+  }
+
+  factory RuntimeCompletionExpression.fromJson(
+      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+    if (json == null) {
+      json = {};
+    }
+    if (json is Map) {
+      int offset;
+      if (json.containsKey("offset")) {
+        offset = jsonDecoder.decodeInt(jsonPath + ".offset", json["offset"]);
+      } else {
+        throw jsonDecoder.mismatch(jsonPath, "offset");
+      }
+      int length;
+      if (json.containsKey("length")) {
+        length = jsonDecoder.decodeInt(jsonPath + ".length", json["length"]);
+      } else {
+        throw jsonDecoder.mismatch(jsonPath, "length");
+      }
+      RuntimeCompletionExpressionType type;
+      if (json.containsKey("type")) {
+        type = new RuntimeCompletionExpressionType.fromJson(
+            jsonDecoder, jsonPath + ".type", json["type"]);
+      }
+      return new RuntimeCompletionExpression(offset, length, type: type);
+    } else {
+      throw jsonDecoder.mismatch(jsonPath, "RuntimeCompletionExpression", json);
+    }
+  }
+
+  @override
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> result = {};
+    result["offset"] = offset;
+    result["length"] = length;
+    if (type != null) {
+      result["type"] = type.toJson();
+    }
+    return result;
+  }
+
+  @override
+  String toString() => json.encode(toJson());
+
+  @override
+  bool operator ==(other) {
+    if (other is RuntimeCompletionExpression) {
+      return offset == other.offset &&
+          length == other.length &&
+          type == other.type;
+    }
+    return false;
+  }
+
+  @override
+  int get hashCode {
+    int hash = 0;
+    hash = JenkinsSmiHash.combine(hash, offset.hashCode);
+    hash = JenkinsSmiHash.combine(hash, length.hashCode);
+    hash = JenkinsSmiHash.combine(hash, type.hashCode);
+    return JenkinsSmiHash.finish(hash);
+  }
+}
+
+/**
+ * RuntimeCompletionExpressionType
+ *
+ * {
+ *   "libraryPath": optional FilePath
+ *   "kind": RuntimeCompletionExpressionTypeKind
+ *   "name": optional String
+ *   "typeArguments": optional List<RuntimeCompletionExpressionType>
+ *   "returnType": optional RuntimeCompletionExpressionType
+ *   "parameterTypes": optional List<RuntimeCompletionExpressionType>
+ *   "parameterNames": optional List<String>
+ * }
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+class RuntimeCompletionExpressionType implements HasToJson {
+  String _libraryPath;
+
+  RuntimeCompletionExpressionTypeKind _kind;
+
+  String _name;
+
+  List<RuntimeCompletionExpressionType> _typeArguments;
+
+  RuntimeCompletionExpressionType _returnType;
+
+  List<RuntimeCompletionExpressionType> _parameterTypes;
+
+  List<String> _parameterNames;
+
+  /**
+   * The path of the library that has this type. Omitted if the type is not
+   * declared in any library, e.g. "dynamic", or "void".
+   */
+  String get libraryPath => _libraryPath;
+
+  /**
+   * The path of the library that has this type. Omitted if the type is not
+   * declared in any library, e.g. "dynamic", or "void".
+   */
+  void set libraryPath(String value) {
+    this._libraryPath = value;
+  }
+
+  /**
+   * The kind of the type.
+   */
+  RuntimeCompletionExpressionTypeKind get kind => _kind;
+
+  /**
+   * The kind of the type.
+   */
+  void set kind(RuntimeCompletionExpressionTypeKind value) {
+    assert(value != null);
+    this._kind = value;
+  }
+
+  /**
+   * The name of the type. Omitted if the type does not have a name, e.g. an
+   * inline function type.
+   */
+  String get name => _name;
+
+  /**
+   * The name of the type. Omitted if the type does not have a name, e.g. an
+   * inline function type.
+   */
+  void set name(String value) {
+    this._name = value;
+  }
+
+  /**
+   * The type arguments of the type. Omitted if the type does not have type
+   * parameters.
+   */
+  List<RuntimeCompletionExpressionType> get typeArguments => _typeArguments;
+
+  /**
+   * The type arguments of the type. Omitted if the type does not have type
+   * parameters.
+   */
+  void set typeArguments(List<RuntimeCompletionExpressionType> value) {
+    this._typeArguments = value;
+  }
+
+  /**
+   * If the type is a function type, the return type of the function. Omitted
+   * if the type is not a function type.
+   */
+  RuntimeCompletionExpressionType get returnType => _returnType;
+
+  /**
+   * If the type is a function type, the return type of the function. Omitted
+   * if the type is not a function type.
+   */
+  void set returnType(RuntimeCompletionExpressionType value) {
+    this._returnType = value;
+  }
+
+  /**
+   * If the type is a function type, the types of the function parameters of
+   * all kinds - required, optional positional, and optional named. Omitted if
+   * the type is not a function type.
+   */
+  List<RuntimeCompletionExpressionType> get parameterTypes => _parameterTypes;
+
+  /**
+   * If the type is a function type, the types of the function parameters of
+   * all kinds - required, optional positional, and optional named. Omitted if
+   * the type is not a function type.
+   */
+  void set parameterTypes(List<RuntimeCompletionExpressionType> value) {
+    this._parameterTypes = value;
+  }
+
+  /**
+   * If the type is a function type, the names of the function parameters of
+   * all kinds - required, optional positional, and optional named. The names
+   * of positional parameters are empty strings. Omitted if the type is not a
+   * function type.
+   */
+  List<String> get parameterNames => _parameterNames;
+
+  /**
+   * If the type is a function type, the names of the function parameters of
+   * all kinds - required, optional positional, and optional named. The names
+   * of positional parameters are empty strings. Omitted if the type is not a
+   * function type.
+   */
+  void set parameterNames(List<String> value) {
+    this._parameterNames = value;
+  }
+
+  RuntimeCompletionExpressionType(RuntimeCompletionExpressionTypeKind kind,
+      {String libraryPath,
+      String name,
+      List<RuntimeCompletionExpressionType> typeArguments,
+      RuntimeCompletionExpressionType returnType,
+      List<RuntimeCompletionExpressionType> parameterTypes,
+      List<String> parameterNames}) {
+    this.libraryPath = libraryPath;
+    this.kind = kind;
+    this.name = name;
+    this.typeArguments = typeArguments;
+    this.returnType = returnType;
+    this.parameterTypes = parameterTypes;
+    this.parameterNames = parameterNames;
+  }
+
+  factory RuntimeCompletionExpressionType.fromJson(
+      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+    if (json == null) {
+      json = {};
+    }
+    if (json is Map) {
+      String libraryPath;
+      if (json.containsKey("libraryPath")) {
+        libraryPath = jsonDecoder.decodeString(
+            jsonPath + ".libraryPath", json["libraryPath"]);
+      }
+      RuntimeCompletionExpressionTypeKind kind;
+      if (json.containsKey("kind")) {
+        kind = new RuntimeCompletionExpressionTypeKind.fromJson(
+            jsonDecoder, jsonPath + ".kind", json["kind"]);
+      } else {
+        throw jsonDecoder.mismatch(jsonPath, "kind");
+      }
+      String name;
+      if (json.containsKey("name")) {
+        name = jsonDecoder.decodeString(jsonPath + ".name", json["name"]);
+      }
+      List<RuntimeCompletionExpressionType> typeArguments;
+      if (json.containsKey("typeArguments")) {
+        typeArguments = jsonDecoder.decodeList(
+            jsonPath + ".typeArguments",
+            json["typeArguments"],
+            (String jsonPath, Object json) =>
+                new RuntimeCompletionExpressionType.fromJson(
+                    jsonDecoder, jsonPath, json));
+      }
+      RuntimeCompletionExpressionType returnType;
+      if (json.containsKey("returnType")) {
+        returnType = new RuntimeCompletionExpressionType.fromJson(
+            jsonDecoder, jsonPath + ".returnType", json["returnType"]);
+      }
+      List<RuntimeCompletionExpressionType> parameterTypes;
+      if (json.containsKey("parameterTypes")) {
+        parameterTypes = jsonDecoder.decodeList(
+            jsonPath + ".parameterTypes",
+            json["parameterTypes"],
+            (String jsonPath, Object json) =>
+                new RuntimeCompletionExpressionType.fromJson(
+                    jsonDecoder, jsonPath, json));
+      }
+      List<String> parameterNames;
+      if (json.containsKey("parameterNames")) {
+        parameterNames = jsonDecoder.decodeList(jsonPath + ".parameterNames",
+            json["parameterNames"], jsonDecoder.decodeString);
+      }
+      return new RuntimeCompletionExpressionType(kind,
+          libraryPath: libraryPath,
+          name: name,
+          typeArguments: typeArguments,
+          returnType: returnType,
+          parameterTypes: parameterTypes,
+          parameterNames: parameterNames);
+    } else {
+      throw jsonDecoder.mismatch(
+          jsonPath, "RuntimeCompletionExpressionType", json);
+    }
+  }
+
+  @override
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> result = {};
+    if (libraryPath != null) {
+      result["libraryPath"] = libraryPath;
+    }
+    result["kind"] = kind.toJson();
+    if (name != null) {
+      result["name"] = name;
+    }
+    if (typeArguments != null) {
+      result["typeArguments"] = typeArguments
+          .map((RuntimeCompletionExpressionType value) => value.toJson())
+          .toList();
+    }
+    if (returnType != null) {
+      result["returnType"] = returnType.toJson();
+    }
+    if (parameterTypes != null) {
+      result["parameterTypes"] = parameterTypes
+          .map((RuntimeCompletionExpressionType value) => value.toJson())
+          .toList();
+    }
+    if (parameterNames != null) {
+      result["parameterNames"] = parameterNames;
+    }
+    return result;
+  }
+
+  @override
+  String toString() => json.encode(toJson());
+
+  @override
+  bool operator ==(other) {
+    if (other is RuntimeCompletionExpressionType) {
+      return libraryPath == other.libraryPath &&
+          kind == other.kind &&
+          name == other.name &&
+          listEqual(
+              typeArguments,
+              other.typeArguments,
+              (RuntimeCompletionExpressionType a,
+                      RuntimeCompletionExpressionType b) =>
+                  a == b) &&
+          returnType == other.returnType &&
+          listEqual(
+              parameterTypes,
+              other.parameterTypes,
+              (RuntimeCompletionExpressionType a,
+                      RuntimeCompletionExpressionType b) =>
+                  a == b) &&
+          listEqual(parameterNames, other.parameterNames,
+              (String a, String b) => a == b);
+    }
+    return false;
+  }
+
+  @override
+  int get hashCode {
+    int hash = 0;
+    hash = JenkinsSmiHash.combine(hash, libraryPath.hashCode);
+    hash = JenkinsSmiHash.combine(hash, kind.hashCode);
+    hash = JenkinsSmiHash.combine(hash, name.hashCode);
+    hash = JenkinsSmiHash.combine(hash, typeArguments.hashCode);
+    hash = JenkinsSmiHash.combine(hash, returnType.hashCode);
+    hash = JenkinsSmiHash.combine(hash, parameterTypes.hashCode);
+    hash = JenkinsSmiHash.combine(hash, parameterNames.hashCode);
+    return JenkinsSmiHash.finish(hash);
+  }
+}
+
+/**
+ * RuntimeCompletionExpressionTypeKind
+ *
+ * enum {
+ *   DYNAMIC
+ *   FUNCTION
+ *   INTERFACE
+ * }
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+class RuntimeCompletionExpressionTypeKind implements Enum {
+  static const RuntimeCompletionExpressionTypeKind DYNAMIC =
+      const RuntimeCompletionExpressionTypeKind._("DYNAMIC");
+
+  static const RuntimeCompletionExpressionTypeKind FUNCTION =
+      const RuntimeCompletionExpressionTypeKind._("FUNCTION");
+
+  static const RuntimeCompletionExpressionTypeKind INTERFACE =
+      const RuntimeCompletionExpressionTypeKind._("INTERFACE");
+
+  /**
+   * A list containing all of the enum values that are defined.
+   */
+  static const List<RuntimeCompletionExpressionTypeKind> VALUES =
+      const <RuntimeCompletionExpressionTypeKind>[DYNAMIC, FUNCTION, INTERFACE];
+
+  @override
+  final String name;
+
+  const RuntimeCompletionExpressionTypeKind._(this.name);
+
+  factory RuntimeCompletionExpressionTypeKind(String name) {
+    switch (name) {
+      case "DYNAMIC":
+        return DYNAMIC;
+      case "FUNCTION":
+        return FUNCTION;
+      case "INTERFACE":
+        return INTERFACE;
+    }
+    throw new Exception('Illegal enum value: $name');
+  }
+
+  factory RuntimeCompletionExpressionTypeKind.fromJson(
+      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+    if (json is String) {
+      try {
+        return new RuntimeCompletionExpressionTypeKind(json);
+      } catch (_) {
+        // Fall through
+      }
+    }
+    throw jsonDecoder.mismatch(
+        jsonPath, "RuntimeCompletionExpressionTypeKind", json);
+  }
+
+  @override
+  String toString() => "RuntimeCompletionExpressionTypeKind.$name";
+
+  String toJson() => name;
+}
+
+/**
+ * RuntimeCompletionVariable
+ *
+ * {
+ *   "name": String
+ *   "type": RuntimeCompletionExpressionType
+ * }
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+class RuntimeCompletionVariable implements HasToJson {
+  String _name;
+
+  RuntimeCompletionExpressionType _type;
+
+  /**
+   * The name of the variable. The name "this" has a special meaning and is
+   * used as an implicit target for runtime completion, and in explicit "this"
+   * references.
+   */
+  String get name => _name;
+
+  /**
+   * The name of the variable. The name "this" has a special meaning and is
+   * used as an implicit target for runtime completion, and in explicit "this"
+   * references.
+   */
+  void set name(String value) {
+    assert(value != null);
+    this._name = value;
+  }
+
+  /**
+   * The type of the variable.
+   */
+  RuntimeCompletionExpressionType get type => _type;
+
+  /**
+   * The type of the variable.
+   */
+  void set type(RuntimeCompletionExpressionType value) {
+    assert(value != null);
+    this._type = value;
+  }
+
+  RuntimeCompletionVariable(String name, RuntimeCompletionExpressionType type) {
+    this.name = name;
+    this.type = type;
+  }
+
+  factory RuntimeCompletionVariable.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");
+      }
+      RuntimeCompletionExpressionType type;
+      if (json.containsKey("type")) {
+        type = new RuntimeCompletionExpressionType.fromJson(
+            jsonDecoder, jsonPath + ".type", json["type"]);
+      } else {
+        throw jsonDecoder.mismatch(jsonPath, "type");
+      }
+      return new RuntimeCompletionVariable(name, type);
+    } else {
+      throw jsonDecoder.mismatch(jsonPath, "RuntimeCompletionVariable", json);
+    }
+  }
+
+  @override
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> result = {};
+    result["name"] = name;
+    result["type"] = type.toJson();
+    return result;
+  }
+
+  @override
+  String toString() => json.encode(toJson());
+
+  @override
+  bool operator ==(other) {
+    if (other is RuntimeCompletionVariable) {
+      return name == other.name && type == other.type;
+    }
+    return false;
+  }
+
+  @override
+  int get hashCode {
+    int hash = 0;
+    hash = JenkinsSmiHash.combine(hash, name.hashCode);
+    hash = JenkinsSmiHash.combine(hash, type.hashCode);
+    return JenkinsSmiHash.finish(hash);
+  }
+}
+
+/**
  * search.findElementReferences params
  *
  * {
diff --git a/pkg/analysis_server/lib/src/analysis_server.dart b/pkg/analysis_server/lib/src/analysis_server.dart
index 110ad96..92eb394 100644
--- a/pkg/analysis_server/lib/src/analysis_server.dart
+++ b/pkg/analysis_server/lib/src/analysis_server.dart
@@ -108,7 +108,7 @@
    * The version of the analysis server. The value should be replaced
    * automatically during the build.
    */
-  static final String VERSION = '1.20.2';
+  static final String VERSION = '1.20.3';
 
   /**
    * The options of this server instance.
@@ -382,7 +382,7 @@
           sink = io.stdout;
         } else if (name.startsWith('file:')) {
           String path = name.substring('file:'.length);
-          sink = new io.File(path).openWrite(mode: io.FileMode.APPEND);
+          sink = new io.File(path).openWrite(mode: io.FileMode.append);
         }
       }
       _analysisPerformanceLogger = new PerformanceLog(sink);
diff --git a/pkg/analysis_server/lib/src/computer/computer_folding.dart b/pkg/analysis_server/lib/src/computer/computer_folding.dart
index bea49f1..ee82362 100644
--- a/pkg/analysis_server/lib/src/computer/computer_folding.dart
+++ b/pkg/analysis_server/lib/src/computer/computer_folding.dart
@@ -3,7 +3,9 @@
 // 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/source/line_info.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer_plugin/protocol/protocol_common.dart';
 
@@ -23,6 +25,7 @@
    * Returns a list of folding regions, not `null`.
    */
   List<FoldingRegion> compute() {
+    _addFileHeaderRegion();
     _unit.accept(new _DartUnitFoldingComputerVisitor(this));
 
     if (_firstDirective != null &&
@@ -36,6 +39,67 @@
 
     return _foldingRegions;
   }
+
+  void _addFileHeaderRegion() {
+    Token firstToken = _unit.beginToken;
+    while (firstToken?.type == TokenType.SCRIPT_TAG) {
+      firstToken = firstToken.next;
+    }
+
+    final Token firstComment = firstToken?.precedingComments;
+    if (firstComment == null ||
+        firstComment.type != TokenType.SINGLE_LINE_COMMENT) {
+      return;
+    }
+
+    // Walk through the comments looking for a blank line to signal the end of
+    // the file header.
+    Token lastComment = firstComment;
+    while (lastComment.next != null) {
+      lastComment = lastComment.next;
+
+      // If we ran out of tokens, use the original token as starting position.
+      final hasBlankLine =
+          _hasBlankLineBetween(lastComment, lastComment.next ?? firstToken);
+
+      // Also considerd non-single-line-comments as the end
+      final nextCommentIsDifferentType = lastComment.next != null &&
+          lastComment.next.type != TokenType.SINGLE_LINE_COMMENT;
+
+      if (hasBlankLine || nextCommentIsDifferentType) {
+        _addRegion(firstComment.end, lastComment.end, FoldingKind.FILE_HEADER);
+        break;
+      }
+    }
+  }
+
+  _addRegion(int startOffset, int endOffset, FoldingKind kind) {
+    final CharacterLocation start = _lineInfo.getLocation(startOffset);
+    final CharacterLocation end = _lineInfo.getLocation(endOffset);
+
+    if (start.lineNumber != end.lineNumber) {
+      _foldingRegions
+          .add(new FoldingRegion(kind, startOffset, endOffset - startOffset));
+    }
+  }
+
+  _addRegionForAnnotations(List<Annotation> annotations) {
+    if (annotations.isNotEmpty) {
+      _addRegion(annotations.first.name.end, annotations.last.end,
+          FoldingKind.ANNOTATIONS);
+    }
+  }
+
+  bool _hasBlankLineBetween(Token first, Token second) {
+    final CharacterLocation firstLoc = _lineInfo.getLocation(first.end);
+    final CharacterLocation secondLoc = _lineInfo.getLocation(second.offset);
+    return secondLoc.lineNumber - firstLoc.lineNumber > 1;
+  }
+
+  _recordDirective(Directive node) {
+    _firstDirective ??= node;
+    _lastDirective = node;
+  }
 }
 
 /**
@@ -47,88 +111,79 @@
 
   @override
   Object visitBlockFunctionBody(BlockFunctionBody node) {
-    final FoldingKind kind = node.parent is ConstructorDeclaration ||
-            node.parent is MethodDeclaration
-        ? FoldingKind.CLASS_MEMBER
-        : FoldingKind.TOP_LEVEL_DECLARATION;
-    _addRegion(
-        node.block.leftBracket.end, node.block.rightBracket.offset, kind);
+    _computer._addRegion(node.block.leftBracket.end,
+        node.block.rightBracket.offset, FoldingKind.FUNCTION_BODY);
     return super.visitBlockFunctionBody(node);
   }
 
   @override
   Object visitClassDeclaration(ClassDeclaration node) {
-    _addRegion(node.leftBracket.end, node.rightBracket.offset,
-        FoldingKind.TOP_LEVEL_DECLARATION);
+    _computer._addRegionForAnnotations(node.metadata);
+    _computer._addRegion(
+        node.leftBracket.end, node.rightBracket.offset, FoldingKind.CLASS_BODY);
     return super.visitClassDeclaration(node);
   }
 
   @override
-  Object visitAnnotation(Annotation node) {
-    if (node.arguments != null &&
-        node.arguments.leftParenthesis != null &&
-        node.arguments.rightParenthesis != null) {
-      _addRegion(
-          node.arguments.leftParenthesis.end,
-          node.arguments.rightParenthesis.offset,
-          FoldingKind.TOP_LEVEL_DECLARATION);
-    }
-    return super.visitAnnotation(node);
-  }
-
-  @override
   Object visitComment(Comment node) {
-    final FoldingKind kind = node.isDocumentation
-        ? FoldingKind.DOCUMENTATION_COMMENT
-        : FoldingKind.COMMENT;
-    _addRegion(node.offset, node.end, kind);
+    if (node.isDocumentation) {
+      _computer._addRegion(
+          node.offset, node.end, FoldingKind.DOCUMENTATION_COMMENT);
+    }
     return super.visitComment(node);
   }
 
   @override
+  Object visitConstructorDeclaration(ConstructorDeclaration node) {
+    _computer._addRegionForAnnotations(node.metadata);
+    return super.visitConstructorDeclaration(node);
+  }
+
+  @override
   Object visitExportDirective(ExportDirective node) {
-    _recordDirective(node);
+    _computer._recordDirective(node);
     return super.visitExportDirective(node);
   }
 
   @override
+  Object visitFieldDeclaration(FieldDeclaration node) {
+    _computer._addRegionForAnnotations(node.metadata);
+    return super.visitFieldDeclaration(node);
+  }
+
+  @override
+  Object visitFunctionDeclaration(FunctionDeclaration node) {
+    _computer._addRegionForAnnotations(node.metadata);
+    return super.visitFunctionDeclaration(node);
+  }
+
+  @override
   visitImportDirective(ImportDirective node) {
-    _recordDirective(node);
+    _computer._recordDirective(node);
     return super.visitImportDirective(node);
   }
 
   @override
   Object visitLibraryDirective(LibraryDirective node) {
-    _recordDirective(node);
+    _computer._recordDirective(node);
     return super.visitLibraryDirective(node);
   }
 
   @override
+  Object visitMethodDeclaration(MethodDeclaration node) {
+    _computer._addRegionForAnnotations(node.metadata);
+    return super.visitMethodDeclaration(node);
+  }
+
+  @override
   Object visitPartDirective(PartDirective node) {
-    _recordDirective(node);
+    _computer._recordDirective(node);
     return super.visitPartDirective(node);
   }
 
   @override
   Object visitPartOfDirective(PartOfDirective node) {
-    _recordDirective(node);
+    _computer._recordDirective(node);
     return super.visitPartOfDirective(node);
   }
-
-  _addRegion(int startOffset, int endOffset, FoldingKind kind) {
-    // TODO(dantup): This class is marked deprecated; find out what to change it to.
-    final LineInfo_Location start =
-        _computer._lineInfo.getLocation(startOffset);
-    final LineInfo_Location end = _computer._lineInfo.getLocation(endOffset);
-
-    if (start.lineNumber != end.lineNumber) {
-      _computer._foldingRegions
-          .add(new FoldingRegion(kind, startOffset, endOffset - startOffset));
-    }
-  }
-
-  _recordDirective(Directive node) {
-    _computer._firstDirective ??= node;
-    _computer._lastDirective = node;
-  }
 }
diff --git a/pkg/analysis_server/lib/src/domain_completion.dart b/pkg/analysis_server/lib/src/domain_completion.dart
index 5e9f2a6..97d4ec5 100644
--- a/pkg/analysis_server/lib/src/domain_completion.dart
+++ b/pkg/analysis_server/lib/src/domain_completion.dart
@@ -16,7 +16,6 @@
 import 'package:analysis_server/src/services/completion/completion_performance.dart';
 import 'package:analysis_server/src/services/completion/dart/completion_manager.dart';
 import 'package:analyzer/src/dart/analysis/driver.dart';
-import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer_plugin/protocol/protocol.dart' as plugin;
 import 'package:analyzer_plugin/protocol/protocol_common.dart';
 import 'package:analyzer_plugin/protocol/protocol_constants.dart' as plugin;
@@ -176,7 +175,6 @@
     int offset = params.offset;
 
     AnalysisResult result = await server.getAnalysisResult(filePath);
-    Source source;
 
     if (result == null || !result.exists) {
       if (server.onNoAnalysisCompletion != null) {
@@ -185,7 +183,6 @@
             request, this, params, performance, completionId);
         return;
       }
-      source = server.resourceProvider.getFile(filePath).createSource();
     } else {
       if (offset < 0 || offset > result.content.length) {
         server.sendResponse(new Response.invalidParameter(
@@ -195,13 +192,11 @@
             ' but found $offset'));
         return;
       }
-      source =
-          server.resourceProvider.getFile(result.path).createSource(result.uri);
 
-      recordRequest(performance, source, result.content, offset);
+      recordRequest(performance, filePath, result.content, offset);
     }
-    CompletionRequestImpl completionRequest = new CompletionRequestImpl(
-        result, server.resourceProvider, source, offset, performance);
+    CompletionRequestImpl completionRequest =
+        new CompletionRequestImpl(result, offset, performance);
 
     String completionId = (_nextCompletionId++).toString();
 
@@ -233,10 +228,10 @@
    * If tracking code completion performance over time, then
    * record addition information about the request in the performance record.
    */
-  void recordRequest(CompletionPerformance performance, Source source,
+  void recordRequest(CompletionPerformance performance, String path,
       String content, int offset) {
-    performance.source = source;
-    if (performanceListMaxLength == 0 || source == null) {
+    performance.path = path;
+    if (performanceListMaxLength == 0) {
       return;
     }
     performance.setContentsAndOffset(content, offset);
diff --git a/pkg/analysis_server/lib/src/domain_execution.dart b/pkg/analysis_server/lib/src/domain_execution.dart
index ea17e60..16c23fb 100644
--- a/pkg/analysis_server/lib/src/domain_execution.dart
+++ b/pkg/analysis_server/lib/src/domain_execution.dart
@@ -2,7 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-import 'dart:async';
 import 'dart:collection';
 import 'dart:core';
 
@@ -10,6 +9,7 @@
 import 'package:analysis_server/protocol/protocol_constants.dart';
 import 'package:analysis_server/protocol/protocol_generated.dart';
 import 'package:analysis_server/src/analysis_server.dart';
+import 'package:analysis_server/src/domains/execution/completion.dart';
 import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/src/dart/analysis/driver.dart';
 import 'package:analyzer/src/generated/source.dart';
@@ -32,13 +32,7 @@
   /**
    * A table mapping execution context id's to the root of the context.
    */
-  Map<String, String> contextMap = new HashMap<String, String>();
-
-  /**
-   * The subscription to the 'onAnalysisComplete' events,
-   * used to send notifications when
-   */
-  StreamSubscription onFileAnalyzed;
+  final Map<String, String> contextMap = new HashMap<String, String>();
 
   /**
    * Initialize a newly created handler to handle requests for the given [server].
@@ -65,6 +59,30 @@
     return new ExecutionDeleteContextResult().toResponse(request.id);
   }
 
+  /**
+   * Implement the 'execution.getSuggestions' request.
+   */
+  void getSuggestions(Request request) async {
+    var params = new ExecutionGetSuggestionsParams.fromRequest(request);
+    var computer = new RuntimeCompletionComputer(
+        server.resourceProvider,
+        server.fileContentOverlay,
+        server.getAnalysisDriver(params.contextFile),
+        params.code,
+        params.offset,
+        params.contextFile,
+        params.contextOffset,
+        params.variables,
+        params.expressions);
+    RuntimeCompletionResult completionResult = await computer.compute();
+
+    // Send the response.
+    var result = new ExecutionGetSuggestionsResult(
+        suggestions: completionResult.suggestions,
+        expressions: completionResult.expressions);
+    server.sendResponse(result.toResponse(request.id));
+  }
+
   @override
   Response handleRequest(Request request) {
     try {
@@ -73,6 +91,9 @@
         return createContext(request);
       } else if (requestName == EXECUTION_REQUEST_DELETE_CONTEXT) {
         return deleteContext(request);
+      } else if (requestName == EXECUTION_REQUEST_GET_SUGGESTIONS) {
+        getSuggestions(request);
+        return Response.DELAYED_RESPONSE;
       } else if (requestName == EXECUTION_REQUEST_MAP_URI) {
         return mapUri(request);
       } else if (requestName == EXECUTION_REQUEST_SET_SUBSCRIPTIONS) {
diff --git a/pkg/analysis_server/lib/src/domains/execution/completion.dart b/pkg/analysis_server/lib/src/domains/execution/completion.dart
new file mode 100644
index 0000000..9a4e0b3
--- /dev/null
+++ b/pkg/analysis_server/lib/src/domains/execution/completion.dart
@@ -0,0 +1,116 @@
+// 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:analysis_server/src/protocol_server.dart'
+    show
+        CompletionSuggestion,
+        RuntimeCompletionExpression,
+        RuntimeCompletionVariable,
+        SourceEdit;
+import 'package:analysis_server/src/provisional/completion/completion_core.dart';
+import 'package:analysis_server/src/services/completion/completion_core.dart';
+import 'package:analysis_server/src/services/completion/completion_performance.dart';
+import 'package:analysis_server/src/services/completion/dart/completion_manager.dart';
+import 'package:analyzer/file_system/file_system.dart';
+import 'package:analyzer/src/dart/analysis/driver.dart';
+import 'package:analyzer/src/dart/analysis/file_state.dart';
+import 'package:analyzer_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 AnalysisDriver analysisDriver;
+
+  final String code;
+  final int offset;
+
+  final String contextFile;
+  final int contextOffset;
+
+  final List<RuntimeCompletionVariable> variables;
+  final List<RuntimeCompletionExpression> expressions;
+
+  RuntimeCompletionComputer(
+      this.resourceProvider,
+      this.fileContentOverlay,
+      this.analysisDriver,
+      this.code,
+      this.offset,
+      this.contextFile,
+      this.contextOffset,
+      this.variables,
+      this.expressions);
+
+  Future<RuntimeCompletionResult> compute() async {
+    var contextResult = await analysisDriver.getResult(contextFile);
+    var session = contextResult.session;
+
+    const codeMarker = '__code_\_';
+
+    // Insert the code being completed at the context offset.
+    var changeBuilder = new DartChangeBuilder(session);
+    int nextImportPrefixIndex = 0;
+    await changeBuilder.addFileEdit(contextFile, (builder) {
+      builder.addInsertion(contextOffset, (builder) {
+        builder.writeln('{');
+
+        // TODO(scheglov) Use variables.
+
+        builder.write(codeMarker);
+        builder.writeln(';');
+
+        builder.writeln('}');
+      });
+    }, importPrefixGenerator: (uri) => '__prefix${nextImportPrefixIndex++}');
+
+    // Compute the patched context file content.
+    String targetCode = SourceEdit.applySequence(
+      contextResult.content,
+      changeBuilder.sourceChange.edits[0].edits,
+    );
+
+    // Insert the code being completed.
+    int targetOffset = targetCode.indexOf(codeMarker) + offset;
+    targetCode = targetCode.replaceAll(codeMarker, code);
+
+    // Update the context file content to include the code being completed.
+    // Then resolve it, and restore the file to its initial state.
+    AnalysisResult targetResult;
+    String contentFileOverlay = fileContentOverlay[contextFile];
+    try {
+      fileContentOverlay[contextFile] = targetCode;
+      analysisDriver.changeFile(contextFile);
+      targetResult = await analysisDriver.getResult(contextFile);
+    } finally {
+      fileContentOverlay[contextFile] = contentFileOverlay;
+      analysisDriver.changeFile(contextFile);
+    }
+
+    CompletionContributor contributor = new DartCompletionManager();
+    CompletionRequestImpl request = new CompletionRequestImpl(
+      targetResult,
+      targetOffset,
+      new CompletionPerformance(),
+    );
+    var suggestions = await contributor.computeSuggestions(request);
+
+    // Remove completions with synthetic import prefixes.
+    suggestions.removeWhere((s) => s.completion.startsWith('__prefix'));
+
+    // TODO(scheglov) Add support for expressions.
+    var expressions = <RuntimeCompletionExpression>[];
+    return new RuntimeCompletionResult(expressions, suggestions);
+  }
+}
+
+/// The result of performing runtime completion.
+class RuntimeCompletionResult {
+  final List<RuntimeCompletionExpression> expressions;
+  final List<CompletionSuggestion> suggestions;
+
+  RuntimeCompletionResult(this.expressions, this.suggestions);
+}
diff --git a/pkg/analysis_server/lib/src/plugin/notification_manager.dart b/pkg/analysis_server/lib/src/plugin/notification_manager.dart
index 9aad4d5..344697c 100644
--- a/pkg/analysis_server/lib/src/plugin/notification_manager.dart
+++ b/pkg/analysis_server/lib/src/plugin/notification_manager.dart
@@ -86,12 +86,12 @@
   /**
    * The object used to convert results.
    */
-  ResultConverter converter = new ResultConverter();
+  final ResultConverter converter = new ResultConverter();
 
   /**
    * The object used to merge results.
    */
-  ResultMerger merger = new ResultMerger();
+  final ResultMerger merger = new ResultMerger();
 
   /**
    * Initialize a newly created notification manager.
diff --git a/pkg/analysis_server/lib/src/search/element_references.dart b/pkg/analysis_server/lib/src/search/element_references.dart
index 4b53584..fc60fb9 100644
--- a/pkg/analysis_server/lib/src/search/element_references.dart
+++ b/pkg/analysis_server/lib/src/search/element_references.dart
@@ -68,12 +68,15 @@
   /**
    * Returns a [Future] completing with [Element]s to search references to.
    *
-   * If a [ClassMemberElement] is given, each corresponding [Element] in the
-   * hierarchy is returned.
+   * If a [ClassMemberElement] or a named [ParameterElement] is given, each
+   * corresponding [Element] in the hierarchy is returned.
    *
    * Otherwise, only references to [element] should be searched.
    */
   Future<Iterable<Element>> _getRefElements(Element element) {
+    if (element is ParameterElement && element.isNamed) {
+      return getHierarchyNamedParameters(searchEngine, element);
+    }
     if (element is ClassMemberElement) {
       return getHierarchyMembers(searchEngine, element);
     }
diff --git a/pkg/analysis_server/lib/src/server/http_server.dart b/pkg/analysis_server/lib/src/server/http_server.dart
index 131d00a..bcbf428 100644
--- a/pkg/analysis_server/lib/src/server/http_server.dart
+++ b/pkg/analysis_server/lib/src/server/http_server.dart
@@ -107,7 +107,7 @@
 
     try {
       _serverFuture =
-          HttpServer.bind(InternetAddress.LOOPBACK_IP_V4, initialPort ?? 0);
+          HttpServer.bind(InternetAddress.loopbackIPv4, initialPort ?? 0);
 
       HttpServer server = await _serverFuture;
       _handleServer(server);
diff --git a/pkg/analysis_server/lib/src/services/completion/completion_core.dart b/pkg/analysis_server/lib/src/services/completion/completion_core.dart
index 9d15c20..7000f0b 100644
--- a/pkg/analysis_server/lib/src/services/completion/completion_core.dart
+++ b/pkg/analysis_server/lib/src/services/completion/completion_core.dart
@@ -16,9 +16,6 @@
   final AnalysisResult result;
 
   @override
-  final Source source;
-
-  @override
   final int offset;
 
   /**
@@ -39,9 +36,6 @@
    */
   int replacementLength;
 
-  @override
-  final ResourceProvider resourceProvider;
-
   bool _aborted = false;
 
   final CompletionPerformance performance;
@@ -49,14 +43,18 @@
   /**
    * Initialize a newly created completion request based on the given arguments.
    */
-  CompletionRequestImpl(this.result, this.resourceProvider, Source source,
-      int offset, this.performance)
-      : this.source = source,
-        this.offset = offset,
+  CompletionRequestImpl(this.result, int offset, this.performance)
+      : this.offset = offset,
         replacementOffset = offset,
         replacementLength = 0;
 
   @override
+  ResourceProvider get resourceProvider => result.session.resourceProvider;
+
+  @override
+  Source get source => result.unit.element.source;
+
+  @override
   String get sourceContents => result?.content;
 
   /**
diff --git a/pkg/analysis_server/lib/src/services/completion/completion_performance.dart b/pkg/analysis_server/lib/src/services/completion/completion_performance.dart
index fab1435..24b952f 100644
--- a/pkg/analysis_server/lib/src/services/completion/completion_performance.dart
+++ b/pkg/analysis_server/lib/src/services/completion/completion_performance.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 'package:analyzer/src/generated/source.dart';
-
 /**
  * Overall performance of a code completion operation.
  */
@@ -13,7 +11,7 @@
   final Stopwatch _stopwatch = new Stopwatch();
   final List<OperationPerformance> operations = <OperationPerformance>[];
 
-  Source source;
+  String path;
   String snippet = '';
   int notificationCount = -1;
   int suggestionCountFirst = -1;
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 e37be19..1291f78 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
@@ -22,7 +22,7 @@
   if (node is ArgumentList) {
     if (request.target.entity == node.rightParenthesis) {
       // Parser ignores trailing commas
-      if (node.rightParenthesis.previous?.lexeme == ',') {
+      if (node.findPrevious(node.rightParenthesis)?.lexeme == ',') {
         return node.arguments.length + 1;
       }
     }
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 351c240..22062cc5 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
@@ -57,7 +57,7 @@
   Future<List<CompletionSuggestion>> computeSuggestions(
       CompletionRequest request) async {
     request.checkAborted();
-    if (!AnalysisEngine.isDartFileName(request.source.shortName)) {
+    if (!AnalysisEngine.isDartFileName(request.result.path)) {
       return EMPTY_LIST;
     }
 
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/static_member_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/static_member_contributor.dart
index 8239f37..593de24 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/static_member_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/static_member_contributor.dart
@@ -68,6 +68,13 @@
   }
 
   @override
+  visitConstructorElement(ConstructorElement element) {
+    if (element.context.analysisOptions.previewDart2) {
+      _addSuggestion(element);
+    }
+  }
+
+  @override
   visitFieldElement(FieldElement element) {
     if (element.isStatic) {
       _addSuggestion(element);
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/utilities.dart b/pkg/analysis_server/lib/src/services/completion/dart/utilities.dart
index cfd7cf4..9c5afa7 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/utilities.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/utilities.dart
@@ -98,7 +98,7 @@
   return new protocol.Element(kind, name, flags,
       location: location,
       parameters: parameters,
-      returnType: nameForType(returnType));
+      returnType: nameForType(id, returnType));
 }
 
 /**
@@ -141,7 +141,7 @@
       0,
       isDeprecated,
       false,
-      returnType: nameForType(returnType),
+      returnType: nameForType(id, returnType),
       element: element);
   if (classDecl != null) {
     SimpleIdentifier classId = classDecl.name;
@@ -204,33 +204,45 @@
 }
 
 /**
- * Return the name for the given [type].
+ * Return name of the type of the given [identifier], or, if it unresolved, the
+ * name of its declared [declaredType].
  */
-String nameForType(TypeAnnotation type) {
-  if (type == NO_RETURN_TYPE) {
+String nameForType(SimpleIdentifier identifier, TypeAnnotation declaredType) {
+  if (identifier == null) {
     return null;
   }
+
+  // Get the type from the identifier element.
+  DartType type;
+  Element element = identifier.staticElement;
+  if (element == null) {
+    return DYNAMIC;
+  } else if (element is FunctionTypedElement) {
+    if (element is PropertyAccessorElement && element.isSetter) {
+      return null;
+    }
+    type = element.returnType;
+  } else if (element is VariableElement) {
+    type = identifier.bestType;
+  } else {
+    return null;
+  }
+
+  // If the type is unresolved, use the declared type.
+  if (type != null && type.isUndefined) {
+    if (declaredType is TypeName) {
+      Identifier id = declaredType.name;
+      if (id != null) {
+        return id.name;
+      }
+    }
+    return DYNAMIC;
+  }
+
   if (type == null) {
     return DYNAMIC;
   }
-  if (type is TypeName) {
-    Identifier id = type.name;
-    if (id == null) {
-      return DYNAMIC;
-    }
-    String name = id.name;
-    if (name == null || name.length <= 0) {
-      return DYNAMIC;
-    }
-    TypeArgumentList typeArgs = type.typeArguments;
-    if (typeArgs != null) {
-      //TODO (danrubel) include type arguments
-    }
-    return name;
-  } else if (type is GenericFunctionType) {
-    // TODO(brianwilkerson) Implement this.
-  }
-  return DYNAMIC;
+  return type.toString();
 }
 
 //TODO(pq): fix to use getDefaultStringParameterValue()
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 d9ae917..19c6a82 100644
--- a/pkg/analysis_server/lib/src/services/correction/assist_internal.dart
+++ b/pkg/analysis_server/lib/src/services/correction/assist_internal.dart
@@ -1578,71 +1578,41 @@
   }
 
   Future<Null> _addProposal_flutterSwapWithChild() async {
-    InstanceCreationExpression exprGoingDown =
-        flutter.identifyNewExpression(node);
-    if (exprGoingDown == null || !flutter.isWidgetCreation(exprGoingDown)) {
+    InstanceCreationExpression parent = flutter.identifyNewExpression(node);
+    if (!flutter.isWidgetCreation(parent)) {
       _coverageMarker();
       return;
     }
-    InstanceCreationExpression exprGoingUp =
-        flutter.findChildWidget(exprGoingDown);
-    if (exprGoingUp == null) {
+
+    NamedExpression childArgument = flutter.findChildArgument(parent);
+    if (childArgument?.expression is! InstanceCreationExpression ||
+        !flutter.isWidgetCreation(childArgument.expression)) {
       _coverageMarker();
       return;
     }
-    NamedExpression stableChild = flutter.findChildArgument(exprGoingUp);
-    if (stableChild == null || stableChild.expression == null) {
-      _coverageMarker();
-      return;
-    }
-    String exprGoingDownSrc = utils.getNodeText(exprGoingDown);
-    int dnNewlineIdx = exprGoingDownSrc.lastIndexOf(eol);
-    if (dnNewlineIdx < 0 || dnNewlineIdx == exprGoingDownSrc.length - 1) {
-      _coverageMarker();
-      return; // Outer new-expr needs to be in multi-line format already.
-    }
-    String exprGoingUpSrc = utils.getNodeText(exprGoingUp);
-    int upNewlineIdx = exprGoingUpSrc.lastIndexOf(eol);
-    if (upNewlineIdx < 0 || upNewlineIdx == exprGoingUpSrc.length - 1) {
-      _coverageMarker();
-      return; // Inner new-expr needs to be in multi-line format already.
-    }
-    await _swapFlutterWidgets(exprGoingDown, exprGoingUp, stableChild,
-        DartAssistKind.FLUTTER_SWAP_WITH_CHILD);
+    InstanceCreationExpression child = childArgument.expression;
+
+    await _swapParentAndChild(
+        parent, child, DartAssistKind.FLUTTER_SWAP_WITH_CHILD);
   }
 
   Future<Null> _addProposal_flutterSwapWithParent() async {
-    InstanceCreationExpression exprGoingUp =
-        flutter.identifyNewExpression(node);
-    if (exprGoingUp == null || !flutter.isWidgetCreation(exprGoingUp)) {
+    InstanceCreationExpression child = flutter.identifyNewExpression(node);
+    if (!flutter.isWidgetCreation(child)) {
       _coverageMarker();
       return;
     }
-    AstNode expr = exprGoingUp.parent?.parent?.parent;
-    if (expr == null || expr is! InstanceCreationExpression) {
+
+    // NamedExpression (child:), ArgumentList, InstanceCreationExpression
+    AstNode expr = child.parent?.parent?.parent;
+    if (expr is! InstanceCreationExpression) {
       _coverageMarker();
       return;
     }
-    InstanceCreationExpression exprGoingDown = expr;
-    NamedExpression stableChild = flutter.findChildArgument(exprGoingUp);
-    if (stableChild == null || stableChild.expression == null) {
-      _coverageMarker();
-      return;
-    }
-    String exprGoingUpSrc = utils.getNodeText(exprGoingUp);
-    int upNewlineIdx = exprGoingUpSrc.lastIndexOf(eol);
-    if (upNewlineIdx < 0 || upNewlineIdx == exprGoingUpSrc.length - 1) {
-      _coverageMarker();
-      return; // Inner new-expr needs to be in multi-line format already.
-    }
-    String exprGoingDownSrc = utils.getNodeText(exprGoingDown);
-    int dnNewlineIdx = exprGoingDownSrc.lastIndexOf(eol);
-    if (dnNewlineIdx < 0 || dnNewlineIdx == exprGoingDownSrc.length - 1) {
-      _coverageMarker();
-      return; // Outer new-expr needs to be in multi-line format already.
-    }
-    await _swapFlutterWidgets(exprGoingDown, exprGoingUp, stableChild,
-        DartAssistKind.FLUTTER_SWAP_WITH_PARENT);
+    InstanceCreationExpression parent = expr;
+
+    await _swapParentAndChild(
+        parent, child, DartAssistKind.FLUTTER_SWAP_WITH_PARENT);
   }
 
   Future<Null> _addProposal_flutterWrapWidget() async {
@@ -1694,7 +1664,9 @@
     DartChangeBuilder changeBuilder = new DartChangeBuilder(session);
     await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
       builder.addReplacement(range.node(widgetExpr), (DartEditBuilder builder) {
-        builder.write('new ');
+        if (!driver.analysisOptions.previewDart2) {
+          builder.write('new ');
+        }
         if (parentClassElement == null) {
           builder.addSimpleLinkedEdit('WIDGET', 'widget');
         } else {
@@ -1773,7 +1745,9 @@
       DartChangeBuilder changeBuilder = new DartChangeBuilder(session);
       await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
         builder.addReplacement(selectedRange, (DartEditBuilder builder) {
-          builder.write('new ');
+          if (!driver.analysisOptions.previewDart2) {
+            builder.write('new ');
+          }
           builder.writeType(parentClassElement.type);
           builder.write('(');
 
@@ -2085,7 +2059,8 @@
     if (node is SimpleIdentifier &&
         node.parent is AssignmentExpression &&
         (node.parent as AssignmentExpression).leftHandSide == node &&
-        node.parent.parent is ExpressionStatement) {} else {
+        node.parent.parent is ExpressionStatement) {
+    } else {
       _coverageMarker();
       return;
     }
@@ -2107,7 +2082,8 @@
         declNode.parent is VariableDeclaration &&
         (declNode.parent as VariableDeclaration).name == declNode &&
         declNode.parent.parent is VariableDeclarationList &&
-        declNode.parent.parent.parent is VariableDeclarationStatement) {} else {
+        declNode.parent.parent.parent is VariableDeclarationStatement) {
+    } else {
       _coverageMarker();
       return;
     }
@@ -2129,7 +2105,8 @@
     ExpressionStatement assignStatement =
         node.parent.parent as ExpressionStatement;
     if (assignStatement.parent is Block &&
-        assignStatement.parent == declStatement.parent) {} else {
+        assignStatement.parent == declStatement.parent) {
+    } else {
       _coverageMarker();
       return;
     }
@@ -2137,7 +2114,8 @@
     // check that "declaration" and "assignment" statements are adjacent
     List<Statement> statements = block.statements;
     if (statements.indexOf(assignStatement) ==
-        statements.indexOf(declStatement) + 1) {} else {
+        statements.indexOf(declStatement) + 1) {
+    } else {
       _coverageMarker();
       return;
     }
@@ -2155,7 +2133,8 @@
     // prepare enclosing VariableDeclarationList
     VariableDeclarationList declList =
         node.getAncestor((node) => node is VariableDeclarationList);
-    if (declList != null && declList.variables.length == 1) {} else {
+    if (declList != null && declList.variables.length == 1) {
+    } else {
       _coverageMarker();
       return;
     }
@@ -2167,7 +2146,8 @@
     }
     // prepare VariableDeclarationStatement in Block
     if (declList.parent is VariableDeclarationStatement &&
-        declList.parent.parent is Block) {} else {
+        declList.parent.parent is Block) {
+    } else {
       _coverageMarker();
       return;
     }
@@ -2180,20 +2160,23 @@
     {
       // declaration should not be last Statement
       int declIndex = statements.indexOf(declStatement);
-      if (declIndex < statements.length - 1) {} else {
+      if (declIndex < statements.length - 1) {
+      } else {
         _coverageMarker();
         return;
       }
       // next Statement should be assignment
       Statement assignStatement = statements[declIndex + 1];
-      if (assignStatement is ExpressionStatement) {} else {
+      if (assignStatement is ExpressionStatement) {
+      } else {
         _coverageMarker();
         return;
       }
       ExpressionStatement expressionStatement =
           assignStatement as ExpressionStatement;
       // expression should be assignment
-      if (expressionStatement.expression is AssignmentExpression) {} else {
+      if (expressionStatement.expression is AssignmentExpression) {
+      } else {
         _coverageMarker();
         return;
       }
@@ -2570,7 +2553,8 @@
     // prepare DartVariableStatement, should be part of Block
     VariableDeclarationStatement statement =
         node.getAncestor((node) => node is VariableDeclarationStatement);
-    if (statement != null && statement.parent is Block) {} else {
+    if (statement != null && statement.parent is Block) {
+    } else {
       _coverageMarker();
       return;
     }
@@ -3011,87 +2995,84 @@
     return utils.getRangeText(range);
   }
 
-  Future<Null> _swapFlutterWidgets(
-      InstanceCreationExpression exprGoingDown,
-      InstanceCreationExpression exprGoingUp,
-      NamedExpression stableChild,
-      AssistKind assistKind) async {
-    String currentSource = unitElement.context.getContents(source).data;
-    // TODO(messick) Find a better way to get LineInfo for the source.
-    LineInfo lineInfo = new LineInfo.fromContent(currentSource);
-    int currLn = lineInfo.getLocation(exprGoingUp.offset).lineNumber;
-    int lnOffset = lineInfo.getOffsetOfLine(currLn);
+  Future<void> _swapParentAndChild(InstanceCreationExpression parent,
+      InstanceCreationExpression child, AssistKind kind) async {
+    // The child must have its own child.
+    if (flutter.findChildArgument(child) == null) {
+      _coverageMarker();
+      return;
+    }
 
-    DartChangeBuilder changeBuilder = new DartChangeBuilder(session);
-    await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
-      builder.addReplacement(range.node(exprGoingDown),
-          (DartEditBuilder builder) {
-        String argSrc =
-            utils.getText(exprGoingUp.offset, lnOffset - exprGoingUp.offset);
-        builder.write(argSrc); // Append child new-expr plus rest of line.
+    var changeBuilder = new DartChangeBuilder(session);
+    await changeBuilder.addFileEdit(file, (builder) {
+      builder.addReplacement(range.node(parent), (builder) {
+        var childArgs = child.argumentList;
+        var parentArgs = parent.argumentList;
+        var childText = _getRangeText(range.startStart(child, childArgs));
+        var parentText = _getRangeText(range.startStart(parent, parentArgs));
 
-        String getSrc(Expression expr) {
-          int startLn = lineInfo.getLocation(expr.offset).lineNumber;
-          int startOffset = lineInfo.getOffsetOfLine(startLn - 1);
-          int endLn =
-              lineInfo.getLocation(expr.offset + expr.length).lineNumber + 1;
-          int curOffset = lineInfo.getOffsetOfLine(endLn - 1);
-          return utils.getText(startOffset, curOffset - startOffset);
+        var parentIndent = utils.getLinePrefix(parent.offset);
+        var childIndent = parentIndent + '  ';
+
+        // Write the beginning of the child.
+        builder.write(childText);
+        builder.writeln('(');
+
+        // Write all the arguments of the parent.
+        // Don't write the "child".
+        Expression stableChild;
+        for (Expression argument in childArgs.arguments) {
+          if (flutter.isChildArgument(argument)) {
+            stableChild = argument;
+          } else {
+            String text = _getNodeText(argument);
+            text = _replaceSourceIndent(text, childIndent, parentIndent);
+            builder.write(parentIndent);
+            builder.write('  ');
+            builder.write(text);
+            builder.writeln(',');
+          }
         }
 
-        String outerIndent = utils.getLinePrefix(exprGoingDown.offset);
-        String innerIndent = utils.getLinePrefix(exprGoingUp.offset);
-        exprGoingUp.argumentList.arguments.forEach((arg) {
-          if (arg is NamedExpression && arg.name.label.name == 'child') {
-            if (stableChild != arg) {
-              _coverageMarker();
-              return;
-            }
-            // Insert exprGoingDown here.
-            // Copy from start of line to offset of exprGoingDown.
-            currLn = lineInfo.getLocation(stableChild.offset).lineNumber;
-            lnOffset = lineInfo.getOffsetOfLine(currLn - 1);
-            argSrc = utils.getText(
-                lnOffset, stableChild.expression.offset - lnOffset);
-            argSrc = _replaceSourceIndent(argSrc, innerIndent, outerIndent);
-            builder.write(argSrc);
-            int nextLn = lineInfo.getLocation(exprGoingDown.offset).lineNumber;
-            lnOffset = lineInfo.getOffsetOfLine(nextLn);
-            argSrc = utils.getText(
-                exprGoingDown.offset, lnOffset - exprGoingDown.offset);
-            builder.write(argSrc);
+        // Write the parent as a new child.
+        builder.write(parentIndent);
+        builder.write('  ');
+        builder.write('child: ');
+        builder.write(parentText);
+        builder.writeln('(');
 
-            exprGoingDown.argumentList.arguments.forEach((val) {
-              if (val is NamedExpression && val.name.label.name == 'child') {
-                // Insert stableChild here at same indent level.
-                builder.write(utils.getNodePrefix(arg.name));
-                argSrc = utils.getNodeText(stableChild);
-                builder.write(argSrc);
-                if (assistKind == DartAssistKind.FLUTTER_SWAP_WITH_PARENT) {
-                  builder.write(',$eol');
-                }
-              } else {
-                argSrc = getSrc(val);
-                argSrc = _replaceSourceIndent(argSrc, outerIndent, innerIndent);
-                builder.write(argSrc);
-              }
-            });
-            if (assistKind == DartAssistKind.FLUTTER_SWAP_WITH_CHILD) {
-              builder.write(',$eol');
-            }
-            builder.write(innerIndent);
-            builder.write('),$eol');
-          } else {
-            argSrc = getSrc(arg);
-            argSrc = _replaceSourceIndent(argSrc, innerIndent, outerIndent);
-            builder.write(argSrc);
+        // Write all arguments of the parent.
+        // Don't write its child.
+        for (Expression argument in parentArgs.arguments) {
+          if (!flutter.isChildArgument(argument)) {
+            String text = _getNodeText(argument);
+            text = _replaceSourceIndent(text, parentIndent, childIndent);
+            builder.write(childIndent);
+            builder.write('  ');
+            builder.write(text);
+            builder.writeln(',');
           }
-        });
-        builder.write(outerIndent);
+        }
+
+        // Write the child of the "child" now, as the child of the "parent".
+        {
+          var text = _getNodeText(stableChild);
+          builder.write(childIndent);
+          builder.write('  ');
+          builder.write(text);
+          builder.writeln(',');
+        }
+
+        // Close the parent expression.
+        builder.write(childIndent);
+        builder.writeln('),');
+
+        // Close the child expression.
+        builder.write(parentIndent);
         builder.write(')');
       });
     });
-    _addAssistFromBuilder(changeBuilder, assistKind);
+    _addAssistFromBuilder(changeBuilder, kind);
   }
 
   /**
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 a97741f..3df2168 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
@@ -403,6 +403,7 @@
     if (errorCode == HintCode.UNDEFINED_METHOD ||
         errorCode == StaticTypeWarningCode.UNDEFINED_METHOD) {
       await _addFix_importLibrary_withFunction();
+      await _addFix_importLibrary_withType();
       await _addFix_undefinedMethod_useSimilar();
       await _addFix_undefinedMethod_create();
       await _addFix_undefinedFunction_create();
@@ -1954,13 +1955,13 @@
     _addFixFromBuilder(changeBuilder, DartFixKind.REPLACE_RETURN_TYPE_FUTURE);
   }
 
-  Future<Null> _addFix_importLibrary(FixKind kind, Source library) async {
-    String libraryUri = getLibrarySourceUri(unitLibraryElement, library);
+  Future<Null> _addFix_importLibrary(FixKind kind, Uri library) async {
+    String uriText;
     DartChangeBuilder changeBuilder = new DartChangeBuilder(session);
     await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
-      builder.importLibraries([library]);
+      uriText = builder.importLibrary(library);
     });
-    _addFixFromBuilder(changeBuilder, kind, args: [libraryUri]);
+    _addFixFromBuilder(changeBuilder, kind, args: [uriText]);
   }
 
   Future<Null> _addFix_importLibrary_withElement(String name,
@@ -2060,7 +2061,7 @@
           fixKind = DartFixKind.IMPORT_LIBRARY_PROJECT1;
         }
         // Add the fix.
-        await _addFix_importLibrary(fixKind, librarySource);
+        await _addFix_importLibrary(fixKind, librarySource.uri);
       }
     }
   }
@@ -2348,9 +2349,11 @@
     } else {
       DartChangeBuilder changeBuilder = new DartChangeBuilder(session);
       await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
-        builder.addSimpleReplacement(
-            range.endEnd(emptyStatement.beginToken.previous, emptyStatement),
-            ' {}');
+        Token previous = emptyStatement.findPrevious(emptyStatement.beginToken);
+        if (previous != null) {
+          builder.addSimpleReplacement(
+              range.endEnd(previous, emptyStatement), ' {}');
+        }
       });
       _addFixFromBuilder(changeBuilder, DartFixKind.REPLACE_WITH_BRACKETS);
     }
@@ -2820,7 +2823,8 @@
 
   Future<Null> _addFix_undefinedFunction_create() async {
     // should be the name of the invocation
-    if (node is SimpleIdentifier && node.parent is MethodInvocation) {} else {
+    if (node is SimpleIdentifier && node.parent is MethodInvocation) {
+    } else {
       return;
     }
     String name = (node as SimpleIdentifier).name;
diff --git a/pkg/analysis_server/lib/src/services/correction/util.dart b/pkg/analysis_server/lib/src/services/correction/util.dart
index 5878f8c..d5bd83e 100644
--- a/pkg/analysis_server/lib/src/services/correction/util.dart
+++ b/pkg/analysis_server/lib/src/services/correction/util.dart
@@ -21,14 +21,14 @@
     show SourceChange, SourceEdit;
 import 'package:analyzer_plugin/src/utilities/string_utilities.dart';
 import 'package:analyzer_plugin/utilities/range_factory.dart';
-import 'package:path/path.dart';
+import 'package:path/path.dart' as pathos;
 
 /**
  * Adds edits to the given [change] that ensure that all the [libraries] are
  * imported into the given [targetLibrary].
  */
-void addLibraryImports(
-    SourceChange change, LibraryElement targetLibrary, Set<Source> libraries) {
+void addLibraryImports(pathos.Context pathContext, SourceChange change,
+    LibraryElement targetLibrary, Set<Source> libraries) {
   CorrectionUtils libUtils;
   try {
     CompilationUnitElement unitElement = targetLibrary.definingCompilationUnit;
@@ -52,7 +52,8 @@
 
   // Prepare all URIs to import.
   List<String> uriList = libraries
-      .map((library) => getLibrarySourceUri(targetLibrary, library))
+      .map((library) =>
+          getLibrarySourceUri(pathContext, targetLibrary, library.uri))
       .toList();
   uriList.sort((a, b) => a.compareTo(b));
 
@@ -347,18 +348,14 @@
 /**
  * Computes the best URI to import [what] into [from].
  */
-String getLibrarySourceUri(LibraryElement from, Source what) {
-  String whatPath = what.fullName;
-  // check if an absolute URI (such as 'dart:' or 'package:')
-  Uri whatUri = what.uri;
-  String whatUriScheme = whatUri.scheme;
-  if (whatUriScheme != '' && whatUriScheme != 'file') {
-    return whatUri.toString();
+String getLibrarySourceUri(
+    pathos.Context pathContext, LibraryElement from, Uri what) {
+  if (what.scheme == 'file') {
+    String fromFolder = pathContext.dirname(from.source.fullName);
+    String relativeFile = pathContext.relative(what.path, from: fromFolder);
+    return pathContext.split(relativeFile).join('/');
   }
-  // compute a relative URI
-  String fromFolder = dirname(from.source.fullName);
-  String relativeFile = relative(whatPath, from: fromFolder);
-  return split(relativeFile).join('/');
+  return what.toString();
 }
 
 /**
diff --git a/pkg/analysis_server/lib/src/services/refactoring/extract_method.dart b/pkg/analysis_server/lib/src/services/refactoring/extract_method.dart
index c1ce1cb..4a1d37a 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/extract_method.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/extract_method.dart
@@ -389,7 +389,8 @@
       }
     }
     // done
-    addLibraryImports(change, libraryElement, librariesToImport);
+    addLibraryImports(session.resourceProvider.pathContext, change,
+        libraryElement, librariesToImport);
     return change;
   }
 
diff --git a/pkg/analysis_server/lib/src/services/refactoring/rename_local.dart b/pkg/analysis_server/lib/src/services/refactoring/rename_local.dart
index 4b1c9eb4..eca6220 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/rename_local.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/rename_local.dart
@@ -26,7 +26,7 @@
   final AstProvider astProvider;
   final ResolvedUnitCache unitCache;
 
-  Set<LocalElement> elements = new Set<LocalElement>();
+  List<LocalElement> elements = [];
 
   RenameLocalRefactoringImpl(
       SearchEngine searchEngine, this.astProvider, LocalElement element)
@@ -92,25 +92,11 @@
    * Fills [elements] with [Element]s to rename.
    */
   Future _prepareElements() async {
-    Element enclosing = element.enclosingElement;
-    if (enclosing is MethodElement &&
-        element is ParameterElement &&
-        (element as ParameterElement).isNamed) {
-      // prepare hierarchy methods
-      Set<ClassMemberElement> methods =
-          await getHierarchyMembers(searchEngine, enclosing);
-      // add named parameter from each method
-      for (ClassMemberElement method in methods) {
-        if (method is MethodElement) {
-          for (ParameterElement parameter in method.parameters) {
-            if (parameter.isNamed && parameter.name == element.name) {
-              elements.add(parameter);
-            }
-          }
-        }
-      }
+    Element element = this.element;
+    if (element is ParameterElement && element.isNamed) {
+      elements = await getHierarchyNamedParameters(searchEngine, element);
     } else {
-      elements = new Set.from([element]);
+      elements = [element];
     }
   }
 }
diff --git a/pkg/analysis_server/lib/src/services/search/hierarchy.dart b/pkg/analysis_server/lib/src/services/search/hierarchy.dart
index 3f9bb483..6441488 100644
--- a/pkg/analysis_server/lib/src/services/search/hierarchy.dart
+++ b/pkg/analysis_server/lib/src/services/search/hierarchy.dart
@@ -100,6 +100,34 @@
 }
 
 /**
+ * If the [element] is a named parameter in a [MethodElement], return all
+ * corresponding named parameters in the method hierarchy.
+ */
+Future<List<ParameterElement>> getHierarchyNamedParameters(
+    SearchEngine searchEngine, ParameterElement element) async {
+  if (element.isNamed) {
+    Element method = element.enclosingElement;
+    if (method is MethodElement) {
+      var hierarchyParameters = <ParameterElement>[];
+      var hierarchyMembers = await getHierarchyMembers(searchEngine, method);
+      for (ClassMemberElement hierarchyMethod in hierarchyMembers) {
+        if (hierarchyMethod is MethodElement) {
+          for (var hierarchyParameter in hierarchyMethod.parameters) {
+            if (hierarchyParameter.isNamed &&
+                hierarchyParameter.name == element.name) {
+              hierarchyParameters.add(hierarchyParameter);
+              break;
+            }
+          }
+        }
+      }
+      return hierarchyParameters;
+    }
+  }
+  return [element];
+}
+
+/**
  * Returns non-synthetic members of the given [ClassElement] and its super
  * classes.
  *
diff --git a/pkg/analysis_server/lib/src/status/diagnostics.dart b/pkg/analysis_server/lib/src/status/diagnostics.dart
index ac435fd..b579add 100644
--- a/pkg/analysis_server/lib/src/status/diagnostics.dart
+++ b/pkg/analysis_server/lib/src/status/diagnostics.dart
@@ -11,7 +11,6 @@
 import 'package:analysis_server/src/analysis_server.dart';
 import 'package:analysis_server/src/domain_completion.dart';
 import 'package:analysis_server/src/domain_diagnostic.dart';
-import 'package:analysis_server/src/domain_execution.dart';
 import 'package:analysis_server/src/plugin/plugin_manager.dart';
 import 'package:analysis_server/src/server/http_server.dart';
 import 'package:analysis_server/src/services/completion/completion_performance.dart';
@@ -351,12 +350,14 @@
     buf.writeln('<table>');
     buf.writeln(
         '<tr><th>Time</th><th>Results</th><th>Source</th><th>Snippet</th></tr>');
+    var pathContext = completionDomain.server.resourceProvider.pathContext;
     for (CompletionPerformance completion in completions) {
+      String shortName = pathContext.basename(completion.path);
       buf.writeln('<tr>'
           '<td class="pre right">${printMilliseconds(
           completion.elapsedInMilliseconds)}</td>'
           '<td class="right">${completion.suggestionCount}</td>'
-          '<td>${escape(completion.source.shortName)}</td>'
+          '<td>${escape(shortName)}</td>'
           '<td><code>${escape(completion.snippet)}</code></td>'
           '</tr>');
     }
@@ -1310,19 +1311,5 @@
         buf.write('$item');
       });
     }
-
-    // execution domain
-    ExecutionDomainHandler domain = server.handlers.firstWhere(
-        (handler) => handler is ExecutionDomainHandler,
-        orElse: () => null);
-
-    h3('Execution domain');
-    ul(ExecutionService.VALUES, (item) {
-      if (domain.onFileAnalyzed != null) {
-        buf.write('$item (has subscriptions)');
-      } else {
-        buf.write('$item (no subscriptions)');
-      }
-    });
   }
 }
diff --git a/pkg/analysis_server/lib/src/utilities/flutter.dart b/pkg/analysis_server/lib/src/utilities/flutter.dart
index bb06c05..ce4d959 100644
--- a/pkg/analysis_server/lib/src/utilities/flutter.dart
+++ b/pkg/analysis_server/lib/src/utilities/flutter.dart
@@ -111,18 +111,16 @@
  * [newExpr], or `null` if none.
  */
 NamedExpression findChildArgument(InstanceCreationExpression newExpr) =>
-    newExpr.argumentList.arguments.firstWhere(
-        (arg) => arg is NamedExpression && arg.name.label.name == 'child',
-        orElse: () => null);
+    newExpr.argumentList.arguments
+        .firstWhere(isChildArgument, orElse: () => null);
 
 /**
  * Return the named expression representing the `children` argument of the
  * given [newExpr], or `null` if none.
  */
 NamedExpression findChildrenArgument(InstanceCreationExpression newExpr) =>
-    newExpr.argumentList.arguments.firstWhere(
-        (arg) => arg is NamedExpression && arg.name.label.name == 'children',
-        orElse: () => null);
+    newExpr.argumentList.arguments
+        .firstWhere(isChildrenArgument, orElse: () => null);
 
 /**
  * Return the Flutter instance creation expression that is the value of the
@@ -244,6 +242,18 @@
 }
 
 /**
+ * Return `true` is the given [argument] is the `child` argument.
+ */
+bool isChildArgument(Expression argument) =>
+    argument is NamedExpression && argument.name.label.name == 'child';
+
+/**
+ * Return `true` is the given [argument] is the `child` argument.
+ */
+bool isChildrenArgument(Expression argument) =>
+    argument is NamedExpression && argument.name.label.name == 'children';
+
+/**
  * Return `true` if the given [type] is the Flutter class `StatefulWidget`.
  */
 bool isExactlyStatefulWidgetType(DartType type) {
@@ -331,7 +341,13 @@
  * subtype.
  */
 bool isWidgetExpression(AstNode node) {
-  if (node?.parent is TypeName || node?.parent?.parent is TypeName) {
+  if (node == null) {
+    return false;
+  }
+  if (node.parent is TypeName || node.parent?.parent is TypeName) {
+    return false;
+  }
+  if (node.parent is ConstructorName) {
     return false;
   }
   if (node is NamedExpression) {
diff --git a/pkg/analysis_server/test/abstract_context.dart b/pkg/analysis_server/test/abstract_context.dart
index 3ee2c09..8cf628e 100644
--- a/pkg/analysis_server/test/abstract_context.dart
+++ b/pkg/analysis_server/test/abstract_context.dart
@@ -53,7 +53,7 @@
   UriResolver resourceResolver;
 
   StringBuffer _logBuffer = new StringBuffer();
-  FileContentOverlay _fileContentOverlay = new FileContentOverlay();
+  FileContentOverlay fileContentOverlay = new FileContentOverlay();
   AnalysisDriver _driver;
 
   AnalysisDriver get driver => _driver;
@@ -101,7 +101,7 @@
     Source source = file.createSource(uri);
     driver.addFile(file.path);
     driver.changeFile(file.path);
-    _fileContentOverlay[file.path] = content;
+    fileContentOverlay[file.path] = content;
     return source;
   }
 
@@ -136,7 +136,7 @@
         log,
         resourceProvider,
         new MemoryByteStore(),
-        _fileContentOverlay,
+        fileContentOverlay,
         new ContextRoot(resourceProvider.convertPath('/project'), []),
         sourceFactory,
         new AnalysisOptionsImpl()..strongMode = true);
diff --git a/pkg/analysis_server/test/completion_test.dart b/pkg/analysis_server/test/completion_test.dart
index 1e1aec8..9d2093d 100644
--- a/pkg/analysis_server/test/completion_test.dart
+++ b/pkg/analysis_server/test/completion_test.dart
@@ -732,21 +732,17 @@
         <String>["1+fooConst", "1-fooNotConst", "1-bar"],
         failingTests: '1');
 
-    buildTests(
-        'testCompletion_annotation_type',
-        '''
+    buildTests('testCompletion_annotation_type', '''
 class AAA {
   const AAA({int a, int b});
   const AAA.nnn(int c, int d);
 }
 @AAA!1
 main() {
-}''',
-        <String>[
-          "1+AAA" /*":" + ProposalKind.CONSTRUCTOR*/,
-          "1+AAA.nnn" /*":" + ProposalKind.CONSTRUCTOR*/
-        ],
-        failingTests: '1');
+}''', <String>[
+      "1+AAA" /*":" + ProposalKind.CONSTRUCTOR*/,
+      "1+AAA.nnn" /*":" + ProposalKind.CONSTRUCTOR*/
+    ]);
 
     buildTests('testCompletion_annotation_type_inClass_withoutMember', '''
 class AAA {
diff --git a/pkg/analysis_server/test/domain_completion_test.dart b/pkg/analysis_server/test/domain_completion_test.dart
index 078a2bb..07c23fa 100644
--- a/pkg/analysis_server/test/domain_completion_test.dart
+++ b/pkg/analysis_server/test/domain_completion_test.dart
@@ -619,8 +619,11 @@
     assertHasResult(CompletionSuggestionKind.INVOCATION, 'A',
         elementKind: ElementKind.CLASS);
 
-    // No constructors suggested.
-    assertNoResult('A.named');
+    // Both constructors - default and named, are suggested.
+    assertHasResult(CompletionSuggestionKind.INVOCATION, 'A',
+        elementKind: ElementKind.CONSTRUCTOR);
+    assertHasResult(CompletionSuggestionKind.INVOCATION, 'A.named',
+        elementKind: ElementKind.CONSTRUCTOR);
   }
 
   test_local_named_constructor() {
diff --git a/pkg/analysis_server/test/domain_execution_test.dart b/pkg/analysis_server/test/domain_execution_test.dart
index 02b95c1..296c28b 100644
--- a/pkg/analysis_server/test/domain_execution_test.dart
+++ b/pkg/analysis_server/test/domain_execution_test.dart
@@ -6,6 +6,7 @@
 import 'package:analysis_server/protocol/protocol_generated.dart';
 import 'package:analysis_server/src/analysis_server.dart';
 import 'package:analysis_server/src/domain_execution.dart';
+import 'package:analysis_server/src/protocol_server.dart';
 import 'package:analyzer/file_system/memory_file_system.dart';
 import 'package:analyzer/instrumentation/instrumentation.dart';
 import 'package:analyzer/src/generated/sdk.dart';
@@ -177,6 +178,38 @@
     super.tearDown();
   }
 
+  test_getSuggestions() async {
+    var code = r'''
+class A {
+  int foo;
+}
+
+void contextFunction() {
+  var a = new A();
+  // context line
+}
+''';
+
+    String path = newFile('/test.dart').path;
+    newFile(path, content: code);
+
+    Request request = new ExecutionGetSuggestionsParams(
+        'a.',
+        2,
+        path,
+        code.indexOf('// context line'),
+        <RuntimeCompletionVariable>[]).toRequest('0');
+    Response response = await waitResponse(request);
+
+    var result = new ExecutionGetSuggestionsResult.fromResponse(response);
+    expect(result.suggestions, isNotEmpty);
+
+    expect(
+        result.suggestions,
+        contains(
+            predicate<CompletionSuggestion>((s) => s.completion == 'foo')));
+  }
+
   void test_mapUri_file() {
     String path = newFile('/a/b.dart').path;
     // map the file
diff --git a/pkg/analysis_server/test/integration/coverage.md b/pkg/analysis_server/test/integration/coverage.md
index 4dbeae6..466c66e 100644
--- a/pkg/analysis_server/test/integration/coverage.md
+++ b/pkg/analysis_server/test/integration/coverage.md
@@ -53,6 +53,7 @@
 ## execution domain
 - [x] execution.createContext
 - [x] execution.deleteContext
+- [ ] execution.getSuggestions
 - [x] execution.mapUri
 - [x] execution.setSubscriptions
 - [ ] execution.launchData
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 9b77a47..41880e3 100644
--- a/pkg/analysis_server/test/integration/support/integration_test_methods.dart
+++ b/pkg/analysis_server/test/integration/support/integration_test_methods.dart
@@ -1830,6 +1830,98 @@
   }
 
   /**
+   * Request completion suggestions for the given runtime context.
+   *
+   * It might take one or two requests of this type to get completion
+   * suggestions. The first request should have only "code", "offset", and
+   * "variables", but not "expressions". If there are sub-expressions that can
+   * have different runtime types, and are considered to be safe to evaluate at
+   * runtime (e.g. getters), so using their actual runtime types can improve
+   * completion results, the server will not include the "suggestions" field in
+   * the response, and instead will return the "expressions" field. The client
+   * will use debug API to get current runtime types for these sub-expressions
+   * and send another request, this time with "expressions". If there are no
+   * interesting sub-expressions to get runtime types for, or when the
+   * "expressions" field is provided by the client, the server will return
+   * "suggestions" in the response.
+   *
+   * Parameters
+   *
+   * code: String
+   *
+   *   The code to get suggestions in.
+   *
+   * offset: int
+   *
+   *   The offset within the code to get suggestions at.
+   *
+   * contextFile: FilePath
+   *
+   *   The path of the context file, e.g. the file of the current debugger
+   *   frame. The combination of the context file and context offset can be
+   *   used to ensure that all variables of the context are available for
+   *   completion (with their static types).
+   *
+   * contextOffset: int
+   *
+   *   The offset in the context file, e.g. the line offset in the current
+   *   debugger frame.
+   *
+   * variables: List<RuntimeCompletionVariable>
+   *
+   *   The runtime context variables that are potentially referenced in the
+   *   code.
+   *
+   * expressions: List<RuntimeCompletionExpression> (optional)
+   *
+   *   The list of sub-expressions in the code for which the client wants to
+   *   provide runtime types. It does not have to be the full list of
+   *   expressions requested by the server, for missing expressions their
+   *   static types will be used.
+   *
+   *   When this field is omitted, the server will return completion
+   *   suggestions only when there are no interesting sub-expressions in the
+   *   given code. The client may provide an empty list, in this case the
+   *   server will return completion suggestions.
+   *
+   * Returns
+   *
+   * suggestions: List<CompletionSuggestion> (optional)
+   *
+   *   The completion suggestions. In contrast to usual completion request,
+   *   suggestions for private elements also will be provided.
+   *
+   *   If there are sub-expressions that can have different runtime types, and
+   *   are considered to be safe to evaluate at runtime (e.g. getters), so
+   *   using their actual runtime types can improve completion results, the
+   *   server omits this field in the response, and instead will return the
+   *   "expressions" field.
+   *
+   * expressions: List<RuntimeCompletionExpression> (optional)
+   *
+   *   The list of sub-expressions in the code for which the server would like
+   *   to know runtime types to provide better completion suggestions.
+   *
+   *   This field is omitted the field "suggestions" is returned.
+   */
+  Future<ExecutionGetSuggestionsResult> sendExecutionGetSuggestions(
+      String code,
+      int offset,
+      String contextFile,
+      int contextOffset,
+      List<RuntimeCompletionVariable> variables,
+      {List<RuntimeCompletionExpression> expressions}) async {
+    var params = new ExecutionGetSuggestionsParams(
+            code, offset, contextFile, contextOffset, variables,
+            expressions: expressions)
+        .toJson();
+    var result = await server.send("execution.getSuggestions", params);
+    ResponseDecoder decoder = new ResponseDecoder(null);
+    return new ExecutionGetSuggestionsResult.fromJson(
+        decoder, 'result', result);
+  }
+
+  /**
    * Map a URI from the execution context to the file that it corresponds to,
    * or map a file to the URI that it corresponds to in the execution context.
    *
diff --git a/pkg/analysis_server/test/integration/support/protocol_matchers.dart b/pkg/analysis_server/test/integration/support/protocol_matchers.dart
index dd07221..bdb6726 100644
--- a/pkg/analysis_server/test/integration/support/protocol_matchers.dart
+++ b/pkg/analysis_server/test/integration/support/protocol_matchers.dart
@@ -572,19 +572,21 @@
  * FoldingKind
  *
  * enum {
- *   COMMENT
- *   CLASS_MEMBER
+ *   ANNOTATIONS
+ *   CLASS_BODY
  *   DIRECTIVES
  *   DOCUMENTATION_COMMENT
- *   TOP_LEVEL_DECLARATION
+ *   FILE_HEADER
+ *   FUNCTION_BODY
  * }
  */
 final Matcher isFoldingKind = new MatchesEnum("FoldingKind", [
-  "COMMENT",
-  "CLASS_MEMBER",
+  "ANNOTATIONS",
+  "CLASS_BODY",
   "DIRECTIVES",
   "DOCUMENTATION_COMMENT",
-  "TOP_LEVEL_DECLARATION"
+  "FILE_HEADER",
+  "FUNCTION_BODY"
 ]);
 
 /**
@@ -1277,6 +1279,70 @@
 ]);
 
 /**
+ * RuntimeCompletionExpression
+ *
+ * {
+ *   "offset": int
+ *   "length": int
+ *   "type": optional RuntimeCompletionExpressionType
+ * }
+ */
+final Matcher isRuntimeCompletionExpression = new LazyMatcher(() =>
+    new MatchesJsonObject(
+        "RuntimeCompletionExpression", {"offset": isInt, "length": isInt},
+        optionalFields: {"type": isRuntimeCompletionExpressionType}));
+
+/**
+ * RuntimeCompletionExpressionType
+ *
+ * {
+ *   "libraryPath": optional FilePath
+ *   "kind": RuntimeCompletionExpressionTypeKind
+ *   "name": optional String
+ *   "typeArguments": optional List<RuntimeCompletionExpressionType>
+ *   "returnType": optional RuntimeCompletionExpressionType
+ *   "parameterTypes": optional List<RuntimeCompletionExpressionType>
+ *   "parameterNames": optional List<String>
+ * }
+ */
+final Matcher isRuntimeCompletionExpressionType = new LazyMatcher(
+    () => new MatchesJsonObject("RuntimeCompletionExpressionType", {
+          "kind": isRuntimeCompletionExpressionTypeKind
+        }, optionalFields: {
+          "libraryPath": isFilePath,
+          "name": isString,
+          "typeArguments": isListOf(isRuntimeCompletionExpressionType),
+          "returnType": isRuntimeCompletionExpressionType,
+          "parameterTypes": isListOf(isRuntimeCompletionExpressionType),
+          "parameterNames": isListOf(isString)
+        }));
+
+/**
+ * RuntimeCompletionExpressionTypeKind
+ *
+ * enum {
+ *   DYNAMIC
+ *   FUNCTION
+ *   INTERFACE
+ * }
+ */
+final Matcher isRuntimeCompletionExpressionTypeKind = new MatchesEnum(
+    "RuntimeCompletionExpressionTypeKind",
+    ["DYNAMIC", "FUNCTION", "INTERFACE"]);
+
+/**
+ * RuntimeCompletionVariable
+ *
+ * {
+ *   "name": String
+ *   "type": RuntimeCompletionExpressionType
+ * }
+ */
+final Matcher isRuntimeCompletionVariable = new LazyMatcher(() =>
+    new MatchesJsonObject("RuntimeCompletionVariable",
+        {"name": isString, "type": isRuntimeCompletionExpressionType}));
+
+/**
  * SearchId
  *
  * String
@@ -2329,6 +2395,44 @@
 final Matcher isExecutionDeleteContextResult = isNull;
 
 /**
+ * execution.getSuggestions params
+ *
+ * {
+ *   "code": String
+ *   "offset": int
+ *   "contextFile": FilePath
+ *   "contextOffset": int
+ *   "variables": List<RuntimeCompletionVariable>
+ *   "expressions": optional List<RuntimeCompletionExpression>
+ * }
+ */
+final Matcher isExecutionGetSuggestionsParams = new LazyMatcher(
+    () => new MatchesJsonObject("execution.getSuggestions params", {
+          "code": isString,
+          "offset": isInt,
+          "contextFile": isFilePath,
+          "contextOffset": isInt,
+          "variables": isListOf(isRuntimeCompletionVariable)
+        }, optionalFields: {
+          "expressions": isListOf(isRuntimeCompletionExpression)
+        }));
+
+/**
+ * execution.getSuggestions result
+ *
+ * {
+ *   "suggestions": optional List<CompletionSuggestion>
+ *   "expressions": optional List<RuntimeCompletionExpression>
+ * }
+ */
+final Matcher isExecutionGetSuggestionsResult = new LazyMatcher(() =>
+    new MatchesJsonObject("execution.getSuggestions result", null,
+        optionalFields: {
+          "suggestions": isListOf(isCompletionSuggestion),
+          "expressions": isListOf(isRuntimeCompletionExpression)
+        }));
+
+/**
  * execution.launchData params
  *
  * {
diff --git a/pkg/analysis_server/test/mock_sdk.dart b/pkg/analysis_server/test/mock_sdk.dart
index de74dd3..bbe7e01 100644
--- a/pkg/analysis_server/test/mock_sdk.dart
+++ b/pkg/analysis_server/test/mock_sdk.dart
@@ -128,6 +128,7 @@
 abstract class Iterable<E> {
   Iterator<E> get iterator;
   bool get isEmpty;
+  void forEach(void f(E element));
   Iterable<T> map<T>(T f(E e)) => null;
   T fold<T>(T initialValue, T combine(T previousValue, E element));
   List<E> toList({bool growable: true});
diff --git a/pkg/analysis_server/test/search/element_references_test.dart b/pkg/analysis_server/test/search/element_references_test.dart
index 3e411f4..d320dbb 100644
--- a/pkg/analysis_server/test/search/element_references_test.dart
+++ b/pkg/analysis_server/test/search/element_references_test.dart
@@ -305,6 +305,30 @@
     assertHasResult(SearchResultKind.INVOCATION, 'mmm(20)');
   }
 
+  test_hierarchy_namedParameter() async {
+    addTestFile('''
+class A {
+  m({p}) {} // in A
+}
+class B extends A {
+  m({p}) {} // in B
+}
+class C extends B {
+  m({p}) {} // in C
+}
+main(A a, B b, C c) {
+  a.m(p: 1);
+  b.m(p: 2);
+  c.m(p: 3);
+}
+''');
+    await findElementReferences('p}) {} // in B', false);
+    expect(searchElement.kind, ElementKind.PARAMETER);
+    assertHasResult(SearchResultKind.REFERENCE, 'p: 1');
+    assertHasResult(SearchResultKind.REFERENCE, 'p: 2');
+    assertHasResult(SearchResultKind.REFERENCE, 'p: 3');
+  }
+
   test_label() async {
     addTestFile('''
 main() {
diff --git a/pkg/analysis_server/test/services/completion/dart/completion_contributor_util.dart b/pkg/analysis_server/test/services/completion/dart/completion_contributor_util.dart
index 558129a..d6d8191 100644
--- a/pkg/analysis_server/test/services/completion/dart/completion_contributor_util.dart
+++ b/pkg/analysis_server/test/services/completion/dart/completion_contributor_util.dart
@@ -11,7 +11,6 @@
     show DartCompletionRequestImpl;
 import 'package:analyzer/src/dart/analysis/driver.dart';
 import 'package:analyzer/src/generated/parser.dart' as analyzer;
-import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer_plugin/protocol/protocol_common.dart';
 import 'package:test/test.dart';
 
@@ -26,7 +25,6 @@
 abstract class DartCompletionContributorTest extends AbstractContextTest {
   static const String _UNCHECKED = '__UNCHECKED__';
   String testFile;
-  Source testSource;
   int completionOffset;
   int replacementOffset;
   int replacementLength;
@@ -47,7 +45,7 @@
    * Return `true` if contributors should suggest constructors in contexts where
    * there is no `new` or `const` keyword.
    */
-  bool get suggestConstructorsWithoutNew => false;
+  bool get suggestConstructorsWithoutNew => true;
 
   bool get usingFastaParser => analyzer.Parser.useFasta;
 
@@ -59,7 +57,7 @@
     expect(nextOffset, equals(-1), reason: 'too many ^');
     content = content.substring(0, completionOffset) +
         content.substring(completionOffset + 1);
-    testSource = addSource(testFile, content);
+    addSource(testFile, content);
   }
 
   void assertHasNoParameterInfo(CompletionSuggestion suggestion) {
@@ -473,13 +471,8 @@
   Future computeSuggestions({int times = 200}) async {
     AnalysisResult analysisResult =
         await driver.getResult(convertPath(testFile));
-    testSource = analysisResult.unit.element.source;
     CompletionRequestImpl baseRequest = new CompletionRequestImpl(
-        analysisResult,
-        resourceProvider,
-        testSource,
-        completionOffset,
-        new CompletionPerformance());
+        analysisResult, completionOffset, new CompletionPerformance());
 
     // Build the request
     Completer<DartCompletionRequest> requestCompleter =
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 d0717e8..51950f4 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
@@ -48,8 +48,6 @@
     // Build the request
     CompletionRequestImpl baseRequest = new CompletionRequestImpl(
         await driver.getResult(testFile),
-        resourceProvider,
-        testSource,
         completionOffset,
         new CompletionPerformance());
     Completer<DartCompletionRequest> requestCompleter =
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 8f6efea..60b262c 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
@@ -2449,12 +2449,12 @@
     await computeSuggestions();
 
     assertSuggestClass('A');
-    assertNotSuggested('A.a1');
-    assertNotSuggested('A.a2');
+    assertSuggestConstructor('A.a1');
+    assertSuggestConstructor('A.a2');
 
     assertSuggestClass('B');
-    assertNotSuggested('B.b1');
-    assertNotSuggested('B.b2');
+    assertSuggestConstructor('B.b1');
+    assertSuggestConstructor('B.b2');
   }
 
   test_ImportDirective_dart() async {
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 fb5a912..1aa985c 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
@@ -330,7 +330,7 @@
     assertSuggestFunction('bar', 'String',
         kind: CompletionSuggestionKind.IDENTIFIER,
         relevance: DART_RELEVANCE_LOCAL_FUNCTION);
-    assertSuggestFunction('boo', 'dynamic',
+    assertSuggestFunction('boo', 'Null',
         kind: CompletionSuggestionKind.IDENTIFIER,
         relevance: DART_RELEVANCE_LOCAL_FUNCTION);
     assertNotSuggested('hasLength');
@@ -365,7 +365,7 @@
         kind: CompletionSuggestionKind.IDENTIFIER,
         relevance:
             DART_RELEVANCE_LOCAL_FUNCTION + DART_RELEVANCE_BOOST_SUBTYPE);
-    assertSuggestFunction('boo', 'dynamic',
+    assertSuggestFunction('boo', 'Null',
         kind: CompletionSuggestionKind.IDENTIFIER,
         relevance:
             DART_RELEVANCE_LOCAL_FUNCTION + DART_RELEVANCE_BOOST_SUBTYPE);
@@ -871,7 +871,7 @@
     assertSuggestMethod('a', 'X', null, relevance: DART_RELEVANCE_LOCAL_METHOD);
     assertSuggestMethod('b', 'X', 'void',
         relevance: DART_RELEVANCE_LOCAL_METHOD);
-    assertSuggestFunction('localF', null,
+    assertSuggestFunction('localF', 'Null',
         relevance: DART_RELEVANCE_LOCAL_FUNCTION);
     assertSuggestLocalVariable('f', null);
     // Don't suggest locals out of scope
@@ -2352,7 +2352,7 @@
 
     expect(replacementOffset, completionOffset);
     expect(replacementLength, 0);
-    assertSuggestLocalVariable('values', 'List');
+    assertSuggestLocalVariable('values', 'List<int>');
     assertNotSuggested('index');
   }
 
@@ -2363,7 +2363,7 @@
 
     expect(replacementOffset, completionOffset - 1);
     expect(replacementLength, 1);
-    assertSuggestLocalVariable('values', 'List');
+    assertSuggestLocalVariable('values', 'List<int>');
     assertNotSuggested('index');
   }
 
@@ -2374,7 +2374,7 @@
 
     expect(replacementOffset, completionOffset - 1);
     expect(replacementLength, 1);
-    assertSuggestLocalVariable('values', 'List');
+    assertSuggestLocalVariable('values', 'List<int>');
     assertNotSuggested('index');
   }
 
@@ -2742,7 +2742,7 @@
     }
     assertSuggestFunction('bar', 'void',
         relevance: DART_RELEVANCE_LOCAL_FUNCTION);
-    assertSuggestParameter('args', 'List');
+    assertSuggestParameter('args', 'List<dynamic>');
     assertSuggestParameter('b', 'R');
     assertNotSuggested('Object');
   }
@@ -4202,6 +4202,12 @@
     assertSuggestLocalVariable('_ab', null);
   }
 
+  test_inferredType() async {
+    addTestSource('main() { var v = 42; ^ }');
+    await computeSuggestions();
+    assertSuggestLocalVariable('v', 'int');
+  }
+
   test_prioritization_public() async {
     addTestSource('main() {var ab; var _ab; a^}');
     await computeSuggestions();
diff --git a/pkg/analysis_server/test/services/completion/dart/static_member_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/static_member_contributor_test.dart
index 8aebb55..2987710 100644
--- a/pkg/analysis_server/test/services/completion/dart/static_member_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/static_member_contributor_test.dart
@@ -114,8 +114,8 @@
 ''');
     await computeSuggestions();
 
-    assertNotSuggested('foo');
-    assertNotSuggested('bar');
+    assertSuggestConstructor('foo', elementName: 'foo');
+    assertSuggestConstructor('bar', elementName: 'bar');
   }
 
   test_keyword() async {
diff --git a/pkg/analysis_server/test/services/correction/assist_test.dart b/pkg/analysis_server/test/services/correction/assist_test.dart
index 0cc4f57..752c8af 100644
--- a/pkg/analysis_server/test/services/correction/assist_test.dart
+++ b/pkg/analysis_server/test/services/correction/assist_test.dart
@@ -38,7 +38,7 @@
   String resultCode;
   LinkedEditGroup linkedPositionGroup;
 
-  bool get omitNew => false;
+  bool get omitNew => true;
 
   /**
    * Asserts that there is an [Assist] of the given [kind] at [offset] which
@@ -518,7 +518,7 @@
 ''');
     await assertHasAssistAt('v =', DartAssistKind.ADD_TYPE_ANNOTATION, '''
 main() {
-  Function v = () => 1;
+  int Function() v = () => 1;
 }
 ''');
   }
@@ -3405,6 +3405,7 @@
   return new Scaffold(
 // start
     body: new Center(
+      key: null,
       child: new /*caret*/GestureDetector(
         onTap: () => startResize(),
         child: new Container(
@@ -3412,7 +3413,6 @@
           height: 300.0,
         ),
       ),
-      key: null,
     ),
 // end
   );
@@ -3421,6 +3421,58 @@
 ''');
   }
 
+  test_flutterSwapWithChild_OK_notFormatted() async {
+    addFlutterPackage();
+    await resolveTestUnit('''
+import 'package:flutter/material.dart';
+
+class Foo extends StatefulWidget {
+  @override
+  _State createState() => new _State();
+}
+
+class _State extends State<Foo> {
+  @override
+  Widget build(BuildContext context) {
+    return new /*caret*/Expanded(
+      flex: 2,
+      child: new GestureDetector(
+        child: new Text(
+          'foo',
+        ), onTap: () {
+          print(42);
+      },
+      ),
+    );
+  }
+}''');
+    _setCaretLocation();
+    await assertHasAssist(DartAssistKind.FLUTTER_SWAP_WITH_CHILD, '''
+import 'package:flutter/material.dart';
+
+class Foo extends StatefulWidget {
+  @override
+  _State createState() => new _State();
+}
+
+class _State extends State<Foo> {
+  @override
+  Widget build(BuildContext context) {
+    return new GestureDetector(
+      onTap: () {
+        print(42);
+    },
+      child: new /*caret*/Expanded(
+        flex: 2,
+        child: new Text(
+          'foo',
+        ),
+      ),
+    );
+  }
+}''');
+  }
+
   test_flutterSwapWithParent_OK() async {
     addFlutterPackage();
     await resolveTestUnit('''
@@ -3452,11 +3504,11 @@
     body: new /*caret*/GestureDetector(
       onTap: () => startResize(),
       child: new Center(
+        key: null,
         child: new Container(
           width: 200.0,
           height: 300.0,
         ),
-        key: null,
       ),
     ),
 // end
@@ -3466,6 +3518,58 @@
 ''');
   }
 
+  test_flutterSwapWithParent_OK_notFormatted() async {
+    addFlutterPackage();
+    await resolveTestUnit('''
+import 'package:flutter/material.dart';
+
+class Foo extends StatefulWidget {
+  @override
+  _State createState() => new _State();
+}
+
+class _State extends State<Foo> {
+  @override
+  Widget build(BuildContext context) {
+    return new GestureDetector(
+      child: new /*caret*/Expanded(
+        child: new Text(
+          'foo',
+        ),
+        flex: 2,
+      ), onTap: () {
+        print(42);
+    },
+    );
+  }
+}''');
+    _setCaretLocation();
+    await assertHasAssist(DartAssistKind.FLUTTER_SWAP_WITH_PARENT, '''
+import 'package:flutter/material.dart';
+
+class Foo extends StatefulWidget {
+  @override
+  _State createState() => new _State();
+}
+
+class _State extends State<Foo> {
+  @override
+  Widget build(BuildContext context) {
+    return new /*caret*/Expanded(
+      flex: 2,
+      child: new GestureDetector(
+        onTap: () {
+          print(42);
+      },
+        child: new Text(
+          'foo',
+        ),
+      ),
+    );
+  }
+}''');
+  }
+
   test_flutterSwapWithParent_OK_outerIsInChildren() async {
     addFlutterPackage();
     await resolveTestUnit('''
@@ -3568,7 +3672,7 @@
 import 'package:flutter/widgets.dart';
 class FakeFlutter {
   main() {
-    return /*caret*/new Container();
+    return /*caret*/Container();
   }
 }
 ''');
@@ -3577,12 +3681,59 @@
 import 'package:flutter/widgets.dart';
 class FakeFlutter {
   main() {
-    return /*caret*/new Center(child: new Container());
+    return /*caret*/Center(child: Container());
   }
 }
 ''');
   }
 
+  test_flutterWrapCenter_OK_namedConstructor() async {
+    addFlutterPackage();
+    await resolveTestUnit('''
+import 'package:flutter/widgets.dart';
+
+class MyWidget extends StatelessWidget {
+  MyWidget.named();
+
+  Widget build(BuildContext context) => null;
+}
+
+main() {
+  return MyWidget./*caret*/named();
+}
+''');
+    _setCaretLocation();
+    if (omitNew) {
+      await assertHasAssist(DartAssistKind.FLUTTER_WRAP_CENTER, '''
+import 'package:flutter/widgets.dart';
+
+class MyWidget extends StatelessWidget {
+  MyWidget.named();
+
+  Widget build(BuildContext context) => null;
+}
+
+main() {
+  return Center(child: MyWidget./*caret*/named());
+}
+''');
+    } else {
+      await assertHasAssist(DartAssistKind.FLUTTER_WRAP_CENTER, '''
+import 'package:flutter/widgets.dart';
+
+class MyWidget extends StatelessWidget {
+  MyWidget.named();
+
+  Widget build(BuildContext context) => null;
+}
+
+main() {
+  return new Center(child: MyWidget./*caret*/named());
+}
+''');
+    }
+  }
+
   test_flutterWrapColumn_OK_coveredByWidget() async {
     addFlutterPackage();
     await resolveTestUnit('''
@@ -3704,7 +3855,7 @@
 
 main() {
   return Container(
-    child: /*caret*/new Text('aaa'),
+    child: /*caret*/Text('aaa'),
   );
 }
 ''');
@@ -3714,9 +3865,9 @@
 
 main() {
   return Container(
-    child: /*caret*/new Column(
+    child: /*caret*/Column(
       children: <Widget>[
-        new Text('aaa'),
+        Text('aaa'),
       ],
     ),
   );
diff --git a/pkg/analysis_server/test/services/correction/fix_test.dart b/pkg/analysis_server/test/services/correction/fix_test.dart
index be7a4cc..cde73fd 100644
--- a/pkg/analysis_server/test/services/correction/fix_test.dart
+++ b/pkg/analysis_server/test/services/correction/fix_test.dart
@@ -4533,6 +4533,84 @@
 ''');
   }
 
+  test_importLibrarySdk_withClass_instanceCreation_explicitNew() async {
+    await resolveTestUnit('''
+class C {
+  foo() {
+    new Future();
+  }
+}
+''');
+    await assertHasFix(DartFixKind.IMPORT_LIBRARY_SDK, '''
+import 'dart:async';
+
+class C {
+  foo() {
+    new Future();
+  }
+}
+''');
+  }
+
+  test_importLibrarySdk_withClass_instanceCreation_explicitNew_namedConstructor() async {
+    await resolveTestUnit('''
+class C {
+  foo() {
+    new Future.value(0);
+  }
+}
+''');
+    await assertHasFix(DartFixKind.IMPORT_LIBRARY_SDK, '''
+import 'dart:async';
+
+class C {
+  foo() {
+    new Future.value(0);
+  }
+}
+''');
+  }
+
+  test_importLibrarySdk_withClass_instanceCreation_implicitNew() async {
+    configurePreviewDart2();
+    await resolveTestUnit('''
+class C {
+  foo() {
+    Future();
+  }
+}
+''');
+    await assertHasFix(DartFixKind.IMPORT_LIBRARY_SDK, '''
+import 'dart:async';
+
+class C {
+  foo() {
+    Future();
+  }
+}
+''');
+  }
+
+  test_importLibrarySdk_withClass_instanceCreation_implicitNew_namedConstructor() async {
+    configurePreviewDart2();
+    await resolveTestUnit('''
+class C {
+  foo() {
+    Future.value(0);
+  }
+}
+''');
+    await assertHasFix(DartFixKind.IMPORT_LIBRARY_SDK, '''
+import 'dart:async';
+
+class C {
+  foo() {
+    Future.value(0);
+  }
+}
+''');
+  }
+
   test_importLibrarySdk_withClass_invocationTarget() async {
     await resolveTestUnit('''
 main() {
diff --git a/pkg/analysis_server/test/services/correction/util_test.dart b/pkg/analysis_server/test/services/correction/util_test.dart
index 05866c9..3e1981c 100644
--- a/pkg/analysis_server/test/services/correction/util_test.dart
+++ b/pkg/analysis_server/test/services/correction/util_test.dart
@@ -287,7 +287,8 @@
 
   void _assertAddLibraryImport(List<Source> newLibraries, String expectedCode) {
     SourceChange change = new SourceChange('');
-    addLibraryImports(change, testLibraryElement, newLibraries.toSet());
+    addLibraryImports(resourceProvider.pathContext, change, testLibraryElement,
+        newLibraries.toSet());
     SourceFileEdit testEdit = change.getFileEdit(testFile);
     expect(testEdit, isNotNull);
     String resultCode = SourceEdit.applySequence(testCode, testEdit.edits);
diff --git a/pkg/analysis_server/test/services/search/hierarchy_test.dart b/pkg/analysis_server/test/services/search/hierarchy_test.dart
index d81893d..a6827ee 100644
--- a/pkg/analysis_server/test/services/search/hierarchy_test.dart
+++ b/pkg/analysis_server/test/services/search/hierarchy_test.dart
@@ -254,6 +254,95 @@
     return Future.wait([futureA, futureB, futureD]);
   }
 
+  test_getHierarchyNamedParameters() async {
+    await _indexTestUnit('''
+class A {
+  foo({p}) {}
+}
+class B extends A {
+  foo({p}) {}
+}
+class C extends B {
+  foo({p}) {}
+}
+class D {
+  foo({p}) {}
+}
+class E extends D {
+  foo({p}) {}
+}
+''');
+    ClassElement classA = findElement('A');
+    ClassElement classB = findElement('B');
+    ClassElement classC = findElement('C');
+    ClassElement classD = findElement('D');
+    ClassElement classE = findElement('E');
+    ParameterElement parameterA = classA.methods[0].parameters[0];
+    ParameterElement parameterB = classB.methods[0].parameters[0];
+    ParameterElement parameterC = classC.methods[0].parameters[0];
+    ParameterElement parameterD = classD.methods[0].parameters[0];
+    ParameterElement parameterE = classE.methods[0].parameters[0];
+
+    {
+      var result = await getHierarchyNamedParameters(searchEngine, parameterA);
+      expect(result, unorderedEquals([parameterA, parameterB, parameterC]));
+    }
+
+    {
+      var result = await getHierarchyNamedParameters(searchEngine, parameterB);
+      expect(result, unorderedEquals([parameterA, parameterB, parameterC]));
+    }
+
+    {
+      var result = await getHierarchyNamedParameters(searchEngine, parameterC);
+      expect(result, unorderedEquals([parameterA, parameterB, parameterC]));
+    }
+
+    {
+      var result = await getHierarchyNamedParameters(searchEngine, parameterD);
+      expect(result, unorderedEquals([parameterD, parameterE]));
+    }
+
+    {
+      var result = await getHierarchyNamedParameters(searchEngine, parameterE);
+      expect(result, unorderedEquals([parameterD, parameterE]));
+    }
+  }
+
+  test_getHierarchyNamedParameters_invalid_missing() async {
+    verifyNoTestUnitErrors = false;
+    await _indexTestUnit('''
+class A {
+  foo({p}) {}
+}
+class B extends A {
+  foo() {}
+}
+''');
+    ClassElement classA = findElement('A');
+    ParameterElement parameterA = classA.methods[0].parameters[0];
+
+    var result = await getHierarchyNamedParameters(searchEngine, parameterA);
+    expect(result, unorderedEquals([parameterA]));
+  }
+
+  test_getHierarchyNamedParameters_invalid_notNamed() async {
+    verifyNoTestUnitErrors = false;
+    await _indexTestUnit('''
+class A {
+  foo({p}) {}
+}
+class B extends A {
+  foo(p) {}
+}
+''');
+    ClassElement classA = findElement('A');
+    ParameterElement parameterA = classA.methods[0].parameters[0];
+
+    var result = await getHierarchyNamedParameters(searchEngine, parameterA);
+    expect(result, unorderedEquals([parameterA]));
+  }
+
   test_getMembers() async {
     await _indexTestUnit('''
 class A {
diff --git a/pkg/analysis_server/test/src/computer/folding_computer_test.dart b/pkg/analysis_server/test/src/computer/folding_computer_test.dart
index 72a26a7..55d864b 100644
--- a/pkg/analysis_server/test/src/computer/folding_computer_test.dart
+++ b/pkg/analysis_server/test/src/computer/folding_computer_test.dart
@@ -35,6 +35,7 @@
 """;
 
     // Since there are no region comment markers above
+    // just check the length instead of the contents
     final regions = await _computeRegions(content);
     expect(regions, hasLength(0));
   }
@@ -79,7 +80,7 @@
 
 main() {/*1:INC*/
   print("Hello, world!");
-/*1:INC:TOP_LEVEL_DECLARATION*/}
+/*1:INC:FUNCTION_BODY*/}
 
 // Content after
 """;
@@ -96,7 +97,7 @@
 /// that spans lines/*1:INC:DOCUMENTATION_COMMENT*/
 main() {/*2:INC*/
   print("Hello, world!");
-/*2:INC:TOP_LEVEL_DECLARATION*/}
+/*2:INC:FUNCTION_BODY*/}
 
 // Content after
 """;
@@ -112,9 +113,9 @@
 main() {/*1:INC*/
   doPrint() {/*2:INC*/
     print("Hello, world!");
-  /*2:INC:TOP_LEVEL_DECLARATION*/}
+  /*2:INC:FUNCTION_BODY*/}
   doPrint();
-/*1:INC:TOP_LEVEL_DECLARATION*/}
+/*1:INC:FUNCTION_BODY*/}
 
 // Content after
 """;
@@ -130,12 +131,12 @@
 class Person {/*1:INC*/
   Person() {/*2:INC*/
     print("Hello, world!");
-  /*2:INC:CLASS_MEMBER*/}
+  /*2:INC:FUNCTION_BODY*/}
 
   void sayHello() {/*3:INC*/
     print("Hello, world!");
-  /*3:INC:CLASS_MEMBER*/}
-/*1:INC:TOP_LEVEL_DECLARATION*/}
+  /*3:INC:FUNCTION_BODY*/}
+/*1:INC:CLASS_BODY*/}
 
 // Content after
 """;
@@ -146,21 +147,137 @@
 
   test_annotations() async {
     String content = """
-@myMultilineAnnotation(/*1:INC*/
+@myMultilineAnnotation/*1:INC*/(
   "this",
   "is a test"
-/*1:INC:TOP_LEVEL_DECLARATION*/)
-@another()
-@andAnother
-main() {/*2:INC*/
-  print("Hello, world!");
-/*2:INC:TOP_LEVEL_DECLARATION*/}
+)/*1:EXC:ANNOTATIONS*/
+main() {}
+
+@noFoldNecessary
+main2() {}
+
+@multipleAnnotations1/*2:INC*/(
+  "this",
+  "is a test"
+)
+@multipleAnnotations2()
+@multipleAnnotations3/*2:EXC:ANNOTATIONS*/
+main3() {}
+
+@noFoldsForSingleClassAnnotation
+class MyClass {}
+
+@folded.classAnnotation1/*3:INC*/()
+@foldedClassAnnotation2/*3:EXC:ANNOTATIONS*/
+class MyClass2 {/*4:INC*/
+  @fieldAnnotation1/*5:INC*/
+  @fieldAnnotation2/*5:EXC:ANNOTATIONS*/
+  int myField;
+
+  @getterAnnotation1/*6:INC*/
+  @getterAnnotation2/*6:EXC:ANNOTATIONS*/
+  int get myThing => 1;
+
+  @setterAnnotation1/*7:INC*/
+  @setterAnnotation2/*7:EXC:ANNOTATIONS*/
+  void set myThing(int value) {}
+  
+  @methodAnnotation1/*8:INC*/
+  @methodAnnotation2/*8:EXC:ANNOTATIONS*/
+  void myMethod() {}
+
+  @constructorAnnotation1/*9:INC*/
+  @constructorAnnotation1/*9:EXC:ANNOTATIONS*/
+  MyClass2() {}
+/*4:INC:CLASS_BODY*/}
 """;
 
     final regions = await _computeRegions(content);
     _compareRegions(regions, content);
   }
 
+  test_file_header() async {
+    String content = """
+// Copyright some year by some people/*1:EXC*/
+// See LICENCE etc./*1:INC:FILE_HEADER*/
+
+// This is not the file header
+// It's just a comment
+main() {}
+""";
+
+    final regions = await _computeRegions(content);
+    _compareRegions(regions, content);
+  }
+
+  test_file_header_with_no_function_comment() async {
+    String content = """
+// Copyright some year by some people/*1:EXC*/
+// See LICENCE etc./*1:INC:FILE_HEADER*/
+
+main() {}
+""";
+
+    final regions = await _computeRegions(content);
+    _compareRegions(regions, content);
+  }
+
+  test_file_header_with_non_end_of_line_comment() async {
+    String content = """
+// Copyright some year by some people/*1:EXC*/
+// See LICENCE etc./*1:INC:FILE_HEADER*/
+/* This shouldn't be part of the file header */
+
+main() {}
+""";
+
+    final regions = await _computeRegions(content);
+    _compareRegions(regions, content);
+  }
+
+  test_file_header_does_not_include_block_comments() async {
+    String content = """
+/*
+ * Copyright some year by some people
+ * See LICENCE etc.
+ */
+/* This shouldn't be part of the file header */
+
+main() {}
+""";
+
+    final regions = await _computeRegions(content);
+    expect(regions, hasLength(0));
+  }
+
+  test_file_header_with_script_prefix() async {
+    String content = """
+#! /usr/bin/dart
+// Copyright some year by some people/*1:EXC*/
+// See LICENCE etc./*1:INC:FILE_HEADER*/
+
+// This is not the file header
+// It's just a comment
+main() {}
+""";
+
+    final regions = await _computeRegions(content);
+    _compareRegions(regions, content);
+  }
+
+  test_comment_is_not_considered_file_header() async {
+    String content = """
+// This is not the file header
+// It's just a comment
+main() {}
+""";
+
+    // Since there are no region comment markers above
+    // just check the length instead of the contents
+    final regions = await _computeRegions(content);
+    expect(regions, hasLength(0));
+  }
+
   /// Compares provided folding regions with expected
   /// regions extracted from the comments in the provided content.
   void _compareRegions(List<FoldingRegion> regions, String content) {
diff --git a/pkg/analysis_server/test/src/domains/execution/completion_test.dart b/pkg/analysis_server/test/src/domains/execution/completion_test.dart
new file mode 100644
index 0000000..4ba0ecd
--- /dev/null
+++ b/pkg/analysis_server/test/src/domains/execution/completion_test.dart
@@ -0,0 +1,379 @@
+// 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:analysis_server/src/domains/execution/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 '../../../abstract_context.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(RuntimeCompletionComputerTest);
+  });
+}
+
+@reflectiveTest
+class RuntimeCompletionComputerTest extends AbstractContextTest {
+  String contextFile;
+  int contextOffset;
+
+  RuntimeCompletionResult result;
+
+  void addContextFile(String content) {
+    contextFile = convertPath('/test/lib/context.dart');
+    addSource(contextFile, content);
+
+    contextOffset = content.indexOf('// context line');
+    expect(contextOffset, isNonNegative,
+        reason: "Not found '// context line'.");
+  }
+
+  void assertNotSuggested(String completion) {
+    CompletionSuggestion suggestion = getSuggest(completion);
+    if (suggestion != null) {
+      failedCompletion('unexpected $completion');
+    }
+  }
+
+  void assertSuggested(String completion, {String returnType}) {
+    CompletionSuggestion suggestion = getSuggest(completion);
+    if (suggestion == null) {
+      failedCompletion('expected $completion');
+    }
+    if (returnType != null) {
+      expect(suggestion.returnType, returnType);
+    }
+  }
+
+  Future<void> computeCompletion(
+    String code, {
+    List<RuntimeCompletionVariable> variables,
+    List<RuntimeCompletionExpression> expressions,
+  }) async {
+    int codeOffset = code.indexOf('^');
+    expect(codeOffset, isNonNegative);
+    code = code.replaceAll('^', '');
+
+    var computer = new RuntimeCompletionComputer(
+        resourceProvider,
+        fileContentOverlay,
+        driver,
+        code,
+        codeOffset,
+        contextFile,
+        contextOffset,
+        variables,
+        expressions);
+    result = await computer.compute();
+  }
+
+  void failedCompletion(String message) {
+    var sb = new StringBuffer(message);
+    if (result.suggestions != null) {
+      sb.write('\n  found');
+      result.suggestions.toList()
+        ..sort((a, b) => a.completion.compareTo(b.completion))
+        ..forEach((suggestion) {
+          sb.write('\n    ${suggestion.completion} -> $suggestion');
+        });
+    }
+    fail(sb.toString());
+  }
+
+  CompletionSuggestion getSuggest(String completion) {
+    expect(result.suggestions, isNotNull);
+    for (var suggestion in result.suggestions) {
+      if (suggestion.completion == completion) {
+        return suggestion;
+      }
+    }
+    return null;
+  }
+
+  test_class_fields() async {
+    addContextFile(r'''
+class A {
+  int a;
+}
+class B extends A {
+  double b, c;
+  void foo() {
+    // context line
+  }
+}
+''');
+    await computeCompletion('^');
+    assertSuggested('a', returnType: 'int');
+    assertSuggested('b', returnType: 'double');
+    assertSuggested('c', returnType: 'double');
+  }
+
+  test_class_methods() async {
+    addContextFile(r'''
+class A {
+  int a() => null;
+}
+class B extends A {
+  double b() => null;
+  void foo() {
+    // context line
+  }
+}
+''');
+    await computeCompletion('^');
+    assertSuggested('a', returnType: 'int');
+    assertSuggested('b', returnType: 'double');
+  }
+
+  test_inPart() async {
+    addSource('/test/lib/a.dart', r'''
+part 'b.dart';
+part 'context.dart';
+
+int a;
+''');
+    addSource('/test/lib/b.dart', r'''
+part of 'a.dart';
+
+double b;
+''');
+    addContextFile(r'''
+part of 'a.dart';
+
+String c;
+
+void main() {
+  // context line
+}
+''');
+    await computeCompletion('^');
+    assertSuggested('a', returnType: 'int');
+    assertSuggested('b', returnType: 'double');
+    assertSuggested('c', returnType: 'String');
+  }
+
+  test_locals_block() async {
+    addContextFile(r'''
+class A {
+  int foo;
+}
+
+void contextFunction() {
+  var a = new A();
+  // context line
+}
+''');
+    await computeCompletion('a.^');
+    assertSuggested('foo');
+
+    // There was an issue with cleaning up
+    // Check that the second time it works too.
+    await computeCompletion('a.^');
+    assertSuggested('foo');
+  }
+
+  test_locals_block_codeWithClosure() async {
+    addContextFile(r'''
+main() {
+  var items = <String>[];
+  // context line
+}
+''');
+    await computeCompletion('items.forEach((e) => e.^)');
+    assertSuggested('toUpperCase');
+  }
+
+  test_locals_block_nested() async {
+    addContextFile(r'''
+void main() {
+  var a = 0;
+  var b = 0.0;
+  {
+    var a = '';
+    // context line
+  }
+  var c = 0;
+}
+''');
+    await computeCompletion('^');
+    assertSuggested('a', returnType: 'String');
+    assertSuggested('b', returnType: 'double');
+
+    // "c" is defined after the context offset, so is not visible.
+    assertNotSuggested('c');
+  }
+
+  test_locals_for() async {
+    addContextFile(r'''
+void main(List<int> intItems, List<double> doubleItems) {
+  for (var a = 0, b = 0.0; a < 5; a++) {
+    // context line
+  }
+}
+''');
+    await computeCompletion('^');
+    assertSuggested('a', returnType: 'int');
+    assertSuggested('b', returnType: 'double');
+  }
+
+  test_locals_forEach() async {
+    addContextFile(r'''
+void main(List<int> intItems, List<double> doubleItems) {
+  for (var a in intItems) {
+    for (var b in doubleItems) {
+      // context line
+    }
+  }
+}sosol
+''');
+    await computeCompletion('^');
+    assertSuggested('a', returnType: 'int');
+    assertSuggested('b', returnType: 'double');
+  }
+
+  test_parameters_constructor() async {
+    addContextFile(r'''
+class C {
+  C(int a, double b) {
+    // context line
+  }
+}
+''');
+    await computeCompletion('^');
+    assertSuggested('a', returnType: 'int');
+    assertSuggested('b', returnType: 'double');
+  }
+
+  test_parameters_function() async {
+    addContextFile(r'''
+void main(int a, double b) {
+  // context line
+}
+''');
+    await computeCompletion('^');
+    assertSuggested('a', returnType: 'int');
+    assertSuggested('b', returnType: 'double');
+  }
+
+  test_parameters_function_locals() async {
+    addContextFile(r'''
+void main(int a, int b) {
+  String a;
+  double c;
+  // context line
+}
+''');
+    await computeCompletion('^');
+    assertSuggested('a', returnType: 'String');
+    assertSuggested('b', returnType: 'int');
+    assertSuggested('c', returnType: 'double');
+  }
+
+  test_parameters_function_nested() async {
+    addContextFile(r'''
+void foo(int a, double b) {
+  void bar(String a, bool c) {
+    // context line
+  }
+}
+''');
+    await computeCompletion('^');
+    assertSuggested('a', returnType: 'String');
+    assertSuggested('b', returnType: 'double');
+    assertSuggested('c', returnType: 'bool');
+  }
+
+  test_parameters_functionExpression() async {
+    addContextFile(r'''
+void main(List<int> intItems, List<double> doubleItems) {
+  intItems.forEach((a) {
+    doubleItems.forEach((b) {
+      // context line
+    });
+  });
+}
+''');
+    await computeCompletion('^');
+    assertSuggested('a', returnType: 'int');
+    assertSuggested('b', returnType: 'double');
+  }
+
+  test_parameters_method() async {
+    addContextFile(r'''
+class C {
+  void main(int a, double b) {
+    // context line
+  }
+}
+''');
+    await computeCompletion('^');
+    assertSuggested('a', returnType: 'int');
+    assertSuggested('b', returnType: 'double');
+  }
+
+  test_parameters_method_locals() async {
+    addContextFile(r'''
+class C {
+  void main(int a, int b) {
+    String a;
+    double c;
+    // context line
+  }
+}
+''');
+    await computeCompletion('^');
+    assertSuggested('a', returnType: 'String');
+    assertSuggested('b', returnType: 'int');
+    assertSuggested('c', returnType: 'double');
+  }
+
+  test_syntheticImportPrefix() async {
+    newFile('/test/lib/a.dart', content: 'class A {}');
+    newFile('/test/lib/b.dart', content: 'class B {}');
+    addContextFile(r'''
+import 'a.dart';
+impoty 'b.dart';
+main() {
+  var a = new A();
+  var b = new B();
+  // context line
+}
+''');
+    await computeCompletion('^');
+    for (var suggestion in result.suggestions) {
+      expect(suggestion.completion, isNot(startsWith('__prefix')));
+    }
+  }
+
+  test_topLevelFunctions() async {
+    addContextFile(r'''
+int a() => null;
+double b() => null;
+void main() {
+  // context line
+}
+''');
+    await computeCompletion('^');
+    assertSuggested('a', returnType: 'int');
+    assertSuggested('b', returnType: 'double');
+  }
+
+  test_topLevelVariables() async {
+    addContextFile(r'''
+int a;
+double b;
+
+void main() {
+  // context line
+}
+''');
+    await computeCompletion('^');
+    assertSuggested('a', returnType: 'int');
+    assertSuggested('b', returnType: 'double');
+  }
+}
diff --git a/pkg/analysis_server/test/src/plugin/protocol_test_utilities.dart b/pkg/analysis_server/test/src/plugin/protocol_test_utilities.dart
index 91ff506..6bfaf1d 100644
--- a/pkg/analysis_server/test/src/plugin/protocol_test_utilities.dart
+++ b/pkg/analysis_server/test/src/plugin/protocol_test_utilities.dart
@@ -91,7 +91,7 @@
   String fileName(int stringIndex) => '${strings[stringIndex]}.dart';
 
   FoldingRegion foldingRegion(int offset, int length) =>
-      new FoldingRegion(FoldingKind.COMMENT, offset, length);
+      new FoldingRegion(FoldingKind.FILE_HEADER, offset, length);
 
   HighlightRegion highlightRegion(int offset, int length) =>
       new HighlightRegion(HighlightRegionType.FIELD, offset, length);
diff --git a/pkg/analysis_server/test/src/plugin/result_merger_test.dart b/pkg/analysis_server/test/src/plugin/result_merger_test.dart
index dc409fc..75f11fa 100644
--- a/pkg/analysis_server/test/src/plugin/result_merger_test.dart
+++ b/pkg/analysis_server/test/src/plugin/result_merger_test.dart
@@ -129,7 +129,7 @@
   }
 
   void test_mergeFoldingRegion() {
-    FoldingKind kind = FoldingKind.COMMENT;
+    FoldingKind kind = FoldingKind.FILE_HEADER;
     FoldingRegion region1 = new FoldingRegion(kind, 30, 5);
     FoldingRegion region2 = new FoldingRegion(kind, 0, 4);
     FoldingRegion region3 = new FoldingRegion(kind, 20, 6);
diff --git a/pkg/analysis_server/test/src/utilities/flutter_test.dart b/pkg/analysis_server/test/src/utilities/flutter_test.dart
index fb85da9..7ec839b 100644
--- a/pkg/analysis_server/test/src/utilities/flutter_test.dart
+++ b/pkg/analysis_server/test/src/utilities/flutter_test.dart
@@ -272,6 +272,7 @@
 import 'package:flutter/widgets.dart';
 
 main() {
+  MyWidget.named(); // use
   var text = new Text('abc');
   text;
   createEmptyText();
@@ -280,9 +281,20 @@
   intVariable;
 }
 
+class MyWidget extends StatelessWidget {
+  MyWidget.named();
+}
+
 Text createEmptyText() => new Text('');
 ''');
     {
+      Expression expression = findNodeAtString('named(); // use');
+      expect(isWidgetExpression(expression), isFalse);
+      var creation = expression.parent.parent as InstanceCreationExpression;
+      expect(isWidgetExpression(creation), isTrue);
+    }
+
+    {
       Expression expression = findNodeAtString("new Text('abc')");
       expect(isWidgetExpression(expression), isTrue);
     }
diff --git a/pkg/analysis_server/test/src/utilities/flutter_util.dart b/pkg/analysis_server/test/src/utilities/flutter_util.dart
index 83b5b82..e7012a1 100644
--- a/pkg/analysis_server/test/src/utilities/flutter_util.dart
+++ b/pkg/analysis_server/test/src/utilities/flutter_util.dart
@@ -229,6 +229,14 @@
     Widget child,
   });
 }
+
+class Expanded extends StatelessWidget {
+  const Expanded({
+    Key key,
+    int flex: 1,
+    @required Widget child,
+  });
+}
 ''');
 
     newFile('$flutterPkgLibPath/src/widgets/container.dart', r'''
diff --git a/pkg/analysis_server/tool/instrumentation/server.dart b/pkg/analysis_server/tool/instrumentation/server.dart
index 768c8b8..64f77bb 100644
--- a/pkg/analysis_server/tool/instrumentation/server.dart
+++ b/pkg/analysis_server/tool/instrumentation/server.dart
@@ -101,7 +101,7 @@
    * Begin serving HTTP requests over the given [port].
    */
   void serveHttp(int port) {
-    _server = HttpServer.bind(InternetAddress.LOOPBACK_IP_V4, port);
+    _server = HttpServer.bind(InternetAddress.loopbackIPv4, port);
     _server.then(_handleServer).catchError((_) {/* Ignore errors. */});
   }
 
diff --git a/pkg/analysis_server/tool/spec/generated/java/AnalysisServer.java b/pkg/analysis_server/tool/spec/generated/java/AnalysisServer.java
index 6272649..f8991b5 100644
--- a/pkg/analysis_server/tool/spec/generated/java/AnalysisServer.java
+++ b/pkg/analysis_server/tool/spec/generated/java/AnalysisServer.java
@@ -576,6 +576,38 @@
   public void execution_deleteContext(String id);
 
   /**
+   * {@code execution.getSuggestions}
+   *
+   * Request completion suggestions for the given runtime context.
+   *
+   * It might take one or two requests of this type to get completion suggestions. The first request
+   * should have only "code", "offset", and "variables", but not "expressions". If there are
+   * sub-expressions that can have different runtime types, and are considered to be safe to evaluate
+   * at runtime (e.g. getters), so using their actual runtime types can improve completion results,
+   * the server will not include the "suggestions" field in the response, and instead will return the
+   * "expressions" field. The client will use debug API to get current runtime types for these
+   * sub-expressions and send another request, this time with "expressions". If there are no
+   * interesting sub-expressions to get runtime types for, or when the "expressions" field is
+   * provided by the client, the server will return "suggestions" in the response.
+   *
+   * @param code The code to get suggestions in.
+   * @param offset The offset within the code to get suggestions at.
+   * @param contextFile The path of the context file, e.g. the file of the current debugger frame.
+   *         The combination of the context file and context offset can be used to ensure that all
+   *         variables of the context are available for completion (with their static types).
+   * @param contextOffset The offset in the context file, e.g. the line offset in the current
+   *         debugger frame.
+   * @param variables The runtime context variables that are potentially referenced in the code.
+   * @param expressions The list of sub-expressions in the code for which the client wants to provide
+   *         runtime types. It does not have to be the full list of expressions requested by the
+   *         server, for missing expressions their static types will be used. When this field is
+   *         omitted, the server will return completion suggestions only when there are no
+   *         interesting sub-expressions in the given code. The client may provide an empty list, in
+   *         this case the server will return completion suggestions.
+   */
+  public void execution_getSuggestions(String code, int offset, String contextFile, int contextOffset, List<RuntimeCompletionVariable> variables, List<RuntimeCompletionExpression> expressions, GetSuggestionsConsumer consumer);
+
+  /**
    * {@code execution.mapUri}
    *
    * Map a URI from the execution context to the file that it corresponds to, or map a file to the
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/FoldingKind.java b/pkg/analysis_server/tool/spec/generated/java/types/FoldingKind.java
index f1d947b..e4fdb2e 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/FoldingKind.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/FoldingKind.java
@@ -15,14 +15,16 @@
  */
 public class FoldingKind {
 
-  public static final String COMMENT = "COMMENT";
+  public static final String ANNOTATIONS = "ANNOTATIONS";
 
-  public static final String CLASS_MEMBER = "CLASS_MEMBER";
+  public static final String CLASS_BODY = "CLASS_BODY";
 
   public static final String DIRECTIVES = "DIRECTIVES";
 
   public static final String DOCUMENTATION_COMMENT = "DOCUMENTATION_COMMENT";
 
-  public static final String TOP_LEVEL_DECLARATION = "TOP_LEVEL_DECLARATION";
+  public static final String FILE_HEADER = "FILE_HEADER";
+
+  public static final String FUNCTION_BODY = "FUNCTION_BODY";
 
 }
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/RuntimeCompletionExpression.java b/pkg/analysis_server/tool/spec/generated/java/types/RuntimeCompletionExpression.java
new file mode 100644
index 0000000..c0cc239
--- /dev/null
+++ b/pkg/analysis_server/tool/spec/generated/java/types/RuntimeCompletionExpression.java
@@ -0,0 +1,151 @@
+/*
+ * 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;
+
+/**
+ * An expression for which we want to know its runtime type. In expressions like `a.b.c.where((e)
+ * =&gt; e.^)` we want to know the runtime type of `a.b.c` to enforce it statically at the time
+ * when we compute completion suggestions, and get better type for `e`.
+ *
+ * @coverage dart.server.generated.types
+ */
+@SuppressWarnings("unused")
+public class RuntimeCompletionExpression {
+
+  public static final RuntimeCompletionExpression[] EMPTY_ARRAY = new RuntimeCompletionExpression[0];
+
+  public static final List<RuntimeCompletionExpression> EMPTY_LIST = Lists.newArrayList();
+
+  /**
+   * The offset of the expression in the code for completion.
+   */
+  private final int offset;
+
+  /**
+   * The length of the expression in the code for completion.
+   */
+  private final int length;
+
+  /**
+   * When the expression is sent from the server to the client, the type is omitted. The client
+   * should fill the type when it sends the request to the server again.
+   */
+  private final RuntimeCompletionExpressionType type;
+
+  /**
+   * Constructor for {@link RuntimeCompletionExpression}.
+   */
+  public RuntimeCompletionExpression(int offset, int length, RuntimeCompletionExpressionType type) {
+    this.offset = offset;
+    this.length = length;
+    this.type = type;
+  }
+
+  @Override
+  public boolean equals(Object obj) {
+    if (obj instanceof RuntimeCompletionExpression) {
+      RuntimeCompletionExpression other = (RuntimeCompletionExpression) obj;
+      return
+        other.offset == offset &&
+        other.length == length &&
+        ObjectUtilities.equals(other.type, type);
+    }
+    return false;
+  }
+
+  public static RuntimeCompletionExpression fromJson(JsonObject jsonObject) {
+    int offset = jsonObject.get("offset").getAsInt();
+    int length = jsonObject.get("length").getAsInt();
+    RuntimeCompletionExpressionType type = jsonObject.get("type") == null ? null : RuntimeCompletionExpressionType.fromJson(jsonObject.get("type").getAsJsonObject());
+    return new RuntimeCompletionExpression(offset, length, type);
+  }
+
+  public static List<RuntimeCompletionExpression> fromJsonArray(JsonArray jsonArray) {
+    if (jsonArray == null) {
+      return EMPTY_LIST;
+    }
+    ArrayList<RuntimeCompletionExpression> list = new ArrayList<RuntimeCompletionExpression>(jsonArray.size());
+    Iterator<JsonElement> iterator = jsonArray.iterator();
+    while (iterator.hasNext()) {
+      list.add(fromJson(iterator.next().getAsJsonObject()));
+    }
+    return list;
+  }
+
+  /**
+   * The length of the expression in the code for completion.
+   */
+  public int getLength() {
+    return length;
+  }
+
+  /**
+   * The offset of the expression in the code for completion.
+   */
+  public int getOffset() {
+    return offset;
+  }
+
+  /**
+   * When the expression is sent from the server to the client, the type is omitted. The client
+   * should fill the type when it sends the request to the server again.
+   */
+  public RuntimeCompletionExpressionType getType() {
+    return type;
+  }
+
+  @Override
+  public int hashCode() {
+    HashCodeBuilder builder = new HashCodeBuilder();
+    builder.append(offset);
+    builder.append(length);
+    builder.append(type);
+    return builder.toHashCode();
+  }
+
+  public JsonObject toJson() {
+    JsonObject jsonObject = new JsonObject();
+    jsonObject.addProperty("offset", offset);
+    jsonObject.addProperty("length", length);
+    if (type != null) {
+      jsonObject.add("type", type.toJson());
+    }
+    return jsonObject;
+  }
+
+  @Override
+  public String toString() {
+    StringBuilder builder = new StringBuilder();
+    builder.append("[");
+    builder.append("offset=");
+    builder.append(offset + ", ");
+    builder.append("length=");
+    builder.append(length + ", ");
+    builder.append("type=");
+    builder.append(type);
+    builder.append("]");
+    return builder.toString();
+  }
+
+}
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/RuntimeCompletionExpressionType.java b/pkg/analysis_server/tool/spec/generated/java/types/RuntimeCompletionExpressionType.java
new file mode 100644
index 0000000..c31710a
--- /dev/null
+++ b/pkg/analysis_server/tool/spec/generated/java/types/RuntimeCompletionExpressionType.java
@@ -0,0 +1,255 @@
+/*
+ * 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 type at runtime.
+ *
+ * @coverage dart.server.generated.types
+ */
+@SuppressWarnings("unused")
+public class RuntimeCompletionExpressionType {
+
+  public static final RuntimeCompletionExpressionType[] EMPTY_ARRAY = new RuntimeCompletionExpressionType[0];
+
+  public static final List<RuntimeCompletionExpressionType> EMPTY_LIST = Lists.newArrayList();
+
+  /**
+   * The path of the library that has this type. Omitted if the type is not declared in any library,
+   * e.g. "dynamic", or "void".
+   */
+  private final String libraryPath;
+
+  /**
+   * The kind of the type.
+   */
+  private final String kind;
+
+  /**
+   * The name of the type. Omitted if the type does not have a name, e.g. an inline function type.
+   */
+  private final String name;
+
+  /**
+   * The type arguments of the type. Omitted if the type does not have type parameters.
+   */
+  private final List<RuntimeCompletionExpressionType> typeArguments;
+
+  /**
+   * If the type is a function type, the return type of the function. Omitted if the type is not a
+   * function type.
+   */
+  private final RuntimeCompletionExpressionType returnType;
+
+  /**
+   * If the type is a function type, the types of the function parameters of all kinds - required,
+   * optional positional, and optional named. Omitted if the type is not a function type.
+   */
+  private final List<RuntimeCompletionExpressionType> parameterTypes;
+
+  /**
+   * If the type is a function type, the names of the function parameters of all kinds - required,
+   * optional positional, and optional named. The names of positional parameters are empty strings.
+   * Omitted if the type is not a function type.
+   */
+  private final List<String> parameterNames;
+
+  /**
+   * Constructor for {@link RuntimeCompletionExpressionType}.
+   */
+  public RuntimeCompletionExpressionType(String libraryPath, String kind, String name, List<RuntimeCompletionExpressionType> typeArguments, RuntimeCompletionExpressionType returnType, List<RuntimeCompletionExpressionType> parameterTypes, List<String> parameterNames) {
+    this.libraryPath = libraryPath;
+    this.kind = kind;
+    this.name = name;
+    this.typeArguments = typeArguments;
+    this.returnType = returnType;
+    this.parameterTypes = parameterTypes;
+    this.parameterNames = parameterNames;
+  }
+
+  @Override
+  public boolean equals(Object obj) {
+    if (obj instanceof RuntimeCompletionExpressionType) {
+      RuntimeCompletionExpressionType other = (RuntimeCompletionExpressionType) obj;
+      return
+        ObjectUtilities.equals(other.libraryPath, libraryPath) &&
+        ObjectUtilities.equals(other.kind, kind) &&
+        ObjectUtilities.equals(other.name, name) &&
+        ObjectUtilities.equals(other.typeArguments, typeArguments) &&
+        ObjectUtilities.equals(other.returnType, returnType) &&
+        ObjectUtilities.equals(other.parameterTypes, parameterTypes) &&
+        ObjectUtilities.equals(other.parameterNames, parameterNames);
+    }
+    return false;
+  }
+
+  public static RuntimeCompletionExpressionType fromJson(JsonObject jsonObject) {
+    String libraryPath = jsonObject.get("libraryPath") == null ? null : jsonObject.get("libraryPath").getAsString();
+    String kind = jsonObject.get("kind").getAsString();
+    String name = jsonObject.get("name") == null ? null : jsonObject.get("name").getAsString();
+    List<RuntimeCompletionExpressionType> typeArguments = jsonObject.get("typeArguments") == null ? null : RuntimeCompletionExpressionType.fromJsonArray(jsonObject.get("typeArguments").getAsJsonArray());
+    RuntimeCompletionExpressionType returnType = jsonObject.get("returnType") == null ? null : RuntimeCompletionExpressionType.fromJson(jsonObject.get("returnType").getAsJsonObject());
+    List<RuntimeCompletionExpressionType> parameterTypes = jsonObject.get("parameterTypes") == null ? null : RuntimeCompletionExpressionType.fromJsonArray(jsonObject.get("parameterTypes").getAsJsonArray());
+    List<String> parameterNames = jsonObject.get("parameterNames") == null ? null : JsonUtilities.decodeStringList(jsonObject.get("parameterNames").getAsJsonArray());
+    return new RuntimeCompletionExpressionType(libraryPath, kind, name, typeArguments, returnType, parameterTypes, parameterNames);
+  }
+
+  public static List<RuntimeCompletionExpressionType> fromJsonArray(JsonArray jsonArray) {
+    if (jsonArray == null) {
+      return EMPTY_LIST;
+    }
+    ArrayList<RuntimeCompletionExpressionType> list = new ArrayList<RuntimeCompletionExpressionType>(jsonArray.size());
+    Iterator<JsonElement> iterator = jsonArray.iterator();
+    while (iterator.hasNext()) {
+      list.add(fromJson(iterator.next().getAsJsonObject()));
+    }
+    return list;
+  }
+
+  /**
+   * The kind of the type.
+   */
+  public String getKind() {
+    return kind;
+  }
+
+  /**
+   * The path of the library that has this type. Omitted if the type is not declared in any library,
+   * e.g. "dynamic", or "void".
+   */
+  public String getLibraryPath() {
+    return libraryPath;
+  }
+
+  /**
+   * The name of the type. Omitted if the type does not have a name, e.g. an inline function type.
+   */
+  public String getName() {
+    return name;
+  }
+
+  /**
+   * If the type is a function type, the names of the function parameters of all kinds - required,
+   * optional positional, and optional named. The names of positional parameters are empty strings.
+   * Omitted if the type is not a function type.
+   */
+  public List<String> getParameterNames() {
+    return parameterNames;
+  }
+
+  /**
+   * If the type is a function type, the types of the function parameters of all kinds - required,
+   * optional positional, and optional named. Omitted if the type is not a function type.
+   */
+  public List<RuntimeCompletionExpressionType> getParameterTypes() {
+    return parameterTypes;
+  }
+
+  /**
+   * If the type is a function type, the return type of the function. Omitted if the type is not a
+   * function type.
+   */
+  public RuntimeCompletionExpressionType getReturnType() {
+    return returnType;
+  }
+
+  /**
+   * The type arguments of the type. Omitted if the type does not have type parameters.
+   */
+  public List<RuntimeCompletionExpressionType> getTypeArguments() {
+    return typeArguments;
+  }
+
+  @Override
+  public int hashCode() {
+    HashCodeBuilder builder = new HashCodeBuilder();
+    builder.append(libraryPath);
+    builder.append(kind);
+    builder.append(name);
+    builder.append(typeArguments);
+    builder.append(returnType);
+    builder.append(parameterTypes);
+    builder.append(parameterNames);
+    return builder.toHashCode();
+  }
+
+  public JsonObject toJson() {
+    JsonObject jsonObject = new JsonObject();
+    if (libraryPath != null) {
+      jsonObject.addProperty("libraryPath", libraryPath);
+    }
+    jsonObject.addProperty("kind", kind);
+    if (name != null) {
+      jsonObject.addProperty("name", name);
+    }
+    if (typeArguments != null) {
+      JsonArray jsonArrayTypeArguments = new JsonArray();
+      for (RuntimeCompletionExpressionType elt : typeArguments) {
+        jsonArrayTypeArguments.add(elt.toJson());
+      }
+      jsonObject.add("typeArguments", jsonArrayTypeArguments);
+    }
+    if (returnType != null) {
+      jsonObject.add("returnType", returnType.toJson());
+    }
+    if (parameterTypes != null) {
+      JsonArray jsonArrayParameterTypes = new JsonArray();
+      for (RuntimeCompletionExpressionType elt : parameterTypes) {
+        jsonArrayParameterTypes.add(elt.toJson());
+      }
+      jsonObject.add("parameterTypes", jsonArrayParameterTypes);
+    }
+    if (parameterNames != null) {
+      JsonArray jsonArrayParameterNames = new JsonArray();
+      for (String elt : parameterNames) {
+        jsonArrayParameterNames.add(new JsonPrimitive(elt));
+      }
+      jsonObject.add("parameterNames", jsonArrayParameterNames);
+    }
+    return jsonObject;
+  }
+
+  @Override
+  public String toString() {
+    StringBuilder builder = new StringBuilder();
+    builder.append("[");
+    builder.append("libraryPath=");
+    builder.append(libraryPath + ", ");
+    builder.append("kind=");
+    builder.append(kind + ", ");
+    builder.append("name=");
+    builder.append(name + ", ");
+    builder.append("typeArguments=");
+    builder.append(StringUtils.join(typeArguments, ", ") + ", ");
+    builder.append("returnType=");
+    builder.append(returnType + ", ");
+    builder.append("parameterTypes=");
+    builder.append(StringUtils.join(parameterTypes, ", ") + ", ");
+    builder.append("parameterNames=");
+    builder.append(StringUtils.join(parameterNames, ", "));
+    builder.append("]");
+    return builder.toString();
+  }
+
+}
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/RuntimeCompletionExpressionTypeKind.java b/pkg/analysis_server/tool/spec/generated/java/types/RuntimeCompletionExpressionTypeKind.java
new file mode 100644
index 0000000..c544c9f
--- /dev/null
+++ b/pkg/analysis_server/tool/spec/generated/java/types/RuntimeCompletionExpressionTypeKind.java
@@ -0,0 +1,24 @@
+/*
+ * 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 kinds of runtime expression types.
+ *
+ * @coverage dart.server.generated.types
+ */
+public class RuntimeCompletionExpressionTypeKind {
+
+  public static final String DYNAMIC = "DYNAMIC";
+
+  public static final String FUNCTION = "FUNCTION";
+
+  public static final String INTERFACE = "INTERFACE";
+
+}
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/RuntimeCompletionVariable.java b/pkg/analysis_server/tool/spec/generated/java/types/RuntimeCompletionVariable.java
new file mode 100644
index 0000000..05e9040
--- /dev/null
+++ b/pkg/analysis_server/tool/spec/generated/java/types/RuntimeCompletionVariable.java
@@ -0,0 +1,128 @@
+/*
+ * 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 variable in a runtime context.
+ *
+ * @coverage dart.server.generated.types
+ */
+@SuppressWarnings("unused")
+public class RuntimeCompletionVariable {
+
+  public static final RuntimeCompletionVariable[] EMPTY_ARRAY = new RuntimeCompletionVariable[0];
+
+  public static final List<RuntimeCompletionVariable> EMPTY_LIST = Lists.newArrayList();
+
+  /**
+   * The name of the variable. The name "this" has a special meaning and is used as an implicit
+   * target for runtime completion, and in explicit "this" references.
+   */
+  private final String name;
+
+  /**
+   * The type of the variable.
+   */
+  private final RuntimeCompletionExpressionType type;
+
+  /**
+   * Constructor for {@link RuntimeCompletionVariable}.
+   */
+  public RuntimeCompletionVariable(String name, RuntimeCompletionExpressionType type) {
+    this.name = name;
+    this.type = type;
+  }
+
+  @Override
+  public boolean equals(Object obj) {
+    if (obj instanceof RuntimeCompletionVariable) {
+      RuntimeCompletionVariable other = (RuntimeCompletionVariable) obj;
+      return
+        ObjectUtilities.equals(other.name, name) &&
+        ObjectUtilities.equals(other.type, type);
+    }
+    return false;
+  }
+
+  public static RuntimeCompletionVariable fromJson(JsonObject jsonObject) {
+    String name = jsonObject.get("name").getAsString();
+    RuntimeCompletionExpressionType type = RuntimeCompletionExpressionType.fromJson(jsonObject.get("type").getAsJsonObject());
+    return new RuntimeCompletionVariable(name, type);
+  }
+
+  public static List<RuntimeCompletionVariable> fromJsonArray(JsonArray jsonArray) {
+    if (jsonArray == null) {
+      return EMPTY_LIST;
+    }
+    ArrayList<RuntimeCompletionVariable> list = new ArrayList<RuntimeCompletionVariable>(jsonArray.size());
+    Iterator<JsonElement> iterator = jsonArray.iterator();
+    while (iterator.hasNext()) {
+      list.add(fromJson(iterator.next().getAsJsonObject()));
+    }
+    return list;
+  }
+
+  /**
+   * The name of the variable. The name "this" has a special meaning and is used as an implicit
+   * target for runtime completion, and in explicit "this" references.
+   */
+  public String getName() {
+    return name;
+  }
+
+  /**
+   * The type of the variable.
+   */
+  public RuntimeCompletionExpressionType getType() {
+    return type;
+  }
+
+  @Override
+  public int hashCode() {
+    HashCodeBuilder builder = new HashCodeBuilder();
+    builder.append(name);
+    builder.append(type);
+    return builder.toHashCode();
+  }
+
+  public JsonObject toJson() {
+    JsonObject jsonObject = new JsonObject();
+    jsonObject.addProperty("name", name);
+    jsonObject.add("type", type.toJson());
+    return jsonObject;
+  }
+
+  @Override
+  public String toString() {
+    StringBuilder builder = new StringBuilder();
+    builder.append("[");
+    builder.append("name=");
+    builder.append(name + ", ");
+    builder.append("type=");
+    builder.append(type);
+    builder.append("]");
+    return builder.toString();
+  }
+
+}
diff --git a/pkg/analysis_server/tool/spec/spec_input.html b/pkg/analysis_server/tool/spec/spec_input.html
index 0d1c534..7e8bc43 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.20.2</version>
+  <version>1.20.3</version>
 </h1>
 <p>
   This document contains a specification of the API provided by the
@@ -2307,6 +2307,111 @@
       </field>
     </params>
   </request>
+  <request method="getSuggestions">
+    <p>
+      Request completion suggestions for the given runtime context.
+    </p>
+    <p>
+      It might take one or two requests of this type to get completion
+      suggestions. The first request should have only "code", "offset",
+      and "variables", but not "expressions". If there are sub-expressions that
+      can have different runtime types, and are considered to be safe to
+      evaluate at runtime (e.g. getters), so using their actual runtime types
+      can improve completion results, the server will not include the
+      "suggestions" field in the response, and instead will return the
+      "expressions" field. The client will use debug API to get current runtime
+      types for these sub-expressions and send another request, this time with
+      "expressions". If there are no interesting sub-expressions to get
+      runtime types for, or when the "expressions" field is provided by the
+      client, the server will return "suggestions" in the response.
+    </p>
+    <params>
+      <field name="code">
+        <ref>String</ref>
+        <p>
+          The code to get suggestions in.
+        </p>
+      </field>
+      <field name="offset">
+        <ref>int</ref>
+        <p>
+          The offset within the code to get suggestions at.
+        </p>
+      </field>
+      <field name="contextFile">
+        <ref>FilePath</ref>
+        <p>
+          The path of the context file, e.g. the file of the current debugger
+          frame. The combination of the context file and context offset can
+          be used to ensure that all variables of the context are available
+          for completion (with their static types).
+        </p>
+      </field>
+      <field name="contextOffset">
+        <ref>int</ref>
+        <p>
+          The offset in the context file, e.g. the line offset in the current
+          debugger frame.
+        </p>
+      </field>
+      <field name="variables">
+        <list>
+          <ref>RuntimeCompletionVariable</ref>
+        </list>
+        <p>
+          The runtime context variables that are potentially referenced in the
+          code.
+        </p>
+      </field>
+      <field name="expressions" optional="true">
+        <list>
+          <ref>RuntimeCompletionExpression</ref>
+        </list>
+        <p>
+          The list of sub-expressions in the code for which the client wants
+          to provide runtime types. It does not have to be the full list of
+          expressions requested by the server, for missing expressions their
+          static types will be used.
+        </p>
+        <p>
+          When this field is omitted, the server will return completion
+          suggestions only when there are no interesting sub-expressions in the
+          given code. The client may provide an empty list, in this case the
+          server will return completion suggestions.
+        </p>
+      </field>
+    </params>
+    <result>
+      <field name="suggestions" optional="true">
+        <list>
+          <ref>CompletionSuggestion</ref>
+        </list>
+        <p>
+          The completion suggestions. In contrast to usual completion request,
+          suggestions for private elements also will be provided.
+        </p>
+        <p>
+          If there are sub-expressions that can have different runtime types,
+          and are considered to be safe to evaluate at runtime (e.g. getters),
+          so using their actual runtime types can improve completion results,
+          the server omits this field in the response, and instead will return
+          the "expressions" field.
+        </p>
+      </field>
+      <field name="expressions" optional="true">
+        <list>
+          <ref>RuntimeCompletionExpression</ref>
+        </list>
+        <p>
+          The list of sub-expressions in the code for which the server would
+          like to know runtime types to provide better completion suggestions.
+        </p>
+        <p>
+          This field is omitted the field "suggestions" is returned.
+        </p>
+      </field>
+    </result>
+  </request>
   <request method="mapUri">
     <p>
       Map a URI from the execution context to the file that it corresponds
@@ -3075,6 +3180,132 @@
       The identifier for a execution context.
     </p>
   </type>
+  <type name="RuntimeCompletionExpression">
+    <p>
+      An expression for which we want to know its runtime type.
+      In expressions like `a.b.c.where((e) => e.^)` we want to know the
+      runtime type of `a.b.c` to enforce it statically at the time when we
+      compute completion suggestions, and get better type for `e`.
+    </p>
+    <object>
+      <field name="offset">
+        <ref>int</ref>
+        <p>
+          The offset of the expression in the code for completion.
+        </p>
+      </field>
+      <field name="length">
+        <ref>int</ref>
+        <p>
+          The length of the expression in the code for completion.
+        </p>
+      </field>
+      <field name="type" optional="true">
+        <ref>RuntimeCompletionExpressionType</ref>
+        <p>
+          When the expression is sent from the server to the client, the
+          type is omitted. The client should fill the type when it sends the
+          request to the server again.
+        </p>
+      </field>
+    </object>
+  </type>
+  <type name="RuntimeCompletionVariable">
+    <p>
+      A variable in a runtime context.
+    </p>
+    <object>
+      <field name="name">
+        <ref>String</ref>
+        <p>
+          The name of the variable.
+          The name "this" has a special meaning and is used as an implicit
+          target for runtime completion, and in explicit "this" references.
+        </p>
+      </field>
+      <field name="type">
+        <ref>RuntimeCompletionExpressionType</ref>
+        <p>
+          The type of the variable.
+        </p>
+      </field>
+    </object>
+  </type>
+  <type name="RuntimeCompletionExpressionType">
+    <p>
+      A type at runtime.
+    </p>
+    <object>
+      <field name="libraryPath" optional="true">
+        <ref>FilePath</ref>
+        <p>
+          The path of the library that has this type.
+          Omitted if the type is not declared in any library, e.g. "dynamic",
+          or "void".
+        </p>
+      </field>
+      <field name="kind">
+        <ref>RuntimeCompletionExpressionTypeKind</ref>
+        <p>
+          The kind of the type.
+        </p>
+      </field>
+      <field name="name" optional="true">
+        <ref>String</ref>
+        <p>
+          The name of the type. Omitted if the type does not have a name, e.g.
+          an inline function type.
+        </p>
+      </field>
+      <field name="typeArguments" optional="true">
+        <list>
+          <ref>RuntimeCompletionExpressionType</ref>
+        </list>
+        <p>
+          The type arguments of the type.
+          Omitted if the type does not have type parameters.
+        </p>
+      </field>
+      <field name="returnType" optional="true">
+        <ref>RuntimeCompletionExpressionType</ref>
+        <p>
+          If the type is a function type, the return type of the function.
+          Omitted if the type is not a function type.
+        </p>
+      </field>
+      <field name="parameterTypes" optional="true">
+        <list>
+          <ref>RuntimeCompletionExpressionType</ref>
+        </list>
+        <p>
+          If the type is a function type, the types of the function parameters
+          of all kinds - required, optional positional, and optional named.
+          Omitted if the type is not a function type.
+        </p>
+      </field>
+      <field name="parameterNames" optional="true">
+        <list>
+          <ref>String</ref>
+        </list>
+        <p>
+          If the type is a function type, the names of the function parameters
+          of all kinds - required, optional positional, and optional named.
+          The names of positional parameters are empty strings.
+          Omitted if the type is not a function type.
+        </p>
+      </field>
+    </object>
+  </type>
+  <type name="RuntimeCompletionExpressionTypeKind">
+    <p>
+      An enumeration of the kinds of runtime expression types.
+    </p>
+    <enum>
+      <value><code>DYNAMIC</code></value>
+      <value><code>FUNCTION</code></value>
+      <value><code>INTERFACE</code></value>
+    </enum>
+  </type>
   <type name="ExecutionService">
     <p>
       An enumeration of the services provided by the execution
diff --git a/pkg/analysis_server_client/test/analysis_server_client_test.dart b/pkg/analysis_server_client/test/analysis_server_client_test.dart
index 6ceabe2..baaf679 100644
--- a/pkg/analysis_server_client/test/analysis_server_client_test.dart
+++ b/pkg/analysis_server_client/test/analysis_server_client_test.dart
@@ -105,7 +105,7 @@
   int get pid => null;
 
   @override
-  bool kill([ProcessSignal signal = ProcessSignal.SIGTERM]) => null;
+  bool kill([ProcessSignal signal = ProcessSignal.sigterm]) => null;
 }
 
 class MockStdin implements IOSink {
diff --git a/pkg/analyzer/CHANGELOG.md b/pkg/analyzer/CHANGELOG.md
index d25a9bb..8d9ed60 100644
--- a/pkg/analyzer/CHANGELOG.md
+++ b/pkg/analyzer/CHANGELOG.md
@@ -1,3 +1,27 @@
+## 0.32.0
+
+* Allow annotations on enum constants.
+* Analyzer fully supports being run on the VM with --preview-dart-2.
+* Fix heap usage regression by not storing bytes in the file cache.
+* Add AnalysisSessionHelper.getTopLevelPropertyAccessor().
+* Don't infer types when there's an irreconcilable type mismatch (#32305)
+* Many fasta parser improvements.
+* Use @isTest and @isTestGroup to understand executable element as a
+  test/group.  To use, add `@isTest` annotations (from package:meta)
+  to the methods in their package which define a test.
+```dart
+@isTest
+void myMagicTest(String name, FutureOr Function() body) {
+  test(name, body);
+}
+```
+  When subscribed to [notifications for outlines of a test file](https://htmlpreview.github.io/?https://github.com/dart-lang/sdk/blob/master/pkg/analysis_server/doc/api.html#notification_analysis.outline),
+  they will include elements for UNIT_TEST_GROUP and UNIT_TEST_TEST.
+* Improve guess for type name identifier. (#32765)
+* Fix LineInfo.getOffsetOfLineAfter().
+* Remove some flutter specific analysis code.
+* Fix resolution tests when run locally.
+
 ## 0.31.2-alpha.2
 
 * Refactoring to make element model logic sharable with
diff --git a/pkg/analyzer/lib/dart/analysis/session.dart b/pkg/analyzer/lib/dart/analysis/session.dart
index a39a2f7..dd8c595 100644
--- a/pkg/analyzer/lib/dart/analysis/session.dart
+++ b/pkg/analyzer/lib/dart/analysis/session.dart
@@ -7,6 +7,7 @@
 import 'package:analyzer/dart/analysis/results.dart';
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/exception/exception.dart';
+import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/src/dart/analysis/top_level_declaration.dart';
 import 'package:analyzer/src/generated/resolver.dart';
 import 'package:analyzer/src/generated/source.dart';
@@ -22,6 +23,11 @@
  */
 abstract class AnalysisSession {
   /**
+   * Return the [ResourceProvider] that is used to access the file system.
+   */
+  ResourceProvider get resourceProvider;
+
+  /**
    * Return the source factory used to resolve URIs.
    */
   SourceFactory get sourceFactory;
diff --git a/pkg/analyzer/lib/error/error.dart b/pkg/analyzer/lib/error/error.dart
index b2743a7..5679752 100644
--- a/pkg/analyzer/lib/error/error.dart
+++ b/pkg/analyzer/lib/error/error.dart
@@ -320,7 +320,6 @@
   ParserErrorCode.ABSTRACT_TOP_LEVEL_FUNCTION,
   ParserErrorCode.ABSTRACT_TOP_LEVEL_VARIABLE,
   ParserErrorCode.ABSTRACT_TYPEDEF,
-  ParserErrorCode.ANNOTATION_ON_ENUM_CONSTANT,
   ParserErrorCode.ASYNC_KEYWORD_USED_AS_IDENTIFIER,
   ParserErrorCode.BREAK_OUTSIDE_OF_LOOP,
   ParserErrorCode.CATCH_SYNTAX,
diff --git a/pkg/analyzer/lib/src/dart/analysis/driver.dart b/pkg/analyzer/lib/src/dart/analysis/driver.dart
index f8b1648..bf98050 100644
--- a/pkg/analyzer/lib/src/dart/analysis/driver.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/driver.dart
@@ -431,6 +431,11 @@
   }
 
   /**
+   * Return the [ResourceProvider] that is used to access the file system.
+   */
+  ResourceProvider get resourceProvider => _resourceProvider;
+
+  /**
    * Return the [Stream] that produces [AnalysisResult]s for added files.
    *
    * Note that the stream supports only one single subscriber.
diff --git a/pkg/analyzer/lib/src/dart/analysis/kernel_metadata.dart b/pkg/analyzer/lib/src/dart/analysis/kernel_metadata.dart
index f96c5c6..6962a80 100644
--- a/pkg/analyzer/lib/src/dart/analysis/kernel_metadata.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/kernel_metadata.dart
@@ -79,14 +79,16 @@
       <kernel.TreeNode, AnalyzerMetadata>{};
 
   @override
-  AnalyzerMetadata readFromBinary(kernel.BinarySource source) {
+  AnalyzerMetadata readFromBinary(
+      kernel.Node node, kernel.BinarySource source) {
     return new AnalyzerMetadata()
       ..constructorNameOffset = _readOffset(source)
       ..documentationComment = _readOptionalString(source);
   }
 
   @override
-  void writeToBinary(AnalyzerMetadata metadata, kernel.BinarySink sink) {
+  void writeToBinary(
+      AnalyzerMetadata metadata, kernel.Node node, kernel.BinarySink sink) {
     _writeOffset(sink, metadata.constructorNameOffset);
     _writeOptionalString(sink, metadata.documentationComment);
   }
diff --git a/pkg/analyzer/lib/src/dart/analysis/session.dart b/pkg/analyzer/lib/src/dart/analysis/session.dart
index 37ad32e..f627fa8 100644
--- a/pkg/analyzer/lib/src/dart/analysis/session.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/session.dart
@@ -7,6 +7,7 @@
 import 'package:analyzer/dart/analysis/results.dart';
 import 'package:analyzer/dart/analysis/session.dart';
 import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/src/dart/analysis/driver.dart' as driver;
 import 'package:analyzer/src/dart/analysis/top_level_declaration.dart';
 import 'package:analyzer/src/generated/resolver.dart';
@@ -42,6 +43,9 @@
   AnalysisSessionImpl(this._driver);
 
   @override
+  ResourceProvider get resourceProvider => _driver.resourceProvider;
+
+  @override
   SourceFactory get sourceFactory => _driver.sourceFactory;
 
   @override
diff --git a/pkg/analyzer/lib/src/dart/constant/value.dart b/pkg/analyzer/lib/src/dart/constant/value.dart
index 1ba6e80..b9ac011e 100644
--- a/pkg/analyzer/lib/src/dart/constant/value.dart
+++ b/pkg/analyzer/lib/src/dart/constant/value.dart
@@ -699,6 +699,15 @@
     return null;
   }
 
+  /**
+   * If this constant represents a library function or static method, returns
+   * it, otherwise returns `null`.
+   */
+  ExecutableElement toFunctionValue() {
+    InstanceState state = _state;
+    return state is FunctionState ? state._element : null;
+  }
+
   @override
   int toIntValue() {
     InstanceState state = _state;
diff --git a/pkg/analyzer/lib/src/dart/error/syntactic_errors.dart b/pkg/analyzer/lib/src/dart/error/syntactic_errors.dart
index f794006..ac0dd3e 100644
--- a/pkg/analyzer/lib/src/dart/error/syntactic_errors.dart
+++ b/pkg/analyzer/lib/src/dart/error/syntactic_errors.dart
@@ -46,11 +46,6 @@
       'ABSTRACT_TYPEDEF', "Typedefs can't be declared to be 'abstract'.",
       correction: "Try removing the keyword 'abstract'.");
 
-  static const ParserErrorCode ANNOTATION_ON_ENUM_CONSTANT =
-      const ParserErrorCode('ANNOTATION_ON_ENUM_CONSTANT',
-          "Enum constants can't have annotations.",
-          correction: "Try removing the annotation.");
-
   /**
    * 16.32 Identifier Reference: It is a compile-time error if any of the
    * identifiers async, await, or yield is used as an identifier in a function
diff --git a/pkg/analyzer/lib/src/fasta/ast_body_builder.dart b/pkg/analyzer/lib/src/fasta/ast_body_builder.dart
index c24180f1..e5e7442 100644
--- a/pkg/analyzer/lib/src/fasta/ast_body_builder.dart
+++ b/pkg/analyzer/lib/src/fasta/ast_body_builder.dart
@@ -35,6 +35,11 @@
             coreTypes, classBuilder, isInstanceMember, uri, typeInferrer);
 
   @override
+  void enterThenForTypePromotion(Expression condition) {
+    // Do nothing.
+  }
+
+  @override
   void printEvent(String name) {
     // TODO(scheglov): Call of super is commented out to prevent spamming.
 //    super.printEvent(name);
diff --git a/pkg/analyzer/lib/src/fasta/ast_builder.dart b/pkg/analyzer/lib/src/fasta/ast_builder.dart
index b654900..052b7ba 100644
--- a/pkg/analyzer/lib/src/fasta/ast_builder.dart
+++ b/pkg/analyzer/lib/src/fasta/ast_builder.dart
@@ -45,6 +45,7 @@
         messageMissingAssignableSelector,
         messageNativeClauseShouldBeAnnotation,
         messageStaticConstructor,
+        messageTypedefNotFunction,
         templateDuplicateLabelInSwitchStatement,
         templateExpectedType;
 import 'package:front_end/src/fasta/kernel/kernel_builder.dart'
@@ -173,6 +174,12 @@
   }
 
   @override
+  void handleParenthesizedCondition(Token leftParenthesis) {
+    // TODO(danrubel): Implement rather than forwarding.
+    handleParenthesizedExpression(leftParenthesis);
+  }
+
+  @override
   void handleParenthesizedExpression(Token leftParenthesis) {
     assert(optional('(', leftParenthesis));
     debugEvent("ParenthesizedExpression");
@@ -2410,8 +2417,8 @@
       List<Annotation> metadata = pop();
       Comment comment = _findComment(metadata, typedefKeyword);
       if (type is! GenericFunctionType) {
-        // TODO(paulberry) Generate an error and recover (better than
-        // this).
+        // This error is also reported in the OutlineBuilder.
+        handleRecoverableError(messageTypedefNotFunction, equals, equals);
         type = null;
       }
       declarations.add(ast.genericTypeAlias(
diff --git a/pkg/analyzer/lib/src/fasta/ast_building_factory.dart b/pkg/analyzer/lib/src/fasta/ast_building_factory.dart
index 4382c12..52839a7 100644
--- a/pkg/analyzer/lib/src/fasta/ast_building_factory.dart
+++ b/pkg/analyzer/lib/src/fasta/ast_building_factory.dart
@@ -2,10 +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/dart/ast/ast.dart' hide Identifier;
 import 'package:analyzer/dart/ast/token.dart';
 import 'package:analyzer/src/dart/ast/ast_factory.dart';
 import 'package:analyzer/src/generated/resolver.dart' show TypeProvider;
+import 'package:front_end/src/fasta/kernel/body_builder.dart'
+    show Identifier, Operator;
 import 'package:front_end/src/fasta/kernel/forest.dart';
 import 'package:kernel/ast.dart' as kernel;
 
@@ -61,9 +63,12 @@
   Expression asLiteralString(Expression value) => value;
 
   @override
-  Expression awaitExpression(Expression operand, Token awaitKeyword) {
-    return astFactory.awaitExpression(awaitKeyword, operand);
-  }
+  Expression awaitExpression(Expression operand, Token awaitKeyword) =>
+      astFactory.awaitExpression(awaitKeyword, operand);
+
+  @override
+  Block block(Token openBrace, List<Statement> statements, Token closeBrace) =>
+      astFactory.block(openBrace, statements, closeBrace);
 
   @override
   kernel.Arguments castArguments(_Arguments arguments) {
@@ -84,6 +89,25 @@
           condition, question, thenExpression, colon, elseExpression);
 
   @override
+  Statement doStatement(Token doKeyword, Statement body, Token whileKeyword,
+          ParenthesizedExpression condition, Token semicolon) =>
+      astFactory.doStatement(
+          doKeyword,
+          body,
+          whileKeyword,
+          condition.leftParenthesis,
+          condition.expression,
+          condition.rightParenthesis,
+          semicolon);
+
+  @override
+  Statement emptyStatement(Token semicolon) =>
+      astFactory.emptyStatement(semicolon);
+
+  Statement expressionStatement(Expression expression, Token semicolon) =>
+      astFactory.expressionStatement(expression, semicolon);
+
+  @override
   kernel.DartType getTypeAt(TypeArgumentList typeArguments, int index) {
     return null; // typeArguments.arguments[index].type.kernelType;
   }
@@ -93,7 +117,26 @@
       typeArguments.arguments.length;
 
   @override
-  bool isErroneousNode(covariant node) => false; // ???
+  Statement ifStatement(
+          Token ifKeyword,
+          ParenthesizedExpression condition,
+          Statement thenStatement,
+          Token elseKeyword,
+          Statement elseStatement) =>
+      astFactory.ifStatement(
+          ifKeyword,
+          condition.leftParenthesis,
+          condition.expression,
+          condition.rightParenthesis,
+          thenStatement,
+          elseKeyword,
+          elseStatement);
+
+  @override
+  bool isBlock(Object node) => node is Block;
+
+  @override
+  bool isErroneousNode(Object node) => false /* ??? */;
 
   @override
   Expression isExpression(Expression expression, Token isOperator,
@@ -101,6 +144,13 @@
       astFactory.isExpression(expression, isOperator, notOperator, type);
 
   @override
+  bool isThisExpression(Object node) => node is ThisExpression;
+
+  @override
+  bool isVariablesDeclaration(Object node) =>
+      node is VariableDeclarationStatement && node.variables != 1;
+
+  @override
   Expression literalBool(bool value, Token location) =>
       astFactory.booleanLiteral(location, value)
         ..staticType = _typeProvider?.boolType;
@@ -150,9 +200,24 @@
         ..staticType = _typeProvider?.stringType;
 
   @override
-  Expression literalSymbol(String value, Token location) {
-    // TODO(brianwilkerson) Get the missing information.
-    return astFactory.symbolLiteral(location, null /* components */)
+  Expression literalSymbolMultiple(
+          String value, Token hash, List<Identifier> components) =>
+      astFactory.symbolLiteral(
+          hash, components.map((identifier) => identifier.token).toList())
+        ..staticType = _typeProvider?.symbolType;
+
+  @override
+  Expression literalSymbolSingluar(String value, Token hash, Object component) {
+    Token token;
+    if (component is Identifier) {
+      token = component.token;
+    } else if (component is Operator) {
+      token = component.token;
+    } else {
+      throw new ArgumentError(
+          'Unexpected class of component: ${component.runtimeType}');
+    }
+    return astFactory.symbolLiteral(hash, <Token>[token])
       ..staticType = _typeProvider?.symbolType;
   }
 
@@ -182,16 +247,90 @@
         ..staticType = _typeProvider?.boolType;
 
   @override
+  Object parenthesizedCondition(Token leftParenthesis, Expression expression,
+          Token rightParenthesis) =>
+      astFactory.parenthesizedExpression(
+          leftParenthesis, expression, rightParenthesis);
+
+  @override
   int readOffset(AstNode node) => node.offset;
 
   @override
+  void resolveBreak(Statement target, BreakStatement user) {
+    user.target = target;
+  }
+
+  @override
+  void resolveContinue(Statement target, ContinueStatement user) {
+    user.target = target;
+  }
+
+  @override
+  void resolveContinueInSwitch(SwitchStatement target, ContinueStatement user) {
+    user.target = target;
+  }
+
+  @override
+  Statement rethrowStatement(Token rethrowKeyword, Token semicolon) =>
+      astFactory.expressionStatement(
+          astFactory.rethrowExpression(rethrowKeyword), semicolon);
+
+  @override
+  Statement returnStatement(
+          Token returnKeyword, Expression expression, Token semicolon) =>
+      astFactory.returnStatement(returnKeyword, expression, semicolon);
+
+  @override
   Expression stringConcatenationExpression(
           List<Expression> strings, Token location) =>
-      astFactory.adjacentStrings(strings);
+      astFactory.adjacentStrings(strings.cast<StringLiteral>());
+
+  @override
+  Statement syntheticLabeledStatement(Statement statement) => statement;
 
   @override
   Expression thisExpression(Token thisKeyword) =>
       astFactory.thisExpression(thisKeyword);
+
+  @override
+  Expression throwExpression(Token throwKeyword, Expression expression) =>
+      astFactory.throwExpression(throwKeyword, expression);
+
+  @override
+  Statement tryStatement(
+          Token tryKeyword,
+          Statement body,
+          List<CatchClause> catchClauses,
+          Token finallyKeyword,
+          Statement finallyBlock) =>
+      astFactory.tryStatement(
+          tryKeyword, body, catchClauses, finallyKeyword, finallyBlock);
+
+  @override
+  VariableDeclarationStatement variablesDeclaration(
+      List<VariableDeclaration> declarations, Uri uri) {
+    // TODO(brianwilkerson) Implement this.
+    throw new UnimplementedError();
+  }
+
+  @override
+  NodeList<VariableDeclaration> variablesDeclarationExtractDeclarations(
+          VariableDeclarationStatement variablesDeclaration) =>
+      variablesDeclaration.variables.variables;
+
+  @override
+  Statement whileStatement(Token whileKeyword,
+          ParenthesizedExpression condition, Statement body) =>
+      astFactory.whileStatement(whileKeyword, condition.leftParenthesis,
+          condition.expression, condition.rightParenthesis, body);
+
+  @override
+  Statement wrapVariables(Statement statement) => statement;
+
+  @override
+  Statement yieldStatement(Token yieldKeyword, Token star,
+          Expression expression, Token semicolon) =>
+      astFactory.yieldStatement(yieldKeyword, star, expression, semicolon);
 }
 
 /// A data holder used to conform to the [Forest] API.
diff --git a/pkg/analyzer/lib/src/fasta/error_converter.dart b/pkg/analyzer/lib/src/fasta/error_converter.dart
index 660a6b6..7207018 100644
--- a/pkg/analyzer/lib/src/fasta/error_converter.dart
+++ b/pkg/analyzer/lib/src/fasta/error_converter.dart
@@ -29,10 +29,6 @@
         errorReporter?.reportErrorForOffset(
             ParserErrorCode.ABSTRACT_CLASS_MEMBER, offset, length);
         return;
-      case "ANNOTATION_ON_ENUM_CONSTANT":
-        errorReporter?.reportErrorForOffset(
-            ParserErrorCode.ANNOTATION_ON_ENUM_CONSTANT, offset, length);
-        return;
       case "ASYNC_FOR_IN_WRONG_CONTEXT":
         errorReporter?.reportErrorForOffset(
             CompileTimeErrorCode.ASYNC_FOR_IN_WRONG_CONTEXT, offset, length);
@@ -353,6 +349,10 @@
         errorReporter?.reportErrorForOffset(
             StrongModeCode.INVALID_CAST_NEW_EXPR, offset, length);
         return;
+      case "INVALID_GENERIC_FUNCTION_TYPE":
+        errorReporter?.reportErrorForOffset(
+            ParserErrorCode.INVALID_GENERIC_FUNCTION_TYPE, offset, length);
+        return;
       case "INVALID_METHOD_OVERRIDE":
         errorReporter?.reportErrorForOffset(
             StrongModeCode.INVALID_METHOD_OVERRIDE, offset, length);
diff --git a/pkg/analyzer/lib/src/generated/error_verifier.dart b/pkg/analyzer/lib/src/generated/error_verifier.dart
index f13507a..86a305f 100644
--- a/pkg/analyzer/lib/src/generated/error_verifier.dart
+++ b/pkg/analyzer/lib/src/generated/error_verifier.dart
@@ -209,6 +209,24 @@
    */
   ClassElementImpl _enclosingClass;
 
+  ClassElement get enclosingClass => _enclosingClass;
+
+  /**
+   * For consumers of error verification as a library, (currently just the
+   * angular plugin), expose a setter that can make the errors reported more
+   * accurate when dangling code snippets are being resolved from a class
+   * context. Note that this setter is very defensive for potential misuse; it
+   * should not be modified in the middle of visiting a tree and requires an
+   * analyzer-provided Impl instance to work.
+   */
+  set enclosingClass(ClassElement classElement) {
+    assert(classElement is ClassElementImpl);
+    assert(_enclosingClass == null);
+    assert(_enclosingEnum == null);
+    assert(_enclosingFunction == null);
+    _enclosingClass = classElement;
+  }
+
   /**
    * The enum containing the AST nodes being visited, or `null` if we are not
    * in the scope of an enum.
diff --git a/pkg/analyzer/lib/src/generated/parser.dart b/pkg/analyzer/lib/src/generated/parser.dart
index 8d228f3..a60c8ab 100644
--- a/pkg/analyzer/lib/src/generated/parser.dart
+++ b/pkg/analyzer/lib/src/generated/parser.dart
@@ -6824,10 +6824,6 @@
     } else {
       name = createSyntheticIdentifier();
     }
-    if (commentAndMetadata.hasMetadata) {
-      _reportErrorForNode(ParserErrorCode.ANNOTATION_ON_ENUM_CONSTANT,
-          commentAndMetadata.metadata[0]);
-    }
     return astFactory.enumConstantDeclaration(
         commentAndMetadata.comment, commentAndMetadata.metadata, name);
   }
diff --git a/pkg/analyzer/lib/src/generated/resolver.dart b/pkg/analyzer/lib/src/generated/resolver.dart
index 503d7b1..185d6d3 100644
--- a/pkg/analyzer/lib/src/generated/resolver.dart
+++ b/pkg/analyzer/lib/src/generated/resolver.dart
@@ -1304,7 +1304,7 @@
         rhsType != null &&
         !lhsType.isDynamic &&
         !rhsType.isDynamic &&
-        lhsType.isMoreSpecificThan(rhsType)) {
+        _typeSystem.isMoreSpecificThan(lhsType, rhsType)) {
       _errorReporter.reportErrorForNode(HintCode.UNNECESSARY_CAST, node);
       return true;
     }
diff --git a/pkg/analyzer/pubspec.yaml b/pkg/analyzer/pubspec.yaml
index 9e72153..03cdb82 100644
--- a/pkg/analyzer/pubspec.yaml
+++ b/pkg/analyzer/pubspec.yaml
@@ -1,20 +1,20 @@
 name: analyzer
-version: 0.31.2-alpha.2
+version: 0.32.0
 author: Dart Team <misc@dartlang.org>
 description: Static analyzer for Dart.
 homepage: https://github.com/dart-lang/sdk/tree/master/pkg/analyzer
 environment:
-  sdk: '>=2.0.0-dev <2.0.0'
+  sdk: '>=2.0.0-dev.48.0 <2.0.0'
 dependencies:
   args: '>=0.12.1 <2.0.0'
   charcode: ^1.1.0
   collection: ^1.10.1
   convert: ^2.0.0
   crypto: '>=1.1.1 <3.0.0'
-  front_end: 0.1.0-alpha.12
+  front_end: 0.1.0
   glob: ^1.0.3
   html: '>=0.12.0 <1.14.0'
-  kernel: 0.3.0-alpha.12
+  kernel: 0.3.0
   meta: ^1.0.2
   package_config: '>=0.1.5 <2.0.0'
   path: '>=0.9.0 <2.0.0'
diff --git a/pkg/analyzer/test/generated/non_hint_code_test.dart b/pkg/analyzer/test/generated/non_hint_code_test.dart
index 6ba10ce..d418538 100644
--- a/pkg/analyzer/test/generated/non_hint_code_test.dart
+++ b/pkg/analyzer/test/generated/non_hint_code_test.dart
@@ -1094,6 +1094,35 @@
     verify([source]);
   }
 
+  test_unnecessaryCast_function() async {
+    Source source = addSource(r'''
+void main() {
+  Function(Null) f = (String x) => x;
+  (f as Function(int))(3); 
+}
+''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_unnecessaryCast_function2() async {
+    Source source = addSource(r'''
+class A {}
+
+class B<T extends A> {
+  void foo() {
+    T Function(T) f;
+    A Function(A) g;
+    g = f as A Function(A);
+  }
+}
+''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
   test_unnecessaryCast_generics() async {
     // dartbug.com/18953
     Source source = addSource(r'''
diff --git a/pkg/analyzer/test/generated/parser_fasta_test.dart b/pkg/analyzer/test/generated/parser_fasta_test.dart
index 5103eca..e634c00 100644
--- a/pkg/analyzer/test/generated/parser_fasta_test.dart
+++ b/pkg/analyzer/test/generated/parser_fasta_test.dart
@@ -488,70 +488,6 @@
     // Expected 1 errors of type ParserErrorCode.MISSING_FUNCTION_PARAMETERS, found 0
     super.test_missingFunctionParameters_topLevel_void_expression();
   }
-
-  @override
-  @failingTest
-  void test_unexpectedToken_endOfFieldDeclarationStatement() {
-    // TODO(brianwilkerson) Wrong errors:
-    // Expected 1 errors of type ParserErrorCode.UNEXPECTED_TOKEN, found 0
-    super.test_unexpectedToken_endOfFieldDeclarationStatement();
-  }
-
-  @override
-//  @failingTest
-  void test_voidVariable_parseClassMember_initializer() {
-    // TODO(brianwilkerson) Passes, but ought to fail.
-    super.test_voidVariable_parseClassMember_initializer();
-  }
-
-  @override
-//  @failingTest
-  void test_voidVariable_parseClassMember_noInitializer() {
-    // TODO(brianwilkerson) Passes, but ought to fail.
-    super.test_voidVariable_parseClassMember_noInitializer();
-  }
-
-  @override
-//  @failingTest
-  void test_voidVariable_parseCompilationUnit_initializer() {
-    // TODO(brianwilkerson) Passes, but ought to fail.
-    super.test_voidVariable_parseCompilationUnit_initializer();
-  }
-
-  @override
-//  @failingTest
-  void test_voidVariable_parseCompilationUnit_noInitializer() {
-    // TODO(brianwilkerson) Passes, but ought to fail.
-    super.test_voidVariable_parseCompilationUnit_noInitializer();
-  }
-
-  @override
-//  @failingTest
-  void test_voidVariable_parseCompilationUnitMember_initializer() {
-    // TODO(brianwilkerson) Passes, but ought to fail.
-    super.test_voidVariable_parseCompilationUnitMember_initializer();
-  }
-
-  @override
-//  @failingTest
-  void test_voidVariable_parseCompilationUnitMember_noInitializer() {
-    // TODO(brianwilkerson) Passes, but ought to fail.
-    super.test_voidVariable_parseCompilationUnitMember_noInitializer();
-  }
-
-  @override
-//  @failingTest
-  void test_voidVariable_statement_initializer() {
-    // TODO(brianwilkerson) Passes, but ought to fail.
-    super.test_voidVariable_statement_initializer();
-  }
-
-  @override
-//  @failingTest
-  void test_voidVariable_statement_noInitializer() {
-    // TODO(brianwilkerson) Passes, but ought to fail.
-    super.test_voidVariable_statement_noInitializer();
-  }
 }
 
 /**
@@ -636,11 +572,8 @@
   }
 
   @override
-  @failingTest
   void test_parseInstanceCreationExpression_type_named_typeArgumentComments() {
-    // TODO(brianwilkerson) Does not inject generic type arguments.
-    super
-        .test_parseInstanceCreationExpression_type_named_typeArgumentComments();
+    // Ignored: Fasta does not support the generic comment syntax.
   }
 
   @override
diff --git a/pkg/analyzer/test/generated/parser_forest_test.dart b/pkg/analyzer/test/generated/parser_forest_test.dart
index 5c22fec..425b0a0 100644
--- a/pkg/analyzer/test/generated/parser_forest_test.dart
+++ b/pkg/analyzer/test/generated/parser_forest_test.dart
@@ -2,6 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import '../src/fasta/body_builder_test_helper.dart';
@@ -9,23 +10,2523 @@
 
 main() async {
   defineReflectiveSuite(() {
-    // TODO(brianwilkerson) Implement the remaining parser tests.
-//    defineReflectiveTests(ClassMemberParserTest_Forest);
-//    defineReflectiveTests(ComplexParserTest_Forest);
-//    defineReflectiveTests(ErrorParserTest_Forest);
+    defineReflectiveTests(ClassMemberParserTest_Forest);
+    defineReflectiveTests(ComplexParserTest_Forest);
+    defineReflectiveTests(ErrorParserTest_Forest);
     defineReflectiveTests(ExpressionParserTest_Forest);
-//    defineReflectiveTests(FormalParameterParserTest_Forest);
-//    defineReflectiveTests(NonErrorParserTest_Forest);
-//    defineReflectiveTests(RecoveryParserTest_Forest);
-//    defineReflectiveTests(SimpleParserTest_Forest);
+    defineReflectiveTests(FormalParameterParserTest_Forest);
+    defineReflectiveTests(RecoveryParserTest_Forest);
+    defineReflectiveTests(SimpleParserTest_Forest);
     defineReflectiveTests(StatementParserTest_Forest);
     defineReflectiveTests(TopLevelParserTest_Forest);
   });
 }
 
-/**
- * Tests of the fasta parser based on [ExpressionParserTestMixin].
- */
+@reflectiveTest
+class ClassMemberParserTest_Forest extends FastaBodyBuilderTestCase
+    with ClassMemberParserTestMixin {
+  ClassMemberParserTest_Forest() : super(false);
+
+  @failingTest
+  void test_parseAwaitExpression_asStatement_inAsync() {
+    super.test_parseAwaitExpression_asStatement_inAsync();
+  }
+
+  @failingTest
+  void test_parseAwaitExpression_asStatement_inSync() {
+    super.test_parseAwaitExpression_asStatement_inSync();
+  }
+
+  @failingTest
+  void test_parseAwaitExpression_inSync() {
+    super.test_parseAwaitExpression_inSync();
+  }
+
+  @failingTest
+  void test_parseClassMember_constructor_withDocComment() {
+    super.test_parseClassMember_constructor_withDocComment();
+  }
+
+  @failingTest
+  void test_parseClassMember_constructor_withInitializers() {
+    super.test_parseClassMember_constructor_withInitializers();
+  }
+
+  @failingTest
+  void test_parseClassMember_field_covariant() {
+    super.test_parseClassMember_field_covariant();
+  }
+
+  @failingTest
+  void test_parseClassMember_field_generic() {
+    super.test_parseClassMember_field_generic();
+  }
+
+  @failingTest
+  void test_parseClassMember_field_gftType_gftReturnType() {
+    super.test_parseClassMember_field_gftType_gftReturnType();
+  }
+
+  @failingTest
+  void test_parseClassMember_field_gftType_noReturnType() {
+    super.test_parseClassMember_field_gftType_noReturnType();
+  }
+
+  @failingTest
+  void test_parseClassMember_field_instance_prefixedType() {
+    super.test_parseClassMember_field_instance_prefixedType();
+  }
+
+  @failingTest
+  void test_parseClassMember_field_namedGet() {
+    super.test_parseClassMember_field_namedGet();
+  }
+
+  @failingTest
+  void test_parseClassMember_field_namedOperator() {
+    super.test_parseClassMember_field_namedOperator();
+  }
+
+  @failingTest
+  void test_parseClassMember_field_namedOperator_withAssignment() {
+    super.test_parseClassMember_field_namedOperator_withAssignment();
+  }
+
+  @failingTest
+  void test_parseClassMember_field_namedSet() {
+    super.test_parseClassMember_field_namedSet();
+  }
+
+  @failingTest
+  void test_parseClassMember_field_nameKeyword() {
+    super.test_parseClassMember_field_nameKeyword();
+  }
+
+  @failingTest
+  void test_parseClassMember_field_nameMissing() {
+    super.test_parseClassMember_field_nameMissing();
+  }
+
+  @failingTest
+  void test_parseClassMember_field_nameMissing2() {
+    super.test_parseClassMember_field_nameMissing2();
+  }
+
+  @failingTest
+  void test_parseClassMember_field_static() {
+    super.test_parseClassMember_field_static();
+  }
+
+  @failingTest
+  void test_parseClassMember_getter_functionType() {
+    super.test_parseClassMember_getter_functionType();
+  }
+
+  @failingTest
+  void test_parseClassMember_getter_void() {
+    super.test_parseClassMember_getter_void();
+  }
+
+  @failingTest
+  void test_parseClassMember_method_external() {
+    super.test_parseClassMember_method_external();
+  }
+
+  @failingTest
+  void test_parseClassMember_method_external_withTypeAndArgs() {
+    super.test_parseClassMember_method_external_withTypeAndArgs();
+  }
+
+  @failingTest
+  void test_parseClassMember_method_generic_comment_noReturnType() {
+    super.test_parseClassMember_method_generic_comment_noReturnType();
+  }
+
+  @failingTest
+  void test_parseClassMember_method_generic_comment_parameterType() {
+    super.test_parseClassMember_method_generic_comment_parameterType();
+  }
+
+  @failingTest
+  void test_parseClassMember_method_generic_comment_returnType() {
+    super.test_parseClassMember_method_generic_comment_returnType();
+  }
+
+  @failingTest
+  void test_parseClassMember_method_generic_comment_returnType_bound() {
+    super.test_parseClassMember_method_generic_comment_returnType_bound();
+  }
+
+  @failingTest
+  void test_parseClassMember_method_generic_comment_returnType_complex() {
+    super.test_parseClassMember_method_generic_comment_returnType_complex();
+  }
+
+  @failingTest
+  void test_parseClassMember_method_generic_comment_void() {
+    super.test_parseClassMember_method_generic_comment_void();
+  }
+
+  @failingTest
+  void test_parseClassMember_method_generic_noReturnType() {
+    super.test_parseClassMember_method_generic_noReturnType();
+  }
+
+  @failingTest
+  void test_parseClassMember_method_generic_parameterType() {
+    super.test_parseClassMember_method_generic_parameterType();
+  }
+
+  @failingTest
+  void test_parseClassMember_method_generic_returnType() {
+    super.test_parseClassMember_method_generic_returnType();
+  }
+
+  @failingTest
+  void test_parseClassMember_method_generic_returnType_bound() {
+    super.test_parseClassMember_method_generic_returnType_bound();
+  }
+
+  @failingTest
+  void test_parseClassMember_method_generic_returnType_complex() {
+    super.test_parseClassMember_method_generic_returnType_complex();
+  }
+
+  @failingTest
+  void test_parseClassMember_method_generic_returnType_static() {
+    super.test_parseClassMember_method_generic_returnType_static();
+  }
+
+  @failingTest
+  void test_parseClassMember_method_generic_void() {
+    super.test_parseClassMember_method_generic_void();
+  }
+
+  @failingTest
+  void test_parseClassMember_method_get_noType() {
+    super.test_parseClassMember_method_get_noType();
+  }
+
+  @failingTest
+  void test_parseClassMember_method_get_type() {
+    super.test_parseClassMember_method_get_type();
+  }
+
+  @failingTest
+  void test_parseClassMember_method_get_void() {
+    super.test_parseClassMember_method_get_void();
+  }
+
+  @failingTest
+  void test_parseClassMember_method_gftReturnType_noReturnType() {
+    super.test_parseClassMember_method_gftReturnType_noReturnType();
+  }
+
+  @failingTest
+  void test_parseClassMember_method_gftReturnType_voidReturnType() {
+    super.test_parseClassMember_method_gftReturnType_voidReturnType();
+  }
+
+  @failingTest
+  void test_parseClassMember_method_native_allowed() {
+    super.test_parseClassMember_method_native_allowed();
+  }
+
+  @failingTest
+  void test_parseClassMember_method_native_missing_literal_allowed() {
+    super.test_parseClassMember_method_native_missing_literal_allowed();
+  }
+
+  @failingTest
+  void test_parseClassMember_method_native_missing_literal_not_allowed() {
+    super.test_parseClassMember_method_native_missing_literal_not_allowed();
+  }
+
+  @failingTest
+  void test_parseClassMember_method_native_not_allowed() {
+    super.test_parseClassMember_method_native_not_allowed();
+  }
+
+  @failingTest
+  void test_parseClassMember_method_native_with_body_allowed() {
+    super.test_parseClassMember_method_native_with_body_allowed();
+  }
+
+  @failingTest
+  void test_parseClassMember_method_native_with_body_not_allowed() {
+    super.test_parseClassMember_method_native_with_body_not_allowed();
+  }
+
+  @failingTest
+  void test_parseClassMember_method_operator_noType() {
+    super.test_parseClassMember_method_operator_noType();
+  }
+
+  @failingTest
+  void test_parseClassMember_method_operator_type() {
+    super.test_parseClassMember_method_operator_type();
+  }
+
+  @failingTest
+  void test_parseClassMember_method_operator_void() {
+    super.test_parseClassMember_method_operator_void();
+  }
+
+  @failingTest
+  void test_parseClassMember_method_returnType_functionType() {
+    super.test_parseClassMember_method_returnType_functionType();
+  }
+
+  @failingTest
+  void test_parseClassMember_method_returnType_parameterized() {
+    super.test_parseClassMember_method_returnType_parameterized();
+  }
+
+  @failingTest
+  void test_parseClassMember_method_set_noType() {
+    super.test_parseClassMember_method_set_noType();
+  }
+
+  @failingTest
+  void test_parseClassMember_method_set_type() {
+    super.test_parseClassMember_method_set_type();
+  }
+
+  @failingTest
+  void test_parseClassMember_method_set_void() {
+    super.test_parseClassMember_method_set_void();
+  }
+
+  @failingTest
+  void test_parseClassMember_method_static_generic_comment_returnType() {
+    super.test_parseClassMember_method_static_generic_comment_returnType();
+  }
+
+  @failingTest
+  void test_parseClassMember_method_trailing_commas() {
+    super.test_parseClassMember_method_trailing_commas();
+  }
+
+  @failingTest
+  void test_parseClassMember_operator_functionType() {
+    super.test_parseClassMember_operator_functionType();
+  }
+
+  @failingTest
+  void test_parseClassMember_operator_index() {
+    super.test_parseClassMember_operator_index();
+  }
+
+  @failingTest
+  void test_parseClassMember_operator_indexAssign() {
+    super.test_parseClassMember_operator_indexAssign();
+  }
+
+  @failingTest
+  void test_parseClassMember_operator_lessThan() {
+    super.test_parseClassMember_operator_lessThan();
+  }
+
+  @failingTest
+  void test_parseClassMember_redirectingFactory_const() {
+    super.test_parseClassMember_redirectingFactory_const();
+  }
+
+  @failingTest
+  void test_parseClassMember_redirectingFactory_expressionBody() {
+    super.test_parseClassMember_redirectingFactory_expressionBody();
+  }
+
+  @failingTest
+  void test_parseClassMember_redirectingFactory_nonConst() {
+    super.test_parseClassMember_redirectingFactory_nonConst();
+  }
+
+  @failingTest
+  void test_parseConstructor_assert() {
+    super.test_parseConstructor_assert();
+  }
+
+  @failingTest
+  void test_parseConstructor_factory_const_external() {
+    super.test_parseConstructor_factory_const_external();
+  }
+
+  @failingTest
+  void test_parseConstructor_factory_named() {
+    super.test_parseConstructor_factory_named();
+  }
+
+  @failingTest
+  void test_parseConstructor_initializers_field() {
+    super.test_parseConstructor_initializers_field();
+  }
+
+  @failingTest
+  void test_parseConstructor_named() {
+    super.test_parseConstructor_named();
+  }
+
+  @failingTest
+  void test_parseConstructor_unnamed() {
+    super.test_parseConstructor_unnamed();
+  }
+
+  @failingTest
+  void test_parseConstructor_with_pseudo_function_literal() {
+    super.test_parseConstructor_with_pseudo_function_literal();
+  }
+
+  @failingTest
+  void test_parseConstructorFieldInitializer_qualified() {
+    super.test_parseConstructorFieldInitializer_qualified();
+  }
+
+  @failingTest
+  void test_parseConstructorFieldInitializer_unqualified() {
+    super.test_parseConstructorFieldInitializer_unqualified();
+  }
+
+  @failingTest
+  void test_parseGetter_nonStatic() {
+    super.test_parseGetter_nonStatic();
+  }
+
+  @failingTest
+  void test_parseGetter_static() {
+    super.test_parseGetter_static();
+  }
+
+  @failingTest
+  void test_parseInitializedIdentifierList_type() {
+    super.test_parseInitializedIdentifierList_type();
+  }
+
+  @failingTest
+  void test_parseInitializedIdentifierList_var() {
+    super.test_parseInitializedIdentifierList_var();
+  }
+
+  @failingTest
+  void test_parseOperator() {
+    super.test_parseOperator();
+  }
+
+  @failingTest
+  void test_parseSetter_nonStatic() {
+    super.test_parseSetter_nonStatic();
+  }
+
+  @failingTest
+  void test_parseSetter_static() {
+    super.test_parseSetter_static();
+  }
+
+  @failingTest
+  void test_simpleFormalParameter_withDocComment() {
+    super.test_simpleFormalParameter_withDocComment();
+  }
+}
+
+@reflectiveTest
+class ComplexParserTest_Forest extends FastaBodyBuilderTestCase
+    with ComplexParserTestMixin {
+  ComplexParserTest_Forest() : super(false);
+
+  @failingTest
+  void test_additiveExpression_normal() {
+    super.test_additiveExpression_normal();
+  }
+
+  @failingTest
+  void test_additiveExpression_noSpaces() {
+    super.test_additiveExpression_noSpaces();
+  }
+
+  @failingTest
+  void test_additiveExpression_precedence_multiplicative_left() {
+    super.test_additiveExpression_precedence_multiplicative_left();
+  }
+
+  @failingTest
+  void test_additiveExpression_precedence_multiplicative_left_withSuper() {
+    super.test_additiveExpression_precedence_multiplicative_left_withSuper();
+  }
+
+  @failingTest
+  void test_additiveExpression_precedence_multiplicative_right() {
+    super.test_additiveExpression_precedence_multiplicative_right();
+  }
+
+  @failingTest
+  void test_additiveExpression_super() {
+    super.test_additiveExpression_super();
+  }
+
+  @failingTest
+  void test_assignableExpression_arguments_normal_chain() {
+    super.test_assignableExpression_arguments_normal_chain();
+  }
+
+  @failingTest
+  void test_assignableExpression_arguments_normal_chain_typeArgumentComments() {
+    super
+        .test_assignableExpression_arguments_normal_chain_typeArgumentComments();
+  }
+
+  @failingTest
+  void test_assignableExpression_arguments_normal_chain_typeArguments() {
+    super.test_assignableExpression_arguments_normal_chain_typeArguments();
+  }
+
+  @failingTest
+  void test_assignmentExpression_compound() {
+    super.test_assignmentExpression_compound();
+  }
+
+  @failingTest
+  void test_assignmentExpression_indexExpression() {
+    super.test_assignmentExpression_indexExpression();
+  }
+
+  @failingTest
+  void test_assignmentExpression_prefixedIdentifier() {
+    super.test_assignmentExpression_prefixedIdentifier();
+  }
+
+  @failingTest
+  void test_assignmentExpression_propertyAccess() {
+    super.test_assignmentExpression_propertyAccess();
+  }
+
+  @failingTest
+  void test_bitwiseAndExpression_normal() {
+    super.test_bitwiseAndExpression_normal();
+  }
+
+  @failingTest
+  void test_bitwiseAndExpression_precedence_equality_left() {
+    super.test_bitwiseAndExpression_precedence_equality_left();
+  }
+
+  @failingTest
+  void test_bitwiseAndExpression_precedence_equality_right() {
+    super.test_bitwiseAndExpression_precedence_equality_right();
+  }
+
+  @failingTest
+  void test_bitwiseAndExpression_super() {
+    super.test_bitwiseAndExpression_super();
+  }
+
+  @failingTest
+  void test_bitwiseOrExpression_normal() {
+    super.test_bitwiseOrExpression_normal();
+  }
+
+  @failingTest
+  void test_bitwiseOrExpression_precedence_xor_left() {
+    super.test_bitwiseOrExpression_precedence_xor_left();
+  }
+
+  @failingTest
+  void test_bitwiseOrExpression_precedence_xor_right() {
+    super.test_bitwiseOrExpression_precedence_xor_right();
+  }
+
+  @failingTest
+  void test_bitwiseOrExpression_super() {
+    super.test_bitwiseOrExpression_super();
+  }
+
+  @failingTest
+  void test_bitwiseXorExpression_normal() {
+    super.test_bitwiseXorExpression_normal();
+  }
+
+  @failingTest
+  void test_bitwiseXorExpression_precedence_and_left() {
+    super.test_bitwiseXorExpression_precedence_and_left();
+  }
+
+  @failingTest
+  void test_bitwiseXorExpression_precedence_and_right() {
+    super.test_bitwiseXorExpression_precedence_and_right();
+  }
+
+  @failingTest
+  void test_bitwiseXorExpression_super() {
+    super.test_bitwiseXorExpression_super();
+  }
+
+  @failingTest
+  void test_cascade_withAssignment() {
+    super.test_cascade_withAssignment();
+  }
+
+  @failingTest
+  void test_conditionalExpression_precedence_ifNullExpression() {
+    super.test_conditionalExpression_precedence_ifNullExpression();
+  }
+
+  @failingTest
+  void test_conditionalExpression_precedence_logicalOrExpression() {
+    super.test_conditionalExpression_precedence_logicalOrExpression();
+  }
+
+  @failingTest
+  void test_conditionalExpression_precedence_nullableType_as() {
+    super.test_conditionalExpression_precedence_nullableType_as();
+  }
+
+  @failingTest
+  void test_conditionalExpression_precedence_nullableType_is() {
+    super.test_conditionalExpression_precedence_nullableType_is();
+  }
+
+  @failingTest
+  void test_constructor_initializer_withParenthesizedExpression() {
+    super.test_constructor_initializer_withParenthesizedExpression();
+  }
+
+  @failingTest
+  void test_equalityExpression_normal() {
+    super.test_equalityExpression_normal();
+  }
+
+  @failingTest
+  void test_equalityExpression_precedence_relational_left() {
+    super.test_equalityExpression_precedence_relational_left();
+  }
+
+  @failingTest
+  void test_equalityExpression_precedence_relational_right() {
+    super.test_equalityExpression_precedence_relational_right();
+  }
+
+  @failingTest
+  void test_equalityExpression_super() {
+    super.test_equalityExpression_super();
+  }
+
+  @failingTest
+  void test_ifNullExpression() {
+    super.test_ifNullExpression();
+  }
+
+  @failingTest
+  void test_ifNullExpression_precedence_logicalOr_left() {
+    super.test_ifNullExpression_precedence_logicalOr_left();
+  }
+
+  @failingTest
+  void test_ifNullExpression_precedence_logicalOr_right() {
+    super.test_ifNullExpression_precedence_logicalOr_right();
+  }
+
+  @failingTest
+  void test_logicalAndExpression() {
+    super.test_logicalAndExpression();
+  }
+
+  @failingTest
+  void test_logicalAndExpression_precedence_bitwiseOr_left() {
+    super.test_logicalAndExpression_precedence_bitwiseOr_left();
+  }
+
+  @failingTest
+  void test_logicalAndExpression_precedence_bitwiseOr_right() {
+    super.test_logicalAndExpression_precedence_bitwiseOr_right();
+  }
+
+  @failingTest
+  void test_logicalAndExpressionStatement() {
+    super.test_logicalAndExpressionStatement();
+  }
+
+  @failingTest
+  void test_logicalOrExpression() {
+    super.test_logicalOrExpression();
+  }
+
+  @failingTest
+  void test_logicalOrExpression_precedence_logicalAnd_left() {
+    super.test_logicalOrExpression_precedence_logicalAnd_left();
+  }
+
+  @failingTest
+  void test_logicalOrExpression_precedence_logicalAnd_right() {
+    super.test_logicalOrExpression_precedence_logicalAnd_right();
+  }
+
+  @failingTest
+  void test_methodInvocation1() {
+    super.test_methodInvocation1();
+  }
+
+  @failingTest
+  void test_methodInvocation2() {
+    super.test_methodInvocation2();
+  }
+
+  @failingTest
+  void test_methodInvocation3() {
+    super.test_methodInvocation3();
+  }
+
+  @failingTest
+  void test_multipleLabels_statement() {
+    super.test_multipleLabels_statement();
+  }
+
+  @failingTest
+  void test_multiplicativeExpression_normal() {
+    super.test_multiplicativeExpression_normal();
+  }
+
+  @failingTest
+  void test_multiplicativeExpression_precedence_unary_left() {
+    super.test_multiplicativeExpression_precedence_unary_left();
+  }
+
+  @failingTest
+  void test_multiplicativeExpression_precedence_unary_right() {
+    super.test_multiplicativeExpression_precedence_unary_right();
+  }
+
+  @failingTest
+  void test_multiplicativeExpression_super() {
+    super.test_multiplicativeExpression_super();
+  }
+
+  @failingTest
+  void test_relationalExpression_precedence_shift_right() {
+    super.test_relationalExpression_precedence_shift_right();
+  }
+
+  @failingTest
+  void test_shiftExpression_normal() {
+    super.test_shiftExpression_normal();
+  }
+
+  @failingTest
+  void test_shiftExpression_precedence_additive_left() {
+    super.test_shiftExpression_precedence_additive_left();
+  }
+
+  @failingTest
+  void test_shiftExpression_precedence_additive_right() {
+    super.test_shiftExpression_precedence_additive_right();
+  }
+
+  @failingTest
+  void test_shiftExpression_super() {
+    super.test_shiftExpression_super();
+  }
+
+  @failingTest
+  void test_topLevelFunction_nestedGenericFunction() {
+    super.test_topLevelFunction_nestedGenericFunction();
+  }
+}
+
+@reflectiveTest
+class ErrorParserTest_Forest extends FastaBodyBuilderTestCase
+    with ErrorParserTestMixin {
+  ErrorParserTest_Forest() : super(false);
+
+  @failingTest
+  void test_abstractClassMember_constructor() {
+    super.test_abstractClassMember_constructor();
+  }
+
+  @failingTest
+  void test_abstractClassMember_field() {
+    super.test_abstractClassMember_field();
+  }
+
+  @failingTest
+  void test_abstractClassMember_getter() {
+    super.test_abstractClassMember_getter();
+  }
+
+  @failingTest
+  void test_abstractClassMember_method() {
+    super.test_abstractClassMember_method();
+  }
+
+  @failingTest
+  void test_abstractClassMember_setter() {
+    super.test_abstractClassMember_setter();
+  }
+
+  @failingTest
+  void test_abstractEnum() {
+    super.test_abstractEnum();
+  }
+
+  @failingTest
+  void test_abstractTopLevelFunction_function() {
+    super.test_abstractTopLevelFunction_function();
+  }
+
+  @failingTest
+  void test_abstractTopLevelFunction_getter() {
+    super.test_abstractTopLevelFunction_getter();
+  }
+
+  @failingTest
+  void test_abstractTopLevelFunction_setter() {
+    super.test_abstractTopLevelFunction_setter();
+  }
+
+  @failingTest
+  void test_abstractTopLevelVariable() {
+    super.test_abstractTopLevelVariable();
+  }
+
+  @failingTest
+  void test_abstractTypeDef() {
+    super.test_abstractTypeDef();
+  }
+
+  @failingTest
+  void test_breakOutsideOfLoop_breakInDoStatement() {
+    super.test_breakOutsideOfLoop_breakInDoStatement();
+  }
+
+  @failingTest
+  void test_breakOutsideOfLoop_breakInForStatement() {
+    super.test_breakOutsideOfLoop_breakInForStatement();
+  }
+
+  @failingTest
+  void test_breakOutsideOfLoop_breakInIfStatement() {
+    super.test_breakOutsideOfLoop_breakInIfStatement();
+  }
+
+  @failingTest
+  void test_breakOutsideOfLoop_breakInSwitchStatement() {
+    super.test_breakOutsideOfLoop_breakInSwitchStatement();
+  }
+
+  @failingTest
+  void test_breakOutsideOfLoop_breakInWhileStatement() {
+    super.test_breakOutsideOfLoop_breakInWhileStatement();
+  }
+
+  @failingTest
+  void test_breakOutsideOfLoop_functionExpression_inALoop() {
+    super.test_breakOutsideOfLoop_functionExpression_inALoop();
+  }
+
+  @failingTest
+  void test_breakOutsideOfLoop_functionExpression_withALoop() {
+    super.test_breakOutsideOfLoop_functionExpression_withALoop();
+  }
+
+  @failingTest
+  void test_classInClass_abstract() {
+    super.test_classInClass_abstract();
+  }
+
+  @failingTest
+  void test_classInClass_nonAbstract() {
+    super.test_classInClass_nonAbstract();
+  }
+
+  @failingTest
+  void test_classTypeAlias_abstractAfterEq() {
+    super.test_classTypeAlias_abstractAfterEq();
+  }
+
+  @failingTest
+  void test_colonInPlaceOfIn() {
+    super.test_colonInPlaceOfIn();
+  }
+
+  @failingTest
+  void test_constAndCovariant() {
+    super.test_constAndCovariant();
+  }
+
+  @failingTest
+  void test_constAndFinal() {
+    super.test_constAndFinal();
+  }
+
+  @failingTest
+  void test_constAndVar() {
+    super.test_constAndVar();
+  }
+
+  @failingTest
+  void test_constClass() {
+    super.test_constClass();
+  }
+
+  @failingTest
+  void test_constConstructorWithBody() {
+    super.test_constConstructorWithBody();
+  }
+
+  @failingTest
+  void test_constEnum() {
+    super.test_constEnum();
+  }
+
+  @failingTest
+  void test_constFactory() {
+    super.test_constFactory();
+  }
+
+  @failingTest
+  void test_constMethod() {
+    super.test_constMethod();
+  }
+
+  @failingTest
+  void test_constructorPartial() {
+    super.test_constructorPartial();
+  }
+
+  @failingTest
+  void test_constructorWithReturnType() {
+    super.test_constructorWithReturnType();
+  }
+
+  @failingTest
+  void test_constructorWithReturnType_var() {
+    super.test_constructorWithReturnType_var();
+  }
+
+  @failingTest
+  void test_constTypedef() {
+    super.test_constTypedef();
+  }
+
+  @failingTest
+  void test_continueOutsideOfLoop_continueInDoStatement() {
+    super.test_continueOutsideOfLoop_continueInDoStatement();
+  }
+
+  @failingTest
+  void test_continueOutsideOfLoop_continueInForStatement() {
+    super.test_continueOutsideOfLoop_continueInForStatement();
+  }
+
+  @failingTest
+  void test_continueOutsideOfLoop_continueInIfStatement() {
+    super.test_continueOutsideOfLoop_continueInIfStatement();
+  }
+
+  @failingTest
+  void test_continueOutsideOfLoop_continueInSwitchStatement() {
+    super.test_continueOutsideOfLoop_continueInSwitchStatement();
+  }
+
+  @failingTest
+  void test_continueOutsideOfLoop_continueInWhileStatement() {
+    super.test_continueOutsideOfLoop_continueInWhileStatement();
+  }
+
+  @failingTest
+  void test_continueOutsideOfLoop_functionExpression_inALoop() {
+    super.test_continueOutsideOfLoop_functionExpression_inALoop();
+  }
+
+  @failingTest
+  void test_continueOutsideOfLoop_functionExpression_withALoop() {
+    super.test_continueOutsideOfLoop_functionExpression_withALoop();
+  }
+
+  @failingTest
+  void test_continueWithoutLabelInCase_error() {
+    super.test_continueWithoutLabelInCase_error();
+  }
+
+  @failingTest
+  void test_continueWithoutLabelInCase_noError() {
+    super.test_continueWithoutLabelInCase_noError();
+  }
+
+  @failingTest
+  void test_continueWithoutLabelInCase_noError_switchInLoop() {
+    super.test_continueWithoutLabelInCase_noError_switchInLoop();
+  }
+
+  @failingTest
+  void test_covariantAfterVar() {
+    super.test_covariantAfterVar();
+  }
+
+  @failingTest
+  void test_covariantAndFinal() {
+    super.test_covariantAndFinal();
+  }
+
+  @failingTest
+  void test_covariantAndStatic() {
+    super.test_covariantAndStatic();
+  }
+
+  @failingTest
+  void test_covariantAndType_local() {
+    super.test_covariantAndType_local();
+  }
+
+  @failingTest
+  void test_covariantConstructor() {
+    super.test_covariantConstructor();
+  }
+
+  @failingTest
+  void test_covariantMember_getter_noReturnType() {
+    super.test_covariantMember_getter_noReturnType();
+  }
+
+  @failingTest
+  void test_covariantMember_getter_returnType() {
+    super.test_covariantMember_getter_returnType();
+  }
+
+  @failingTest
+  void test_covariantMember_method() {
+    super.test_covariantMember_method();
+  }
+
+  @failingTest
+  void test_covariantTopLevelDeclaration_class() {
+    super.test_covariantTopLevelDeclaration_class();
+  }
+
+  @failingTest
+  void test_covariantTopLevelDeclaration_enum() {
+    super.test_covariantTopLevelDeclaration_enum();
+  }
+
+  @failingTest
+  void test_covariantTopLevelDeclaration_typedef() {
+    super.test_covariantTopLevelDeclaration_typedef();
+  }
+
+  @failingTest
+  void test_defaultValueInFunctionType_named_colon() {
+    super.test_defaultValueInFunctionType_named_colon();
+  }
+
+  @failingTest
+  void test_defaultValueInFunctionType_named_equal() {
+    super.test_defaultValueInFunctionType_named_equal();
+  }
+
+  @failingTest
+  void test_defaultValueInFunctionType_positional() {
+    super.test_defaultValueInFunctionType_positional();
+  }
+
+  @failingTest
+  void test_directiveAfterDeclaration_classBeforeDirective() {
+    super.test_directiveAfterDeclaration_classBeforeDirective();
+  }
+
+  @failingTest
+  void test_directiveAfterDeclaration_classBetweenDirectives() {
+    super.test_directiveAfterDeclaration_classBetweenDirectives();
+  }
+
+  @failingTest
+  void test_duplicatedModifier_const() {
+    super.test_duplicatedModifier_const();
+  }
+
+  @failingTest
+  void test_duplicatedModifier_external() {
+    super.test_duplicatedModifier_external();
+  }
+
+  @failingTest
+  void test_duplicatedModifier_factory() {
+    super.test_duplicatedModifier_factory();
+  }
+
+  @failingTest
+  void test_duplicatedModifier_final() {
+    super.test_duplicatedModifier_final();
+  }
+
+  @failingTest
+  void test_duplicatedModifier_static() {
+    super.test_duplicatedModifier_static();
+  }
+
+  @failingTest
+  void test_duplicatedModifier_var() {
+    super.test_duplicatedModifier_var();
+  }
+
+  @failingTest
+  void test_duplicateLabelInSwitchStatement() {
+    super.test_duplicateLabelInSwitchStatement();
+  }
+
+  @failingTest
+  void test_emptyEnumBody() {
+    super.test_emptyEnumBody();
+  }
+
+  @failingTest
+  void test_enumInClass() {
+    super.test_enumInClass();
+  }
+
+  @failingTest
+  void test_equalityCannotBeEqualityOperand_eq_eq() {
+    super.test_equalityCannotBeEqualityOperand_eq_eq();
+  }
+
+  @failingTest
+  void test_equalityCannotBeEqualityOperand_eq_neq() {
+    super.test_equalityCannotBeEqualityOperand_eq_neq();
+  }
+
+  @failingTest
+  void test_equalityCannotBeEqualityOperand_neq_eq() {
+    super.test_equalityCannotBeEqualityOperand_neq_eq();
+  }
+
+  @failingTest
+  void test_expectedCaseOrDefault() {
+    super.test_expectedCaseOrDefault();
+  }
+
+  @failingTest
+  void test_expectedClassMember_inClass_afterType() {
+    super.test_expectedClassMember_inClass_afterType();
+  }
+
+  @failingTest
+  void test_expectedClassMember_inClass_beforeType() {
+    super.test_expectedClassMember_inClass_beforeType();
+  }
+
+  @failingTest
+  void test_expectedExecutable_afterAnnotation_atEOF() {
+    super.test_expectedExecutable_afterAnnotation_atEOF();
+  }
+
+  @failingTest
+  void test_expectedExecutable_inClass_afterVoid() {
+    super.test_expectedExecutable_inClass_afterVoid();
+  }
+
+  @failingTest
+  void test_expectedExecutable_topLevel_afterType() {
+    super.test_expectedExecutable_topLevel_afterType();
+  }
+
+  @failingTest
+  void test_expectedExecutable_topLevel_afterVoid() {
+    super.test_expectedExecutable_topLevel_afterVoid();
+  }
+
+  @failingTest
+  void test_expectedExecutable_topLevel_beforeType() {
+    super.test_expectedExecutable_topLevel_beforeType();
+  }
+
+  @failingTest
+  void test_expectedExecutable_topLevel_eof() {
+    super.test_expectedExecutable_topLevel_eof();
+  }
+
+  @failingTest
+  void test_expectedInterpolationIdentifier() {
+    super.test_expectedInterpolationIdentifier();
+  }
+
+  @failingTest
+  void test_expectedInterpolationIdentifier_emptyString() {
+    super.test_expectedInterpolationIdentifier_emptyString();
+  }
+
+  @failingTest
+  void test_expectedListOrMapLiteral() {
+    super.test_expectedListOrMapLiteral();
+  }
+
+  @failingTest
+  void test_expectedStringLiteral() {
+    super.test_expectedStringLiteral();
+  }
+
+  @failingTest
+  void test_expectedToken_commaMissingInArgumentList() {
+    super.test_expectedToken_commaMissingInArgumentList();
+  }
+
+  @failingTest
+  void test_expectedToken_parseStatement_afterVoid() {
+    super.test_expectedToken_parseStatement_afterVoid();
+  }
+
+  @failingTest
+  void test_expectedToken_semicolonMissingAfterExport() {
+    super.test_expectedToken_semicolonMissingAfterExport();
+  }
+
+  @failingTest
+  void test_expectedToken_semicolonMissingAfterExpression() {
+    super.test_expectedToken_semicolonMissingAfterExpression();
+  }
+
+  @failingTest
+  void test_expectedToken_semicolonMissingAfterImport() {
+    super.test_expectedToken_semicolonMissingAfterImport();
+  }
+
+  @failingTest
+  void test_expectedToken_uriAndSemicolonMissingAfterExport() {
+    super.test_expectedToken_uriAndSemicolonMissingAfterExport();
+  }
+
+  @failingTest
+  void test_expectedToken_whileMissingInDoStatement() {
+    super.test_expectedToken_whileMissingInDoStatement();
+  }
+
+  @failingTest
+  void test_expectedTypeName_as() {
+    super.test_expectedTypeName_as();
+  }
+
+  @failingTest
+  void test_expectedTypeName_as_void() {
+    super.test_expectedTypeName_as_void();
+  }
+
+  @failingTest
+  void test_expectedTypeName_is() {
+    super.test_expectedTypeName_is();
+  }
+
+  @failingTest
+  void test_expectedTypeName_is_void() {
+    super.test_expectedTypeName_is_void();
+  }
+
+  @failingTest
+  void test_exportAsType() {
+    super.test_exportAsType();
+  }
+
+  @failingTest
+  void test_exportAsType_inClass() {
+    super.test_exportAsType_inClass();
+  }
+
+  @failingTest
+  void test_exportDirectiveAfterPartDirective() {
+    super.test_exportDirectiveAfterPartDirective();
+  }
+
+  @failingTest
+  void test_externalAfterConst() {
+    super.test_externalAfterConst();
+  }
+
+  @failingTest
+  void test_externalAfterFactory() {
+    super.test_externalAfterFactory();
+  }
+
+  @failingTest
+  void test_externalAfterStatic() {
+    super.test_externalAfterStatic();
+  }
+
+  @failingTest
+  void test_externalClass() {
+    super.test_externalClass();
+  }
+
+  @failingTest
+  void test_externalConstructorWithBody_factory() {
+    super.test_externalConstructorWithBody_factory();
+  }
+
+  @failingTest
+  void test_externalConstructorWithBody_named() {
+    super.test_externalConstructorWithBody_named();
+  }
+
+  @failingTest
+  void test_externalEnum() {
+    super.test_externalEnum();
+  }
+
+  @failingTest
+  void test_externalField_const() {
+    super.test_externalField_const();
+  }
+
+  @failingTest
+  void test_externalField_final() {
+    super.test_externalField_final();
+  }
+
+  @failingTest
+  void test_externalField_static() {
+    super.test_externalField_static();
+  }
+
+  @failingTest
+  void test_externalField_typed() {
+    super.test_externalField_typed();
+  }
+
+  @failingTest
+  void test_externalField_untyped() {
+    super.test_externalField_untyped();
+  }
+
+  @failingTest
+  void test_externalGetterWithBody() {
+    super.test_externalGetterWithBody();
+  }
+
+  @failingTest
+  void test_externalMethodWithBody() {
+    super.test_externalMethodWithBody();
+  }
+
+  @failingTest
+  void test_externalOperatorWithBody() {
+    super.test_externalOperatorWithBody();
+  }
+
+  @failingTest
+  void test_externalSetterWithBody() {
+    super.test_externalSetterWithBody();
+  }
+
+  @failingTest
+  void test_externalTypedef() {
+    super.test_externalTypedef();
+  }
+
+  @failingTest
+  void test_extraCommaInParameterList() {
+    super.test_extraCommaInParameterList();
+  }
+
+  @failingTest
+  void test_extraCommaTrailingNamedParameterGroup() {
+    super.test_extraCommaTrailingNamedParameterGroup();
+  }
+
+  @failingTest
+  void test_extraCommaTrailingPositionalParameterGroup() {
+    super.test_extraCommaTrailingPositionalParameterGroup();
+  }
+
+  @failingTest
+  void test_extraTrailingCommaInParameterList() {
+    super.test_extraTrailingCommaInParameterList();
+  }
+
+  @failingTest
+  void test_factoryTopLevelDeclaration_class() {
+    super.test_factoryTopLevelDeclaration_class();
+  }
+
+  @failingTest
+  void test_factoryTopLevelDeclaration_enum() {
+    super.test_factoryTopLevelDeclaration_enum();
+  }
+
+  @failingTest
+  void test_factoryTopLevelDeclaration_typedef() {
+    super.test_factoryTopLevelDeclaration_typedef();
+  }
+
+  @failingTest
+  void test_factoryWithInitializers() {
+    super.test_factoryWithInitializers();
+  }
+
+  @failingTest
+  void test_factoryWithoutBody() {
+    super.test_factoryWithoutBody();
+  }
+
+  @failingTest
+  void test_fieldInitializerOutsideConstructor() {
+    super.test_fieldInitializerOutsideConstructor();
+  }
+
+  @failingTest
+  void test_finalAndCovariant() {
+    super.test_finalAndCovariant();
+  }
+
+  @failingTest
+  void test_finalAndVar() {
+    super.test_finalAndVar();
+  }
+
+  @failingTest
+  void test_finalClass() {
+    super.test_finalClass();
+  }
+
+  @failingTest
+  void test_finalClassMember_modifierOnly() {
+    super.test_finalClassMember_modifierOnly();
+  }
+
+  @failingTest
+  void test_finalConstructor() {
+    super.test_finalConstructor();
+  }
+
+  @failingTest
+  void test_finalEnum() {
+    super.test_finalEnum();
+  }
+
+  @failingTest
+  void test_finalMethod() {
+    super.test_finalMethod();
+  }
+
+  @failingTest
+  void test_finalTypedef() {
+    super.test_finalTypedef();
+  }
+
+  @failingTest
+  void test_functionTypedField_invalidType_abstract() {
+    super.test_functionTypedField_invalidType_abstract();
+  }
+
+  @failingTest
+  void test_functionTypedField_invalidType_class() {
+    super.test_functionTypedField_invalidType_class();
+  }
+
+  @failingTest
+  void test_functionTypedParameter_const() {
+    super.test_functionTypedParameter_const();
+  }
+
+  @failingTest
+  void test_functionTypedParameter_final() {
+    super.test_functionTypedParameter_final();
+  }
+
+  @failingTest
+  void test_functionTypedParameter_incomplete1() {
+    super.test_functionTypedParameter_incomplete1();
+  }
+
+  @failingTest
+  void test_functionTypedParameter_var() {
+    super.test_functionTypedParameter_var();
+  }
+
+  @failingTest
+  void test_genericFunctionType_asIdentifier() {
+    super.test_genericFunctionType_asIdentifier();
+  }
+
+  @failingTest
+  void test_genericFunctionType_asIdentifier2() {
+    super.test_genericFunctionType_asIdentifier2();
+  }
+
+  @failingTest
+  void test_genericFunctionType_asIdentifier3() {
+    super.test_genericFunctionType_asIdentifier3();
+  }
+
+  @failingTest
+  void test_genericFunctionType_extraLessThan() {
+    super.test_genericFunctionType_extraLessThan();
+  }
+
+  @failingTest
+  void test_getterInFunction_block_noReturnType() {
+    super.test_getterInFunction_block_noReturnType();
+  }
+
+  @failingTest
+  void test_getterInFunction_block_returnType() {
+    super.test_getterInFunction_block_returnType();
+  }
+
+  @failingTest
+  void test_getterInFunction_expression_noReturnType() {
+    super.test_getterInFunction_expression_noReturnType();
+  }
+
+  @failingTest
+  void test_getterInFunction_expression_returnType() {
+    super.test_getterInFunction_expression_returnType();
+  }
+
+  @failingTest
+  void test_getterWithParameters() {
+    super.test_getterWithParameters();
+  }
+
+  @failingTest
+  void test_illegalAssignmentToNonAssignable_assign_int() {
+    super.test_illegalAssignmentToNonAssignable_assign_int();
+  }
+
+  @failingTest
+  void test_illegalAssignmentToNonAssignable_assign_this() {
+    super.test_illegalAssignmentToNonAssignable_assign_this();
+  }
+
+  @failingTest
+  void test_illegalAssignmentToNonAssignable_postfix_minusMinus_literal() {
+    super.test_illegalAssignmentToNonAssignable_postfix_minusMinus_literal();
+  }
+
+  @failingTest
+  void test_illegalAssignmentToNonAssignable_postfix_plusPlus_literal() {
+    super.test_illegalAssignmentToNonAssignable_postfix_plusPlus_literal();
+  }
+
+  @failingTest
+  void test_illegalAssignmentToNonAssignable_postfix_plusPlus_parenthesized() {
+    super
+        .test_illegalAssignmentToNonAssignable_postfix_plusPlus_parenthesized();
+  }
+
+  @failingTest
+  void test_illegalAssignmentToNonAssignable_primarySelectorPostfix() {
+    super.test_illegalAssignmentToNonAssignable_primarySelectorPostfix();
+  }
+
+  @failingTest
+  void test_illegalAssignmentToNonAssignable_superAssigned() {
+    super.test_illegalAssignmentToNonAssignable_superAssigned();
+  }
+
+  @failingTest
+  void test_implementsBeforeExtends() {
+    super.test_implementsBeforeExtends();
+  }
+
+  @failingTest
+  void test_implementsBeforeWith() {
+    super.test_implementsBeforeWith();
+  }
+
+  @failingTest
+  void test_importDirectiveAfterPartDirective() {
+    super.test_importDirectiveAfterPartDirective();
+  }
+
+  @failingTest
+  void test_initializedVariableInForEach() {
+    super.test_initializedVariableInForEach();
+  }
+
+  @failingTest
+  void test_initializedVariableInForEach_annotation() {
+    super.test_initializedVariableInForEach_annotation();
+  }
+
+  @failingTest
+  void test_initializedVariableInForEach_localFunction() {
+    super.test_initializedVariableInForEach_localFunction();
+  }
+
+  @failingTest
+  void test_initializedVariableInForEach_localFunction2() {
+    super.test_initializedVariableInForEach_localFunction2();
+  }
+
+  @failingTest
+  void test_initializedVariableInForEach_var() {
+    super.test_initializedVariableInForEach_var();
+  }
+
+  @failingTest
+  void test_invalidAwaitInFor() {
+    super.test_invalidAwaitInFor();
+  }
+
+  @failingTest
+  void test_invalidCodePoint() {
+    super.test_invalidCodePoint();
+  }
+
+  @failingTest
+  void test_invalidCommentReference__new_nonIdentifier() {
+    super.test_invalidCommentReference__new_nonIdentifier();
+  }
+
+  @failingTest
+  void test_invalidCommentReference__new_tooMuch() {
+    super.test_invalidCommentReference__new_tooMuch();
+  }
+
+  @failingTest
+  void test_invalidCommentReference__nonNew_nonIdentifier() {
+    super.test_invalidCommentReference__nonNew_nonIdentifier();
+  }
+
+  @failingTest
+  void test_invalidCommentReference__nonNew_tooMuch() {
+    super.test_invalidCommentReference__nonNew_tooMuch();
+  }
+
+  @failingTest
+  void test_invalidConstructorName_star() {
+    super.test_invalidConstructorName_star();
+  }
+
+  @failingTest
+  void test_invalidConstructorName_with() {
+    super.test_invalidConstructorName_with();
+  }
+
+  @failingTest
+  void test_invalidHexEscape_invalidDigit() {
+    super.test_invalidHexEscape_invalidDigit();
+  }
+
+  @failingTest
+  void test_invalidHexEscape_tooFewDigits() {
+    super.test_invalidHexEscape_tooFewDigits();
+  }
+
+  @failingTest
+  void test_invalidInterpolationIdentifier_startWithDigit() {
+    super.test_invalidInterpolationIdentifier_startWithDigit();
+  }
+
+  @failingTest
+  void test_invalidLiteralInConfiguration() {
+    super.test_invalidLiteralInConfiguration();
+  }
+
+  @failingTest
+  void test_invalidOperator() {
+    super.test_invalidOperator();
+  }
+
+  @failingTest
+  void test_invalidOperator_unary() {
+    super.test_invalidOperator_unary();
+  }
+
+  @failingTest
+  void test_invalidOperatorAfterSuper_assignableExpression() {
+    super.test_invalidOperatorAfterSuper_assignableExpression();
+  }
+
+  @failingTest
+  void test_invalidOperatorAfterSuper_primaryExpression() {
+    super.test_invalidOperatorAfterSuper_primaryExpression();
+  }
+
+  @failingTest
+  void test_invalidOperatorForSuper() {
+    super.test_invalidOperatorForSuper();
+  }
+
+  @failingTest
+  void test_invalidStarAfterAsync() {
+    super.test_invalidStarAfterAsync();
+  }
+
+  @failingTest
+  void test_invalidSync() {
+    super.test_invalidSync();
+  }
+
+  @failingTest
+  void test_invalidTopLevelSetter() {
+    super.test_invalidTopLevelSetter();
+  }
+
+  @failingTest
+  void test_invalidTopLevelVar() {
+    super.test_invalidTopLevelVar();
+  }
+
+  @failingTest
+  void test_invalidTypedef() {
+    super.test_invalidTypedef();
+  }
+
+  @failingTest
+  void test_invalidTypedef2() {
+    super.test_invalidTypedef2();
+  }
+
+  @failingTest
+  void test_invalidUnicodeEscape_incomplete_noDigits() {
+    super.test_invalidUnicodeEscape_incomplete_noDigits();
+  }
+
+  @failingTest
+  void test_invalidUnicodeEscape_incomplete_someDigits() {
+    super.test_invalidUnicodeEscape_incomplete_someDigits();
+  }
+
+  @failingTest
+  void test_invalidUnicodeEscape_invalidDigit() {
+    super.test_invalidUnicodeEscape_invalidDigit();
+  }
+
+  @failingTest
+  void test_invalidUnicodeEscape_tooFewDigits_fixed() {
+    super.test_invalidUnicodeEscape_tooFewDigits_fixed();
+  }
+
+  @failingTest
+  void test_invalidUnicodeEscape_tooFewDigits_variable() {
+    super.test_invalidUnicodeEscape_tooFewDigits_variable();
+  }
+
+  @failingTest
+  void test_invalidUnicodeEscape_tooManyDigits_variable() {
+    super.test_invalidUnicodeEscape_tooManyDigits_variable();
+  }
+
+  @failingTest
+  void test_libraryDirectiveNotFirst() {
+    super.test_libraryDirectiveNotFirst();
+  }
+
+  @failingTest
+  void test_libraryDirectiveNotFirst_afterPart() {
+    super.test_libraryDirectiveNotFirst_afterPart();
+  }
+
+  @failingTest
+  void test_localFunction_annotation() {
+    super.test_localFunction_annotation();
+  }
+
+  @failingTest
+  void test_localFunctionDeclarationModifier_abstract() {
+    super.test_localFunctionDeclarationModifier_abstract();
+  }
+
+  @failingTest
+  void test_localFunctionDeclarationModifier_external() {
+    super.test_localFunctionDeclarationModifier_external();
+  }
+
+  @failingTest
+  void test_localFunctionDeclarationModifier_factory() {
+    super.test_localFunctionDeclarationModifier_factory();
+  }
+
+  @failingTest
+  void test_localFunctionDeclarationModifier_static() {
+    super.test_localFunctionDeclarationModifier_static();
+  }
+
+  @failingTest
+  void test_method_invalidTypeParameterComments() {
+    super.test_method_invalidTypeParameterComments();
+  }
+
+  @failingTest
+  void test_method_invalidTypeParameterExtends() {
+    super.test_method_invalidTypeParameterExtends();
+  }
+
+  @failingTest
+  void test_method_invalidTypeParameterExtendsComment() {
+    super.test_method_invalidTypeParameterExtendsComment();
+  }
+
+  @failingTest
+  void test_method_invalidTypeParameters() {
+    super.test_method_invalidTypeParameters();
+  }
+
+  @failingTest
+  void test_missingAssignableSelector_identifiersAssigned() {
+    super.test_missingAssignableSelector_identifiersAssigned();
+  }
+
+  @failingTest
+  void test_missingAssignableSelector_prefix_minusMinus_literal() {
+    super.test_missingAssignableSelector_prefix_minusMinus_literal();
+  }
+
+  @failingTest
+  void test_missingAssignableSelector_prefix_plusPlus_literal() {
+    super.test_missingAssignableSelector_prefix_plusPlus_literal();
+  }
+
+  @failingTest
+  void test_missingAssignableSelector_selector() {
+    super.test_missingAssignableSelector_selector();
+  }
+
+  @failingTest
+  void test_missingAssignableSelector_superPrimaryExpression() {
+    super.test_missingAssignableSelector_superPrimaryExpression();
+  }
+
+  @failingTest
+  void test_missingAssignableSelector_superPropertyAccessAssigned() {
+    super.test_missingAssignableSelector_superPropertyAccessAssigned();
+  }
+
+  @failingTest
+  void test_missingCatchOrFinally() {
+    super.test_missingCatchOrFinally();
+  }
+
+  @failingTest
+  void test_missingClassBody() {
+    super.test_missingClassBody();
+  }
+
+  @failingTest
+  void test_missingClosingParenthesis() {
+    super.test_missingClosingParenthesis();
+  }
+
+  @failingTest
+  void test_missingConstFinalVarOrType_static() {
+    super.test_missingConstFinalVarOrType_static();
+  }
+
+  @failingTest
+  void test_missingConstFinalVarOrType_topLevel() {
+    super.test_missingConstFinalVarOrType_topLevel();
+  }
+
+  @failingTest
+  void test_missingEnumBody() {
+    super.test_missingEnumBody();
+  }
+
+  @failingTest
+  void test_missingEnumComma() {
+    super.test_missingEnumComma();
+  }
+
+  @failingTest
+  void test_missingExpressionInThrow() {
+    super.test_missingExpressionInThrow();
+  }
+
+  @failingTest
+  void test_missingFunctionBody_emptyNotAllowed() {
+    super.test_missingFunctionBody_emptyNotAllowed();
+  }
+
+  @failingTest
+  void test_missingFunctionBody_invalid() {
+    super.test_missingFunctionBody_invalid();
+  }
+
+  @failingTest
+  void test_missingFunctionParameters_local_nonVoid_block() {
+    super.test_missingFunctionParameters_local_nonVoid_block();
+  }
+
+  @failingTest
+  void test_missingFunctionParameters_local_nonVoid_expression() {
+    super.test_missingFunctionParameters_local_nonVoid_expression();
+  }
+
+  @failingTest
+  void test_missingFunctionParameters_local_void_block() {
+    super.test_missingFunctionParameters_local_void_block();
+  }
+
+  @failingTest
+  void test_missingFunctionParameters_local_void_expression() {
+    super.test_missingFunctionParameters_local_void_expression();
+  }
+
+  @failingTest
+  void test_missingFunctionParameters_topLevel_nonVoid_block() {
+    super.test_missingFunctionParameters_topLevel_nonVoid_block();
+  }
+
+  @failingTest
+  void test_missingFunctionParameters_topLevel_nonVoid_expression() {
+    super.test_missingFunctionParameters_topLevel_nonVoid_expression();
+  }
+
+  @failingTest
+  void test_missingFunctionParameters_topLevel_void_block() {
+    super.test_missingFunctionParameters_topLevel_void_block();
+  }
+
+  @failingTest
+  void test_missingFunctionParameters_topLevel_void_expression() {
+    super.test_missingFunctionParameters_topLevel_void_expression();
+  }
+
+  @failingTest
+  void test_missingIdentifier_afterOperator() {
+    super.test_missingIdentifier_afterOperator();
+  }
+
+  @failingTest
+  void test_missingIdentifier_beforeClosingCurly() {
+    super.test_missingIdentifier_beforeClosingCurly();
+  }
+
+  @failingTest
+  void test_missingIdentifier_inEnum() {
+    super.test_missingIdentifier_inEnum();
+  }
+
+  @failingTest
+  void test_missingIdentifier_inParameterGroupNamed() {
+    super.test_missingIdentifier_inParameterGroupNamed();
+  }
+
+  @failingTest
+  void test_missingIdentifier_inParameterGroupOptional() {
+    super.test_missingIdentifier_inParameterGroupOptional();
+  }
+
+  @failingTest
+  void test_missingIdentifier_inSymbol_afterPeriod() {
+    super.test_missingIdentifier_inSymbol_afterPeriod();
+  }
+
+  @failingTest
+  void test_missingIdentifier_inSymbol_first() {
+    super.test_missingIdentifier_inSymbol_first();
+  }
+
+  @failingTest
+  void test_missingIdentifierForParameterGroup() {
+    super.test_missingIdentifierForParameterGroup();
+  }
+
+  @failingTest
+  void test_missingKeywordOperator() {
+    super.test_missingKeywordOperator();
+  }
+
+  @failingTest
+  void test_missingKeywordOperator_parseClassMember() {
+    super.test_missingKeywordOperator_parseClassMember();
+  }
+
+  @failingTest
+  void test_missingKeywordOperator_parseClassMember_afterTypeName() {
+    super.test_missingKeywordOperator_parseClassMember_afterTypeName();
+  }
+
+  @failingTest
+  void test_missingKeywordOperator_parseClassMember_afterVoid() {
+    super.test_missingKeywordOperator_parseClassMember_afterVoid();
+  }
+
+  @failingTest
+  void test_missingMethodParameters_void_block() {
+    super.test_missingMethodParameters_void_block();
+  }
+
+  @failingTest
+  void test_missingMethodParameters_void_expression() {
+    super.test_missingMethodParameters_void_expression();
+  }
+
+  @failingTest
+  void test_missingNameForNamedParameter_colon() {
+    super.test_missingNameForNamedParameter_colon();
+  }
+
+  @failingTest
+  void test_missingNameForNamedParameter_equals() {
+    super.test_missingNameForNamedParameter_equals();
+  }
+
+  @failingTest
+  void test_missingNameForNamedParameter_noDefault() {
+    super.test_missingNameForNamedParameter_noDefault();
+  }
+
+  @failingTest
+  void test_missingNameInLibraryDirective() {
+    super.test_missingNameInLibraryDirective();
+  }
+
+  @failingTest
+  void test_missingNameInPartOfDirective() {
+    super.test_missingNameInPartOfDirective();
+  }
+
+  @failingTest
+  void test_missingPrefixInDeferredImport() {
+    super.test_missingPrefixInDeferredImport();
+  }
+
+  @failingTest
+  void test_missingStartAfterSync() {
+    super.test_missingStartAfterSync();
+  }
+
+  @failingTest
+  void test_missingStatement() {
+    super.test_missingStatement();
+  }
+
+  @failingTest
+  void test_missingStatement_afterVoid() {
+    super.test_missingStatement_afterVoid();
+  }
+
+  @failingTest
+  void test_missingTerminatorForParameterGroup_named() {
+    super.test_missingTerminatorForParameterGroup_named();
+  }
+
+  @failingTest
+  void test_missingTerminatorForParameterGroup_optional() {
+    super.test_missingTerminatorForParameterGroup_optional();
+  }
+
+  @failingTest
+  void test_missingTypedefParameters_nonVoid() {
+    super.test_missingTypedefParameters_nonVoid();
+  }
+
+  @failingTest
+  void test_missingTypedefParameters_typeParameters() {
+    super.test_missingTypedefParameters_typeParameters();
+  }
+
+  @failingTest
+  void test_missingTypedefParameters_void() {
+    super.test_missingTypedefParameters_void();
+  }
+
+  @failingTest
+  void test_missingVariableInForEach() {
+    super.test_missingVariableInForEach();
+  }
+
+  @failingTest
+  void test_mixedParameterGroups_namedPositional() {
+    super.test_mixedParameterGroups_namedPositional();
+  }
+
+  @failingTest
+  void test_mixedParameterGroups_positionalNamed() {
+    super.test_mixedParameterGroups_positionalNamed();
+  }
+
+  @failingTest
+  void test_mixin_application_lacks_with_clause() {
+    super.test_mixin_application_lacks_with_clause();
+  }
+
+  @failingTest
+  void test_multipleExtendsClauses() {
+    super.test_multipleExtendsClauses();
+  }
+
+  @failingTest
+  void test_multipleImplementsClauses() {
+    super.test_multipleImplementsClauses();
+  }
+
+  @failingTest
+  void test_multipleLibraryDirectives() {
+    super.test_multipleLibraryDirectives();
+  }
+
+  @failingTest
+  void test_multipleNamedParameterGroups() {
+    super.test_multipleNamedParameterGroups();
+  }
+
+  @failingTest
+  void test_multiplePartOfDirectives() {
+    super.test_multiplePartOfDirectives();
+  }
+
+  @failingTest
+  void test_multiplePositionalParameterGroups() {
+    super.test_multiplePositionalParameterGroups();
+  }
+
+  @failingTest
+  void test_multipleVariablesInForEach() {
+    super.test_multipleVariablesInForEach();
+  }
+
+  @failingTest
+  void test_multipleWithClauses() {
+    super.test_multipleWithClauses();
+  }
+
+  @failingTest
+  void test_namedFunctionExpression() {
+    super.test_namedFunctionExpression();
+  }
+
+  @failingTest
+  void test_namedParameterOutsideGroup() {
+    super.test_namedParameterOutsideGroup();
+  }
+
+  @failingTest
+  void test_nonConstructorFactory_field() {
+    super.test_nonConstructorFactory_field();
+  }
+
+  @failingTest
+  void test_nonConstructorFactory_method() {
+    super.test_nonConstructorFactory_method();
+  }
+
+  @failingTest
+  void test_nonIdentifierLibraryName_library() {
+    super.test_nonIdentifierLibraryName_library();
+  }
+
+  @failingTest
+  void test_nonIdentifierLibraryName_partOf() {
+    super.test_nonIdentifierLibraryName_partOf();
+  }
+
+  @failingTest
+  void test_nonPartOfDirectiveInPart_after() {
+    super.test_nonPartOfDirectiveInPart_after();
+  }
+
+  @failingTest
+  void test_nonPartOfDirectiveInPart_before() {
+    super.test_nonPartOfDirectiveInPart_before();
+  }
+
+  @failingTest
+  void test_nonUserDefinableOperator() {
+    super.test_nonUserDefinableOperator();
+  }
+
+  @failingTest
+  void test_optionalAfterNormalParameters_named() {
+    super.test_optionalAfterNormalParameters_named();
+  }
+
+  @failingTest
+  void test_optionalAfterNormalParameters_positional() {
+    super.test_optionalAfterNormalParameters_positional();
+  }
+
+  @failingTest
+  void test_parseCascadeSection_missingIdentifier() {
+    super.test_parseCascadeSection_missingIdentifier();
+  }
+
+  @failingTest
+  void test_parseCascadeSection_missingIdentifier_typeArguments() {
+    super.test_parseCascadeSection_missingIdentifier_typeArguments();
+  }
+
+  @failingTest
+  void test_positionalAfterNamedArgument() {
+    super.test_positionalAfterNamedArgument();
+  }
+
+  @failingTest
+  void test_positionalParameterOutsideGroup() {
+    super.test_positionalParameterOutsideGroup();
+  }
+
+  @failingTest
+  void test_redirectingConstructorWithBody_named() {
+    super.test_redirectingConstructorWithBody_named();
+  }
+
+  @failingTest
+  void test_redirectingConstructorWithBody_unnamed() {
+    super.test_redirectingConstructorWithBody_unnamed();
+  }
+
+  @failingTest
+  void test_redirectionInNonFactoryConstructor() {
+    super.test_redirectionInNonFactoryConstructor();
+  }
+
+  @failingTest
+  void test_setterInFunction_block() {
+    super.test_setterInFunction_block();
+  }
+
+  @failingTest
+  void test_setterInFunction_expression() {
+    super.test_setterInFunction_expression();
+  }
+
+  @failingTest
+  void test_staticAfterConst() {
+    super.test_staticAfterConst();
+  }
+
+  @failingTest
+  void test_staticAfterFinal() {
+    super.test_staticAfterFinal();
+  }
+
+  @failingTest
+  void test_staticAfterVar() {
+    super.test_staticAfterVar();
+  }
+
+  @failingTest
+  void test_staticConstructor() {
+    super.test_staticConstructor();
+  }
+
+  @failingTest
+  void test_staticGetterWithoutBody() {
+    super.test_staticGetterWithoutBody();
+  }
+
+  @failingTest
+  void test_staticOperator_noReturnType() {
+    super.test_staticOperator_noReturnType();
+  }
+
+  @failingTest
+  void test_staticOperator_returnType() {
+    super.test_staticOperator_returnType();
+  }
+
+  @failingTest
+  void test_staticSetterWithoutBody() {
+    super.test_staticSetterWithoutBody();
+  }
+
+  @failingTest
+  void test_staticTopLevelDeclaration_class() {
+    super.test_staticTopLevelDeclaration_class();
+  }
+
+  @failingTest
+  void test_staticTopLevelDeclaration_enum() {
+    super.test_staticTopLevelDeclaration_enum();
+  }
+
+  @failingTest
+  void test_staticTopLevelDeclaration_function() {
+    super.test_staticTopLevelDeclaration_function();
+  }
+
+  @failingTest
+  void test_staticTopLevelDeclaration_typedef() {
+    super.test_staticTopLevelDeclaration_typedef();
+  }
+
+  @failingTest
+  void test_staticTopLevelDeclaration_variable() {
+    super.test_staticTopLevelDeclaration_variable();
+  }
+
+  @failingTest
+  void test_string_unterminated_interpolation_block() {
+    super.test_string_unterminated_interpolation_block();
+  }
+
+  @failingTest
+  void test_switchCase_missingColon() {
+    super.test_switchCase_missingColon();
+  }
+
+  @failingTest
+  void test_switchDefault_missingColon() {
+    super.test_switchDefault_missingColon();
+  }
+
+  @failingTest
+  void test_switchHasCaseAfterDefaultCase() {
+    super.test_switchHasCaseAfterDefaultCase();
+  }
+
+  @failingTest
+  void test_switchHasCaseAfterDefaultCase_repeated() {
+    super.test_switchHasCaseAfterDefaultCase_repeated();
+  }
+
+  @failingTest
+  void test_switchHasMultipleDefaultCases() {
+    super.test_switchHasMultipleDefaultCases();
+  }
+
+  @failingTest
+  void test_switchHasMultipleDefaultCases_repeated() {
+    super.test_switchHasMultipleDefaultCases_repeated();
+  }
+
+  @failingTest
+  void test_switchMissingBlock() {
+    super.test_switchMissingBlock();
+  }
+
+  @failingTest
+  void test_topLevel_getter() {
+    super.test_topLevel_getter();
+  }
+
+  @failingTest
+  void test_topLevelFactory_withFunction() {
+    super.test_topLevelFactory_withFunction();
+  }
+
+  @failingTest
+  void test_topLevelOperator_withFunction() {
+    super.test_topLevelOperator_withFunction();
+  }
+
+  @failingTest
+  void test_topLevelOperator_withoutOperator() {
+    super.test_topLevelOperator_withoutOperator();
+  }
+
+  @failingTest
+  void test_topLevelOperator_withoutType() {
+    super.test_topLevelOperator_withoutType();
+  }
+
+  @failingTest
+  void test_topLevelOperator_withType() {
+    super.test_topLevelOperator_withType();
+  }
+
+  @failingTest
+  void test_topLevelOperator_withVoid() {
+    super.test_topLevelOperator_withVoid();
+  }
+
+  @failingTest
+  void test_topLevelVariable_withMetadata() {
+    super.test_topLevelVariable_withMetadata();
+  }
+
+  @failingTest
+  void test_typedef_incomplete() {
+    super.test_typedef_incomplete();
+  }
+
+  @failingTest
+  void test_typedef_namedFunction() {
+    super.test_typedef_namedFunction();
+  }
+
+  @failingTest
+  void test_typedefInClass_withoutReturnType() {
+    super.test_typedefInClass_withoutReturnType();
+  }
+
+  @failingTest
+  void test_typedefInClass_withReturnType() {
+    super.test_typedefInClass_withReturnType();
+  }
+
+  @failingTest
+  void test_unexpectedTerminatorForParameterGroup_named() {
+    super.test_unexpectedTerminatorForParameterGroup_named();
+  }
+
+  @failingTest
+  void test_unexpectedTerminatorForParameterGroup_optional() {
+    super.test_unexpectedTerminatorForParameterGroup_optional();
+  }
+
+  @failingTest
+  void test_unexpectedToken_endOfFieldDeclarationStatement() {
+    super.test_unexpectedToken_endOfFieldDeclarationStatement();
+  }
+
+  @failingTest
+  void test_unexpectedToken_invalidPostfixExpression() {
+    super.test_unexpectedToken_invalidPostfixExpression();
+  }
+
+  @failingTest
+  void test_unexpectedToken_invalidPrefixExpression() {
+    super.test_unexpectedToken_invalidPrefixExpression();
+  }
+
+  @failingTest
+  void test_unexpectedToken_returnInExpressionFunctionBody() {
+    super.test_unexpectedToken_returnInExpressionFunctionBody();
+  }
+
+  @failingTest
+  void test_unexpectedToken_semicolonBetweenClassMembers() {
+    super.test_unexpectedToken_semicolonBetweenClassMembers();
+  }
+
+  @failingTest
+  void test_unexpectedToken_semicolonBetweenCompilationUnitMembers() {
+    super.test_unexpectedToken_semicolonBetweenCompilationUnitMembers();
+  }
+
+  @failingTest
+  void test_unterminatedString_at_eof() {
+    super.test_unterminatedString_at_eof();
+  }
+
+  @failingTest
+  void test_unterminatedString_at_eol() {
+    super.test_unterminatedString_at_eol();
+  }
+
+  @failingTest
+  void test_unterminatedString_multiline_at_eof_3_quotes() {
+    super.test_unterminatedString_multiline_at_eof_3_quotes();
+  }
+
+  @failingTest
+  void test_unterminatedString_multiline_at_eof_4_quotes() {
+    super.test_unterminatedString_multiline_at_eof_4_quotes();
+  }
+
+  @failingTest
+  void test_unterminatedString_multiline_at_eof_5_quotes() {
+    super.test_unterminatedString_multiline_at_eof_5_quotes();
+  }
+
+  @failingTest
+  void test_useOfUnaryPlusOperator() {
+    super.test_useOfUnaryPlusOperator();
+  }
+
+  @failingTest
+  void test_varAndType_field() {
+    super.test_varAndType_field();
+  }
+
+  @failingTest
+  void test_varAndType_local() {
+    super.test_varAndType_local();
+  }
+
+  @failingTest
+  void test_varAndType_parameter() {
+    super.test_varAndType_parameter();
+  }
+
+  @failingTest
+  void test_varAndType_topLevelVariable() {
+    super.test_varAndType_topLevelVariable();
+  }
+
+  @failingTest
+  void test_varAsTypeName_as() {
+    super.test_varAsTypeName_as();
+  }
+
+  @failingTest
+  void test_varClass() {
+    super.test_varClass();
+  }
+
+  @failingTest
+  void test_varEnum() {
+    super.test_varEnum();
+  }
+
+  @failingTest
+  void test_varReturnType() {
+    super.test_varReturnType();
+  }
+
+  @failingTest
+  void test_varTypedef() {
+    super.test_varTypedef();
+  }
+
+  @failingTest
+  void test_voidParameter() {
+    super.test_voidParameter();
+  }
+
+  @failingTest
+  void test_voidVariable_parseClassMember_initializer() {
+    super.test_voidVariable_parseClassMember_initializer();
+  }
+
+  @failingTest
+  void test_voidVariable_parseClassMember_noInitializer() {
+    super.test_voidVariable_parseClassMember_noInitializer();
+  }
+
+  @failingTest
+  void test_voidVariable_parseCompilationUnit_initializer() {
+    super.test_voidVariable_parseCompilationUnit_initializer();
+  }
+
+  @failingTest
+  void test_voidVariable_parseCompilationUnit_noInitializer() {
+    super.test_voidVariable_parseCompilationUnit_noInitializer();
+  }
+
+  @failingTest
+  void test_voidVariable_parseCompilationUnitMember_initializer() {
+    super.test_voidVariable_parseCompilationUnitMember_initializer();
+  }
+
+  @failingTest
+  void test_voidVariable_parseCompilationUnitMember_noInitializer() {
+    super.test_voidVariable_parseCompilationUnitMember_noInitializer();
+  }
+
+  @failingTest
+  void test_voidVariable_statement_initializer() {
+    super.test_voidVariable_statement_initializer();
+  }
+
+  @failingTest
+  void test_voidVariable_statement_noInitializer() {
+    super.test_voidVariable_statement_noInitializer();
+  }
+
+  @failingTest
+  void test_withBeforeExtends() {
+    super.test_withBeforeExtends();
+  }
+
+  @failingTest
+  void test_withWithoutExtends() {
+    super.test_withWithoutExtends();
+  }
+
+  @failingTest
+  void test_wrongSeparatorForPositionalParameter() {
+    super.test_wrongSeparatorForPositionalParameter();
+  }
+
+  @failingTest
+  void test_wrongTerminatorForParameterGroup_named() {
+    super.test_wrongTerminatorForParameterGroup_named();
+  }
+
+  @failingTest
+  void test_wrongTerminatorForParameterGroup_optional() {
+    super.test_wrongTerminatorForParameterGroup_optional();
+  }
+}
+
 @reflectiveTest
 class ExpressionParserTest_Forest extends FastaBodyBuilderTestCase
     with ExpressionParserTestMixin {
@@ -532,21 +3033,11 @@
   }
 
   @failingTest
-  void test_parseListLiteral_empty_oneToken() {
-    super.test_parseListLiteral_empty_oneToken();
-  }
-
-  @failingTest
   void test_parseListLiteral_empty_oneToken_withComment() {
     super.test_parseListLiteral_empty_oneToken_withComment();
   }
 
   @failingTest
-  void test_parseListLiteral_empty_twoTokens() {
-    super.test_parseListLiteral_empty_twoTokens();
-  }
-
-  @failingTest
   void test_parseListLiteral_single_withTypeArgument() {
     super.test_parseListLiteral_single_withTypeArgument();
   }
@@ -808,11 +3299,6 @@
   }
 
   @failingTest
-  void test_parseRethrowExpression() {
-    super.test_parseRethrowExpression();
-  }
-
-  @failingTest
   void test_parseShiftExpression_normal() {
     super.test_parseShiftExpression_normal();
   }
@@ -833,11 +3319,6 @@
   }
 
   @failingTest
-  void test_parseStringLiteral_adjacent() {
-    super.test_parseStringLiteral_adjacent();
-  }
-
-  @failingTest
   void test_parseStringLiteral_endsWithInterpolation() {
     super.test_parseStringLiteral_endsWithInterpolation();
   }
@@ -883,31 +3364,6 @@
   }
 
   @failingTest
-  void test_parseSymbolLiteral_builtInIdentifier() {
-    super.test_parseSymbolLiteral_builtInIdentifier();
-  }
-
-  @failingTest
-  void test_parseSymbolLiteral_multiple() {
-    super.test_parseSymbolLiteral_multiple();
-  }
-
-  @failingTest
-  void test_parseSymbolLiteral_operator() {
-    super.test_parseSymbolLiteral_operator();
-  }
-
-  @failingTest
-  void test_parseSymbolLiteral_single() {
-    super.test_parseSymbolLiteral_single();
-  }
-
-  @failingTest
-  void test_parseSymbolLiteral_void() {
-    super.test_parseSymbolLiteral_void();
-  }
-
-  @failingTest
   void test_parseThrowExpression() {
     super.test_parseThrowExpression();
   }
@@ -983,9 +3439,1559 @@
   }
 }
 
-/**
- * Tests of the fasta parser based on [StatementParserTestMixin].
- */
+@reflectiveTest
+class FormalParameterParserTest_Forest extends FastaBodyBuilderTestCase
+    with FormalParameterParserTestMixin {
+  FormalParameterParserTest_Forest() : super(false);
+
+  @failingTest
+  void test_parseFormalParameter_covariant_final_named() {
+    super.test_parseFormalParameter_covariant_final_named();
+  }
+
+  @failingTest
+  void test_parseFormalParameter_covariant_final_normal() {
+    super.test_parseFormalParameter_covariant_final_normal();
+  }
+
+  @failingTest
+  void test_parseFormalParameter_covariant_final_positional() {
+    super.test_parseFormalParameter_covariant_final_positional();
+  }
+
+  @failingTest
+  void test_parseFormalParameter_covariant_final_type_named() {
+    super.test_parseFormalParameter_covariant_final_type_named();
+  }
+
+  @failingTest
+  void test_parseFormalParameter_covariant_final_type_normal() {
+    super.test_parseFormalParameter_covariant_final_type_normal();
+  }
+
+  @failingTest
+  void test_parseFormalParameter_covariant_final_type_positional() {
+    super.test_parseFormalParameter_covariant_final_type_positional();
+  }
+
+  @failingTest
+  void test_parseFormalParameter_covariant_type_function() {
+    super.test_parseFormalParameter_covariant_type_function();
+  }
+
+  @failingTest
+  void test_parseFormalParameter_covariant_type_named() {
+    super.test_parseFormalParameter_covariant_type_named();
+  }
+
+  @failingTest
+  void test_parseFormalParameter_covariant_type_normal() {
+    super.test_parseFormalParameter_covariant_type_normal();
+  }
+
+  @failingTest
+  void test_parseFormalParameter_covariant_type_positional() {
+    super.test_parseFormalParameter_covariant_type_positional();
+  }
+
+  @failingTest
+  void test_parseFormalParameter_covariant_var_named() {
+    super.test_parseFormalParameter_covariant_var_named();
+  }
+
+  @failingTest
+  void test_parseFormalParameter_covariant_var_normal() {
+    super.test_parseFormalParameter_covariant_var_normal();
+  }
+
+  @failingTest
+  void test_parseFormalParameter_covariant_var_positional() {
+    super.test_parseFormalParameter_covariant_var_positional();
+  }
+
+  @failingTest
+  void test_parseFormalParameter_final_named() {
+    super.test_parseFormalParameter_final_named();
+  }
+
+  @failingTest
+  void test_parseFormalParameter_final_normal() {
+    super.test_parseFormalParameter_final_normal();
+  }
+
+  @failingTest
+  void test_parseFormalParameter_final_positional() {
+    super.test_parseFormalParameter_final_positional();
+  }
+
+  @failingTest
+  void test_parseFormalParameter_final_type_named() {
+    super.test_parseFormalParameter_final_type_named();
+  }
+
+  @failingTest
+  void test_parseFormalParameter_final_type_normal() {
+    super.test_parseFormalParameter_final_type_normal();
+  }
+
+  @failingTest
+  void test_parseFormalParameter_final_type_positional() {
+    super.test_parseFormalParameter_final_type_positional();
+  }
+
+  @failingTest
+  void test_parseFormalParameter_type_function() {
+    super.test_parseFormalParameter_type_function();
+  }
+
+  @failingTest
+  void test_parseFormalParameter_type_named() {
+    super.test_parseFormalParameter_type_named();
+  }
+
+  @failingTest
+  void test_parseFormalParameter_type_named_noDefault() {
+    super.test_parseFormalParameter_type_named_noDefault();
+  }
+
+  @failingTest
+  void test_parseFormalParameter_type_normal() {
+    super.test_parseFormalParameter_type_normal();
+  }
+
+  @failingTest
+  void test_parseFormalParameter_type_positional() {
+    super.test_parseFormalParameter_type_positional();
+  }
+
+  @failingTest
+  void test_parseFormalParameter_type_positional_noDefault() {
+    super.test_parseFormalParameter_type_positional_noDefault();
+  }
+
+  @failingTest
+  void test_parseFormalParameter_var_named() {
+    super.test_parseFormalParameter_var_named();
+  }
+
+  @failingTest
+  void test_parseFormalParameter_var_normal() {
+    super.test_parseFormalParameter_var_normal();
+  }
+
+  @failingTest
+  void test_parseFormalParameter_var_positional() {
+    super.test_parseFormalParameter_var_positional();
+  }
+
+  @failingTest
+  void test_parseFormalParameterList_empty() {
+    super.test_parseFormalParameterList_empty();
+  }
+
+  @failingTest
+  void test_parseFormalParameterList_named_multiple() {
+    super.test_parseFormalParameterList_named_multiple();
+  }
+
+  @failingTest
+  void test_parseFormalParameterList_named_single() {
+    super.test_parseFormalParameterList_named_single();
+  }
+
+  @failingTest
+  void test_parseFormalParameterList_named_trailing_comma() {
+    super.test_parseFormalParameterList_named_trailing_comma();
+  }
+
+  @failingTest
+  void test_parseFormalParameterList_normal_multiple() {
+    super.test_parseFormalParameterList_normal_multiple();
+  }
+
+  @failingTest
+  void test_parseFormalParameterList_normal_named() {
+    super.test_parseFormalParameterList_normal_named();
+  }
+
+  @failingTest
+  void test_parseFormalParameterList_normal_named_inFunctionType() {
+    super.test_parseFormalParameterList_normal_named_inFunctionType();
+  }
+
+  @failingTest
+  void test_parseFormalParameterList_normal_positional() {
+    super.test_parseFormalParameterList_normal_positional();
+  }
+
+  @failingTest
+  void test_parseFormalParameterList_normal_single() {
+    super.test_parseFormalParameterList_normal_single();
+  }
+
+  @failingTest
+  void test_parseFormalParameterList_normal_single_Function() {
+    super.test_parseFormalParameterList_normal_single_Function();
+  }
+
+  @failingTest
+  void test_parseFormalParameterList_normal_single_trailing_comma() {
+    super.test_parseFormalParameterList_normal_single_trailing_comma();
+  }
+
+  @failingTest
+  void test_parseFormalParameterList_positional_multiple() {
+    super.test_parseFormalParameterList_positional_multiple();
+  }
+
+  @failingTest
+  void test_parseFormalParameterList_positional_single() {
+    super.test_parseFormalParameterList_positional_single();
+  }
+
+  @failingTest
+  void test_parseFormalParameterList_positional_trailing_comma() {
+    super.test_parseFormalParameterList_positional_trailing_comma();
+  }
+
+  @failingTest
+  void test_parseFormalParameterList_prefixedType() {
+    super.test_parseFormalParameterList_prefixedType();
+  }
+
+  @failingTest
+  void test_parseFormalParameterList_prefixedType_missingName() {
+    super.test_parseFormalParameterList_prefixedType_missingName();
+  }
+
+  @failingTest
+  void test_parseFormalParameterList_prefixedType_partial() {
+    super.test_parseFormalParameterList_prefixedType_partial();
+  }
+
+  @failingTest
+  void test_parseFormalParameterList_prefixedType_partial2() {
+    super.test_parseFormalParameterList_prefixedType_partial2();
+  }
+
+  @failingTest
+  void test_parseNormalFormalParameter_field_const_noType() {
+    super.test_parseNormalFormalParameter_field_const_noType();
+  }
+
+  @failingTest
+  void test_parseNormalFormalParameter_field_const_type() {
+    super.test_parseNormalFormalParameter_field_const_type();
+  }
+
+  @failingTest
+  void test_parseNormalFormalParameter_field_final_noType() {
+    super.test_parseNormalFormalParameter_field_final_noType();
+  }
+
+  @failingTest
+  void test_parseNormalFormalParameter_field_final_type() {
+    super.test_parseNormalFormalParameter_field_final_type();
+  }
+
+  @failingTest
+  void test_parseNormalFormalParameter_field_function_nested() {
+    super.test_parseNormalFormalParameter_field_function_nested();
+  }
+
+  @failingTest
+  void test_parseNormalFormalParameter_field_function_noNested() {
+    super.test_parseNormalFormalParameter_field_function_noNested();
+  }
+
+  @failingTest
+  void test_parseNormalFormalParameter_field_function_withDocComment() {
+    super.test_parseNormalFormalParameter_field_function_withDocComment();
+  }
+
+  @failingTest
+  void test_parseNormalFormalParameter_field_noType() {
+    super.test_parseNormalFormalParameter_field_noType();
+  }
+
+  @failingTest
+  void test_parseNormalFormalParameter_field_type() {
+    super.test_parseNormalFormalParameter_field_type();
+  }
+
+  @failingTest
+  void test_parseNormalFormalParameter_field_var() {
+    super.test_parseNormalFormalParameter_field_var();
+  }
+
+  @failingTest
+  void test_parseNormalFormalParameter_field_withDocComment() {
+    super.test_parseNormalFormalParameter_field_withDocComment();
+  }
+
+  @failingTest
+  void test_parseNormalFormalParameter_function_named() {
+    super.test_parseNormalFormalParameter_function_named();
+  }
+
+  @failingTest
+  void test_parseNormalFormalParameter_function_noType() {
+    super.test_parseNormalFormalParameter_function_noType();
+  }
+
+  @failingTest
+  void test_parseNormalFormalParameter_function_noType_covariant() {
+    super.test_parseNormalFormalParameter_function_noType_covariant();
+  }
+
+  @failingTest
+  void test_parseNormalFormalParameter_function_noType_typeParameterComments() {
+    super
+        .test_parseNormalFormalParameter_function_noType_typeParameterComments();
+  }
+
+  @failingTest
+  void test_parseNormalFormalParameter_function_noType_typeParameters() {
+    super.test_parseNormalFormalParameter_function_noType_typeParameters();
+  }
+
+  @failingTest
+  void test_parseNormalFormalParameter_function_type() {
+    super.test_parseNormalFormalParameter_function_type();
+  }
+
+  @failingTest
+  void test_parseNormalFormalParameter_function_type_typeParameterComments() {
+    super.test_parseNormalFormalParameter_function_type_typeParameterComments();
+  }
+
+  @failingTest
+  void test_parseNormalFormalParameter_function_type_typeParameters() {
+    super.test_parseNormalFormalParameter_function_type_typeParameters();
+  }
+
+  @failingTest
+  void test_parseNormalFormalParameter_function_typeVoid_covariant() {
+    super.test_parseNormalFormalParameter_function_typeVoid_covariant();
+  }
+
+  @failingTest
+  void test_parseNormalFormalParameter_function_void() {
+    super.test_parseNormalFormalParameter_function_void();
+  }
+
+  @failingTest
+  void test_parseNormalFormalParameter_function_void_typeParameterComments() {
+    super.test_parseNormalFormalParameter_function_void_typeParameterComments();
+  }
+
+  @failingTest
+  void test_parseNormalFormalParameter_function_void_typeParameters() {
+    super.test_parseNormalFormalParameter_function_void_typeParameters();
+  }
+
+  @failingTest
+  void test_parseNormalFormalParameter_function_withDocComment() {
+    super.test_parseNormalFormalParameter_function_withDocComment();
+  }
+
+  @failingTest
+  void test_parseNormalFormalParameter_simple_const_noType() {
+    super.test_parseNormalFormalParameter_simple_const_noType();
+  }
+
+  @failingTest
+  void test_parseNormalFormalParameter_simple_const_type() {
+    super.test_parseNormalFormalParameter_simple_const_type();
+  }
+
+  @failingTest
+  void test_parseNormalFormalParameter_simple_final_noType() {
+    super.test_parseNormalFormalParameter_simple_final_noType();
+  }
+
+  @failingTest
+  void test_parseNormalFormalParameter_simple_final_type() {
+    super.test_parseNormalFormalParameter_simple_final_type();
+  }
+
+  @failingTest
+  void test_parseNormalFormalParameter_simple_noName() {
+    super.test_parseNormalFormalParameter_simple_noName();
+  }
+
+  @failingTest
+  void test_parseNormalFormalParameter_simple_noType() {
+    super.test_parseNormalFormalParameter_simple_noType();
+  }
+
+  @failingTest
+  void test_parseNormalFormalParameter_simple_noType_namedCovariant() {
+    super.test_parseNormalFormalParameter_simple_noType_namedCovariant();
+  }
+
+  @failingTest
+  void test_parseNormalFormalParameter_simple_type() {
+    super.test_parseNormalFormalParameter_simple_type();
+  }
+}
+
+@reflectiveTest
+class RecoveryParserTest_Forest extends FastaBodyBuilderTestCase
+    with RecoveryParserTestMixin {
+  RecoveryParserTest_Forest() : super(false);
+
+  @failingTest
+  void test_additiveExpression_missing_LHS() {
+    super.test_additiveExpression_missing_LHS();
+  }
+
+  @failingTest
+  void test_additiveExpression_missing_LHS_RHS() {
+    super.test_additiveExpression_missing_LHS_RHS();
+  }
+
+  @failingTest
+  void test_additiveExpression_missing_RHS() {
+    super.test_additiveExpression_missing_RHS();
+  }
+
+  @failingTest
+  void test_additiveExpression_missing_RHS_super() {
+    super.test_additiveExpression_missing_RHS_super();
+  }
+
+  @failingTest
+  void test_additiveExpression_precedence_multiplicative_left() {
+    super.test_additiveExpression_precedence_multiplicative_left();
+  }
+
+  @failingTest
+  void test_additiveExpression_precedence_multiplicative_right() {
+    super.test_additiveExpression_precedence_multiplicative_right();
+  }
+
+  @failingTest
+  void test_additiveExpression_super() {
+    super.test_additiveExpression_super();
+  }
+
+  @failingTest
+  void test_assignableSelector() {
+    super.test_assignableSelector();
+  }
+
+  @failingTest
+  void test_assignmentExpression_missing_compound1() {
+    super.test_assignmentExpression_missing_compound1();
+  }
+
+  @failingTest
+  void test_assignmentExpression_missing_compound2() {
+    super.test_assignmentExpression_missing_compound2();
+  }
+
+  @failingTest
+  void test_assignmentExpression_missing_compound3() {
+    super.test_assignmentExpression_missing_compound3();
+  }
+
+  @failingTest
+  void test_assignmentExpression_missing_LHS() {
+    super.test_assignmentExpression_missing_LHS();
+  }
+
+  @failingTest
+  void test_assignmentExpression_missing_RHS() {
+    super.test_assignmentExpression_missing_RHS();
+  }
+
+  @failingTest
+  void test_bitwiseAndExpression_missing_LHS() {
+    super.test_bitwiseAndExpression_missing_LHS();
+  }
+
+  @failingTest
+  void test_bitwiseAndExpression_missing_LHS_RHS() {
+    super.test_bitwiseAndExpression_missing_LHS_RHS();
+  }
+
+  @failingTest
+  void test_bitwiseAndExpression_missing_RHS() {
+    super.test_bitwiseAndExpression_missing_RHS();
+  }
+
+  @failingTest
+  void test_bitwiseAndExpression_missing_RHS_super() {
+    super.test_bitwiseAndExpression_missing_RHS_super();
+  }
+
+  @failingTest
+  void test_bitwiseAndExpression_precedence_equality_left() {
+    super.test_bitwiseAndExpression_precedence_equality_left();
+  }
+
+  @failingTest
+  void test_bitwiseAndExpression_precedence_equality_right() {
+    super.test_bitwiseAndExpression_precedence_equality_right();
+  }
+
+  @failingTest
+  void test_bitwiseAndExpression_super() {
+    super.test_bitwiseAndExpression_super();
+  }
+
+  @failingTest
+  void test_bitwiseOrExpression_missing_LHS() {
+    super.test_bitwiseOrExpression_missing_LHS();
+  }
+
+  @failingTest
+  void test_bitwiseOrExpression_missing_LHS_RHS() {
+    super.test_bitwiseOrExpression_missing_LHS_RHS();
+  }
+
+  @failingTest
+  void test_bitwiseOrExpression_missing_RHS() {
+    super.test_bitwiseOrExpression_missing_RHS();
+  }
+
+  @failingTest
+  void test_bitwiseOrExpression_missing_RHS_super() {
+    super.test_bitwiseOrExpression_missing_RHS_super();
+  }
+
+  @failingTest
+  void test_bitwiseOrExpression_precedence_xor_left() {
+    super.test_bitwiseOrExpression_precedence_xor_left();
+  }
+
+  @failingTest
+  void test_bitwiseOrExpression_precedence_xor_right() {
+    super.test_bitwiseOrExpression_precedence_xor_right();
+  }
+
+  @failingTest
+  void test_bitwiseOrExpression_super() {
+    super.test_bitwiseOrExpression_super();
+  }
+
+  @failingTest
+  void test_bitwiseXorExpression_missing_LHS() {
+    super.test_bitwiseXorExpression_missing_LHS();
+  }
+
+  @failingTest
+  void test_bitwiseXorExpression_missing_LHS_RHS() {
+    super.test_bitwiseXorExpression_missing_LHS_RHS();
+  }
+
+  @failingTest
+  void test_bitwiseXorExpression_missing_RHS() {
+    super.test_bitwiseXorExpression_missing_RHS();
+  }
+
+  @failingTest
+  void test_bitwiseXorExpression_missing_RHS_super() {
+    super.test_bitwiseXorExpression_missing_RHS_super();
+  }
+
+  @failingTest
+  void test_bitwiseXorExpression_precedence_and_left() {
+    super.test_bitwiseXorExpression_precedence_and_left();
+  }
+
+  @failingTest
+  void test_bitwiseXorExpression_precedence_and_right() {
+    super.test_bitwiseXorExpression_precedence_and_right();
+  }
+
+  @failingTest
+  void test_bitwiseXorExpression_super() {
+    super.test_bitwiseXorExpression_super();
+  }
+
+  @failingTest
+  void test_classTypeAlias_withBody() {
+    super.test_classTypeAlias_withBody();
+  }
+
+  @failingTest
+  void test_combinator_missingIdentifier() {
+    super.test_combinator_missingIdentifier();
+  }
+
+  @failingTest
+  void test_conditionalExpression_missingElse() {
+    super.test_conditionalExpression_missingElse();
+  }
+
+  @failingTest
+  void test_conditionalExpression_missingThen() {
+    super.test_conditionalExpression_missingThen();
+  }
+
+  @failingTest
+  void test_declarationBeforeDirective() {
+    super.test_declarationBeforeDirective();
+  }
+
+  @failingTest
+  void test_equalityExpression_missing_LHS() {
+    super.test_equalityExpression_missing_LHS();
+  }
+
+  @failingTest
+  void test_equalityExpression_missing_LHS_RHS() {
+    super.test_equalityExpression_missing_LHS_RHS();
+  }
+
+  @failingTest
+  void test_equalityExpression_missing_RHS() {
+    super.test_equalityExpression_missing_RHS();
+  }
+
+  @failingTest
+  void test_equalityExpression_missing_RHS_super() {
+    super.test_equalityExpression_missing_RHS_super();
+  }
+
+  @failingTest
+  void test_equalityExpression_precedence_relational_left() {
+    super.test_equalityExpression_precedence_relational_left();
+  }
+
+  @failingTest
+  void test_equalityExpression_precedence_relational_right() {
+    super.test_equalityExpression_precedence_relational_right();
+  }
+
+  @failingTest
+  void test_equalityExpression_super() {
+    super.test_equalityExpression_super();
+  }
+
+  @failingTest
+  void test_expressionList_multiple_end() {
+    super.test_expressionList_multiple_end();
+  }
+
+  @failingTest
+  void test_expressionList_multiple_middle() {
+    super.test_expressionList_multiple_middle();
+  }
+
+  @failingTest
+  void test_expressionList_multiple_start() {
+    super.test_expressionList_multiple_start();
+  }
+
+  @failingTest
+  void test_functionExpression_in_ConstructorFieldInitializer() {
+    super.test_functionExpression_in_ConstructorFieldInitializer();
+  }
+
+  @failingTest
+  void test_functionExpression_named() {
+    super.test_functionExpression_named();
+  }
+
+  @failingTest
+  void test_ifStatement_noElse_statement() {
+    super.test_ifStatement_noElse_statement();
+  }
+
+  @failingTest
+  void test_importDirectivePartial_as() {
+    super.test_importDirectivePartial_as();
+  }
+
+  @failingTest
+  void test_importDirectivePartial_hide() {
+    super.test_importDirectivePartial_hide();
+  }
+
+  @failingTest
+  void test_importDirectivePartial_show() {
+    super.test_importDirectivePartial_show();
+  }
+
+  @failingTest
+  void test_incomplete_conditionalExpression() {
+    super.test_incomplete_conditionalExpression();
+  }
+
+  @failingTest
+  void test_incomplete_constructorInitializers_empty() {
+    super.test_incomplete_constructorInitializers_empty();
+  }
+
+  @failingTest
+  void test_incomplete_constructorInitializers_missingEquals() {
+    super.test_incomplete_constructorInitializers_missingEquals();
+  }
+
+  @failingTest
+  void test_incomplete_constructorInitializers_this() {
+    super.test_incomplete_constructorInitializers_this();
+  }
+
+  @failingTest
+  void test_incomplete_constructorInitializers_thisField() {
+    super.test_incomplete_constructorInitializers_thisField();
+  }
+
+  @failingTest
+  void test_incomplete_constructorInitializers_thisPeriod() {
+    super.test_incomplete_constructorInitializers_thisPeriod();
+  }
+
+  @failingTest
+  void test_incomplete_constructorInitializers_variable() {
+    super.test_incomplete_constructorInitializers_variable();
+  }
+
+  @failingTest
+  void test_incomplete_functionExpression() {
+    super.test_incomplete_functionExpression();
+  }
+
+  @failingTest
+  void test_incomplete_functionExpression2() {
+    super.test_incomplete_functionExpression2();
+  }
+
+  @failingTest
+  void test_incomplete_returnType() {
+    super.test_incomplete_returnType();
+  }
+
+  @failingTest
+  void test_incomplete_topLevelFunction() {
+    super.test_incomplete_topLevelFunction();
+  }
+
+  @failingTest
+  void test_incomplete_topLevelVariable() {
+    super.test_incomplete_topLevelVariable();
+  }
+
+  @failingTest
+  void test_incomplete_topLevelVariable_const() {
+    super.test_incomplete_topLevelVariable_const();
+  }
+
+  @failingTest
+  void test_incomplete_topLevelVariable_final() {
+    super.test_incomplete_topLevelVariable_final();
+  }
+
+  @failingTest
+  void test_incomplete_topLevelVariable_var() {
+    super.test_incomplete_topLevelVariable_var();
+  }
+
+  @failingTest
+  void test_incompleteField_const() {
+    super.test_incompleteField_const();
+  }
+
+  @failingTest
+  void test_incompleteField_final() {
+    super.test_incompleteField_final();
+  }
+
+  @failingTest
+  void test_incompleteField_static() {
+    super.test_incompleteField_static();
+  }
+
+  @failingTest
+  void test_incompleteField_static2() {
+    super.test_incompleteField_static2();
+  }
+
+  @failingTest
+  void test_incompleteField_type() {
+    super.test_incompleteField_type();
+  }
+
+  @failingTest
+  void test_incompleteField_var() {
+    super.test_incompleteField_var();
+  }
+
+  @failingTest
+  void test_incompleteForEach() {
+    super.test_incompleteForEach();
+  }
+
+  @failingTest
+  void test_incompleteLocalVariable_atTheEndOfBlock() {
+    super.test_incompleteLocalVariable_atTheEndOfBlock();
+  }
+
+  @failingTest
+  void test_incompleteLocalVariable_atTheEndOfBlock_modifierOnly() {
+    super.test_incompleteLocalVariable_atTheEndOfBlock_modifierOnly();
+  }
+
+  @failingTest
+  void test_incompleteLocalVariable_beforeIdentifier() {
+    super.test_incompleteLocalVariable_beforeIdentifier();
+  }
+
+  @failingTest
+  void test_incompleteLocalVariable_beforeKeyword() {
+    super.test_incompleteLocalVariable_beforeKeyword();
+  }
+
+  @failingTest
+  void test_incompleteLocalVariable_beforeNextBlock() {
+    super.test_incompleteLocalVariable_beforeNextBlock();
+  }
+
+  @failingTest
+  void test_incompleteLocalVariable_parameterizedType() {
+    super.test_incompleteLocalVariable_parameterizedType();
+  }
+
+  @failingTest
+  void test_incompleteTypeArguments_field() {
+    super.test_incompleteTypeArguments_field();
+  }
+
+  @failingTest
+  void test_incompleteTypeParameters() {
+    super.test_incompleteTypeParameters();
+  }
+
+  @failingTest
+  void test_incompleteTypeParameters2() {
+    super.test_incompleteTypeParameters2();
+  }
+
+  @failingTest
+  void test_invalidFunctionBodyModifier() {
+    super.test_invalidFunctionBodyModifier();
+  }
+
+  @failingTest
+  void test_invalidTypeParameters() {
+    super.test_invalidTypeParameters();
+  }
+
+  @failingTest
+  void test_isExpression_noType() {
+    super.test_isExpression_noType();
+  }
+
+  @failingTest
+  void test_keywordInPlaceOfIdentifier() {
+    super.test_keywordInPlaceOfIdentifier();
+  }
+
+  @failingTest
+  void test_logicalAndExpression_missing_LHS() {
+    super.test_logicalAndExpression_missing_LHS();
+  }
+
+  @failingTest
+  void test_logicalAndExpression_missing_LHS_RHS() {
+    super.test_logicalAndExpression_missing_LHS_RHS();
+  }
+
+  @failingTest
+  void test_logicalAndExpression_missing_RHS() {
+    super.test_logicalAndExpression_missing_RHS();
+  }
+
+  @failingTest
+  void test_logicalAndExpression_precedence_bitwiseOr_left() {
+    super.test_logicalAndExpression_precedence_bitwiseOr_left();
+  }
+
+  @failingTest
+  void test_logicalAndExpression_precedence_bitwiseOr_right() {
+    super.test_logicalAndExpression_precedence_bitwiseOr_right();
+  }
+
+  @failingTest
+  void test_logicalOrExpression_missing_LHS() {
+    super.test_logicalOrExpression_missing_LHS();
+  }
+
+  @failingTest
+  void test_logicalOrExpression_missing_LHS_RHS() {
+    super.test_logicalOrExpression_missing_LHS_RHS();
+  }
+
+  @failingTest
+  void test_logicalOrExpression_missing_RHS() {
+    super.test_logicalOrExpression_missing_RHS();
+  }
+
+  @failingTest
+  void test_logicalOrExpression_precedence_logicalAnd_left() {
+    super.test_logicalOrExpression_precedence_logicalAnd_left();
+  }
+
+  @failingTest
+  void test_logicalOrExpression_precedence_logicalAnd_right() {
+    super.test_logicalOrExpression_precedence_logicalAnd_right();
+  }
+
+  @failingTest
+  void test_method_missingBody() {
+    super.test_method_missingBody();
+  }
+
+  @failingTest
+  void test_missing_commaInArgumentList() {
+    super.test_missing_commaInArgumentList();
+  }
+
+  @failingTest
+  void test_missingComma_beforeNamedArgument() {
+    super.test_missingComma_beforeNamedArgument();
+  }
+
+  @failingTest
+  void test_missingGet() {
+    super.test_missingGet();
+  }
+
+  @failingTest
+  void test_missingIdentifier_afterAnnotation() {
+    super.test_missingIdentifier_afterAnnotation();
+  }
+
+  @failingTest
+  void test_missingSemicolon_varialeDeclarationList() {
+    super.test_missingSemicolon_varialeDeclarationList();
+  }
+
+  @failingTest
+  void test_multiplicativeExpression_missing_LHS() {
+    super.test_multiplicativeExpression_missing_LHS();
+  }
+
+  @failingTest
+  void test_multiplicativeExpression_missing_LHS_RHS() {
+    super.test_multiplicativeExpression_missing_LHS_RHS();
+  }
+
+  @failingTest
+  void test_multiplicativeExpression_missing_RHS() {
+    super.test_multiplicativeExpression_missing_RHS();
+  }
+
+  @failingTest
+  void test_multiplicativeExpression_missing_RHS_super() {
+    super.test_multiplicativeExpression_missing_RHS_super();
+  }
+
+  @failingTest
+  void test_multiplicativeExpression_precedence_unary_left() {
+    super.test_multiplicativeExpression_precedence_unary_left();
+  }
+
+  @failingTest
+  void test_multiplicativeExpression_precedence_unary_right() {
+    super.test_multiplicativeExpression_precedence_unary_right();
+  }
+
+  @failingTest
+  void test_multiplicativeExpression_super() {
+    super.test_multiplicativeExpression_super();
+  }
+
+  @failingTest
+  void test_namedParameterOutsideGroup() {
+    super.test_namedParameterOutsideGroup();
+  }
+
+  @failingTest
+  void test_nonStringLiteralUri_import() {
+    super.test_nonStringLiteralUri_import();
+  }
+
+  @failingTest
+  void test_prefixExpression_missing_operand_minus() {
+    super.test_prefixExpression_missing_operand_minus();
+  }
+
+  @failingTest
+  void test_primaryExpression_argumentDefinitionTest() {
+    super.test_primaryExpression_argumentDefinitionTest();
+  }
+
+  @failingTest
+  void test_propertyAccess_missing_LHS_RHS() {
+    super.test_propertyAccess_missing_LHS_RHS();
+  }
+
+  @failingTest
+  void test_relationalExpression_missing_LHS() {
+    super.test_relationalExpression_missing_LHS();
+  }
+
+  @failingTest
+  void test_relationalExpression_missing_LHS_RHS() {
+    super.test_relationalExpression_missing_LHS_RHS();
+  }
+
+  @failingTest
+  void test_relationalExpression_missing_RHS() {
+    super.test_relationalExpression_missing_RHS();
+  }
+
+  @failingTest
+  void test_relationalExpression_precedence_shift_right() {
+    super.test_relationalExpression_precedence_shift_right();
+  }
+
+  @failingTest
+  void test_shiftExpression_missing_LHS() {
+    super.test_shiftExpression_missing_LHS();
+  }
+
+  @failingTest
+  void test_shiftExpression_missing_LHS_RHS() {
+    super.test_shiftExpression_missing_LHS_RHS();
+  }
+
+  @failingTest
+  void test_shiftExpression_missing_RHS() {
+    super.test_shiftExpression_missing_RHS();
+  }
+
+  @failingTest
+  void test_shiftExpression_missing_RHS_super() {
+    super.test_shiftExpression_missing_RHS_super();
+  }
+
+  @failingTest
+  void test_shiftExpression_precedence_unary_left() {
+    super.test_shiftExpression_precedence_unary_left();
+  }
+
+  @failingTest
+  void test_shiftExpression_precedence_unary_right() {
+    super.test_shiftExpression_precedence_unary_right();
+  }
+
+  @failingTest
+  void test_shiftExpression_super() {
+    super.test_shiftExpression_super();
+  }
+
+  @failingTest
+  void test_typedef_eof() {
+    super.test_typedef_eof();
+  }
+
+  @failingTest
+  void test_unaryPlus() {
+    super.test_unaryPlus();
+  }
+}
+
+@reflectiveTest
+class SimpleParserTest_Forest extends FastaBodyBuilderTestCase
+    with SimpleParserTestMixin {
+  SimpleParserTest_Forest() : super(false);
+
+  @failingTest
+  void test_classDeclaration_complexTypeParam() {
+    super.test_classDeclaration_complexTypeParam();
+  }
+
+  @failingTest
+  void test_parseAnnotation_n1() {
+    super.test_parseAnnotation_n1();
+  }
+
+  @failingTest
+  void test_parseAnnotation_n1_a() {
+    super.test_parseAnnotation_n1_a();
+  }
+
+  @failingTest
+  void test_parseAnnotation_n2() {
+    super.test_parseAnnotation_n2();
+  }
+
+  @failingTest
+  void test_parseAnnotation_n2_a() {
+    super.test_parseAnnotation_n2_a();
+  }
+
+  @failingTest
+  void test_parseAnnotation_n3() {
+    super.test_parseAnnotation_n3();
+  }
+
+  @failingTest
+  void test_parseAnnotation_n3_a() {
+    super.test_parseAnnotation_n3_a();
+  }
+
+  @failingTest
+  void test_parseArgumentList_empty() {
+    super.test_parseArgumentList_empty();
+  }
+
+  @failingTest
+  void test_parseArgumentList_mixed() {
+    super.test_parseArgumentList_mixed();
+  }
+
+  @failingTest
+  void test_parseArgumentList_noNamed() {
+    super.test_parseArgumentList_noNamed();
+  }
+
+  @failingTest
+  void test_parseArgumentList_onlyNamed() {
+    super.test_parseArgumentList_onlyNamed();
+  }
+
+  @failingTest
+  void test_parseArgumentList_trailing_comma() {
+    super.test_parseArgumentList_trailing_comma();
+  }
+
+  @failingTest
+  void test_parseArgumentList_typeArguments() {
+    super.test_parseArgumentList_typeArguments();
+  }
+
+  @failingTest
+  void test_parseArgumentList_typeArguments_none() {
+    super.test_parseArgumentList_typeArguments_none();
+  }
+
+  @failingTest
+  void test_parseArgumentList_typeArguments_prefixed() {
+    super.test_parseArgumentList_typeArguments_prefixed();
+  }
+
+  @failingTest
+  void test_parseCombinators_h() {
+    super.test_parseCombinators_h();
+  }
+
+  @failingTest
+  void test_parseCombinators_hs() {
+    super.test_parseCombinators_hs();
+  }
+
+  @failingTest
+  void test_parseCombinators_hshs() {
+    super.test_parseCombinators_hshs();
+  }
+
+  @failingTest
+  void test_parseCombinators_s() {
+    super.test_parseCombinators_s();
+  }
+
+  @failingTest
+  void test_parseCommentAndMetadata_c() {
+    super.test_parseCommentAndMetadata_c();
+  }
+
+  @failingTest
+  void test_parseCommentAndMetadata_cmc() {
+    super.test_parseCommentAndMetadata_cmc();
+  }
+
+  @failingTest
+  void test_parseCommentAndMetadata_cmcm() {
+    super.test_parseCommentAndMetadata_cmcm();
+  }
+
+  @failingTest
+  void test_parseCommentAndMetadata_cmm() {
+    super.test_parseCommentAndMetadata_cmm();
+  }
+
+  @failingTest
+  void test_parseCommentAndMetadata_m() {
+    super.test_parseCommentAndMetadata_m();
+  }
+
+  @failingTest
+  void test_parseCommentAndMetadata_mcm() {
+    super.test_parseCommentAndMetadata_mcm();
+  }
+
+  @failingTest
+  void test_parseCommentAndMetadata_mcmc() {
+    super.test_parseCommentAndMetadata_mcmc();
+  }
+
+  @failingTest
+  void test_parseCommentAndMetadata_mm() {
+    super.test_parseCommentAndMetadata_mm();
+  }
+
+  @failingTest
+  void test_parseCommentAndMetadata_none() {
+    super.test_parseCommentAndMetadata_none();
+  }
+
+  @failingTest
+  void test_parseCommentAndMetadata_singleLine() {
+    super.test_parseCommentAndMetadata_singleLine();
+  }
+
+  @failingTest
+  void test_parseConfiguration_noOperator_dottedIdentifier() {
+    super.test_parseConfiguration_noOperator_dottedIdentifier();
+  }
+
+  @failingTest
+  void test_parseConfiguration_noOperator_simpleIdentifier() {
+    super.test_parseConfiguration_noOperator_simpleIdentifier();
+  }
+
+  @failingTest
+  void test_parseConfiguration_operator_dottedIdentifier() {
+    super.test_parseConfiguration_operator_dottedIdentifier();
+  }
+
+  @failingTest
+  void test_parseConfiguration_operator_simpleIdentifier() {
+    super.test_parseConfiguration_operator_simpleIdentifier();
+  }
+
+  @failingTest
+  void test_parseConstructorName_named_noPrefix() {
+    super.test_parseConstructorName_named_noPrefix();
+  }
+
+  @failingTest
+  void test_parseConstructorName_named_prefixed() {
+    super.test_parseConstructorName_named_prefixed();
+  }
+
+  @failingTest
+  void test_parseConstructorName_unnamed_noPrefix() {
+    super.test_parseConstructorName_unnamed_noPrefix();
+  }
+
+  @failingTest
+  void test_parseConstructorName_unnamed_prefixed() {
+    super.test_parseConstructorName_unnamed_prefixed();
+  }
+
+  @failingTest
+  void test_parseDocumentationComment_block() {
+    super.test_parseDocumentationComment_block();
+  }
+
+  @failingTest
+  void test_parseDocumentationComment_block_withReference() {
+    super.test_parseDocumentationComment_block_withReference();
+  }
+
+  @failingTest
+  void test_parseDocumentationComment_endOfLine() {
+    super.test_parseDocumentationComment_endOfLine();
+  }
+
+  @failingTest
+  void test_parseExtendsClause() {
+    super.test_parseExtendsClause();
+  }
+
+  @failingTest
+  void test_parseFunctionBody_block() {
+    super.test_parseFunctionBody_block();
+  }
+
+  @failingTest
+  void test_parseFunctionBody_block_async() {
+    super.test_parseFunctionBody_block_async();
+  }
+
+  @failingTest
+  void test_parseFunctionBody_block_asyncGenerator() {
+    super.test_parseFunctionBody_block_asyncGenerator();
+  }
+
+  @failingTest
+  void test_parseFunctionBody_block_syncGenerator() {
+    super.test_parseFunctionBody_block_syncGenerator();
+  }
+
+  @failingTest
+  void test_parseFunctionBody_empty() {
+    super.test_parseFunctionBody_empty();
+  }
+
+  @failingTest
+  void test_parseFunctionBody_expression() {
+    super.test_parseFunctionBody_expression();
+  }
+
+  @failingTest
+  void test_parseFunctionBody_expression_async() {
+    super.test_parseFunctionBody_expression_async();
+  }
+
+  @failingTest
+  void test_parseIdentifierList_multiple() {
+    super.test_parseIdentifierList_multiple();
+  }
+
+  @failingTest
+  void test_parseIdentifierList_single() {
+    super.test_parseIdentifierList_single();
+  }
+
+  @failingTest
+  void test_parseImplementsClause_multiple() {
+    super.test_parseImplementsClause_multiple();
+  }
+
+  @failingTest
+  void test_parseImplementsClause_single() {
+    super.test_parseImplementsClause_single();
+  }
+
+  @failingTest
+  void test_parseInstanceCreation_noKeyword_noPrefix() {
+    super.test_parseInstanceCreation_noKeyword_noPrefix();
+  }
+
+  @failingTest
+  void test_parseInstanceCreation_noKeyword_prefix() {
+    super.test_parseInstanceCreation_noKeyword_prefix();
+  }
+
+  @failingTest
+  void test_parseInstanceCreation_noKeyword_varInit() {
+    super.test_parseInstanceCreation_noKeyword_varInit();
+  }
+
+  @failingTest
+  void test_parseLibraryIdentifier_builtin() {
+    super.test_parseLibraryIdentifier_builtin();
+  }
+
+  @failingTest
+  void test_parseLibraryIdentifier_invalid() {
+    super.test_parseLibraryIdentifier_invalid();
+  }
+
+  @failingTest
+  void test_parseLibraryIdentifier_multiple() {
+    super.test_parseLibraryIdentifier_multiple();
+  }
+
+  @failingTest
+  void test_parseLibraryIdentifier_pseudo() {
+    super.test_parseLibraryIdentifier_pseudo();
+  }
+
+  @failingTest
+  void test_parseLibraryIdentifier_single() {
+    super.test_parseLibraryIdentifier_single();
+  }
+
+  @failingTest
+  void test_parseReturnStatement_value() {
+    super.test_parseReturnStatement_value();
+  }
+
+  @failingTest
+  void test_parseStatement_function_noReturnType() {
+    super.test_parseStatement_function_noReturnType();
+  }
+
+  @failingTest
+  void test_parseTypeAnnotation_function_noReturnType_noParameters() {
+    super.test_parseTypeAnnotation_function_noReturnType_noParameters();
+  }
+
+  @failingTest
+  void test_parseTypeAnnotation_function_noReturnType_parameters() {
+    super.test_parseTypeAnnotation_function_noReturnType_parameters();
+  }
+
+  @failingTest
+  void test_parseTypeAnnotation_function_noReturnType_typeParameters() {
+    super.test_parseTypeAnnotation_function_noReturnType_typeParameters();
+  }
+
+  @failingTest
+  void
+      test_parseTypeAnnotation_function_noReturnType_typeParameters_parameters() {
+    super
+        .test_parseTypeAnnotation_function_noReturnType_typeParameters_parameters();
+  }
+
+  @failingTest
+  void test_parseTypeAnnotation_function_returnType_classFunction() {
+    super.test_parseTypeAnnotation_function_returnType_classFunction();
+  }
+
+  @failingTest
+  void test_parseTypeAnnotation_function_returnType_function() {
+    super.test_parseTypeAnnotation_function_returnType_function();
+  }
+
+  @failingTest
+  void test_parseTypeAnnotation_function_returnType_noParameters() {
+    super.test_parseTypeAnnotation_function_returnType_noParameters();
+  }
+
+  @failingTest
+  void test_parseTypeAnnotation_function_returnType_parameters() {
+    super.test_parseTypeAnnotation_function_returnType_parameters();
+  }
+
+  @failingTest
+  void test_parseTypeAnnotation_function_returnType_simple() {
+    super.test_parseTypeAnnotation_function_returnType_simple();
+  }
+
+  @failingTest
+  void test_parseTypeAnnotation_function_returnType_typeParameters() {
+    super.test_parseTypeAnnotation_function_returnType_typeParameters();
+  }
+
+  @failingTest
+  void
+      test_parseTypeAnnotation_function_returnType_typeParameters_parameters() {
+    super
+        .test_parseTypeAnnotation_function_returnType_typeParameters_parameters();
+  }
+
+  @failingTest
+  void test_parseTypeAnnotation_function_returnType_withArguments() {
+    super.test_parseTypeAnnotation_function_returnType_withArguments();
+  }
+
+  @failingTest
+  void test_parseTypeAnnotation_named() {
+    super.test_parseTypeAnnotation_named();
+  }
+
+  @failingTest
+  void test_parseTypeArgumentList_empty() {
+    super.test_parseTypeArgumentList_empty();
+  }
+
+  @failingTest
+  void test_parseTypeArgumentList_multiple() {
+    super.test_parseTypeArgumentList_multiple();
+  }
+
+  @failingTest
+  void test_parseTypeArgumentList_nested() {
+    super.test_parseTypeArgumentList_nested();
+  }
+
+  @failingTest
+  void test_parseTypeArgumentList_nested_withComment_double() {
+    super.test_parseTypeArgumentList_nested_withComment_double();
+  }
+
+  @failingTest
+  void test_parseTypeArgumentList_nested_withComment_tripple() {
+    super.test_parseTypeArgumentList_nested_withComment_tripple();
+  }
+
+  @failingTest
+  void test_parseTypeArgumentList_single() {
+    super.test_parseTypeArgumentList_single();
+  }
+
+  @failingTest
+  void test_parseTypeName_parameterized() {
+    super.test_parseTypeName_parameterized();
+  }
+
+  @failingTest
+  void test_parseTypeName_simple() {
+    super.test_parseTypeName_simple();
+  }
+
+  @failingTest
+  void test_parseTypeParameter_bounded_functionType_noReturn() {
+    super.test_parseTypeParameter_bounded_functionType_noReturn();
+  }
+
+  @failingTest
+  void test_parseTypeParameter_bounded_functionType_return() {
+    super.test_parseTypeParameter_bounded_functionType_return();
+  }
+
+  @failingTest
+  void test_parseTypeParameter_bounded_generic() {
+    super.test_parseTypeParameter_bounded_generic();
+  }
+
+  @failingTest
+  void test_parseTypeParameter_bounded_simple() {
+    super.test_parseTypeParameter_bounded_simple();
+  }
+
+  @failingTest
+  void test_parseTypeParameter_simple() {
+    super.test_parseTypeParameter_simple();
+  }
+
+  @failingTest
+  void test_parseTypeParameterList_multiple() {
+    super.test_parseTypeParameterList_multiple();
+  }
+
+  @failingTest
+  void test_parseTypeParameterList_parameterizedWithTrailingEquals() {
+    super.test_parseTypeParameterList_parameterizedWithTrailingEquals();
+  }
+
+  @failingTest
+  void test_parseTypeParameterList_parameterizedWithTrailingEquals2() {
+    super.test_parseTypeParameterList_parameterizedWithTrailingEquals2();
+  }
+
+  @failingTest
+  void test_parseTypeParameterList_single() {
+    super.test_parseTypeParameterList_single();
+  }
+
+  @failingTest
+  void test_parseTypeParameterList_withTrailingEquals() {
+    super.test_parseTypeParameterList_withTrailingEquals();
+  }
+
+  @failingTest
+  void test_parseVariableDeclaration_equals() {
+    super.test_parseVariableDeclaration_equals();
+  }
+
+  @failingTest
+  void test_parseVariableDeclaration_noEquals() {
+    super.test_parseVariableDeclaration_noEquals();
+  }
+
+  @failingTest
+  void test_parseWithClause_multiple() {
+    super.test_parseWithClause_multiple();
+  }
+
+  @failingTest
+  void test_parseWithClause_single() {
+    super.test_parseWithClause_single();
+  }
+}
+
 @reflectiveTest
 class StatementParserTest_Forest extends FastaBodyBuilderTestCase
     with StatementParserTestMixin {
@@ -1032,16 +5038,6 @@
   }
 
   @failingTest
-  void test_parseBlock_empty() {
-    super.test_parseBlock_empty();
-  }
-
-  @failingTest
-  void test_parseBlock_nonEmpty() {
-    super.test_parseBlock_nonEmpty();
-  }
-
-  @failingTest
   void test_parseBreakStatement_label() {
     super.test_parseBreakStatement_label();
   }
@@ -1067,11 +5063,6 @@
   }
 
   @failingTest
-  void test_parseEmptyStatement() {
-    super.test_parseEmptyStatement();
-  }
-
-  @failingTest
   void test_parseForStatement_each_await() {
     super.test_parseForStatement_each_await();
   }
@@ -1177,6 +5168,13 @@
   }
 
   @failingTest
+  void test_parseIfStatement_else_emptyStatements() {
+    super.test_parseIfStatement_else_emptyStatements();
+    fail(
+        'This passes under Dart 1, but fails under Dart 2 because of a cast exception');
+  }
+
+  @failingTest
   void test_parseIfStatement_else_statement() {
     super.test_parseIfStatement_else_statement();
   }
@@ -1192,21 +5190,6 @@
   }
 
   @failingTest
-  void test_parseNonLabeledStatement_const_list_empty() {
-    super.test_parseNonLabeledStatement_const_list_empty();
-  }
-
-  @failingTest
-  void test_parseNonLabeledStatement_const_list_nonEmpty() {
-    super.test_parseNonLabeledStatement_const_list_nonEmpty();
-  }
-
-  @failingTest
-  void test_parseNonLabeledStatement_const_map_empty() {
-    super.test_parseNonLabeledStatement_const_map_empty();
-  }
-
-  @failingTest
   void test_parseNonLabeledStatement_const_map_nonEmpty() {
     super.test_parseNonLabeledStatement_const_map_nonEmpty();
   }
@@ -1227,11 +5210,6 @@
   }
 
   @failingTest
-  void test_parseNonLabeledStatement_false() {
-    super.test_parseNonLabeledStatement_false();
-  }
-
-  @failingTest
   void test_parseNonLabeledStatement_functionDeclaration() {
     super.test_parseNonLabeledStatement_functionDeclaration();
   }
@@ -1262,21 +5240,11 @@
   }
 
   @failingTest
-  void test_parseNonLabeledStatement_null() {
-    super.test_parseNonLabeledStatement_null();
-  }
-
-  @failingTest
   void test_parseNonLabeledStatement_startingWithBuiltInIdentifier() {
     super.test_parseNonLabeledStatement_startingWithBuiltInIdentifier();
   }
 
   @failingTest
-  void test_parseNonLabeledStatement_true() {
-    super.test_parseNonLabeledStatement_true();
-  }
-
-  @failingTest
   void test_parseNonLabeledStatement_typeCast() {
     super.test_parseNonLabeledStatement_typeCast();
   }
@@ -1359,11 +5327,6 @@
   }
 
   @failingTest
-  void test_parseStatement_functionDeclaration_noReturnType() {
-    super.test_parseStatement_functionDeclaration_noReturnType();
-  }
-
-  @failingTest
   void
       test_parseStatement_functionDeclaration_noReturnType_typeParameterComments() {
     super
@@ -1451,11 +5414,6 @@
   }
 
   @failingTest
-  void test_parseTryStatement_finally() {
-    super.test_parseTryStatement_finally();
-  }
-
-  @failingTest
   void test_parseTryStatement_multiple() {
     super.test_parseTryStatement_multiple();
   }
diff --git a/pkg/analyzer/test/generated/parser_test.dart b/pkg/analyzer/test/generated/parser_test.dart
index 7c45cac..611ee186 100644
--- a/pkg/analyzer/test/generated/parser_test.dart
+++ b/pkg/analyzer/test/generated/parser_test.dart
@@ -1573,7 +1573,7 @@
     createParser('external const factory C();');
     ClassMember member = parser.parseClassMember('C');
     expectNotNullIfNoErrors(member);
-    listener.assertNoErrors();
+    assertNoErrors();
   }
 
   void test_parseConstructor_factory_named() {
@@ -2542,28 +2542,16 @@
         errors: [expectedError(ParserErrorCode.ABSTRACT_TYPEDEF, 0, 8)]);
   }
 
-  void test_annotationOnEnumConstant_first() {
-    parseCompilationUnit("enum E { @override C }", errors: [
-      expectedError(ParserErrorCode.ANNOTATION_ON_ENUM_CONSTANT, 9, 9)
-    ]);
-  }
-
-  void test_annotationOnEnumConstant_middle() {
-    parseCompilationUnit("enum E { C, @override D, E }", errors: [
-      expectedError(ParserErrorCode.ANNOTATION_ON_ENUM_CONSTANT, 12, 9)
-    ]);
-  }
-
   void test_breakOutsideOfLoop_breakInDoStatement() {
     DoStatement statement = parseStatement('do {break;} while (x);');
     expectNotNullIfNoErrors(statement);
-    listener.assertNoErrors();
+    assertNoErrors();
   }
 
   void test_breakOutsideOfLoop_breakInForStatement() {
     Statement statement = parseStatement('for (; x;) {break;}');
     expectNotNullIfNoErrors(statement);
-    listener.assertNoErrors();
+    assertNoErrors();
   }
 
   void test_breakOutsideOfLoop_breakInIfStatement() {
@@ -2576,13 +2564,13 @@
   void test_breakOutsideOfLoop_breakInSwitchStatement() {
     SwitchStatement statement = parseStatement('switch (x) {case 1: break;}');
     expectNotNullIfNoErrors(statement);
-    listener.assertNoErrors();
+    assertNoErrors();
   }
 
   void test_breakOutsideOfLoop_breakInWhileStatement() {
     WhileStatement statement = parseStatement('while (x) {break;}');
     expectNotNullIfNoErrors(statement);
-    listener.assertNoErrors();
+    assertNoErrors();
   }
 
   void test_breakOutsideOfLoop_functionExpression_inALoop() {
@@ -2613,11 +2601,16 @@
   void test_classTypeAlias_abstractAfterEq() {
     // This syntax has been removed from the language in favor of
     // "abstract class A = B with C;" (issue 18098).
-    createParser('class A = abstract B with C;');
+    createParser('class A = abstract B with C;', expectedEndOffset: 21);
     CompilationUnitMember member = parseFullCompilationUnitMember();
     expectNotNullIfNoErrors(member);
     listener.assertErrors(usingFastaParser
-        ? [expectedError(ParserErrorCode.EXPECTED_TYPE_NAME, 10, 8)]
+        ? [
+            expectedError(
+                CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE, 10, 8),
+            expectedError(ParserErrorCode.EXPECTED_TOKEN, 19, 1),
+            expectedError(ParserErrorCode.EXPECTED_TOKEN, 21, 4)
+          ]
         : [
             expectedError(ParserErrorCode.EXPECTED_TOKEN, 0, 0),
             expectedError(ParserErrorCode.EXPECTED_TOKEN, 0, 0)
@@ -2742,13 +2735,13 @@
   void test_continueOutsideOfLoop_continueInDoStatement() {
     DoStatement statement = parseStatement('do {continue;} while (x);');
     expectNotNullIfNoErrors(statement);
-    listener.assertNoErrors();
+    assertNoErrors();
   }
 
   void test_continueOutsideOfLoop_continueInForStatement() {
     Statement statement = parseStatement('for (; x;) {continue;}');
     expectNotNullIfNoErrors(statement);
-    listener.assertNoErrors();
+    assertNoErrors();
   }
 
   void test_continueOutsideOfLoop_continueInIfStatement() {
@@ -2762,13 +2755,13 @@
     SwitchStatement statement =
         parseStatement('switch (x) {case 1: continue a;}');
     expectNotNullIfNoErrors(statement);
-    listener.assertNoErrors();
+    assertNoErrors();
   }
 
   void test_continueOutsideOfLoop_continueInWhileStatement() {
     WhileStatement statement = parseStatement('while (x) {continue;}');
     expectNotNullIfNoErrors(statement);
-    listener.assertNoErrors();
+    assertNoErrors();
   }
 
   void test_continueOutsideOfLoop_functionExpression_inALoop() {
@@ -2793,14 +2786,14 @@
     SwitchStatement statement =
         parseStatement('switch (x) {case 1: continue a;}');
     expectNotNullIfNoErrors(statement);
-    listener.assertNoErrors();
+    assertNoErrors();
   }
 
   void test_continueWithoutLabelInCase_noError_switchInLoop() {
     WhileStatement statement =
         parseStatement('while (a) { switch (b) {default: continue;}}');
     expectNotNullIfNoErrors(statement);
-    listener.assertNoErrors();
+    assertNoErrors();
   }
 
   void test_covariantAfterVar() {
@@ -4175,11 +4168,11 @@
     parseCompilationUnit("typedef var Function(var arg);",
         errors: usingFastaParser
             ? [
-                expectedError(ParserErrorCode.EXPECTED_TYPE_NAME, 8, 3),
-                expectedError(ParserErrorCode.VAR_AND_TYPE, 21, 3),
-                expectedError(ParserErrorCode.MISSING_IDENTIFIER, 29, 1),
-                expectedError(
-                    ParserErrorCode.MISSING_TYPEDEF_PARAMETERS, 29, 1),
+                expectedError(ParserErrorCode.MISSING_IDENTIFIER, 8, 3),
+                expectedError(ParserErrorCode.MISSING_TYPEDEF_PARAMETERS, 8, 3),
+                expectedError(ParserErrorCode.EXPECTED_TOKEN, 8, 3),
+                expectedError(ParserErrorCode.VAR_RETURN_TYPE, 8, 3),
+                expectedError(ParserErrorCode.MISSING_FUNCTION_BODY, 29, 1),
               ]
             : [
                 expectedError(ParserErrorCode.MISSING_IDENTIFIER, 8, 3),
@@ -4189,6 +4182,31 @@
               ]);
   }
 
+  void test_invalidTypedef2() {
+    // https://github.com/dart-lang/sdk/issues/31171
+    parseCompilationUnit(
+        "typedef T = typedef F = Map<String, dynamic> Function();",
+        errors: usingFastaParser
+            ? [
+                expectedError(ParserErrorCode.EXPECTED_TYPE_NAME, 12, 7),
+                expectedError(ParserErrorCode.EXPECTED_TOKEN, 12, 7),
+                expectedError(
+                    ParserErrorCode.INVALID_GENERIC_FUNCTION_TYPE, 10, 1),
+              ]
+            : [
+                expectedError(ParserErrorCode.EXPECTED_TOKEN, 12, 7),
+                expectedError(
+                    ParserErrorCode.INVALID_GENERIC_FUNCTION_TYPE, 20, 1),
+                expectedError(
+                    ParserErrorCode.MISSING_CONST_FINAL_VAR_OR_TYPE, 20, 1),
+                expectedError(ParserErrorCode.EXPECTED_TOKEN, 36, 7),
+                expectedError(ParserErrorCode.EXPECTED_EXECUTABLE, 43, 1),
+                expectedError(ParserErrorCode.UNEXPECTED_TOKEN, 43, 1),
+                expectedError(ParserErrorCode.EXPECTED_EXECUTABLE, 55, 1),
+                expectedError(ParserErrorCode.UNEXPECTED_TOKEN, 55, 1),
+              ]);
+  }
+
   void test_invalidUnicodeEscape_incomplete_noDigits() {
     Expression expression = parseStringLiteral("'\\u{'");
     expectNotNullIfNoErrors(expression);
@@ -5428,7 +5446,7 @@
     createParser('get x => 7;');
     CompilationUnitMember member = parseFullCompilationUnitMember();
     expectNotNullIfNoErrors(member);
-    listener.assertNoErrors();
+    assertNoErrors();
     expect(member, new isInstanceOf<FunctionDeclaration>());
     FunctionDeclaration function = member;
     expect(function.functionExpression.parameters, isNull);
@@ -5513,13 +5531,9 @@
   }
 
   void test_typedef_namedFunction() {
-    // TODO(brianwilkerson) Improve recovery for this case.
     parseCompilationUnit('typedef void Function();',
         codes: usingFastaParser
-            ? [
-                ParserErrorCode.MISSING_IDENTIFIER,
-                ParserErrorCode.MISSING_TYPEDEF_PARAMETERS
-              ]
+            ? [ParserErrorCode.MISSING_IDENTIFIER]
             : [
                 ParserErrorCode.UNEXPECTED_TOKEN,
                 ParserErrorCode.MISSING_IDENTIFIER,
@@ -5565,9 +5579,10 @@
   }
 
   void test_unexpectedToken_endOfFieldDeclarationStatement() {
-    parseStatement("String s = (null));");
-    listener
-        .assertErrors([expectedError(ParserErrorCode.UNEXPECTED_TOKEN, 17, 1)]);
+    parseStatement("String s = (null));", expectedEndOffset: 17);
+    listener.assertErrors(usingFastaParser
+        ? [expectedError(ParserErrorCode.EXPECTED_TOKEN, 17, 1)]
+        : [expectedError(ParserErrorCode.UNEXPECTED_TOKEN, 17, 1)]);
   }
 
   void test_unexpectedToken_invalidPostfixExpression() {
@@ -5805,21 +5820,21 @@
     NormalFormalParameter parameter =
         parseFormalParameterList('(void a)').parameters[0];
     expectNotNullIfNoErrors(parameter);
-    listener.assertNoErrors();
+    assertNoErrors();
   }
 
   void test_voidVariable_parseClassMember_initializer() {
     createParser('void x = 0;');
     ClassMember member = parser.parseClassMember('C');
     expectNotNullIfNoErrors(member);
-    listener.assertNoErrors();
+    assertNoErrors();
   }
 
   void test_voidVariable_parseClassMember_noInitializer() {
     createParser('void x;');
     ClassMember member = parser.parseClassMember('C');
     expectNotNullIfNoErrors(member);
-    listener.assertNoErrors();
+    assertNoErrors();
   }
 
   void test_voidVariable_parseCompilationUnit_initializer() {
@@ -5834,24 +5849,24 @@
     createParser('void a = 0;');
     CompilationUnitMember member = parseFullCompilationUnitMember();
     expectNotNullIfNoErrors(member);
-    listener.assertNoErrors();
+    assertNoErrors();
   }
 
   void test_voidVariable_parseCompilationUnitMember_noInitializer() {
     createParser('void a;');
     CompilationUnitMember member = parseFullCompilationUnitMember();
     expectNotNullIfNoErrors(member);
-    listener.assertNoErrors();
+    assertNoErrors();
   }
 
   void test_voidVariable_statement_initializer() {
     parseStatement("void x = 0;");
-    listener.assertNoErrors();
+    assertNoErrors();
   }
 
   void test_voidVariable_statement_noInitializer() {
     parseStatement("void x;");
-    listener.assertNoErrors();
+    assertNoErrors();
   }
 
   void test_withBeforeExtends() {
@@ -9731,13 +9746,27 @@
 
 @reflectiveTest
 class NonErrorParserTest extends ParserTestCase {
+  void test_annotationOnEnumConstant_first() {
+    createParser("enum E { @override C }");
+    CompilationUnit unit = parser.parseCompilationUnit2();
+    expectNotNullIfNoErrors(unit);
+    assertNoErrors();
+  }
+
+  void test_annotationOnEnumConstant_middle() {
+    createParser("enum E { C, @override D, E }");
+    CompilationUnit unit = parser.parseCompilationUnit2();
+    expectNotNullIfNoErrors(unit);
+    assertNoErrors();
+  }
+
   void test_staticMethod_notParsingFunctionBodies() {
     ParserTestCase.parseFunctionBodies = false;
     try {
       createParser('class C { static void m() {} }');
       CompilationUnit unit = parser.parseCompilationUnit2();
       expectNotNullIfNoErrors(unit);
-      listener.assertNoErrors();
+      assertNoErrors();
     } finally {
       ParserTestCase.parseFunctionBodies = true;
     }
@@ -10902,7 +10931,7 @@
     // and instead parseExpressionList is mapped to parseExpression('[$code]')
     // which allows and ignores an optional trailing comma.
     if (usingFastaParser) {
-      listener.assertNoErrors();
+      assertNoErrors();
       expect(result, hasLength(3));
     } else {
       listener.assertErrors(
@@ -12319,7 +12348,7 @@
     createParser('');
     CommentReference reference = parser.parseCommentReference('new a.b', 7);
     expectNotNullIfNoErrors(reference);
-    listener.assertNoErrors();
+    assertNoErrors();
     expect(reference.identifier, new isInstanceOf<PrefixedIdentifier>());
     PrefixedIdentifier prefixedIdentifier = reference.identifier;
     SimpleIdentifier prefix = prefixedIdentifier.prefix;
@@ -12337,7 +12366,7 @@
     createParser('');
     CommentReference reference = parser.parseCommentReference('new a', 5);
     expectNotNullIfNoErrors(reference);
-    listener.assertNoErrors();
+    assertNoErrors();
     expect(reference.identifier, new isInstanceOf<SimpleIdentifier>());
     SimpleIdentifier identifier = reference.identifier;
     expect(identifier.token, isNotNull);
@@ -12349,7 +12378,7 @@
     createParser('');
     CommentReference reference = parser.parseCommentReference('operator ==', 5);
     expectNotNullIfNoErrors(reference);
-    listener.assertNoErrors();
+    assertNoErrors();
     expect(reference.identifier, new isInstanceOf<SimpleIdentifier>());
     SimpleIdentifier identifier = reference.identifier;
     expect(identifier.token, isNotNull);
@@ -12362,7 +12391,7 @@
     CommentReference reference =
         parser.parseCommentReference('Object.operator==', 7);
     expectNotNullIfNoErrors(reference);
-    listener.assertNoErrors();
+    assertNoErrors();
     expect(reference.identifier, new isInstanceOf<PrefixedIdentifier>());
     PrefixedIdentifier prefixedIdentifier = reference.identifier;
     SimpleIdentifier prefix = prefixedIdentifier.prefix;
@@ -12380,7 +12409,7 @@
     createParser('');
     CommentReference reference = parser.parseCommentReference('==', 5);
     expectNotNullIfNoErrors(reference);
-    listener.assertNoErrors();
+    assertNoErrors();
     expect(reference.identifier, new isInstanceOf<SimpleIdentifier>());
     SimpleIdentifier identifier = reference.identifier;
     expect(identifier.token, isNotNull);
@@ -12392,7 +12421,7 @@
     createParser('');
     CommentReference reference = parser.parseCommentReference('Object.==', 7);
     expectNotNullIfNoErrors(reference);
-    listener.assertNoErrors();
+    assertNoErrors();
     expect(reference.identifier, new isInstanceOf<PrefixedIdentifier>());
     PrefixedIdentifier prefixedIdentifier = reference.identifier;
     SimpleIdentifier prefix = prefixedIdentifier.prefix;
@@ -12410,7 +12439,7 @@
     createParser('');
     CommentReference reference = parser.parseCommentReference('a.b', 7);
     expectNotNullIfNoErrors(reference);
-    listener.assertNoErrors();
+    assertNoErrors();
     expect(reference.identifier, new isInstanceOf<PrefixedIdentifier>());
     PrefixedIdentifier prefixedIdentifier = reference.identifier;
     SimpleIdentifier prefix = prefixedIdentifier.prefix;
@@ -12428,7 +12457,7 @@
     createParser('');
     CommentReference reference = parser.parseCommentReference('a', 5);
     expectNotNullIfNoErrors(reference);
-    listener.assertNoErrors();
+    assertNoErrors();
     expect(reference.identifier, new isInstanceOf<SimpleIdentifier>());
     SimpleIdentifier identifier = reference.identifier;
     expect(identifier.token, isNotNull);
@@ -12440,7 +12469,7 @@
     createParser('');
     CommentReference reference = parser.parseCommentReference('', 5);
     expectNotNullIfNoErrors(reference);
-    listener.assertNoErrors();
+    assertNoErrors();
     expect(reference.identifier, new isInstanceOf<SimpleIdentifier>());
     SimpleIdentifier identifier = reference.identifier;
     expect(identifier, isNotNull);
@@ -12461,7 +12490,7 @@
     createParser('');
     CommentReference reference = parser.parseCommentReference('this', 5);
     expectNotNullIfNoErrors(reference);
-    listener.assertNoErrors();
+    assertNoErrors();
     SimpleIdentifier identifier = EngineTestCase.assertInstanceOf(
         (obj) => obj is SimpleIdentifier,
         SimpleIdentifier,
@@ -12478,7 +12507,7 @@
     createParser('');
     List<CommentReference> references = parser.parseCommentReferences(tokens);
     expectNotNullIfNoErrors(references);
-    listener.assertNoErrors();
+    assertNoErrors();
     List<Token> tokenReferences = token.references;
     expect(references, hasLength(2));
     expect(tokenReferences, hasLength(2));
@@ -12511,7 +12540,7 @@
     List<CommentReference> references =
         parser.parseCommentReferences(<DocumentationCommentToken>[docToken]);
     expectNotNullIfNoErrors(references);
-    listener.assertNoErrors();
+    assertNoErrors();
     expect(docToken.references, hasLength(1));
     expect(references, hasLength(1));
     Token referenceToken = docToken.references[0];
@@ -12534,7 +12563,7 @@
     List<CommentReference> references =
         parser.parseCommentReferences(<DocumentationCommentToken>[docToken]);
     expectNotNullIfNoErrors(references);
-    listener.assertNoErrors();
+    assertNoErrors();
     expect(docToken.references, hasLength(1));
     expect(references, hasLength(1));
     Token referenceToken = docToken.references[0];
@@ -12560,7 +12589,7 @@
     createParser('');
     List<CommentReference> references = parser.parseCommentReferences(tokens);
     expectNotNullIfNoErrors(references);
-    listener.assertNoErrors();
+    assertNoErrors();
     expect(references, hasLength(3));
     CommentReference reference = references[0];
     expect(reference, isNotNull);
@@ -12584,7 +12613,7 @@
     createParser('');
     List<CommentReference> references = parser.parseCommentReferences(tokens);
     expectNotNullIfNoErrors(references);
-    listener.assertNoErrors();
+    assertNoErrors();
     expect(references, isEmpty);
   }
 
@@ -12598,7 +12627,7 @@
     createParser('');
     List<CommentReference> references = parser.parseCommentReferences(tokens);
     expectNotNullIfNoErrors(references);
-    listener.assertNoErrors();
+    assertNoErrors();
     expect(references, isEmpty);
   }
 
@@ -12610,7 +12639,7 @@
     createParser('');
     List<CommentReference> references = parser.parseCommentReferences(tokens);
     expectNotNullIfNoErrors(references);
-    listener.assertNoErrors();
+    assertNoErrors();
     expect(references, hasLength(1));
     CommentReference reference = references[0];
     expect(reference, isNotNull);
@@ -12626,7 +12655,7 @@
     createParser('');
     List<CommentReference> references = parser.parseCommentReferences(tokens);
     expectNotNullIfNoErrors(references);
-    listener.assertNoErrors();
+    assertNoErrors();
     expect(references, hasLength(1));
     CommentReference reference = references[0];
     expect(reference, isNotNull);
@@ -12652,7 +12681,7 @@
     createParser('');
     List<CommentReference> references = parser.parseCommentReferences(tokens);
     expectNotNullIfNoErrors(references);
-    listener.assertNoErrors();
+    assertNoErrors();
     expect(references, isEmpty);
   }
 
@@ -12672,7 +12701,7 @@
     createParser('');
     List<CommentReference> references = parser.parseCommentReferences(tokens);
     expectNotNullIfNoErrors(references);
-    listener.assertNoErrors();
+    assertNoErrors();
     expect(references, isEmpty);
   }
 
@@ -12684,7 +12713,7 @@
     createParser('');
     List<CommentReference> references = parser.parseCommentReferences(tokens);
     expectNotNullIfNoErrors(references);
-    listener.assertNoErrors();
+    assertNoErrors();
     expect(references, hasLength(2));
   }
 
@@ -12696,7 +12725,7 @@
     createParser('');
     List<CommentReference> references = parser.parseCommentReferences(tokens);
     expectNotNullIfNoErrors(references);
-    listener.assertNoErrors();
+    assertNoErrors();
     expect(references, hasLength(1));
     CommentReference reference = references[0];
     expect(reference, isNotNull);
@@ -12712,7 +12741,7 @@
     createParser('');
     List<CommentReference> references = parser.parseCommentReferences(tokens);
     expectNotNullIfNoErrors(references);
-    listener.assertNoErrors();
+    assertNoErrors();
     expect(references, hasLength(1));
     CommentReference reference = references[0];
     expect(reference, isNotNull);
@@ -12728,7 +12757,7 @@
     createParser('');
     List<CommentReference> references = parser.parseCommentReferences(tokens);
     expectNotNullIfNoErrors(references);
-    listener.assertNoErrors();
+    assertNoErrors();
     expect(references, hasLength(1));
     CommentReference reference = references[0];
     expect(reference, isNotNull);
@@ -12744,7 +12773,7 @@
     createParser('');
     List<CommentReference> references = parser.parseCommentReferences(tokens);
     expectNotNullIfNoErrors(references);
-    listener.assertNoErrors();
+    assertNoErrors();
     expect(references, hasLength(1));
     CommentReference reference = references[0];
     expect(reference, isNotNull);
@@ -12756,7 +12785,7 @@
     createParser('a.b.c');
     DottedName name = parser.parseDottedName();
     expectNotNullIfNoErrors(name);
-    listener.assertNoErrors();
+    assertNoErrors();
     expectDottedName(name, ["a", "b", "c"]);
   }
 
@@ -12764,7 +12793,7 @@
     createParser('a');
     DottedName name = parser.parseDottedName();
     expectNotNullIfNoErrors(name);
-    listener.assertNoErrors();
+    assertNoErrors();
     expectDottedName(name, ["a"]);
   }
 
@@ -12772,7 +12801,7 @@
     createParser('const int Function(int) f');
     FinalConstVarOrType result = parser.parseFinalConstVarOrType(false);
     expectNotNullIfNoErrors(result);
-    listener.assertNoErrors();
+    assertNoErrors();
     Token keyword = result.keyword;
     expect(keyword, isNotNull);
     expect(keyword.type.isKeyword, true);
@@ -12784,7 +12813,7 @@
     createParser('const A a');
     FinalConstVarOrType result = parser.parseFinalConstVarOrType(false);
     expectNotNullIfNoErrors(result);
-    listener.assertNoErrors();
+    assertNoErrors();
     Token keyword = result.keyword;
     expect(keyword, isNotNull);
     expect(keyword.type.isKeyword, true);
@@ -12796,7 +12825,7 @@
     createParser('const');
     FinalConstVarOrType result = parser.parseFinalConstVarOrType(false);
     expectNotNullIfNoErrors(result);
-    listener.assertNoErrors();
+    assertNoErrors();
     Token keyword = result.keyword;
     expect(keyword, isNotNull);
     expect(keyword.type.isKeyword, true);
@@ -12808,7 +12837,7 @@
     createParser('final int Function(int) f');
     FinalConstVarOrType result = parser.parseFinalConstVarOrType(false);
     expectNotNullIfNoErrors(result);
-    listener.assertNoErrors();
+    assertNoErrors();
     Token keyword = result.keyword;
     expect(keyword, isNotNull);
     expect(keyword.type.isKeyword, true);
@@ -12820,7 +12849,7 @@
     createParser('final A a');
     FinalConstVarOrType result = parser.parseFinalConstVarOrType(false);
     expectNotNullIfNoErrors(result);
-    listener.assertNoErrors();
+    assertNoErrors();
     Token keyword = result.keyword;
     expect(keyword, isNotNull);
     expect(keyword.type.isKeyword, true);
@@ -12832,7 +12861,7 @@
     createParser('final');
     FinalConstVarOrType result = parser.parseFinalConstVarOrType(false);
     expectNotNullIfNoErrors(result);
-    listener.assertNoErrors();
+    assertNoErrors();
     Token keyword = result.keyword;
     expect(keyword, isNotNull);
     expect(keyword.type.isKeyword, true);
@@ -12844,7 +12873,7 @@
     createParser('final p.A a');
     FinalConstVarOrType result = parser.parseFinalConstVarOrType(false);
     expectNotNullIfNoErrors(result);
-    listener.assertNoErrors();
+    assertNoErrors();
     Token keyword = result.keyword;
     expect(keyword, isNotNull);
     expect(keyword.type.isKeyword, true);
@@ -12856,7 +12885,7 @@
     createParser('int Function(int) f');
     FinalConstVarOrType result = parser.parseFinalConstVarOrType(false);
     expectNotNullIfNoErrors(result);
-    listener.assertNoErrors();
+    assertNoErrors();
     expect(result.keyword, isNull);
     expect(result.type, isNotNull);
   }
@@ -12865,7 +12894,7 @@
     createParser('A<B> a');
     FinalConstVarOrType result = parser.parseFinalConstVarOrType(false);
     expectNotNullIfNoErrors(result);
-    listener.assertNoErrors();
+    assertNoErrors();
     expect(result.keyword, isNull);
     expect(result.type, isNotNull);
   }
@@ -12874,7 +12903,7 @@
     createParser('p.A a');
     FinalConstVarOrType result = parser.parseFinalConstVarOrType(false);
     expectNotNullIfNoErrors(result);
-    listener.assertNoErrors();
+    assertNoErrors();
     expect(result.keyword, isNull);
     expect(result.type, isNotNull);
   }
@@ -12883,7 +12912,7 @@
     createParser('p.A,');
     FinalConstVarOrType result = parser.parseFinalConstVarOrType(false);
     expectNotNullIfNoErrors(result);
-    listener.assertNoErrors();
+    assertNoErrors();
     expect(result.keyword, isNull);
     expect(result.type, isNotNull);
   }
@@ -12892,7 +12921,7 @@
     createParser('p.A<B> a');
     FinalConstVarOrType result = parser.parseFinalConstVarOrType(false);
     expectNotNullIfNoErrors(result);
-    listener.assertNoErrors();
+    assertNoErrors();
     expect(result.keyword, isNull);
     expect(result.type, isNotNull);
   }
@@ -12901,7 +12930,7 @@
     createParser('A a');
     FinalConstVarOrType result = parser.parseFinalConstVarOrType(false);
     expectNotNullIfNoErrors(result);
-    listener.assertNoErrors();
+    assertNoErrors();
     expect(result.keyword, isNull);
     expect(result.type, isNotNull);
   }
@@ -12911,7 +12940,7 @@
     FinalConstVarOrType result =
         parser.parseFinalConstVarOrType(false, inFunctionType: true);
     expectNotNullIfNoErrors(result);
-    listener.assertNoErrors();
+    assertNoErrors();
     expect(result.keyword, isNull);
     expect(result.type, isNotNull);
   }
@@ -12920,7 +12949,7 @@
     createParser('var');
     FinalConstVarOrType result = parser.parseFinalConstVarOrType(false);
     expectNotNullIfNoErrors(result);
-    listener.assertNoErrors();
+    assertNoErrors();
     Token keyword = result.keyword;
     expect(keyword, isNotNull);
     expect(keyword.type.isKeyword, true);
@@ -12932,7 +12961,7 @@
     createParser('void f()');
     FinalConstVarOrType result = parser.parseFinalConstVarOrType(false);
     expectNotNullIfNoErrors(result);
-    listener.assertNoErrors();
+    assertNoErrors();
     expect(result.keyword, isNull);
     expect(result.type, isNotNull);
   }
@@ -12941,7 +12970,7 @@
     createParser('void x');
     FinalConstVarOrType result = parser.parseFinalConstVarOrType(false);
     expectNotNullIfNoErrors(result);
-    listener.assertNoErrors();
+    assertNoErrors();
     expect(result.keyword, isNull);
     expect(result.type, isNotNull);
   }
@@ -12959,7 +12988,7 @@
     createParser('{}');
     FunctionBody functionBody = parser.parseFunctionBody(false, null, false);
     expectNotNullIfNoErrors(functionBody);
-    listener.assertNoErrors();
+    assertNoErrors();
     expect(functionBody, new isInstanceOf<EmptyFunctionBody>());
   }
 
@@ -12981,7 +13010,7 @@
     createParser('{ {} }');
     FunctionBody functionBody = parser.parseFunctionBody(false, null, false);
     expectNotNullIfNoErrors(functionBody);
-    listener.assertNoErrors();
+    assertNoErrors();
     expect(functionBody, new isInstanceOf<EmptyFunctionBody>());
   }
 
@@ -12990,7 +13019,7 @@
     createParser('=> y;');
     FunctionBody functionBody = parser.parseFunctionBody(false, null, false);
     expectNotNullIfNoErrors(functionBody);
-    listener.assertNoErrors();
+    assertNoErrors();
     expect(functionBody, new isInstanceOf<EmptyFunctionBody>());
   }
 
@@ -12998,7 +13027,7 @@
     createParser('abstract A');
     Modifiers modifiers = parser.parseModifiers();
     expectNotNullIfNoErrors(modifiers);
-    listener.assertNoErrors();
+    assertNoErrors();
     expect(modifiers.abstractKeyword, isNotNull);
   }
 
@@ -13006,7 +13035,7 @@
     createParser('const A');
     Modifiers modifiers = parser.parseModifiers();
     expectNotNullIfNoErrors(modifiers);
-    listener.assertNoErrors();
+    assertNoErrors();
     expect(modifiers.constKeyword, isNotNull);
   }
 
@@ -13014,7 +13043,7 @@
     createParser('covariant A');
     Modifiers modifiers = parser.parseModifiers();
     expectNotNullIfNoErrors(modifiers);
-    listener.assertNoErrors();
+    assertNoErrors();
     expect(modifiers.covariantKeyword, isNotNull);
   }
 
@@ -13022,7 +13051,7 @@
     createParser('external A');
     Modifiers modifiers = parser.parseModifiers();
     expectNotNullIfNoErrors(modifiers);
-    listener.assertNoErrors();
+    assertNoErrors();
     expect(modifiers.externalKeyword, isNotNull);
   }
 
@@ -13030,7 +13059,7 @@
     createParser('factory A');
     Modifiers modifiers = parser.parseModifiers();
     expectNotNullIfNoErrors(modifiers);
-    listener.assertNoErrors();
+    assertNoErrors();
     expect(modifiers.factoryKeyword, isNotNull);
   }
 
@@ -13038,7 +13067,7 @@
     createParser('final A');
     Modifiers modifiers = parser.parseModifiers();
     expectNotNullIfNoErrors(modifiers);
-    listener.assertNoErrors();
+    assertNoErrors();
     expect(modifiers.finalKeyword, isNotNull);
   }
 
@@ -13046,7 +13075,7 @@
     createParser('static A');
     Modifiers modifiers = parser.parseModifiers();
     expectNotNullIfNoErrors(modifiers);
-    listener.assertNoErrors();
+    assertNoErrors();
     expect(modifiers.staticKeyword, isNotNull);
   }
 
@@ -13054,7 +13083,7 @@
     createParser('var A');
     Modifiers modifiers = parser.parseModifiers();
     expectNotNullIfNoErrors(modifiers);
-    listener.assertNoErrors();
+    assertNoErrors();
     expect(modifiers.varKeyword, isNotNull);
   }
 
@@ -13067,7 +13096,7 @@
     createParser('List<int>?');
     TypeName typeName = parser.parseTypeName(false);
     expectNotNullIfNoErrors(typeName);
-    listener.assertNoErrors();
+    assertNoErrors();
     expect(typeName.name, isNotNull);
     expect(typeName.typeArguments, isNotNull);
     expect(typeName.question, isNotNull);
@@ -13078,7 +13107,7 @@
     createParser('String?');
     TypeName typeName = parser.parseTypeName(false);
     expectNotNullIfNoErrors(typeName);
-    listener.assertNoErrors();
+    assertNoErrors();
     expect(typeName.name, isNotNull);
     expect(typeName.typeArguments, isNull);
     expect(typeName.question, isNotNull);
@@ -13089,7 +13118,7 @@
     createParser('A extends B?');
     TypeParameter parameter = parser.parseTypeParameter();
     expectNotNullIfNoErrors(parameter);
-    listener.assertNoErrors();
+    assertNoErrors();
     expect(parameter.bound, new isInstanceOf<TypeName>());
     expect(parameter.extendsKeyword, isNotNull);
     expect(parameter.name, isNotNull);
@@ -13240,7 +13269,7 @@
   String _computeStringValue(String lexeme, bool first, bool last) {
     createParser('');
     String value = parser.computeStringValue(lexeme, first, last);
-    listener.assertNoErrors();
+    assertNoErrors();
     return value;
   }
 
@@ -13407,7 +13436,7 @@
     createParser('@A');
     Annotation annotation = parser.parseAnnotation();
     expectNotNullIfNoErrors(annotation);
-    listener.assertNoErrors();
+    assertNoErrors();
     expect(annotation.atSign, isNotNull);
     expect(annotation.name, isNotNull);
     expect(annotation.period, isNull);
@@ -13419,7 +13448,7 @@
     createParser('@A(x,y)');
     Annotation annotation = parser.parseAnnotation();
     expectNotNullIfNoErrors(annotation);
-    listener.assertNoErrors();
+    assertNoErrors();
     expect(annotation.atSign, isNotNull);
     expect(annotation.name, isNotNull);
     expect(annotation.period, isNull);
@@ -13431,7 +13460,7 @@
     createParser('@A.B');
     Annotation annotation = parser.parseAnnotation();
     expectNotNullIfNoErrors(annotation);
-    listener.assertNoErrors();
+    assertNoErrors();
     expect(annotation.atSign, isNotNull);
     expect(annotation.name, isNotNull);
     expect(annotation.period, isNull);
@@ -13443,7 +13472,7 @@
     createParser('@A.B(x,y)');
     Annotation annotation = parser.parseAnnotation();
     expectNotNullIfNoErrors(annotation);
-    listener.assertNoErrors();
+    assertNoErrors();
     expect(annotation.atSign, isNotNull);
     expect(annotation.name, isNotNull);
     expect(annotation.period, isNull);
@@ -13455,7 +13484,7 @@
     createParser('@A.B.C');
     Annotation annotation = parser.parseAnnotation();
     expectNotNullIfNoErrors(annotation);
-    listener.assertNoErrors();
+    assertNoErrors();
     expect(annotation.atSign, isNotNull);
     expect(annotation.name, isNotNull);
     expect(annotation.period, isNotNull);
@@ -13467,7 +13496,7 @@
     createParser('@A.B.C(x,y)');
     Annotation annotation = parser.parseAnnotation();
     expectNotNullIfNoErrors(annotation);
-    listener.assertNoErrors();
+    assertNoErrors();
     expect(annotation.atSign, isNotNull);
     expect(annotation.name, isNotNull);
     expect(annotation.period, isNotNull);
@@ -13479,7 +13508,7 @@
     createParser('()');
     ArgumentList argumentList = parser.parseArgumentList();
     expectNotNullIfNoErrors(argumentList);
-    listener.assertNoErrors();
+    assertNoErrors();
     NodeList<Expression> arguments = argumentList.arguments;
     expect(arguments, hasLength(0));
   }
@@ -13488,7 +13517,7 @@
     createParser('(w, x, y: y, z: z)');
     ArgumentList argumentList = parser.parseArgumentList();
     expectNotNullIfNoErrors(argumentList);
-    listener.assertNoErrors();
+    assertNoErrors();
     NodeList<Expression> arguments = argumentList.arguments;
     expect(arguments, hasLength(4));
   }
@@ -13497,7 +13526,7 @@
     createParser('(x, y, z)');
     ArgumentList argumentList = parser.parseArgumentList();
     expectNotNullIfNoErrors(argumentList);
-    listener.assertNoErrors();
+    assertNoErrors();
     NodeList<Expression> arguments = argumentList.arguments;
     expect(arguments, hasLength(3));
   }
@@ -13506,7 +13535,7 @@
     createParser('(x: x, y: y)');
     ArgumentList argumentList = parser.parseArgumentList();
     expectNotNullIfNoErrors(argumentList);
-    listener.assertNoErrors();
+    assertNoErrors();
     NodeList<Expression> arguments = argumentList.arguments;
     expect(arguments, hasLength(2));
   }
@@ -13515,16 +13544,43 @@
     createParser('(x, y, z,)');
     ArgumentList argumentList = parser.parseArgumentList();
     expectNotNullIfNoErrors(argumentList);
-    listener.assertNoErrors();
+    assertNoErrors();
     NodeList<Expression> arguments = argumentList.arguments;
     expect(arguments, hasLength(3));
   }
 
+  void test_parseArgumentList_typeArguments() {
+    createParser('(a<b,c>(d))');
+    ArgumentList argumentList = parser.parseArgumentList();
+    expectNotNullIfNoErrors(argumentList);
+    assertNoErrors();
+    NodeList<Expression> arguments = argumentList.arguments;
+    expect(arguments, hasLength(1));
+  }
+
+  void test_parseArgumentList_typeArguments_prefixed() {
+    createParser('(a<b,p.c>(d))');
+    ArgumentList argumentList = parser.parseArgumentList();
+    expectNotNullIfNoErrors(argumentList);
+    assertNoErrors();
+    NodeList<Expression> arguments = argumentList.arguments;
+    expect(arguments, hasLength(1));
+  }
+
+  void test_parseArgumentList_typeArguments_none() {
+    createParser('(a<b,p.q.c>(d))');
+    ArgumentList argumentList = parser.parseArgumentList();
+    expectNotNullIfNoErrors(argumentList);
+    assertNoErrors();
+    NodeList<Expression> arguments = argumentList.arguments;
+    expect(arguments, hasLength(2));
+  }
+
   void test_parseCombinators_h() {
     createParser('hide a');
     List<Combinator> combinators = parser.parseCombinators();
     expectNotNullIfNoErrors(combinators);
-    listener.assertNoErrors();
+    assertNoErrors();
     expect(combinators, hasLength(1));
     HideCombinator combinator = combinators[0] as HideCombinator;
     expect(combinator, isNotNull);
@@ -13536,7 +13592,7 @@
     createParser('hide a show b');
     List<Combinator> combinators = parser.parseCombinators();
     expectNotNullIfNoErrors(combinators);
-    listener.assertNoErrors();
+    assertNoErrors();
     expect(combinators, hasLength(2));
     HideCombinator hideCombinator = combinators[0] as HideCombinator;
     expect(hideCombinator, isNotNull);
@@ -13552,7 +13608,7 @@
     createParser('hide a show b hide c show d');
     List<Combinator> combinators = parser.parseCombinators();
     expectNotNullIfNoErrors(combinators);
-    listener.assertNoErrors();
+    assertNoErrors();
     expect(combinators, hasLength(4));
   }
 
@@ -13560,7 +13616,7 @@
     createParser('show a');
     List<Combinator> combinators = parser.parseCombinators();
     expectNotNullIfNoErrors(combinators);
-    listener.assertNoErrors();
+    assertNoErrors();
     expect(combinators, hasLength(1));
     ShowCombinator combinator = combinators[0] as ShowCombinator;
     expect(combinator, isNotNull);
@@ -13572,7 +13628,7 @@
     createParser('/** 1 */ class C {}');
     CompilationUnit unit = parser.parseCompilationUnit2();
     expectNotNullIfNoErrors(unit);
-    listener.assertNoErrors();
+    assertNoErrors();
     ClassDeclaration declaration = unit.declarations[0];
     expect(declaration.documentationComment, isNotNull);
     expect(declaration.metadata, isEmpty);
@@ -13582,7 +13638,7 @@
     createParser('/** 1 */ @A /** 2 */ class C {}');
     CompilationUnit unit = parser.parseCompilationUnit2();
     expectNotNullIfNoErrors(unit);
-    listener.assertNoErrors();
+    assertNoErrors();
     ClassDeclaration declaration = unit.declarations[0];
     expect(declaration.documentationComment, isNotNull);
     expect(declaration.metadata, hasLength(1));
@@ -13592,7 +13648,7 @@
     createParser('/** 1 */ @A /** 2 */ @B class C {}');
     CompilationUnit unit = parser.parseCompilationUnit2();
     expectNotNullIfNoErrors(unit);
-    listener.assertNoErrors();
+    assertNoErrors();
     ClassDeclaration declaration = unit.declarations[0];
     expect(declaration.documentationComment, isNotNull);
     expect(declaration.metadata, hasLength(2));
@@ -13602,7 +13658,7 @@
     createParser('/** 1 */ @A @B class C {}');
     CompilationUnit unit = parser.parseCompilationUnit2();
     expectNotNullIfNoErrors(unit);
-    listener.assertNoErrors();
+    assertNoErrors();
     ClassDeclaration declaration = unit.declarations[0];
     expect(declaration.documentationComment, isNotNull);
     expect(declaration.metadata, hasLength(2));
@@ -13612,7 +13668,7 @@
     createParser('@A class C {}');
     CompilationUnit unit = parser.parseCompilationUnit2();
     expectNotNullIfNoErrors(unit);
-    listener.assertNoErrors();
+    assertNoErrors();
     ClassDeclaration declaration = unit.declarations[0];
     expect(declaration.documentationComment, isNull);
     expect(declaration.metadata, hasLength(1));
@@ -13622,7 +13678,7 @@
     createParser('@A /** 1 */ @B class C {}');
     CompilationUnit unit = parser.parseCompilationUnit2();
     expectNotNullIfNoErrors(unit);
-    listener.assertNoErrors();
+    assertNoErrors();
     ClassDeclaration declaration = unit.declarations[0];
     expect(declaration.documentationComment, isNotNull);
     expect(declaration.metadata, hasLength(2));
@@ -13632,7 +13688,7 @@
     createParser('@A /** 1 */ @B /** 2 */ class C {}');
     CompilationUnit unit = parser.parseCompilationUnit2();
     expectNotNullIfNoErrors(unit);
-    listener.assertNoErrors();
+    assertNoErrors();
     ClassDeclaration declaration = unit.declarations[0];
     expect(declaration.documentationComment, isNotNull);
     expect(declaration.documentationComment.tokens[0].lexeme, contains('2'));
@@ -13643,7 +13699,7 @@
     createParser('@A @B(x) class C {}');
     CompilationUnit unit = parser.parseCompilationUnit2();
     expectNotNullIfNoErrors(unit);
-    listener.assertNoErrors();
+    assertNoErrors();
     ClassDeclaration declaration = unit.declarations[0];
     expect(declaration.documentationComment, isNull);
     expect(declaration.metadata, hasLength(2));
@@ -13653,7 +13709,7 @@
     createParser('class C {}');
     CompilationUnit unit = parser.parseCompilationUnit2();
     expectNotNullIfNoErrors(unit);
-    listener.assertNoErrors();
+    assertNoErrors();
     ClassDeclaration declaration = unit.declarations[0];
     expect(declaration.documentationComment, isNull);
     expect(declaration.metadata, isEmpty);
@@ -13667,7 +13723,7 @@
 ''');
     CompilationUnit unit = parser.parseCompilationUnit2();
     expectNotNullIfNoErrors(unit);
-    listener.assertNoErrors();
+    assertNoErrors();
     ClassDeclaration declaration = unit.declarations[0];
     expect(declaration.documentationComment, isNotNull);
     expect(declaration.metadata, isEmpty);
@@ -13677,7 +13733,7 @@
     createParser("if (a.b) 'c.dart'");
     Configuration configuration = parser.parseConfiguration();
     expectNotNullIfNoErrors(configuration);
-    listener.assertNoErrors();
+    assertNoErrors();
     expect(configuration.ifKeyword, isNotNull);
     expect(configuration.leftParenthesis, isNotNull);
     expectDottedName(configuration.name, ["a", "b"]);
@@ -13691,7 +13747,7 @@
     createParser("if (a) 'b.dart'");
     Configuration configuration = parser.parseConfiguration();
     expectNotNullIfNoErrors(configuration);
-    listener.assertNoErrors();
+    assertNoErrors();
     expect(configuration.ifKeyword, isNotNull);
     expect(configuration.leftParenthesis, isNotNull);
     expectDottedName(configuration.name, ["a"]);
@@ -13705,7 +13761,7 @@
     createParser("if (a.b == 'c') 'd.dart'");
     Configuration configuration = parser.parseConfiguration();
     expectNotNullIfNoErrors(configuration);
-    listener.assertNoErrors();
+    assertNoErrors();
     expect(configuration.ifKeyword, isNotNull);
     expect(configuration.leftParenthesis, isNotNull);
     expectDottedName(configuration.name, ["a", "b"]);
@@ -13719,7 +13775,7 @@
     createParser("if (a == 'b') 'c.dart'");
     Configuration configuration = parser.parseConfiguration();
     expectNotNullIfNoErrors(configuration);
-    listener.assertNoErrors();
+    assertNoErrors();
     expect(configuration.ifKeyword, isNotNull);
     expect(configuration.leftParenthesis, isNotNull);
     expectDottedName(configuration.name, ["a"]);
@@ -13732,7 +13788,7 @@
   void test_parseConstructorName_named_noPrefix() {
     ConstructorName name = parseConstructorName('A.n');
     expectNotNullIfNoErrors(name);
-    listener.assertNoErrors();
+    assertNoErrors();
     expect(name.type, isNotNull);
     expect(name.period, isNull);
     expect(name.name, isNull);
@@ -13741,7 +13797,7 @@
   void test_parseConstructorName_named_prefixed() {
     ConstructorName name = parseConstructorName('p.A.n');
     expectNotNullIfNoErrors(name);
-    listener.assertNoErrors();
+    assertNoErrors();
     expect(name.type, isNotNull);
     expect(name.period, isNotNull);
     expect(name.name, isNotNull);
@@ -13750,7 +13806,7 @@
   void test_parseConstructorName_unnamed_noPrefix() {
     ConstructorName name = parseConstructorName('A');
     expectNotNullIfNoErrors(name);
-    listener.assertNoErrors();
+    assertNoErrors();
     expect(name.type, isNotNull);
     expect(name.period, isNull);
     expect(name.name, isNull);
@@ -13759,7 +13815,7 @@
   void test_parseConstructorName_unnamed_prefixed() {
     ConstructorName name = parseConstructorName('p.A');
     expectNotNullIfNoErrors(name);
-    listener.assertNoErrors();
+    assertNoErrors();
     expect(name.type, isNotNull);
     expect(name.period, isNull);
     expect(name.name, isNull);
@@ -13770,7 +13826,7 @@
     CompilationUnit unit = parser.parseCompilationUnit2();
     Comment comment = unit.declarations[0].documentationComment;
     expectNotNullIfNoErrors(comment);
-    listener.assertNoErrors();
+    assertNoErrors();
     expect(comment.isBlock, isFalse);
     expect(comment.isDocumentation, isTrue);
     expect(comment.isEndOfLine, isFalse);
@@ -13781,7 +13837,7 @@
     CompilationUnit unit = parser.parseCompilationUnit2();
     Comment comment = unit.declarations[0].documentationComment;
     expectNotNullIfNoErrors(comment);
-    listener.assertNoErrors();
+    assertNoErrors();
     expect(comment.isBlock, isFalse);
     expect(comment.isDocumentation, isTrue);
     expect(comment.isEndOfLine, isFalse);
@@ -13797,7 +13853,7 @@
     CompilationUnit unit = parser.parseCompilationUnit2();
     Comment comment = unit.declarations[0].documentationComment;
     expectNotNullIfNoErrors(comment);
-    listener.assertNoErrors();
+    assertNoErrors();
     expect(comment.isBlock, isFalse);
     expect(comment.isDocumentation, isTrue);
     expect(comment.isEndOfLine, isFalse);
@@ -13806,7 +13862,7 @@
   void test_parseExtendsClause() {
     ExtendsClause clause = parseExtendsClause('extends B');
     expectNotNullIfNoErrors(clause);
-    listener.assertNoErrors();
+    assertNoErrors();
     expect(clause.extendsKeyword, isNotNull);
     expect(clause.superclass, isNotNull);
     expect(clause.superclass, new isInstanceOf<TypeName>());
@@ -13816,7 +13872,7 @@
     createParser('{}');
     FunctionBody functionBody = parser.parseFunctionBody(false, null, false);
     expectNotNullIfNoErrors(functionBody);
-    listener.assertNoErrors();
+    assertNoErrors();
     expect(functionBody, new isInstanceOf<BlockFunctionBody>());
     BlockFunctionBody body = functionBody;
     expect(body.keyword, isNull);
@@ -13831,7 +13887,7 @@
     createParser('async {}');
     FunctionBody functionBody = parser.parseFunctionBody(false, null, false);
     expectNotNullIfNoErrors(functionBody);
-    listener.assertNoErrors();
+    assertNoErrors();
     expect(functionBody, new isInstanceOf<BlockFunctionBody>());
     BlockFunctionBody body = functionBody;
     expect(body.keyword, isNotNull);
@@ -13847,7 +13903,7 @@
     createParser('async* {}');
     FunctionBody functionBody = parser.parseFunctionBody(false, null, false);
     expectNotNullIfNoErrors(functionBody);
-    listener.assertNoErrors();
+    assertNoErrors();
     expect(functionBody, new isInstanceOf<BlockFunctionBody>());
     BlockFunctionBody body = functionBody;
     expect(body.keyword, isNotNull);
@@ -13863,7 +13919,7 @@
     createParser('sync* {}');
     FunctionBody functionBody = parser.parseFunctionBody(false, null, false);
     expectNotNullIfNoErrors(functionBody);
-    listener.assertNoErrors();
+    assertNoErrors();
     expect(functionBody, new isInstanceOf<BlockFunctionBody>());
     BlockFunctionBody body = functionBody;
     expect(body.keyword, isNotNull);
@@ -13879,7 +13935,7 @@
     createParser(';');
     FunctionBody functionBody = parser.parseFunctionBody(true, null, false);
     expectNotNullIfNoErrors(functionBody);
-    listener.assertNoErrors();
+    assertNoErrors();
     expect(functionBody, new isInstanceOf<EmptyFunctionBody>());
     EmptyFunctionBody body = functionBody;
     expect(body.semicolon, isNotNull);
@@ -13889,7 +13945,7 @@
     createParser('=> y;');
     FunctionBody functionBody = parser.parseFunctionBody(false, null, false);
     expectNotNullIfNoErrors(functionBody);
-    listener.assertNoErrors();
+    assertNoErrors();
     expect(functionBody, new isInstanceOf<ExpressionFunctionBody>());
     ExpressionFunctionBody body = functionBody;
     expect(body.keyword, isNull);
@@ -13905,7 +13961,7 @@
     createParser('async => y;');
     FunctionBody functionBody = parser.parseFunctionBody(false, null, false);
     expectNotNullIfNoErrors(functionBody);
-    listener.assertNoErrors();
+    assertNoErrors();
     expect(functionBody, new isInstanceOf<ExpressionFunctionBody>());
     ExpressionFunctionBody body = functionBody;
     expect(body.keyword, isNotNull);
@@ -13921,21 +13977,21 @@
   void test_parseIdentifierList_multiple() {
     List<SimpleIdentifier> list = parseIdentifierList('a, b, c');
     expectNotNullIfNoErrors(list);
-    listener.assertNoErrors();
+    assertNoErrors();
     expect(list, hasLength(3));
   }
 
   void test_parseIdentifierList_single() {
     List<SimpleIdentifier> list = parseIdentifierList('a');
     expectNotNullIfNoErrors(list);
-    listener.assertNoErrors();
+    assertNoErrors();
     expect(list, hasLength(1));
   }
 
   void test_parseImplementsClause_multiple() {
     ImplementsClause clause = parseImplementsClause('implements A, B, C');
     expectNotNullIfNoErrors(clause);
-    listener.assertNoErrors();
+    assertNoErrors();
     expect(clause.interfaces, hasLength(3));
     expect(clause.implementsKeyword, isNotNull);
   }
@@ -13943,7 +13999,7 @@
   void test_parseImplementsClause_single() {
     ImplementsClause clause = parseImplementsClause('implements A');
     expectNotNullIfNoErrors(clause);
-    listener.assertNoErrors();
+    assertNoErrors();
     expect(clause.interfaces, hasLength(1));
     expect(clause.implementsKeyword, isNotNull);
   }
@@ -14003,7 +14059,7 @@
     String name = "deferred";
     LibraryIdentifier identifier = parseLibraryIdentifier(name);
     expectNotNullIfNoErrors(identifier);
-    listener.assertNoErrors();
+    assertNoErrors();
     expect(identifier.name, name);
     expect(identifier.beginToken.type.isBuiltIn, isTrue);
   }
@@ -14023,7 +14079,7 @@
     String name = "a.b.c";
     LibraryIdentifier identifier = parseLibraryIdentifier(name);
     expectNotNullIfNoErrors(identifier);
-    listener.assertNoErrors();
+    assertNoErrors();
     expect(identifier.name, name);
   }
 
@@ -14031,7 +14087,7 @@
     String name = "await";
     LibraryIdentifier identifier = parseLibraryIdentifier(name);
     expectNotNullIfNoErrors(identifier);
-    listener.assertNoErrors();
+    assertNoErrors();
     expect(identifier.name, name);
     expect(identifier.beginToken.type.isPseudo, isTrue);
   }
@@ -14040,7 +14096,7 @@
     String name = "a";
     LibraryIdentifier identifier = parseLibraryIdentifier(name);
     expectNotNullIfNoErrors(identifier);
-    listener.assertNoErrors();
+    assertNoErrors();
     expect(identifier.name, name);
   }
 
@@ -14051,7 +14107,7 @@
   void test_parseReturnStatement_noValue() {
     ReturnStatement statement = parseStatement('return;');
     expectNotNullIfNoErrors(statement);
-    listener.assertNoErrors();
+    assertNoErrors();
     expect(statement.returnKeyword, isNotNull);
     expect(statement.expression, isNull);
     expect(statement.semicolon, isNotNull);
@@ -14060,7 +14116,7 @@
   void test_parseReturnStatement_value() {
     ReturnStatement statement = parseStatement('return x;');
     expectNotNullIfNoErrors(statement);
-    listener.assertNoErrors();
+    assertNoErrors();
     expect(statement.returnKeyword, isNotNull);
     expect(statement.expression, isNotNull);
     expect(statement.semicolon, isNotNull);
@@ -14092,7 +14148,7 @@
     createParser('Function()');
     GenericFunctionType functionType = parser.parseTypeAnnotation(false);
     expectNotNullIfNoErrors(functionType);
-    listener.assertNoErrors();
+    assertNoErrors();
     expect(functionType.returnType, isNull);
     expect(functionType.functionKeyword, isNotNull);
     expect(functionType.typeParameters, isNull);
@@ -14105,7 +14161,7 @@
     createParser('Function(int, int)');
     GenericFunctionType functionType = parser.parseTypeAnnotation(false);
     expectNotNullIfNoErrors(functionType);
-    listener.assertNoErrors();
+    assertNoErrors();
     expect(functionType.returnType, isNull);
     expect(functionType.functionKeyword, isNotNull);
     expect(functionType.typeParameters, isNull);
@@ -14131,7 +14187,7 @@
     createParser('Function<S, T>()');
     GenericFunctionType functionType = parser.parseTypeAnnotation(false);
     expectNotNullIfNoErrors(functionType);
-    listener.assertNoErrors();
+    assertNoErrors();
     expect(functionType.returnType, isNull);
     expect(functionType.functionKeyword, isNotNull);
     TypeParameterList typeParameters = functionType.typeParameters;
@@ -14147,7 +14203,7 @@
     createParser('Function<T>(String, {T t})');
     GenericFunctionType functionType = parser.parseTypeAnnotation(false);
     expectNotNullIfNoErrors(functionType);
-    listener.assertNoErrors();
+    assertNoErrors();
     expect(functionType.returnType, isNull);
     expect(functionType.functionKeyword, isNotNull);
     TypeParameterList typeParameters = functionType.typeParameters;
@@ -14162,7 +14218,7 @@
     createParser('Function');
     TypeName functionType = parser.parseTypeAnnotation(false);
     expectNotNullIfNoErrors(functionType);
-    listener.assertNoErrors();
+    assertNoErrors();
   }
 
   void test_parseTypeAnnotation_function_returnType_function() {
@@ -14170,14 +14226,14 @@
     // TODO(scheglov) improve the test to verify also the node properties
     var functionType = parser.parseTypeAnnotation(false) as GenericFunctionType;
     expectNotNullIfNoErrors(functionType);
-    listener.assertNoErrors();
+    assertNoErrors();
   }
 
   void test_parseTypeAnnotation_function_returnType_noParameters() {
     createParser('List<int> Function()');
     GenericFunctionType functionType = parser.parseTypeAnnotation(false);
     expectNotNullIfNoErrors(functionType);
-    listener.assertNoErrors();
+    assertNoErrors();
     expect(functionType.returnType, isNotNull);
     expect(functionType.functionKeyword, isNotNull);
     expect(functionType.typeParameters, isNull);
@@ -14190,7 +14246,7 @@
     createParser('List<int> Function(String s, int i)');
     GenericFunctionType functionType = parser.parseTypeAnnotation(false);
     expectNotNullIfNoErrors(functionType);
-    listener.assertNoErrors();
+    assertNoErrors();
     expect(functionType.returnType, isNotNull);
     expect(functionType.functionKeyword, isNotNull);
     expect(functionType.typeParameters, isNull);
@@ -14219,14 +14275,14 @@
     // TODO(scheglov) improve the test to verify also the node properties
     var functionType = parser.parseTypeAnnotation(false) as GenericFunctionType;
     expectNotNullIfNoErrors(functionType);
-    listener.assertNoErrors();
+    assertNoErrors();
   }
 
   void test_parseTypeAnnotation_function_returnType_typeParameters() {
     createParser('List<T> Function<T>()');
     GenericFunctionType functionType = parser.parseTypeAnnotation(false);
     expectNotNullIfNoErrors(functionType);
-    listener.assertNoErrors();
+    assertNoErrors();
     expect(functionType.returnType, isNotNull);
     expect(functionType.functionKeyword, isNotNull);
     TypeParameterList typeParameters = functionType.typeParameters;
@@ -14242,7 +14298,7 @@
     createParser('List<T> Function<T>(String s, [T])');
     GenericFunctionType functionType = parser.parseTypeAnnotation(false);
     expectNotNullIfNoErrors(functionType);
-    listener.assertNoErrors();
+    assertNoErrors();
     expect(functionType.returnType, isNotNull);
     expect(functionType.functionKeyword, isNotNull);
     TypeParameterList typeParameters = functionType.typeParameters;
@@ -14258,14 +14314,14 @@
     // TODO(scheglov) improve this test to verify also the node properties
     var functionType = parser.parseTypeAnnotation(false) as GenericFunctionType;
     expectNotNullIfNoErrors(functionType);
-    listener.assertNoErrors();
+    assertNoErrors();
   }
 
   void test_parseTypeAnnotation_named() {
     createParser('A<B>');
     TypeName typeName = parser.parseTypeAnnotation(false);
     expectNotNullIfNoErrors(typeName);
-    listener.assertNoErrors();
+    assertNoErrors();
   }
 
   void test_parseTypeArgumentList_empty() {
@@ -14282,7 +14338,7 @@
     createParser('<int, int, int>');
     TypeArgumentList argumentList = parser.parseTypeArgumentList();
     expectNotNullIfNoErrors(argumentList);
-    listener.assertNoErrors();
+    assertNoErrors();
     expect(argumentList.leftBracket, isNotNull);
     expect(argumentList.arguments, hasLength(3));
     expect(argumentList.rightBracket, isNotNull);
@@ -14292,7 +14348,7 @@
     createParser('<A<B>>');
     TypeArgumentList argumentList = parser.parseTypeArgumentList();
     expectNotNullIfNoErrors(argumentList);
-    listener.assertNoErrors();
+    assertNoErrors();
     expect(argumentList.leftBracket, isNotNull);
     expect(argumentList.arguments, hasLength(1));
     TypeName argument = argumentList.arguments[0];
@@ -14307,7 +14363,7 @@
     createParser('<A<B /* 0 */ >>');
     TypeArgumentList argumentList = parser.parseTypeArgumentList();
     expectNotNullIfNoErrors(argumentList);
-    listener.assertNoErrors();
+    assertNoErrors();
     expect(argumentList.leftBracket, isNotNull);
     expect(argumentList.rightBracket, isNotNull);
     expect(argumentList.arguments, hasLength(1));
@@ -14327,7 +14383,7 @@
     createParser('<A<B<C /* 0 */ >>>');
     TypeArgumentList argumentList = parser.parseTypeArgumentList();
     expectNotNullIfNoErrors(argumentList);
-    listener.assertNoErrors();
+    assertNoErrors();
     expect(argumentList.leftBracket, isNotNull);
     expect(argumentList.rightBracket, isNotNull);
     expect(argumentList.arguments, hasLength(1));
@@ -14356,7 +14412,7 @@
     createParser('<int>');
     TypeArgumentList argumentList = parser.parseTypeArgumentList();
     expectNotNullIfNoErrors(argumentList);
-    listener.assertNoErrors();
+    assertNoErrors();
     expect(argumentList.leftBracket, isNotNull);
     expect(argumentList.arguments, hasLength(1));
     expect(argumentList.rightBracket, isNotNull);
@@ -14366,7 +14422,7 @@
     createParser('List<int>');
     TypeName typeName = parser.parseTypeName(false);
     expectNotNullIfNoErrors(typeName);
-    listener.assertNoErrors();
+    assertNoErrors();
     expect(typeName.name, isNotNull);
     expect(typeName.typeArguments, isNotNull);
     expect(typeName.question, isNull);
@@ -14376,7 +14432,7 @@
     createParser('int');
     TypeName typeName = parser.parseTypeName(false);
     expectNotNullIfNoErrors(typeName);
-    listener.assertNoErrors();
+    assertNoErrors();
     expect(typeName.name, isNotNull);
     expect(typeName.typeArguments, isNull);
     expect(typeName.question, isNull);
@@ -14386,7 +14442,7 @@
     createParser('A extends Function(int)');
     TypeParameter parameter = parser.parseTypeParameter();
     expectNotNullIfNoErrors(parameter);
-    listener.assertNoErrors();
+    assertNoErrors();
     expect(parameter.bound, new isInstanceOf<GenericFunctionType>());
     expect(parameter.extendsKeyword, isNotNull);
     expect(parameter.name, isNotNull);
@@ -14396,7 +14452,7 @@
     createParser('A extends String Function(int)');
     TypeParameter parameter = parser.parseTypeParameter();
     expectNotNullIfNoErrors(parameter);
-    listener.assertNoErrors();
+    assertNoErrors();
     expect(parameter.bound, new isInstanceOf<GenericFunctionType>());
     expect(parameter.extendsKeyword, isNotNull);
     expect(parameter.name, isNotNull);
@@ -14406,7 +14462,7 @@
     createParser('A extends B<C>');
     TypeParameter parameter = parser.parseTypeParameter();
     expectNotNullIfNoErrors(parameter);
-    listener.assertNoErrors();
+    assertNoErrors();
     expect(parameter.bound, new isInstanceOf<TypeName>());
     expect(parameter.extendsKeyword, isNotNull);
     expect(parameter.name, isNotNull);
@@ -14416,7 +14472,7 @@
     createParser('A extends B');
     TypeParameter parameter = parser.parseTypeParameter();
     expectNotNullIfNoErrors(parameter);
-    listener.assertNoErrors();
+    assertNoErrors();
     expect(parameter.bound, new isInstanceOf<TypeName>());
     expect(parameter.extendsKeyword, isNotNull);
     expect(parameter.name, isNotNull);
@@ -14426,7 +14482,7 @@
     createParser('A');
     TypeParameter parameter = parser.parseTypeParameter();
     expectNotNullIfNoErrors(parameter);
-    listener.assertNoErrors();
+    assertNoErrors();
     expect(parameter.bound, isNull);
     expect(parameter.extendsKeyword, isNull);
     expect(parameter.name, isNotNull);
@@ -14436,7 +14492,7 @@
     createParser('<A, B extends C, D>');
     TypeParameterList parameterList = parser.parseTypeParameterList();
     expectNotNullIfNoErrors(parameterList);
-    listener.assertNoErrors();
+    assertNoErrors();
     expect(parameterList.leftBracket, isNotNull);
     expect(parameterList.rightBracket, isNotNull);
     expect(parameterList.typeParameters, hasLength(3));
@@ -14446,7 +14502,7 @@
     createParser('<A extends B<E>>=', expectedEndOffset: 16);
     TypeParameterList parameterList = parser.parseTypeParameterList();
     expectNotNullIfNoErrors(parameterList);
-    listener.assertNoErrors();
+    assertNoErrors();
     expect(parameterList.leftBracket, isNotNull);
     expect(parameterList.rightBracket, isNotNull);
     expect(parameterList.typeParameters, hasLength(1));
@@ -14456,7 +14512,7 @@
     createParser('<A extends B<E /* foo */ >>=', expectedEndOffset: 27);
     TypeParameterList parameterList = parser.parseTypeParameterList();
     expectNotNullIfNoErrors(parameterList);
-    listener.assertNoErrors();
+    assertNoErrors();
     expect(parameterList.leftBracket, isNotNull);
     expect(parameterList.rightBracket, isNotNull);
     expect(parameterList.typeParameters, hasLength(1));
@@ -14476,7 +14532,7 @@
     createParser('<<A>');
     TypeParameterList parameterList = parser.parseTypeParameterList();
     expectNotNullIfNoErrors(parameterList);
-    listener.assertNoErrors();
+    assertNoErrors();
     expect(parameterList.leftBracket, isNotNull);
     expect(parameterList.rightBracket, isNotNull);
     expect(parameterList.typeParameters, hasLength(1));
@@ -14486,7 +14542,7 @@
     createParser('<A>=', expectedEndOffset: 3);
     TypeParameterList parameterList = parser.parseTypeParameterList();
     expectNotNullIfNoErrors(parameterList);
-    listener.assertNoErrors();
+    assertNoErrors();
     expect(parameterList.leftBracket, isNotNull);
     expect(parameterList.rightBracket, isNotNull);
     expect(parameterList.typeParameters, hasLength(1));
@@ -14495,7 +14551,7 @@
   void test_parseVariableDeclaration_equals() {
     VariableDeclaration declaration = parseVariableDeclaration('var a = b;');
     expectNotNullIfNoErrors(declaration);
-    listener.assertNoErrors();
+    assertNoErrors();
     expect(declaration.name, isNotNull);
     expect(declaration.equals, isNotNull);
     expect(declaration.initializer, isNotNull);
@@ -14504,7 +14560,7 @@
   void test_parseVariableDeclaration_noEquals() {
     VariableDeclaration declaration = parseVariableDeclaration('var a;');
     expectNotNullIfNoErrors(declaration);
-    listener.assertNoErrors();
+    assertNoErrors();
     expect(declaration.name, isNotNull);
     expect(declaration.equals, isNull);
     expect(declaration.initializer, isNull);
@@ -14513,7 +14569,7 @@
   void test_parseWithClause_multiple() {
     WithClause clause = parseWithClause('with A, B, C');
     expectNotNullIfNoErrors(clause);
-    listener.assertNoErrors();
+    assertNoErrors();
     expect(clause.withKeyword, isNotNull);
     expect(clause.mixinTypes, hasLength(3));
   }
@@ -14521,7 +14577,7 @@
   void test_parseWithClause_single() {
     WithClause clause = parseWithClause('with M');
     expectNotNullIfNoErrors(clause);
-    listener.assertNoErrors();
+    assertNoErrors();
     expect(clause.withKeyword, isNotNull);
     expect(clause.mixinTypes, hasLength(1));
   }
@@ -15031,6 +15087,18 @@
     expect(statement.elseStatement, isNotNull);
   }
 
+  void test_parseIfStatement_else_emptyStatements() {
+    var statement = parseStatement('if (true) ; else ;') as IfStatement;
+    assertNoErrors();
+    expect(statement.ifKeyword, isNotNull);
+    expect(statement.leftParenthesis, isNotNull);
+    expect(statement.condition, isNotNull);
+    expect(statement.rightParenthesis, isNotNull);
+    expect(statement.thenStatement, isNotNull);
+    expect(statement.elseKeyword, isNotNull);
+    expect(statement.elseStatement, isNotNull);
+  }
+
   void test_parseIfStatement_else_statement() {
     var statement = parseStatement('if (x) f(x); else f(y);') as IfStatement;
     assertNoErrors();
diff --git a/pkg/analyzer/test/src/dart/analysis/session_test.dart b/pkg/analyzer/test/src/dart/analysis/session_test.dart
index 8f8a4f4..e518b96 100644
--- a/pkg/analyzer/test/src/dart/analysis/session_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/session_test.dart
@@ -6,6 +6,8 @@
 
 import 'package:analyzer/dart/analysis/session.dart';
 import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/file_system/file_system.dart';
+import 'package:analyzer/file_system/memory_file_system.dart';
 import 'package:analyzer/src/dart/analysis/driver.dart';
 import 'package:analyzer/src/dart/analysis/session.dart';
 import 'package:analyzer/src/dart/analysis/top_level_declaration.dart';
@@ -93,6 +95,12 @@
     expect(await session.getUnitElementSignature('path'), signature);
   }
 
+  test_resourceProvider() {
+    ResourceProvider resourceProvider = new MemoryResourceProvider();
+    driver.resourceProvider = resourceProvider;
+    expect(session.resourceProvider, resourceProvider);
+  }
+
   test_sourceFactory() {
     SourceFactory sourceFactory = new SourceFactory([]);
     driver.sourceFactory = sourceFactory;
@@ -155,6 +163,7 @@
   ErrorsResult errorsResult;
   Map<String, LibraryElement> libraryMap = <String, LibraryElement>{};
   ParseResult parseResult;
+  ResourceProvider resourceProvider;
   AnalysisResult result;
   SourceFactory sourceFactory;
   SourceKind sourceKind;
diff --git a/pkg/analyzer/test/src/dart/ast/ast_test.dart b/pkg/analyzer/test/src/dart/ast/ast_test.dart
index c76c2a4..c860a24 100644
--- a/pkg/analyzer/test/src/dart/ast/ast_test.dart
+++ b/pkg/analyzer/test/src/dart/ast/ast_test.dart
@@ -470,7 +470,18 @@
 
   bool get enableNewAnalysisDriver => true;
 
-  void assertIsConst(String snippet, bool isConst) {
+  void assertCanBeConst(String snippet, bool expectedResult) {
+    int index = testSource.indexOf(snippet);
+    expect(index >= 0, isTrue);
+    NodeLocator visitor = new NodeLocator(index);
+    AstNodeImpl node = visitor.searchWithin(testUnit);
+    node = node.getAncestor((node) => node is InstanceCreationExpressionImpl);
+    expect(node, isNotNull);
+    expect((node as InstanceCreationExpressionImpl).canBeConst(),
+        expectedResult ? isTrue : isFalse);
+  }
+
+  void assertIsConst(String snippet, bool expectedResult) {
     int index = testSource.indexOf(snippet);
     expect(index >= 0, isTrue);
     NodeLocator visitor = new NodeLocator(index);
@@ -478,7 +489,7 @@
     node = node.getAncestor((node) => node is InstanceCreationExpressionImpl);
     expect(node, isNotNull);
     expect((node as InstanceCreationExpressionImpl).isConst,
-        isConst ? isTrue : isFalse);
+        expectedResult ? isTrue : isFalse);
   }
 
   void enablePreviewDart2() {
@@ -490,6 +501,68 @@
     testUnit = await resolveSource2('/test.dart', source);
   }
 
+  void test_canBeConst_false_argument_invocation() async {
+    enablePreviewDart2();
+    await resolve('''
+class A {}
+class B {
+  const B(A a);
+}
+A f() => A();
+B g() => B(f());
+''');
+    assertCanBeConst("B(f", false);
+  }
+
+  void test_canBeConst_false_argument_invocationInList() async {
+    enablePreviewDart2();
+    await resolve('''
+class A {}
+class B {
+  const B(a);
+}
+A f() => A();
+B g() => B([f()]);
+''');
+    assertCanBeConst("B([", false);
+  }
+
+  void test_canBeConst_false_argument_nonConstConstructor() async {
+    enablePreviewDart2();
+    await resolve('''
+class A {}
+class B {
+  const B(A a);
+}
+B f() => B(A());
+''');
+    assertCanBeConst("B(A(", false);
+  }
+
+  void test_canBeConst_false_nonConstConstructor() async {
+    enablePreviewDart2();
+    await resolve('''
+class A {}
+A f() => A();
+''');
+    assertCanBeConst("A(", false);
+  }
+
+  @failingTest
+  void test_canBeConst_true_argument_constConstructor() async {
+    enablePreviewDart2();
+    await resolve('''
+class A {
+  const A();
+}
+class B {
+  const B(A a);
+}
+B f() => B(A());
+''');
+    assertCanBeConst("B(A(", true);
+  }
+
   void
       test_isConst_notInContext_constructor_const_constParam_identifier() async {
     enablePreviewDart2();
diff --git a/pkg/analyzer/test/src/fasta/body_builder_test_helper.dart b/pkg/analyzer/test/src/fasta/body_builder_test_helper.dart
index c39a719..ab21c64 100644
--- a/pkg/analyzer/test/src/fasta/body_builder_test_helper.dart
+++ b/pkg/analyzer/test/src/fasta/body_builder_test_helper.dart
@@ -11,6 +11,7 @@
 import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/dart/element/type.dart';
 import 'package:analyzer/src/fasta/ast_body_builder.dart';
+import 'package:analyzer/src/generated/parser.dart' as analyzer;
 import 'package:analyzer/src/generated/resolver.dart';
 import "package:front_end/src/api_prototype/front_end.dart";
 import "package:front_end/src/api_prototype/memory_file_system.dart";
@@ -25,6 +26,7 @@
 import 'package:front_end/src/fasta/kernel/kernel_builder.dart';
 import "package:front_end/src/fasta/kernel/kernel_target.dart";
 import 'package:front_end/src/fasta/modifier.dart' as Modifier;
+import 'package:front_end/src/fasta/parser/async_modifier.dart';
 import 'package:front_end/src/fasta/parser/parser.dart';
 import 'package:front_end/src/fasta/scanner.dart';
 import 'package:front_end/src/fasta/ticker.dart';
@@ -34,14 +36,13 @@
 import 'package:kernel/class_hierarchy.dart' as kernel;
 import 'package:kernel/core_types.dart' as kernel;
 import 'package:kernel/kernel.dart' as kernel;
+import 'package:test/test.dart';
 
 import '../../generated/parser_test.dart';
 import '../../generated/test_support.dart';
 
-/**
- * Implementation of [AbstractParserTestCase] specialized for testing building
- * Analyzer AST using the fasta [Forest] API.
- */
+/// Implementation of [AbstractParserTestCase] specialized for testing building
+/// Analyzer AST using the fasta [Forest] API.
 class FastaBodyBuilderTestCase extends Object
     with ParserTestHelpers
     implements AbstractParserTestCase {
@@ -63,8 +64,16 @@
 
   final bool resolveTypes;
 
+  String content;
+
+  /// The expected offset of the next token to be parsed after the parser has
+  /// finished parsing, or `null` (the default) if EOF is expected.
+  int expectedEndOffset;
+
   FastaBodyBuilderTestCase(this.resolveTypes);
 
+  analyzer.Parser get parser => new ParserProxy(this);
+
   TypeProvider get typeProvider => _typeProvider;
 
   @override
@@ -72,6 +81,16 @@
     // TODO(brianwilkerson) Implement this.
   }
 
+  void createParser(String content, {int expectedEndOffset}) {
+    this.content = content;
+    this.expectedEndOffset = expectedEndOffset;
+  }
+
+  @override
+  void expectNotNullIfNoErrors(Object result) {
+    // TODO(brianwilkerson) Implement this.
+  }
+
   noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
 
   @override
@@ -92,7 +111,7 @@
 
   @override
   AwaitExpression parseAwaitExpression(String code) {
-    return parseExpression(code);
+    return parseExpression(code, inAsync: true);
   }
 
   @override
@@ -139,7 +158,7 @@
   @override
   CompilationUnit parseDirectives(String source,
       [List<ErrorCode> errorCodes = const <ErrorCode>[]]) {
-    throw new UnimplementedError();
+    return parseCompilationUnit(content, codes: errorCodes);
   }
 
   @override
@@ -151,9 +170,12 @@
   Expression parseExpression(String source,
       {List<ErrorCode> codes,
       List<ExpectedError> errors,
-      int expectedEndOffset}) {
+      int expectedEndOffset,
+      bool inAsync: false,
+      bool inCatchBlock: false}) {
     // TODO(brianwilkerson) Check error codes.
-    return _parse(source, (parser, token) => parser.parseExpression(token));
+    return _parse(source, (parser, token) => parser.parseExpression(token),
+        inAsync: inAsync, inCatchBlock: inCatchBlock);
   }
 
   @override
@@ -182,12 +204,18 @@
 
   @override
   CompilationUnitMember parseFullCompilationUnitMember() {
-    throw new UnimplementedError();
+    CompilationUnit unit = parseCompilationUnit(content);
+    expect(unit.directives, hasLength(0));
+    expect(unit.declarations, hasLength(1));
+    return unit.declarations[0];
   }
 
   @override
   Directive parseFullDirective() {
-    throw new UnimplementedError();
+    CompilationUnit unit = parseCompilationUnit(content);
+    expect(unit.directives, hasLength(1));
+    expect(unit.declarations, hasLength(0));
+    return unit.directives[0];
   }
 
   @override
@@ -204,7 +232,16 @@
   @override
   ListLiteral parseListLiteral(
       Token token, String typeArgumentsCode, String code) {
-    return parseExpression(code);
+    StringBuffer buffer = new StringBuffer();
+    if (token != null) {
+      buffer.write(token.lexeme);
+      buffer.write(' ');
+    }
+    if (typeArgumentsCode != null) {
+      buffer.write(typeArgumentsCode);
+    }
+    buffer.write(code);
+    return parseExpression(buffer.toString());
   }
 
   @override
@@ -225,12 +262,25 @@
   @override
   MapLiteral parseMapLiteral(
       Token token, String typeArgumentsCode, String code) {
-    return parseExpression(code);
+    StringBuffer buffer = new StringBuffer();
+    if (token != null) {
+      buffer.write(token.lexeme);
+      buffer.write(' ');
+    }
+    if (typeArgumentsCode != null) {
+      buffer.write(typeArgumentsCode);
+    }
+    buffer.write(code);
+    return parseExpression(buffer.toString());
   }
 
   @override
   MapLiteralEntry parseMapLiteralEntry(String code) {
-    throw new UnimplementedError();
+    Expression expression = parseExpression('{$code}');
+    expect(expression, new isInstanceOf<MapLiteral>());
+    MapLiteral literal = expression;
+    expect(literal.entries, hasLength(1));
+    return literal.entries[0];
   }
 
   @override
@@ -274,7 +324,11 @@
 
   @override
   RethrowExpression parseRethrowExpression(String code) {
-    return parseExpression(code);
+    Statement statement = parseStatement(code, inCatchBlock: true);
+    expect(statement, new isInstanceOf<ExpressionStatement>());
+    Expression expression = (statement as ExpressionStatement).expression;
+    expect(expression, new isInstanceOf<RethrowExpression>());
+    return expression;
   }
 
   @override
@@ -289,9 +343,12 @@
 
   @override
   Statement parseStatement(String source,
-      {bool enableLazyAssignmentOperators, int expectedEndOffset}) {
+      {bool enableLazyAssignmentOperators,
+      int expectedEndOffset,
+      bool inCatchBlock: true}) {
     // TODO(brianwilkerson) Check error codes.
-    return _parse(source, (parser, token) => parser.parseStatement(token));
+    return _parse(source, (parser, token) => parser.parseStatement(token),
+        inCatchBlock: inCatchBlock);
   }
 
   @override
@@ -321,7 +378,15 @@
 
   @override
   VariableDeclarationList parseVariableDeclarationList(String source) {
-    throw new UnimplementedError();
+    CompilationUnit unit = parseCompilationUnit('''
+f() {
+  $source;
+}
+''');
+    FunctionDeclaration function = unit.declarations[0];
+    BlockFunctionBody body = function.functionExpression.body;
+    VariableDeclarationStatement statement = body.block.statements[0];
+    return statement.variables;
   }
 
   Future setUp() async {
@@ -412,7 +477,8 @@
   }
 
   T _parse<T>(
-      String source, void parseFunction(Parser parser, Token previousToken)) {
+      String source, void parseFunction(Parser parser, Token previousToken),
+      {bool inAsync: false, bool inCatchBlock: false}) {
     ScannerResult scan = scanString(source);
 
     return CompilerContext.runWithOptions(options, (CompilerContext c) {
@@ -463,8 +529,246 @@
       )..constantContext = ConstantContext.none; // .inferred ?
 
       Parser parser = new Parser(builder);
+      if (inAsync) {
+        parser.asyncState = AsyncModifier.Async;
+      }
+      if (inCatchBlock) {
+        builder.inCatchBlock = inCatchBlock;
+      }
       parseFunction(parser, parser.syntheticPreviousToken(scan.tokens));
+      // TODO(brianwilkerson) Check `expectedEndOffset` if it is not `null`.
       return builder.pop();
     });
   }
 }
+
+/// A parser that can be used by [FastaBodyBuilderTestCase] to support the tests
+/// that still call methods on the parser directly.
+class ParserProxy implements analyzer.Parser {
+  final FastaBodyBuilderTestCase testCase;
+
+  ParserProxy(this.testCase);
+
+  @override
+  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
+
+  @override
+  Annotation parseAnnotation() {
+    CompilationUnit unit =
+        testCase.parseCompilationUnit('${testCase.content} var v;');
+    expect(unit.directives, hasLength(0));
+    expect(unit.declarations, hasLength(1));
+    expect(
+        unit.declarations[0], new isInstanceOf<TopLevelVariableDeclaration>());
+    TopLevelVariableDeclaration declaration = unit.declarations[0];
+    expect(declaration.metadata, hasLength(1));
+    return declaration.metadata[0];
+  }
+
+  @override
+  ArgumentList parseArgumentList() {
+    Expression expression = testCase.parseExpression('f${testCase.content}');
+    expect(expression, new isInstanceOf<MethodInvocation>());
+    MethodInvocation invocation = expression;
+    return invocation.argumentList;
+  }
+
+  @override
+  ClassMember parseClassMember(String className) {
+    CompilationUnit unit = testCase
+        .parseCompilationUnit('class $className { ${testCase.content} }');
+    expect(unit.directives, hasLength(0));
+    expect(unit.declarations, hasLength(1));
+    expect(unit.declarations[0], new isInstanceOf<ClassDeclaration>());
+    ClassDeclaration classDeclaration = unit.declarations[0];
+    expect(classDeclaration.members, hasLength(1));
+    return classDeclaration.members[0];
+  }
+
+  @override
+  List<Combinator> parseCombinators() {
+    CompilationUnit unit = testCase
+        .parseCompilationUnit('import "file.dart" ${testCase.content};');
+    expect(unit.directives, hasLength(1));
+    expect(unit.declarations, hasLength(0));
+    expect(unit.directives[0], new isInstanceOf<LibraryDirective>());
+    ImportDirective directive = unit.directives[0];
+    return directive.combinators;
+  }
+
+  @override
+  CommentReference parseCommentReference(
+      String referenceSource, int sourceOffset) {
+    // TODO(brianwilkerson) Implement this.
+    throw new UnimplementedError();
+  }
+
+  @override
+  CompilationUnit parseCompilationUnit2() {
+    return testCase.parseCompilationUnit(testCase.content);
+  }
+
+  @override
+  Configuration parseConfiguration() {
+    CompilationUnit unit = testCase
+        .parseCompilationUnit('import "file.dart" ${testCase.content};');
+    expect(unit.directives, hasLength(1));
+    expect(unit.declarations, hasLength(0));
+    expect(unit.directives[0], new isInstanceOf<LibraryDirective>());
+    ImportDirective directive = unit.directives[0];
+    expect(directive.configurations, hasLength(1));
+    return directive.configurations[0];
+  }
+
+  @override
+  DottedName parseDottedName() {
+    CompilationUnit unit = testCase.parseCompilationUnit(
+        'import "file.dart" if (${testCase.content}) "file2.dart";');
+    expect(unit.directives, hasLength(1));
+    expect(unit.declarations, hasLength(0));
+    expect(unit.directives[0], new isInstanceOf<LibraryDirective>());
+    ImportDirective directive = unit.directives[0];
+    expect(directive.configurations, hasLength(1));
+    return directive.configurations[0].name;
+  }
+
+  @override
+  ExtendsClause parseExtendsClause() {
+    CompilationUnit unit =
+        testCase.parseCompilationUnit('class C ${testCase.content} {}');
+    expect(unit.directives, hasLength(0));
+    expect(unit.declarations, hasLength(1));
+    expect(unit.declarations[0], new isInstanceOf<ClassDeclaration>());
+    ClassDeclaration classDeclaration = unit.declarations[0];
+    return classDeclaration.extendsClause;
+  }
+
+  @override
+  analyzer.FinalConstVarOrType parseFinalConstVarOrType(bool optional,
+      {bool inFunctionType: false}) {
+    // TODO(brianwilkerson) Implement this or re-write the tests.
+    throw new UnimplementedError();
+  }
+
+  @override
+  FormalParameterList parseFormalParameterList({bool inFunctionType: false}) {
+    CompilationUnit unit =
+        testCase.parseCompilationUnit('f${testCase.content} {}');
+    expect(unit.directives, hasLength(0));
+    expect(unit.declarations, hasLength(1));
+    expect(unit.declarations[0], new isInstanceOf<FunctionDeclaration>());
+    FunctionDeclaration function = unit.declarations[0];
+    return function.functionExpression.parameters;
+  }
+
+  @override
+  FunctionBody parseFunctionBody(bool mayBeEmpty,
+      analyzer.ParserErrorCode emptyErrorCode, bool inExpression) {
+    CompilationUnit unit =
+        testCase.parseCompilationUnit('f() ${testCase.content}');
+    expect(unit.directives, hasLength(0));
+    expect(unit.declarations, hasLength(1));
+    expect(unit.declarations[0], new isInstanceOf<FunctionDeclaration>());
+    FunctionDeclaration declaration = unit.declarations[0];
+    return declaration.functionExpression.body;
+  }
+
+  @override
+  ImplementsClause parseImplementsClause() {
+    CompilationUnit unit =
+        testCase.parseCompilationUnit('class C ${testCase.content} {}');
+    expect(unit.directives, hasLength(0));
+    expect(unit.declarations, hasLength(1));
+    expect(unit.declarations[0], new isInstanceOf<ClassDeclaration>());
+    ClassDeclaration classDeclaration = unit.declarations[0];
+    return classDeclaration.implementsClause;
+  }
+
+  @override
+  analyzer.Modifiers parseModifiers() {
+    // TODO(brianwilkerson) Implement this or re-write the tests (this might
+    // need context to create the right kind of declaration for the modifiers).
+    throw new UnimplementedError();
+  }
+
+  @override
+  Expression parseMultiplicativeExpression() {
+    return testCase.parseExpression(testCase.content);
+  }
+
+  @override
+  Expression parsePrimaryExpression() {
+    return testCase.parseExpression(testCase.content);
+  }
+
+  @override
+  SimpleIdentifier parseSimpleIdentifier(
+      {bool allowKeyword: false, bool isDeclaration: false}) {
+    return testCase.parseExpression(testCase.content);
+  }
+
+  @override
+  Statement parseStatement2() {
+    return testCase.parseStatement(testCase.content);
+  }
+
+  @override
+  TypeAnnotation parseTypeAnnotation(bool inExpression) {
+    if (inExpression) {
+      // TODO(brianwilkerson) As far as I can see, this path is not used.
+      throw new UnimplementedError();
+    }
+    CompilationUnit unit =
+        testCase.parseCompilationUnit('${testCase.content} x;');
+    expect(unit.directives, hasLength(0));
+    expect(unit.declarations, hasLength(1));
+    expect(
+        unit.declarations[0], new isInstanceOf<TopLevelVariableDeclaration>());
+    TopLevelVariableDeclaration variable = unit.declarations[0];
+    return variable.variables.type;
+  }
+
+  @override
+  TypeArgumentList parseTypeArgumentList() {
+    CompilationUnit unit =
+        testCase.parseCompilationUnit('C${testCase.content} c;');
+    expect(unit.directives, hasLength(0));
+    expect(unit.declarations, hasLength(1));
+    expect(
+        unit.declarations[0], new isInstanceOf<TopLevelVariableDeclaration>());
+    TopLevelVariableDeclaration variable = unit.declarations[0];
+    return (variable.variables.type as TypeName).typeArguments;
+  }
+
+  @override
+  TypeName parseTypeName(bool inExpression) {
+    return parseTypeAnnotation(inExpression) as TypeName;
+  }
+
+  @override
+  TypeParameter parseTypeParameter() {
+    CompilationUnit unit =
+        testCase.parseCompilationUnit('class C<${testCase.content}> {}');
+    expect(unit.directives, hasLength(0));
+    expect(unit.declarations, hasLength(1));
+    expect(unit.declarations[0], new isInstanceOf<ClassDeclaration>());
+    ClassDeclaration classDeclaration = unit.declarations[0];
+    return classDeclaration.typeParameters.typeParameters[0];
+  }
+
+  @override
+  Expression parseUnaryExpression() {
+    return testCase.parseExpression(testCase.content);
+  }
+
+  @override
+  WithClause parseWithClause() {
+    CompilationUnit unit =
+        testCase.parseCompilationUnit('class C ${testCase.content} {}');
+    expect(unit.directives, hasLength(0));
+    expect(unit.declarations, hasLength(1));
+    expect(unit.declarations[0], new isInstanceOf<ClassDeclaration>());
+    ClassDeclaration classDeclaration = unit.declarations[0];
+    return classDeclaration.withClause;
+  }
+}
diff --git a/pkg/analyzer/test/src/fasta/recovery/paired_tokens_test.dart b/pkg/analyzer/test/src/fasta/recovery/paired_tokens_test.dart
index e6af706..1e2348b 100644
--- a/pkg/analyzer/test/src/fasta/recovery/paired_tokens_test.dart
+++ b/pkg/analyzer/test/src/fasta/recovery/paired_tokens_test.dart
@@ -22,6 +22,66 @@
  */
 @reflectiveTest
 class AngleBracketsTest extends AbstractRecoveryTest {
+  void test_typeParameters_extraGt() {
+    testRecovery('''
+f<T>>() => null;
+''', [
+      ParserErrorCode.TOP_LEVEL_OPERATOR,
+      ParserErrorCode.MISSING_FUNCTION_PARAMETERS,
+      ParserErrorCode.MISSING_FUNCTION_BODY
+    ], '''
+f<T> > () => null;
+''', expectedErrorsInValidCode: [
+      ParserErrorCode.TOP_LEVEL_OPERATOR,
+      ParserErrorCode.MISSING_FUNCTION_PARAMETERS,
+      ParserErrorCode.MISSING_FUNCTION_BODY
+    ]);
+  }
+
+  void test_typeParameters_funct() {
+    testRecovery('''
+f<T extends Function()() => null;
+''', [ParserErrorCode.EXPECTED_TOKEN], '''
+f<T extends Function()>() => null;
+''');
+  }
+
+  void test_typeParameters_funct2() {
+    testRecovery('''
+f<T extends Function<X>()() => null;
+''', [ParserErrorCode.EXPECTED_TOKEN], '''
+f<T extends Function<X>()>() => null;
+''');
+  }
+
+  void test_typeParameters_gtEq() {
+    testRecovery('''
+f<T>=() => null;
+''', [
+      ParserErrorCode.MISSING_FUNCTION_PARAMETERS,
+      ParserErrorCode.MISSING_FUNCTION_BODY
+    ], '''
+f<T> = () => null;
+''', expectedErrorsInValidCode: [
+      ParserErrorCode.MISSING_FUNCTION_PARAMETERS,
+      ParserErrorCode.MISSING_FUNCTION_BODY
+    ]);
+  }
+
+  void test_typeParameters_gtGtEq() {
+    testRecovery('''
+f<T extends List<int>>=() => null;
+''', [
+      ParserErrorCode.MISSING_FUNCTION_PARAMETERS,
+      ParserErrorCode.MISSING_FUNCTION_BODY
+    ], '''
+f<T extends List<int>> = () => null;
+''', expectedErrorsInValidCode: [
+      ParserErrorCode.MISSING_FUNCTION_PARAMETERS,
+      ParserErrorCode.MISSING_FUNCTION_BODY
+    ]);
+  }
+
   @failingTest
   void test_typeArguments_inner_last() {
     // Parser crashes
@@ -51,6 +111,22 @@
 List<int> _s_;
 ''');
   }
+
+  void test_typeParameters_last() {
+    testRecovery('''
+f<T() => null;
+''', [ParserErrorCode.EXPECTED_TOKEN], '''
+f<T>() => null;
+''');
+  }
+
+  void test_typeParameters_outer_last() {
+    testRecovery('''
+f<T extends List<int>() => null;
+''', [ParserErrorCode.EXPECTED_TOKEN], '''
+f<T extends List<int>>() => null;
+''');
+  }
 }
 
 /**
diff --git a/pkg/analyzer/test/src/fasta/recovery/partial_code/class_declaration_test.dart b/pkg/analyzer/test/src/fasta/recovery/partial_code/class_declaration_test.dart
index 5041adb..af6f438 100644
--- a/pkg/analyzer/test/src/fasta/recovery/partial_code/class_declaration_test.dart
+++ b/pkg/analyzer/test/src/fasta/recovery/partial_code/class_declaration_test.dart
@@ -12,17 +12,6 @@
 
 class ClassDeclarationTest extends PartialCodeTest {
   buildAll() {
-    List<String> allExceptEof = <String>[
-      'class',
-      'typedef',
-      'functionVoid',
-      'functionNonVoid',
-      'var',
-      'const',
-      'final',
-      'getter',
-      'setter'
-    ];
     buildTests(
         'class_declaration',
         [
@@ -45,15 +34,14 @@
                 ParserErrorCode.MISSING_CLASS_BODY
               ],
               'class A extends _s_ {}',
-              failing: allExceptEof),
+              failing: ['functionVoid', 'functionNonVoid', 'getter']),
           new TestDescriptor('extendsBody', 'class A extends {}',
               [ParserErrorCode.EXPECTED_TYPE_NAME], 'class A extends _s_ {}'),
           new TestDescriptor(
               'extendsWithNameBody',
               'class A extends with B {}',
               [ParserErrorCode.EXPECTED_TYPE_NAME],
-              'class A extends _s_ with B {}',
-              allFailing: true),
+              'class A extends _s_ with B {}'),
           new TestDescriptor(
               'extendsImplementsNameBody',
               'class A extends implements B {}',
@@ -82,7 +70,7 @@
                 ParserErrorCode.MISSING_CLASS_BODY
               ],
               'class A extends B implements _s_ {}',
-              failing: allExceptEof),
+              failing: ['functionVoid', 'functionNonVoid', 'getter']),
           new TestDescriptor(
               'extendsNameImplementsBody',
               'class A extends B implements {}',
@@ -96,7 +84,7 @@
                 ParserErrorCode.MISSING_CLASS_BODY
               ],
               'class A extends B with C implements _s_ {}',
-              failing: allExceptEof),
+              failing: ['functionVoid', 'functionNonVoid', 'getter']),
           new TestDescriptor(
               'extendsNameWithNameImplementsBody',
               'class A extends B with C implements {}',
@@ -110,7 +98,7 @@
                 ParserErrorCode.MISSING_CLASS_BODY
               ],
               'class A implements _s_ {}',
-              failing: allExceptEof),
+              failing: ['functionVoid', 'functionNonVoid', 'getter']),
           new TestDescriptor(
               'implementsBody',
               'class A implements {}',
@@ -124,12 +112,42 @@
                 ParserErrorCode.MISSING_CLASS_BODY
               ],
               'class A implements B, _s_ {}',
-              failing: allExceptEof),
+              failing: ['functionVoid', 'functionNonVoid', 'getter']),
           new TestDescriptor(
               'implementsNameCommaBody',
               'class A implements B, {}',
               [ParserErrorCode.EXPECTED_TYPE_NAME],
               'class A implements B, _s_ {}'),
+          new TestDescriptor(
+              'equals',
+              'class A =',
+              [
+                ParserErrorCode.EXPECTED_TYPE_NAME,
+                ParserErrorCode.EXPECTED_TOKEN,
+                ParserErrorCode.EXPECTED_TOKEN
+              ],
+              'class A = _s_ with _s_;',
+              failing: ['functionVoid', 'functionNonVoid', 'getter']),
+          new TestDescriptor(
+              'equalsName',
+              'class A = B',
+              [ParserErrorCode.EXPECTED_TOKEN, ParserErrorCode.EXPECTED_TOKEN],
+              'class A = B with _s_;',
+              failing: ['functionVoid', 'functionNonVoid', 'getter']),
+          new TestDescriptor(
+              'equalsNameWith',
+              'class A = B with',
+              [
+                ParserErrorCode.EXPECTED_TYPE_NAME,
+                ParserErrorCode.EXPECTED_TOKEN
+              ],
+              'class A = B with _s_;',
+              failing: ['functionVoid', 'functionNonVoid', 'getter']),
+          new TestDescriptor(
+              'equalsNameName',
+              'class A = B C',
+              [ParserErrorCode.EXPECTED_TOKEN, ParserErrorCode.EXPECTED_TOKEN],
+              'class A = B with C;'),
         ],
         PartialCodeTest.declarationSuffixes);
   }
diff --git a/pkg/analyzer/test/src/fasta/recovery/partial_code/enum_declaration_test.dart b/pkg/analyzer/test/src/fasta/recovery/partial_code/enum_declaration_test.dart
index 22b63e2..167587a 100644
--- a/pkg/analyzer/test/src/fasta/recovery/partial_code/enum_declaration_test.dart
+++ b/pkg/analyzer/test/src/fasta/recovery/partial_code/enum_declaration_test.dart
@@ -12,9 +12,6 @@
 
 class EnumDeclarationTest extends PartialCodeTest {
   buildAll() {
-    List<String> allExceptEof = PartialCodeTest.declarationSuffixes
-        .map((TestSuffix t) => t.name)
-        .toList();
     buildTests(
         'enum_declaration',
         [
diff --git a/pkg/analyzer/test/src/fasta/recovery/partial_code/typedef_test.dart b/pkg/analyzer/test/src/fasta/recovery/partial_code/typedef_test.dart
index 9d91815..95f261e 100644
--- a/pkg/analyzer/test/src/fasta/recovery/partial_code/typedef_test.dart
+++ b/pkg/analyzer/test/src/fasta/recovery/partial_code/typedef_test.dart
@@ -12,8 +12,6 @@
 
 class TypedefTest extends PartialCodeTest {
   buildAll() {
-    List<String> allExceptEof =
-        PartialCodeTest.declarationSuffixes.map((t) => t.name).toList();
     buildTests(
         'typedef',
         [
@@ -26,14 +24,16 @@
                 ParserErrorCode.EXPECTED_TOKEN
               ],
               "typedef _s_();",
-              failing: [
-                'functionVoid',
-                'functionNonVoid',
-                'var',
-                'const',
-                'final',
-                'getter'
-              ]),
+              failing: ['functionVoid', 'functionNonVoid', 'getter']),
+          new TestDescriptor(
+              'name',
+              'typedef T',
+              [
+                ParserErrorCode.MISSING_TYPEDEF_PARAMETERS,
+                ParserErrorCode.EXPECTED_TOKEN
+              ],
+              "typedef T();",
+              failing: ['functionNonVoid', 'getter', 'setter']),
           new TestDescriptor(
               'keywordEquals',
               'typedef =',
@@ -43,7 +43,20 @@
                 ParserErrorCode.EXPECTED_TOKEN
               ],
               "typedef _s_ = _s_;",
-              failing: allExceptEof),
+              allFailing: true),
+          new TestDescriptor(
+              'equals',
+              'typedef T =',
+              [
+                ParserErrorCode.EXPECTED_TYPE_NAME,
+                ParserErrorCode.EXPECTED_TOKEN,
+                ParserErrorCode.INVALID_GENERIC_FUNCTION_TYPE
+              ],
+              "typedef T = _s_;",
+              expectedErrorsInValidCode: [
+                ParserErrorCode.INVALID_GENERIC_FUNCTION_TYPE
+              ],
+              failing: ['functionVoid', 'functionNonVoid', 'getter']),
         ],
         PartialCodeTest.declarationSuffixes);
   }
diff --git a/pkg/analyzer/test/src/task/strong/checker_test.dart b/pkg/analyzer/test/src/task/strong/checker_test.dart
index 3852241..2228fa0 100644
--- a/pkg/analyzer/test/src/task/strong/checker_test.dart
+++ b/pkg/analyzer/test/src/task/strong/checker_test.dart
@@ -2957,18 +2957,18 @@
   // For as, the validity of checks is deferred to runtime.
   Function f;
   f = /*info:UNNECESSARY_CAST*/foo as I2I;
-  f = /*info:UNNECESSARY_CAST*/foo as D2I;
+  f = foo as D2I;
   f = /*info:UNNECESSARY_CAST*/foo as I2D;
-  f = /*info:UNNECESSARY_CAST*/foo as D2D;
+  f = foo as D2D;
 
   f = /*info:UNNECESSARY_CAST*/bar as II2I;
-  f = /*info:UNNECESSARY_CAST*/bar as DI2I;
-  f = /*info:UNNECESSARY_CAST*/bar as ID2I;
+  f = bar as DI2I;
+  f = bar as ID2I;
   f = /*info:UNNECESSARY_CAST*/bar as II2D;
-  f = /*info:UNNECESSARY_CAST*/bar as DD2I;
-  f = /*info:UNNECESSARY_CAST*/bar as DI2D;
-  f = /*info:UNNECESSARY_CAST*/bar as ID2D;
-  f = /*info:UNNECESSARY_CAST*/bar as DD2D;
+  f = bar as DD2I;
+  f = bar as DI2D;
+  f = bar as ID2D;
+  f = bar as DD2D;
 }
 ''');
   }
diff --git a/pkg/analyzer/tool/summary/build_sdk_summaries.dart b/pkg/analyzer/tool/summary/build_sdk_summaries.dart
index fe9302a..4596071 100644
--- a/pkg/analyzer/tool/summary/build_sdk_summaries.dart
+++ b/pkg/analyzer/tool/summary/build_sdk_summaries.dart
@@ -56,7 +56,7 @@
   print('Generating $modeName mode summary.');
   Stopwatch sw = new Stopwatch()..start();
   List<int> bytes = new SummaryBuilder.forSdk(sdkPath, strong).build();
-  new File(outPath).writeAsBytesSync(bytes, mode: FileMode.WRITE_ONLY);
+  new File(outPath).writeAsBytesSync(bytes, mode: FileMode.writeOnly);
   print('\tDone in ${sw.elapsedMilliseconds} ms.');
 }
 
diff --git a/pkg/analyzer_cli/lib/src/ansi.dart b/pkg/analyzer_cli/lib/src/ansi.dart
index c764fd8..1b9a539 100644
--- a/pkg/analyzer_cli/lib/src/ansi.dart
+++ b/pkg/analyzer_cli/lib/src/ansi.dart
@@ -10,7 +10,7 @@
 bool terminalSupportsAnsi() {
   return !runningTests &&
       !Platform.isWindows &&
-      stdioType(stdout) == StdioType.TERMINAL;
+      stdioType(stdout) == StdioType.terminal;
 }
 
 class AnsiLogger {
diff --git a/pkg/analyzer_cli/lib/src/build_mode.dart b/pkg/analyzer_cli/lib/src/build_mode.dart
index 41ecfab8..87f6f10 100644
--- a/pkg/analyzer_cli/lib/src/build_mode.dart
+++ b/pkg/analyzer_cli/lib/src/build_mode.dart
@@ -266,13 +266,13 @@
           if (options.buildSummaryOutput != null) {
             io.File file = new io.File(options.buildSummaryOutput);
             file.writeAsBytesSync(bundle.toBuffer(),
-                mode: io.FileMode.WRITE_ONLY);
+                mode: io.FileMode.writeOnly);
           }
           if (options.buildSummaryOutputSemantic != null) {
             bundle.flushInformative();
             io.File file = new io.File(options.buildSummaryOutputSemantic);
             file.writeAsBytesSync(bundle.toBuffer(),
-                mode: io.FileMode.WRITE_ONLY);
+                mode: io.FileMode.writeOnly);
           }
         });
       } else {
diff --git a/pkg/analyzer_plugin/doc/api.html b/pkg/analyzer_plugin/doc/api.html
index fdf9630..e0d511d 100644
--- a/pkg/analyzer_plugin/doc/api.html
+++ b/pkg/analyzer_plugin/doc/api.html
@@ -1280,7 +1280,7 @@
       An enumeration of the kinds of folding regions.
     </p>
     
-  <dl><dt class="value">COMMENT</dt><dt class="value">CLASS_MEMBER</dt><dt class="value">DIRECTIVES</dt><dt class="value">DOCUMENTATION_COMMENT</dt><dt class="value">TOP_LEVEL_DECLARATION</dt></dl></dd><dt class="typeDefinition"><a name="type_FoldingRegion">FoldingRegion: object</a></dt><dd>
+  <dl><dt class="value">ANNOTATIONS</dt><dt class="value">CLASS_BODY</dt><dt class="value">DIRECTIVES</dt><dt class="value">DOCUMENTATION_COMMENT</dt><dt class="value">FILE_HEADER</dt><dt class="value">FUNCTION_BODY</dt></dl></dd><dt class="typeDefinition"><a name="type_FoldingRegion">FoldingRegion: object</a></dt><dd>
     <p>
       A description of a region that can be folded.
     </p>
diff --git a/pkg/analyzer_plugin/lib/protocol/protocol_common.dart b/pkg/analyzer_plugin/lib/protocol/protocol_common.dart
index d940ac8..e724ab7 100644
--- a/pkg/analyzer_plugin/lib/protocol/protocol_common.dart
+++ b/pkg/analyzer_plugin/lib/protocol/protocol_common.dart
@@ -1963,37 +1963,40 @@
  * FoldingKind
  *
  * enum {
- *   COMMENT
- *   CLASS_MEMBER
+ *   ANNOTATIONS
+ *   CLASS_BODY
  *   DIRECTIVES
  *   DOCUMENTATION_COMMENT
- *   TOP_LEVEL_DECLARATION
+ *   FILE_HEADER
+ *   FUNCTION_BODY
  * }
  *
  * Clients may not extend, implement or mix-in this class.
  */
 class FoldingKind implements Enum {
-  static const FoldingKind COMMENT = const FoldingKind._("COMMENT");
+  static const FoldingKind ANNOTATIONS = const FoldingKind._("ANNOTATIONS");
 
-  static const FoldingKind CLASS_MEMBER = const FoldingKind._("CLASS_MEMBER");
+  static const FoldingKind CLASS_BODY = const FoldingKind._("CLASS_BODY");
 
   static const FoldingKind DIRECTIVES = const FoldingKind._("DIRECTIVES");
 
   static const FoldingKind DOCUMENTATION_COMMENT =
       const FoldingKind._("DOCUMENTATION_COMMENT");
 
-  static const FoldingKind TOP_LEVEL_DECLARATION =
-      const FoldingKind._("TOP_LEVEL_DECLARATION");
+  static const FoldingKind FILE_HEADER = const FoldingKind._("FILE_HEADER");
+
+  static const FoldingKind FUNCTION_BODY = const FoldingKind._("FUNCTION_BODY");
 
   /**
    * A list containing all of the enum values that are defined.
    */
   static const List<FoldingKind> VALUES = const <FoldingKind>[
-    COMMENT,
-    CLASS_MEMBER,
+    ANNOTATIONS,
+    CLASS_BODY,
     DIRECTIVES,
     DOCUMENTATION_COMMENT,
-    TOP_LEVEL_DECLARATION
+    FILE_HEADER,
+    FUNCTION_BODY
   ];
 
   @override
@@ -2003,16 +2006,18 @@
 
   factory FoldingKind(String name) {
     switch (name) {
-      case "COMMENT":
-        return COMMENT;
-      case "CLASS_MEMBER":
-        return CLASS_MEMBER;
+      case "ANNOTATIONS":
+        return ANNOTATIONS;
+      case "CLASS_BODY":
+        return CLASS_BODY;
       case "DIRECTIVES":
         return DIRECTIVES;
       case "DOCUMENTATION_COMMENT":
         return DOCUMENTATION_COMMENT;
-      case "TOP_LEVEL_DECLARATION":
-        return TOP_LEVEL_DECLARATION;
+      case "FILE_HEADER":
+        return FILE_HEADER;
+      case "FUNCTION_BODY":
+        return FUNCTION_BODY;
     }
     throw new Exception('Illegal enum value: $name');
   }
diff --git a/pkg/analyzer_plugin/lib/src/utilities/change_builder/change_builder_core.dart b/pkg/analyzer_plugin/lib/src/utilities/change_builder/change_builder_core.dart
index fe90449..807264c 100644
--- a/pkg/analyzer_plugin/lib/src/utilities/change_builder/change_builder_core.dart
+++ b/pkg/analyzer_plugin/lib/src/utilities/change_builder/change_builder_core.dart
@@ -184,13 +184,15 @@
     } finally {
       int end = offset + _buffer.length;
       int length = end - start;
-      Position position = new Position(fileEditBuilder.fileEdit.file, start);
-      fileEditBuilder.changeBuilder._lockedPositions.add(position);
-      LinkedEditGroup group =
-          fileEditBuilder.changeBuilder.getLinkedEditGroup(groupName);
-      group.addPosition(position, length);
-      for (LinkedEditSuggestion suggestion in builder.suggestions) {
-        group.addSuggestion(suggestion);
+      if (length != 0) {
+        Position position = new Position(fileEditBuilder.fileEdit.file, start);
+        fileEditBuilder.changeBuilder._lockedPositions.add(position);
+        LinkedEditGroup group =
+            fileEditBuilder.changeBuilder.getLinkedEditGroup(groupName);
+        group.addPosition(position, length);
+        for (LinkedEditSuggestion suggestion in builder.suggestions) {
+          group.addSuggestion(suggestion);
+        }
       }
     }
   }
@@ -229,9 +231,8 @@
   }
 
   @override
-  void write(String string, {StringBuffer displayTextBuffer}) {
+  void write(String string) {
     _buffer.write(string);
-    displayTextBuffer?.write(string);
   }
 
   @override
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 b9b3f80..ef91dc7 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
@@ -24,7 +24,6 @@
 import 'package:analyzer_plugin/utilities/range_factory.dart';
 import 'package:charcode/ascii.dart';
 import 'package:meta/meta.dart';
-import 'package:path/path.dart' as path;
 
 /**
  * A [ChangeBuilder] used to build changes in Dart files.
@@ -43,8 +42,14 @@
 
   @override
   Future<Null> addFileEdit(
-          String path, void buildFileEdit(DartFileEditBuilder builder)) =>
-      super.addFileEdit(path, (builder) => buildFileEdit(builder));
+      String path, void buildFileEdit(DartFileEditBuilder builder),
+      {ImportPrefixGenerator importPrefixGenerator}) {
+    return super.addFileEdit(path, (builder) {
+      DartFileEditBuilderImpl dartBuilder = builder;
+      dartBuilder.importPrefixGenerator = importPrefixGenerator;
+      buildFileEdit(dartBuilder);
+    });
+  }
 
   @override
   Future<DartFileEditBuilderImpl> createFileEditBuilder(String path) async {
@@ -65,6 +70,28 @@
   List<String> _KNOWN_METHOD_NAME_PREFIXES = ['get', 'is', 'to'];
 
   /**
+   * Whether [_enclosingClass] and [_enclosingExecutable] have been initialized.
+   */
+  bool _hasEnclosingElementsInitialized = false;
+
+  /**
+   * The enclosing class element, possibly `null`.
+   * This field is lazily initialized in [_initializeEnclosingElements].
+   */
+  ClassElement _enclosingClass;
+
+  /**
+   * The enclosing executable element, possibly `null`.
+   * This field is lazily initialized in [_initializeEnclosingElements].
+   */
+  ExecutableElement _enclosingExecutable;
+
+  /**
+   * If not `null`, [write] will copy everything into this buffer.
+   */
+  StringBuffer _carbonCopyBuffer;
+
+  /**
    * Initialize a newly created builder to build a source edit.
    */
   DartEditBuilderImpl(
@@ -88,11 +115,10 @@
    */
   String getIndent(int level) => '  ' * level;
 
-  /**
-   * Arrange to have an import added for the given [library].
-   */
-  void importLibrary(Source library) {
-    dartFileEditBuilder.librariesToImport.add(library);
+  @override
+  void write(String string) {
+    super.write(string);
+    _carbonCopyBuffer?.write(string);
   }
 
   @override
@@ -335,6 +361,15 @@
   @override
   void writeOverrideOfInheritedMember(ExecutableElement member,
       {StringBuffer displayTextBuffer, String returnTypeGroupName}) {
+    void withCarbonCopyBuffer(f()) {
+      this._carbonCopyBuffer = displayTextBuffer;
+      try {
+        f();
+      } finally {
+        this._carbonCopyBuffer = null;
+      }
+    }
+
     String prefix = getIndent(1);
     String prefix2 = getIndent(2);
     ElementKind elementKind = member.kind;
@@ -376,7 +411,9 @@
     }
 
     // name
-    write(memberName, displayTextBuffer: displayTextBuffer);
+    withCarbonCopyBuffer(() {
+      write(memberName);
+    });
 
     // parameters + body
     if (isGetter) {
@@ -396,11 +433,11 @@
       }
       displayTextBuffer?.write(' => …');
     } else {
-      writeTypeParameters(member.typeParameters,
-          methodBeingCopied: member, displayTextBuffer: displayTextBuffer);
       List<ParameterElement> parameters = member.parameters;
-      writeParameters(parameters,
-          methodBeingCopied: member, displayTextBuffer: displayTextBuffer);
+      withCarbonCopyBuffer(() {
+        writeTypeParameters(member.typeParameters, methodBeingCopied: member);
+        writeParameters(parameters, methodBeingCopied: member);
+      });
       writeln(' {');
 
       // TO-DO
@@ -467,20 +504,18 @@
 
   @override
   void writeParameter(String name,
-      {StringBuffer displayTextBuffer,
-      ExecutableElement methodBeingCopied,
-      DartType type}) {
-    String parameterSource;
+      {ExecutableElement methodBeingCopied, DartType type}) {
     if (type != null) {
-      _EnclosingElementFinder finder = new _EnclosingElementFinder();
-      finder.find(dartFileEditBuilder.unit, offset);
-      parameterSource = _getTypeSource(
-          type, finder.enclosingClass, finder.enclosingExecutable,
-          parameterName: name, methodBeingCopied: methodBeingCopied);
+      bool hasType = _writeType(type, methodBeingCopied: methodBeingCopied);
+      if (name.isNotEmpty) {
+        if (hasType) {
+          write(' ');
+        }
+        write(name);
+      }
     } else {
-      parameterSource = name;
+      write(name);
     }
-    write(parameterSource, displayTextBuffer: displayTextBuffer);
   }
 
   @override
@@ -509,51 +544,49 @@
 
   @override
   void writeParameters(Iterable<ParameterElement> parameters,
-      {StringBuffer displayTextBuffer, ExecutableElement methodBeingCopied}) {
-    write('(', displayTextBuffer: displayTextBuffer);
+      {ExecutableElement methodBeingCopied}) {
+    write('(');
     bool sawNamed = false;
     bool sawPositional = false;
     for (int i = 0; i < parameters.length; i++) {
       ParameterElement parameter = parameters.elementAt(i);
       if (i > 0) {
-        write(', ', displayTextBuffer: displayTextBuffer);
+        write(', ');
       }
       // Might be optional
       if (parameter.isNamed) {
         if (!sawNamed) {
-          write('{', displayTextBuffer: displayTextBuffer);
+          write('{');
           sawNamed = true;
         }
       } else if (parameter.isOptionalPositional) {
         if (!sawPositional) {
-          write('[', displayTextBuffer: displayTextBuffer);
+          write('[');
           sawPositional = true;
         }
       }
       // parameter
       writeParameter(parameter.name,
-          displayTextBuffer: displayTextBuffer,
-          methodBeingCopied: methodBeingCopied,
-          type: parameter.type);
+          methodBeingCopied: methodBeingCopied, type: parameter.type);
       // default value
       String defaultCode = parameter.defaultValueCode;
       if (defaultCode != null) {
         if (sawPositional) {
-          write(' = ', displayTextBuffer: displayTextBuffer);
+          write(' = ');
         } else {
-          write(': ', displayTextBuffer: displayTextBuffer);
+          write(': ');
         }
-        write(defaultCode, displayTextBuffer: displayTextBuffer);
+        write(defaultCode);
       }
     }
     // close parameters
     if (sawNamed) {
-      write('}', displayTextBuffer: displayTextBuffer);
+      write('}');
     }
     if (sawPositional) {
-      write(']', displayTextBuffer: displayTextBuffer);
+      write(']');
     }
-    write(')', displayTextBuffer: displayTextBuffer);
+    write(')');
   }
 
   @override
@@ -582,24 +615,8 @@
   @override
   void writeReference(Element element) {
     if (element.enclosingElement is CompilationUnitElement) {
-      LibraryElement definingLibrary = element.library;
-      LibraryElement importingLibrary =
-          dartFileEditBuilder.unit.element.library;
-
-      // TODO(scheglov) Extract this code (it is already used twice).
-      // TODO(scheglov) Consider updating `show` combinator to show the element.
-      ImportElement existingImport =
-          _getImportElement(element, importingLibrary);
-      if (existingImport != null) {
-        if (existingImport.prefix != null) {
-          write(existingImport.prefix.displayName);
-          write('.');
-        }
-      } else {
-        importLibrary(definingLibrary.source);
-      }
+      _writeLibraryReference(element);
     }
-
     write(element.displayName);
   }
 
@@ -609,66 +626,50 @@
       String groupName,
       ExecutableElement methodBeingCopied,
       bool required: false}) {
+    bool wroteType = false;
     if (type != null && !type.isDynamic) {
-      _EnclosingElementFinder finder = new _EnclosingElementFinder();
-      finder.find(dartFileEditBuilder.unit, offset);
-      String typeSource = _getTypeSource(
-          type, finder.enclosingClass, finder.enclosingExecutable,
-          methodBeingCopied: methodBeingCopied);
-      if (typeSource.isNotEmpty && typeSource != 'dynamic') {
-        if (groupName != null) {
-          addLinkedEdit(groupName, (LinkedEditBuilder builder) {
-            write(typeSource);
-            if (addSupertypeProposals) {
-              _addSuperTypeProposals(builder, type, new Set<DartType>());
-            }
-          });
-        } else {
-          write(typeSource);
-        }
-        return true;
+      if (groupName != null) {
+        addLinkedEdit(groupName, (LinkedEditBuilder builder) {
+          wroteType = _writeType(type, methodBeingCopied: methodBeingCopied);
+          if (wroteType && addSupertypeProposals) {
+            _addSuperTypeProposals(builder, type, new Set<DartType>());
+          }
+        });
+      } else {
+        wroteType = _writeType(type, methodBeingCopied: methodBeingCopied);
       }
     }
-    if (required) {
+    if (!wroteType && required) {
       write(Keyword.VAR.lexeme);
       return true;
     }
-    return false;
+    return wroteType;
   }
 
   @override
   void writeTypeParameter(TypeParameterElement typeParameter,
-      {StringBuffer displayTextBuffer, ExecutableElement methodBeingCopied}) {
-    write(typeParameter.name, displayTextBuffer: displayTextBuffer);
+      {ExecutableElement methodBeingCopied}) {
+    write(typeParameter.name);
     if (typeParameter.bound != null) {
-      _EnclosingElementFinder finder = new _EnclosingElementFinder();
-      finder.find(dartFileEditBuilder.unit, offset);
-      String bound = _getTypeSource(typeParameter.bound, finder.enclosingClass,
-          finder.enclosingExecutable,
-          methodBeingCopied: methodBeingCopied);
-      if (bound != null) {
-        write(' extends ', displayTextBuffer: displayTextBuffer);
-        write(bound, displayTextBuffer: displayTextBuffer);
-      }
+      write(' extends ');
+      _writeType(typeParameter.bound, methodBeingCopied: methodBeingCopied);
     }
   }
 
   @override
   void writeTypeParameters(List<TypeParameterElement> typeParameters,
-      {StringBuffer displayTextBuffer, ExecutableElement methodBeingCopied}) {
+      {ExecutableElement methodBeingCopied}) {
     if (typeParameters.isNotEmpty) {
-      write('<', displayTextBuffer: displayTextBuffer);
+      write('<');
       bool isFirst = true;
       for (TypeParameterElement typeParameter in typeParameters) {
         if (!isFirst) {
-          write(', ', displayTextBuffer: displayTextBuffer);
+          write(', ');
         }
         isFirst = false;
-        writeTypeParameter(typeParameter,
-            methodBeingCopied: methodBeingCopied,
-            displayTextBuffer: displayTextBuffer);
+        writeTypeParameter(typeParameter, methodBeingCopied: methodBeingCopied);
       }
-      write('>', displayTextBuffer: displayTextBuffer);
+      write('>');
     }
   }
 
@@ -847,28 +848,6 @@
   }
 
   /**
-   * Return the import element used to import the given [element] into the given
-   * [library], or `null` if the element was not imported, such as when the
-   * element is declared in the same library.
-   */
-  ImportElement _getImportElement(Element element, LibraryElement library) {
-    for (ImportElement importElement in library.imports) {
-      Map<String, Element> definedNames = _getImportNamespace(importElement);
-      if (definedNames.containsValue(element)) {
-        return importElement;
-      }
-    }
-    return null;
-  }
-
-  /**
-   * Return the namespace added by the given import [element].
-   */
-  Map<String, Element> _getImportNamespace(ImportElement element) {
-    return element.namespace.definedNames;
-  }
-
-  /**
    * Return a list containing the suggested names for a parameter with the given
    * [type] whose value in one location is computed by the given [expression].
    * The list will not contain any names in the set of [excluded] names. The
@@ -887,189 +866,6 @@
   }
 
   /**
-   * Returns the source to reference [type] in this compilation unit.
-   *
-   * If an [enclosingClass] is provided then the reference is being generated
-   * within the class and the type parameters of the class will be considered to
-   * be visible.
-   *
-   * If an [enclosingExecutable] is provided, then the reference is being
-   * generated within the class and the type parameters of the method will be
-   * considered to be visible.
-   *
-   * If a [methodBeingCopied] is provided, then the type parameters of that
-   * method will be duplicated in the copy and will therefore be visible.
-   *
-   * If a [parameterName] is given, then the type is the type of a parameter
-   * and the parameter name will be included, either in-line in a function type
-   * or after the type source for other types.
-   *
-   * Causes any libraries whose elements are used by the generated source, to be
-   * imported.
-   */
-  String _getTypeSource(DartType type, ClassElement enclosingClass,
-      ExecutableElement enclosingExecutable,
-      {String parameterName, ExecutableElement methodBeingCopied}) {
-    // type parameter
-    type = _getVisibleType(type, enclosingClass, enclosingExecutable,
-        methodBeingCopied: methodBeingCopied);
-    if (type == null || type.isDynamic || type.isBottom) {
-      if (parameterName != null) {
-        return parameterName;
-      }
-      return 'dynamic';
-    }
-
-    Element element = type.element;
-
-    // Typedef(s) are represented as GenericFunctionTypeElement(s).
-    if (element is GenericFunctionTypeElement &&
-        element.typeParameters.isEmpty &&
-        element.enclosingElement is GenericTypeAliasElement) {
-      element = element.enclosingElement;
-    }
-
-    // just a Function, not FunctionTypeAliasElement
-    if (type is FunctionType && element is! FunctionTypeAliasElement) {
-      if (parameterName == null) {
-        return 'Function';
-      }
-      // TODO(brianwilkerson) Using a buffer here means that we cannot re-use
-      // the existing `write*` functions. Refactor this code to remove the
-      // duplication.
-      StringBuffer buffer = new StringBuffer();
-      String returnType = _getTypeSource(
-          type.returnType, enclosingClass, enclosingExecutable,
-          methodBeingCopied: methodBeingCopied);
-      if (returnType != null) {
-        buffer.write(returnType);
-        buffer.write(' ');
-      }
-      if (element is GenericFunctionTypeElement) {
-        buffer.write('Function');
-        if (element.typeParameters.isNotEmpty) {
-          buffer.write('<');
-          bool isFirst = true;
-          for (TypeParameterElement typeParameter in element.typeParameters) {
-            if (!isFirst) {
-              buffer.write(', ');
-            }
-            isFirst = false;
-            buffer.write(typeParameter.name);
-            if (typeParameter.bound != null) {
-              String bound = _getTypeSource(
-                  typeParameter.bound, enclosingClass, enclosingExecutable,
-                  methodBeingCopied: methodBeingCopied);
-              if (bound != null) {
-                buffer.write(' extends ');
-                buffer.write(bound);
-              }
-            }
-          }
-          buffer.write('>');
-        }
-      } else {
-        buffer.write(parameterName);
-      }
-      buffer.write('(');
-      int count = type.parameters.length;
-      for (int i = 0; i < count; i++) {
-        ParameterElement parameter = type.parameters[i];
-        String parameterType = _getTypeSource(
-            parameter.type, enclosingClass, enclosingExecutable,
-            parameterName: parameter.name,
-            methodBeingCopied: methodBeingCopied);
-        if (i > 0) {
-          buffer.write(', ');
-        }
-        buffer.write(parameterType);
-      }
-      buffer.write(')');
-      if (element is GenericFunctionTypeElement) {
-        buffer.write(' ');
-        buffer.write(parameterName);
-      }
-      return buffer.toString();
-    }
-    // prepare element
-    if (element == null) {
-      String source = type.toString();
-      source = source.replaceAll('<dynamic>', '');
-      source = source.replaceAll('<dynamic, dynamic>', '');
-      if (parameterName != null) {
-        return '$source $parameterName';
-      }
-      return source;
-    }
-    // check if imported
-    StringBuffer buffer = new StringBuffer();
-    LibraryElement definingLibrary = element.library;
-    LibraryElement importingLibrary = dartFileEditBuilder.unit.element.library;
-    if (definingLibrary != null && definingLibrary != importingLibrary) {
-      // no source, if private
-      if (element.isPrivate) {
-        if (parameterName != null) {
-          return parameterName;
-        }
-        return '';
-      }
-      // ensure import
-      ImportElement importElement =
-          _getImportElement(element, importingLibrary);
-      if (importElement != null) {
-        if (importElement.prefix != null) {
-          buffer.write(importElement.prefix.displayName);
-          buffer.write(".");
-        }
-      } else {
-        importLibrary(definingLibrary.source);
-      }
-    }
-    // append simple name
-    String name = element.displayName;
-    buffer.write(name);
-    // may be type arguments
-    if (type is ParameterizedType) {
-      List<DartType> arguments = type.typeArguments;
-      // check if has arguments
-      bool hasArguments = false;
-      bool allArgumentsVisible = true;
-      for (DartType argument in arguments) {
-        hasArguments = hasArguments || !argument.isDynamic;
-        allArgumentsVisible = allArgumentsVisible &&
-            _getVisibleType(argument, enclosingClass, enclosingExecutable,
-                    methodBeingCopied: methodBeingCopied) !=
-                null;
-      }
-      // append type arguments
-      if (hasArguments && allArgumentsVisible) {
-        buffer.write("<");
-        for (int i = 0; i < arguments.length; i++) {
-          DartType argument = arguments[i];
-          if (i != 0) {
-            buffer.write(", ");
-          }
-          String argumentSrc = _getTypeSource(
-              argument, enclosingClass, enclosingExecutable,
-              methodBeingCopied: methodBeingCopied);
-          if (argumentSrc != null) {
-            buffer.write(argumentSrc);
-          } else {
-            return null;
-          }
-        }
-        buffer.write(">");
-      }
-    }
-    if (parameterName != null) {
-      buffer.write(' ');
-      buffer.write(parameterName);
-    }
-    // done
-    return buffer.toString();
-  }
-
-  /**
    * Returns possible names for a variable with the given expected type and
    * expression assigned.
    */
@@ -1109,15 +905,15 @@
   }
 
   /**
-   * If the given [type] is visible in either the [enclosingExecutable] or
-   * [enclosingClass], or if there is a local equivalent to the type (such as in
-   * the case of a type parameter from a superclass), then return the type that
-   * is locally visible. Otherwise, return `null`.
+   * If the given [type] is visible in either the [_enclosingExecutable] or
+   * [_enclosingClass], or if there is a local equivalent to the type (such as
+   * in the case of a type parameter from a superclass), then return the type
+   * that is locally visible. Otherwise, return `null`.
    */
-  DartType _getVisibleType(DartType type, ClassElement enclosingClass,
-      ExecutableElement enclosingExecutable,
+  DartType _getVisibleType(DartType type,
       {ExecutableElement methodBeingCopied}) {
     if (type is TypeParameterType) {
+      _initializeEnclosingElements();
       TypeParameterElement parameterElement = type.element;
       Element parameterParent = parameterElement.enclosingElement;
       while (parameterParent is GenericFunctionTypeElement ||
@@ -1125,24 +921,24 @@
         parameterParent = parameterParent.enclosingElement;
       }
       // TODO(brianwilkerson) This needs to compare the parameterParent with
-      // each of the parents of the enclosingExecutable. (That means that we
+      // each of the parents of the _enclosingExecutable. (That means that we
       // only need the most closely enclosing element.)
-      if (parameterParent == enclosingExecutable ||
-          parameterParent == enclosingClass ||
+      if (parameterParent == _enclosingExecutable ||
+          parameterParent == _enclosingClass ||
           parameterParent == methodBeingCopied) {
         return type;
       }
-      if (enclosingClass != null &&
+      if (_enclosingClass != null &&
           methodBeingCopied != null &&
           parameterParent is ClassElement &&
           parameterParent == methodBeingCopied.enclosingElement) {
         // The parameter is from the class enclosing the methodBeingCopied. That
         // means that somewhere along the inheritance chain there must be a type
         // argument corresponding to the type parameter (either a concrete type
-        // or a type parameter of the enclosingClass). That's the visible type
+        // or a type parameter of the _enclosingClass). That's the visible type
         // that needs to be returned.
         _InheritanceChain chain = new _InheritanceChain(
-            subtype: enclosingClass, supertype: parameterParent);
+            subtype: _enclosingClass, supertype: parameterParent);
         while (chain != null) {
           DartType mappedType = chain.mapParameter(parameterElement);
           if (mappedType is TypeParameterType) {
@@ -1160,15 +956,136 @@
     if (element == null) {
       return type;
     }
-    LibraryElement definingLibrary = element.library;
-    LibraryElement importingLibrary = dartFileEditBuilder.unit.element.library;
-    if (definingLibrary != null &&
-        definingLibrary != importingLibrary &&
-        element.isPrivate) {
+    if (element.isPrivate && !dartFileEditBuilder._isDefinedLocally(element)) {
       return null;
     }
     return type;
   }
+
+  /**
+   * Initialize the [_enclosingClass] and [_enclosingExecutable].
+   */
+  void _initializeEnclosingElements() {
+    if (!_hasEnclosingElementsInitialized) {
+      _EnclosingElementFinder finder = new _EnclosingElementFinder();
+      finder.find(dartFileEditBuilder.unit, offset);
+      _enclosingClass = finder.enclosingClass;
+      _enclosingExecutable = finder.enclosingExecutable;
+      _hasEnclosingElementsInitialized = true;
+    }
+  }
+
+  /**
+   * Write the import prefix to reference the [element], if needed.
+   *
+   * The prefix is not needed if the [element] is defined in the target library,
+   * or there is already an import without prefix that exports the [element].
+   * If there there are no existing import that exports the [element], a library
+   * that exports the [element] is scheduled for import, possibly with a prefix.
+   */
+  void _writeLibraryReference(Element element) {
+    // If the element is defined in the library, then no prefix needed.
+    if (dartFileEditBuilder._isDefinedLocally(element)) {
+      return;
+    }
+
+    ImportElement import = dartFileEditBuilder._getImportElement(element);
+    if (import != null) {
+      if (import.prefix != null) {
+        write(import.prefix.displayName);
+        write('.');
+      }
+    } else {
+      Uri library = element.library.source.uri;
+      _LibraryToImport import = dartFileEditBuilder._importLibrary(library);
+      if (import.prefix != null) {
+        write(import.prefix);
+        write('.');
+      }
+    }
+  }
+
+  /**
+   * Write the code to reference [type] in this compilation unit.
+   *
+   * If a [methodBeingCopied] is provided, then the type parameters of that
+   * method will be duplicated in the copy and will therefore be visible.
+   *
+   * Causes any libraries whose elements are used by the generated code, to be
+   * imported.
+   */
+  bool _writeType(DartType type, {ExecutableElement methodBeingCopied}) {
+    type = _getVisibleType(type, methodBeingCopied: methodBeingCopied);
+
+    // If not a useful type, don't write it.
+    if (type == null || type.isDynamic || type.isBottom) {
+      return false;
+    }
+
+    Element element = type.element;
+
+    // No element, e.g. "void".
+    if (element == null) {
+      write(type.displayName);
+      return true;
+    }
+
+    // Typedef(s) are represented as GenericFunctionTypeElement(s).
+    if (element is GenericFunctionTypeElement &&
+        element.typeParameters.isEmpty &&
+        element.enclosingElement is GenericTypeAliasElement) {
+      element = element.enclosingElement;
+    }
+
+    // Just a Function, not FunctionTypeAliasElement.
+    if (type is FunctionType &&
+        element is FunctionTypedElement &&
+        element is! FunctionTypeAliasElement) {
+      if (_writeType(type.returnType, methodBeingCopied: methodBeingCopied)) {
+        write(' ');
+      }
+      write('Function');
+      writeTypeParameters(element.typeParameters,
+          methodBeingCopied: methodBeingCopied);
+      writeParameters(type.parameters, methodBeingCopied: methodBeingCopied);
+      return true;
+    }
+
+    // Ensure that the element is imported.
+    _writeLibraryReference(element);
+
+    // Write the simple name.
+    String name = element.displayName;
+    write(name);
+
+    // Write type arguments.
+    if (type is ParameterizedType) {
+      List<DartType> arguments = type.typeArguments;
+      // Check if has arguments.
+      bool hasArguments = false;
+      bool allArgumentsVisible = true;
+      for (DartType argument in arguments) {
+        hasArguments = hasArguments || !argument.isDynamic;
+        allArgumentsVisible = allArgumentsVisible &&
+            _getVisibleType(argument, methodBeingCopied: methodBeingCopied) !=
+                null;
+      }
+      // Write type arguments only if they are useful.
+      if (hasArguments && allArgumentsVisible) {
+        write('<');
+        for (int i = 0; i < arguments.length; i++) {
+          DartType argument = arguments[i];
+          if (i != 0) {
+            write(', ');
+          }
+          _writeType(argument, methodBeingCopied: methodBeingCopied);
+        }
+        write('>');
+      }
+    }
+
+    return true;
+  }
 }
 
 /**
@@ -1179,22 +1096,33 @@
   /**
    * The compilation unit to which the code will be added.
    */
-  CompilationUnit unit;
+  final CompilationUnit unit;
 
   /**
-   * A set containing the sources of the libraries that need to be imported in
-   * order to make visible the names used in generated code.
+   * The target library, which contains the [unit].
    */
-  Set<Source> librariesToImport = new Set<Source>();
+  final LibraryElement libraryElement;
+
+  /**
+   * The optional generator of prefixes for new imports.
+   */
+  ImportPrefixGenerator importPrefixGenerator;
+
+  /**
+   * A mapping from libraries that need to be imported in order to make visible
+   * the names used in generated code, to information about these imports.
+   */
+  Map<Uri, _LibraryToImport> librariesToImport = {};
 
   /**
    * Initialize a newly created builder to build a source file edit within the
    * change being built by the given [changeBuilder]. The file being edited has
-   * the given [source] and [timeStamp], and the given fully resolved [unit].
+   * the given [path] and [timeStamp], and the given fully resolved [unit].
    */
   DartFileEditBuilderImpl(DartChangeBuilderImpl changeBuilder, String path,
       int timeStamp, this.unit)
-      : super(changeBuilder, path, timeStamp);
+      : libraryElement = unit.element.library,
+        super(changeBuilder, path, timeStamp);
 
   @override
   void addInsertion(int offset, void buildEdit(DartEditBuilder builder)) =>
@@ -1226,25 +1154,23 @@
   @override
   Future<Null> finalize() async {
     if (librariesToImport.isNotEmpty) {
-      CompilationUnitElement unitElement = unit.element;
-      LibraryElement libraryElement = unitElement.library;
       CompilationUnitElement definingUnitElement =
           libraryElement.definingCompilationUnit;
-      if (definingUnitElement == unitElement) {
-        _addLibraryImports(libraryElement, librariesToImport);
+      if (definingUnitElement == unit.element) {
+        _addLibraryImports(librariesToImport.values);
       } else {
         await (changeBuilder as DartChangeBuilder).addFileEdit(
             definingUnitElement.source.fullName, (DartFileEditBuilder builder) {
           (builder as DartFileEditBuilderImpl)
-              ._addLibraryImports(libraryElement, librariesToImport);
+              ._addLibraryImports(librariesToImport.values);
         });
       }
     }
   }
 
   @override
-  void importLibraries(Iterable<Source> libraries) {
-    librariesToImport.addAll(libraries);
+  String importLibrary(Uri uri) {
+    return _importLibrary(uri).uriText;
   }
 
   @override
@@ -1274,10 +1200,9 @@
   }
 
   /**
-   * Adds edits ensure that all the [libraries] are imported into the given
-   * [targetLibrary].
+   * Adds edits ensure that all the [imports] are imported into the library.
    */
-  void _addLibraryImports(LibraryElement targetLibrary, Set<Source> libraries) {
+  void _addLibraryImports(Iterable<_LibraryToImport> imports) {
     // Prepare information about existing imports.
     LibraryDirective libraryDirective;
     List<ImportDirective> importDirectives = <ImportDirective>[];
@@ -1289,23 +1214,31 @@
       }
     }
 
-    // Prepare all URIs to import.
-    List<String> uriList = libraries
-        .map((library) => _getLibrarySourceUri(targetLibrary, library))
-        .toList();
-    uriList.sort((a, b) => a.compareTo(b));
+    // Sort imports by URIs.
+    List<_LibraryToImport> importList = imports.toList();
+    importList.sort((a, b) => a.uriText.compareTo(b.uriText));
+
+    void writeImport(EditBuilder builder, _LibraryToImport import) {
+      builder.write("import '");
+      builder.write(import.uriText);
+      builder.write("'");
+      if (import.prefix != null) {
+        builder.write(' as ');
+        builder.write(import.prefix);
+      }
+      builder.write(';');
+    }
 
     // Insert imports: between existing imports.
     if (importDirectives.isNotEmpty) {
-      for (String importUri in uriList) {
-        bool isDart = importUri.startsWith('dart:');
-        bool isPackage = importUri.startsWith('package:');
+      for (var import in importList) {
+        bool isDart = import.uriText.startsWith('dart:');
+        bool isPackage = import.uriText.startsWith('package:');
         bool inserted = false;
 
         void insert(
             {ImportDirective prev,
             ImportDirective next,
-            String uri,
             bool trailingNewLine: false}) {
           LineInfo lineInfo = unit.lineInfo;
           if (prev != null) {
@@ -1320,16 +1253,13 @@
             }
             addInsertion(offset, (EditBuilder builder) {
               builder.writeln();
-              builder.write("import '");
-              builder.write(uri);
-              builder.write("';");
+              writeImport(builder, import);
             });
           } else {
             int offset = next.offset;
             addInsertion(offset, (EditBuilder builder) {
-              builder.write("import '");
-              builder.write(uri);
-              builder.writeln("';");
+              writeImport(builder, import);
+              builder.writeln();
               if (trailingNewLine) {
                 builder.writeln();
               }
@@ -1350,14 +1280,13 @@
           bool isExistingPackage = existingUri.startsWith('package:');
           bool isExistingRelative = !existingUri.contains(':');
 
-          bool isNewBeforeExisting = importUri.compareTo(existingUri) < 0;
+          bool isNewBeforeExisting = import.uriText.compareTo(existingUri) < 0;
 
           if (isDart) {
             if (!isExistingDart || isNewBeforeExisting) {
               insert(
                   prev: lastExistingDart,
                   next: existingImport,
-                  uri: importUri,
                   trailingNewLine: !isExistingDart);
               break;
             }
@@ -1366,13 +1295,12 @@
               insert(
                   prev: lastExistingPackage,
                   next: existingImport,
-                  uri: importUri,
                   trailingNewLine: isExistingRelative);
               break;
             }
           } else {
             if (!isExistingDart && !isExistingPackage && isNewBeforeExisting) {
-              insert(next: existingImport, uri: importUri);
+              insert(next: existingImport);
               break;
             }
           }
@@ -1398,9 +1326,7 @@
               }
             }
             builder.writeln();
-            builder.write("import '");
-            builder.write(importUri);
-            builder.write("';");
+            writeImport(builder, import);
           });
         }
       }
@@ -1409,18 +1335,17 @@
 
     // Insert imports: after the library directive.
     if (libraryDirective != null) {
-      for (int i = 0; i < uriList.length; i++) {
-        String importUri = uriList[i];
-        addInsertion(libraryDirective.end, (EditBuilder builder) {
+      addInsertion(libraryDirective.end, (EditBuilder builder) {
+        for (int i = 0; i < importList.length; i++) {
+          var import = importList[i];
           if (i == 0) {
             builder.writeln();
           }
           builder.writeln();
-          builder.write("import '");
-          builder.write(importUri);
-          builder.writeln("';");
-        });
-      }
+          writeImport(builder, import);
+          builder.writeln();
+        }
+      });
       return;
     }
 
@@ -1433,34 +1358,69 @@
     } else {
       offset = unit.end;
     }
-    for (int i = 0; i < uriList.length; i++) {
-      String importUri = uriList[i];
-      addInsertion(offset, (EditBuilder builder) {
-        builder.write("import '");
-        builder.write(importUri);
-        builder.writeln("';");
-        if (i == uriList.length - 1 && insertEmptyLineAfter) {
+    addInsertion(offset, (EditBuilder builder) {
+      for (int i = 0; i < importList.length; i++) {
+        var import = importList[i];
+        writeImport(builder, import);
+        builder.writeln();
+        if (i == importList.length - 1 && insertEmptyLineAfter) {
           builder.writeln();
         }
-      });
-    }
+      }
+    });
   }
 
   /**
-   * Computes the best URI to import [what] into [from].
+   * Return the import element used to import the given [element] into the
+   * target library, or `null` if the element was not imported, such as when
+   * the element is declared in the same library.
    */
-  String _getLibrarySourceUri(LibraryElement from, Source what) {
-    String whatPath = what.fullName;
-    // check if an absolute URI (such as 'dart:' or 'package:')
-    Uri whatUri = what.uri;
-    String whatUriScheme = whatUri.scheme;
-    if (whatUriScheme != '' && whatUriScheme != 'file') {
-      return whatUri.toString();
+  ImportElement _getImportElement(Element element) {
+    for (ImportElement import in libraryElement.imports) {
+      Map<String, Element> definedNames = import.namespace.definedNames;
+      if (definedNames.containsValue(element)) {
+        return import;
+      }
     }
-    // compute a relative URI
-    String fromFolder = path.dirname(from.source.fullName);
-    String relativeFile = path.relative(whatPath, from: fromFolder);
-    return path.split(relativeFile).join('/');
+    return null;
+  }
+
+  /**
+   * Computes the best URI to import [what] into the target library.
+   */
+  String _getLibraryUriText(Uri what) {
+    if (what.scheme == 'file') {
+      var session = (changeBuilder as DartChangeBuilderImpl).session;
+      var pathContext = session.resourceProvider.pathContext;
+      String whatPath = pathContext.fromUri(what);
+      String libraryPath = libraryElement.source.fullName;
+      String libraryFolder = pathContext.dirname(libraryPath);
+      String relativeFile = pathContext.relative(whatPath, from: libraryFolder);
+      return pathContext.split(relativeFile).join('/');
+    }
+    return what.toString();
+  }
+
+  /**
+   * Arrange to have an import added for the library with the given [uri].
+   */
+  _LibraryToImport _importLibrary(Uri uri) {
+    var import = librariesToImport[uri];
+    if (import == null) {
+      String uriText = _getLibraryUriText(uri);
+      String prefix =
+          importPrefixGenerator != null ? importPrefixGenerator(uri) : null;
+      import = new _LibraryToImport(uriText, prefix);
+      librariesToImport[uri] = import;
+    }
+    return import;
+  }
+
+  /**
+   * Return `true` if the [element] is defined in the target library.
+   */
+  bool _isDefinedLocally(Element element) {
+    return element.library == libraryElement;
   }
 
   /**
@@ -1626,3 +1586,23 @@
     return null;
   }
 }
+
+/**
+ * Information about a new library to import.
+ */
+class _LibraryToImport {
+  final String uriText;
+  final String prefix;
+
+  _LibraryToImport(this.uriText, this.prefix);
+
+  @override
+  int get hashCode => uriText.hashCode;
+
+  @override
+  bool operator ==(other) {
+    return other is _LibraryToImport &&
+        other.uriText == uriText &&
+        other.prefix == prefix;
+  }
+}
diff --git a/pkg/analyzer_plugin/lib/src/utilities/completion/optype.dart b/pkg/analyzer_plugin/lib/src/utilities/completion/optype.dart
index a7a52c0..da284db 100644
--- a/pkg/analyzer_plugin/lib/src/utilities/completion/optype.dart
+++ b/pkg/analyzer_plugin/lib/src/utilities/completion/optype.dart
@@ -121,6 +121,16 @@
     optype.inStaticMethodBody =
         mthDecl is MethodDeclaration && mthDecl.isStatic;
 
+    // If a value should be suggested, suggest also constructors.
+    if (optype.includeReturnValueSuggestions) {
+      // Careful: in angular plugin, `target.unit` may be null!
+      CompilationUnitElement unitElement = target.unit?.element;
+      if (unitElement != null &&
+          unitElement.context.analysisOptions.previewDart2) {
+        optype.includeConstructorSuggestions = true;
+      }
+    }
+
     // Compute the type required by the context and set filters.
     optype._computeRequiredTypeAndFilters(target);
 
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 f1f68be..4cd16ae 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
@@ -14,6 +14,11 @@
 import 'package:analyzer_plugin/utilities/change_builder/change_builder_core.dart';
 
 /**
+ * The optional generator for prefix that should be used for new imports.
+ */
+typedef ImportPrefixGenerator = String Function(Uri);
+
+/**
  * A [ChangeBuilder] used to build changes in Dart files.
  *
  * Clients may not extend, implement or mix-in this class.
@@ -24,9 +29,18 @@
    */
   factory DartChangeBuilder(AnalysisSession session) = DartChangeBuilderImpl;
 
+  /**
+   * Use the [buildFileEdit] function to create a collection of edits to the
+   * file with the given [path]. The edits will be added to the source change
+   * that is being built.
+   *
+   * If [importPrefixGenerator] is provided, it will be asked to generate an
+   * import prefix for every newly imported library.
+   */
   @override
   Future<Null> addFileEdit(
-      String path, void buildFileEdit(DartFileEditBuilder builder));
+      String path, void buildFileEdit(DartFileEditBuilder builder),
+      {ImportPrefixGenerator importPrefixGenerator});
 }
 
 /**
@@ -305,9 +319,12 @@
       FunctionBody body, TypeProvider typeProvider);
 
   /**
-   * Arrange to have imports added for each of the given [libraries].
+   * Arrange to have an import added for the library with the given [uri].
+   *
+   * Returns the text of the URI that will be used in the import directive.
+   * It can be different than the given [Uri].
    */
-  void importLibraries(Iterable<Source> libraries);
+  String importLibrary(Uri uri);
 
   /**
    * Optionally create an edit to replace the given [typeAnnotation] with the
diff --git a/pkg/analyzer_plugin/test/integration/support/protocol_matchers.dart b/pkg/analyzer_plugin/test/integration/support/protocol_matchers.dart
index 30d0bb6..841a96f 100644
--- a/pkg/analyzer_plugin/test/integration/support/protocol_matchers.dart
+++ b/pkg/analyzer_plugin/test/integration/support/protocol_matchers.dart
@@ -317,19 +317,21 @@
  * FoldingKind
  *
  * enum {
- *   COMMENT
- *   CLASS_MEMBER
+ *   ANNOTATIONS
+ *   CLASS_BODY
  *   DIRECTIVES
  *   DOCUMENTATION_COMMENT
- *   TOP_LEVEL_DECLARATION
+ *   FILE_HEADER
+ *   FUNCTION_BODY
  * }
  */
 final Matcher isFoldingKind = new MatchesEnum("FoldingKind", [
-  "COMMENT",
-  "CLASS_MEMBER",
+  "ANNOTATIONS",
+  "CLASS_BODY",
   "DIRECTIVES",
   "DOCUMENTATION_COMMENT",
-  "TOP_LEVEL_DECLARATION"
+  "FILE_HEADER",
+  "FUNCTION_BODY"
 ]);
 
 /**
diff --git a/pkg/analyzer_plugin/test/plugin/folding_mixin_test.dart b/pkg/analyzer_plugin/test/plugin/folding_mixin_test.dart
index bf6ede1..e8e2d46 100644
--- a/pkg/analyzer_plugin/test/plugin/folding_mixin_test.dart
+++ b/pkg/analyzer_plugin/test/plugin/folding_mixin_test.dart
@@ -74,7 +74,7 @@
   @override
   void computeFolding(FoldingRequest request, FoldingCollector collector) {
     for (int i = 0; i < regionCount; i++) {
-      collector.addRegion(i * 20, 10, FoldingKind.COMMENT);
+      collector.addRegion(i * 20, 10, FoldingKind.FILE_HEADER);
     }
   }
 }
diff --git a/pkg/analyzer_plugin/test/src/utilities/change_builder/change_builder_core_test.dart b/pkg/analyzer_plugin/test/src/utilities/change_builder/change_builder_core_test.dart
index fe72dfa..e662d11 100644
--- a/pkg/analyzer_plugin/test/src/utilities/change_builder/change_builder_core_test.dart
+++ b/pkg/analyzer_plugin/test/src/utilities/change_builder/change_builder_core_test.dart
@@ -337,7 +337,8 @@
     await builder.addFileEdit(path, (FileEditBuilder builder) {
       builder.addInsertion(10, (EditBuilder builder) {
         builder.addLinkedEdit(groupName, (LinkedEditBuilder builder) {
-          builder.addSuggestion(LinkedEditSuggestionKind.TYPE, 'A');
+          builder.write('A');
+          builder.addSuggestion(LinkedEditSuggestionKind.TYPE, 'B');
         });
       });
     });
@@ -346,13 +347,28 @@
     expect(group.suggestions, hasLength(1));
   }
 
+  test_addSuggestion_zeroLength() async {
+    String groupName = 'a';
+    ChangeBuilderImpl builder = new ChangeBuilderImpl();
+    await builder.addFileEdit(path, (FileEditBuilder builder) {
+      builder.addInsertion(10, (EditBuilder builder) {
+        builder.addLinkedEdit(groupName, (LinkedEditBuilder builder) {
+          builder.addSuggestion(LinkedEditSuggestionKind.TYPE, 'A');
+        });
+      });
+    });
+
+    expect(builder.sourceChange.linkedEditGroups, isEmpty);
+  }
+
   test_addSuggestions() async {
     String groupName = 'a';
     ChangeBuilderImpl builder = new ChangeBuilderImpl();
     await builder.addFileEdit(path, (FileEditBuilder builder) {
       builder.addInsertion(10, (EditBuilder builder) {
         builder.addLinkedEdit(groupName, (LinkedEditBuilder builder) {
-          builder.addSuggestions(LinkedEditSuggestionKind.TYPE, ['A', 'B']);
+          builder.write('A');
+          builder.addSuggestions(LinkedEditSuggestionKind.TYPE, ['B', 'C']);
         });
       });
     });
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 d8d76f8..c7d2f7b 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
@@ -74,7 +74,7 @@
 class DartEditBuilderImplTest extends AbstractContextTest
     with BuilderTestMixin {
   test_importLibraries_DP() async {
-    await _assertImportLibraries('''
+    await _assertImportLibrary('''
 import 'dart:aaa';
 import 'dart:ccc';
 
@@ -92,7 +92,7 @@
   }
 
   test_importLibraries_PD() async {
-    await _assertImportLibraries('''
+    await _assertImportLibrary('''
 import 'dart:aaa';
 import 'dart:ccc';
 
@@ -110,7 +110,7 @@
   }
 
   test_importLibrary_afterLibraryDirective_dart() async {
-    await _assertImportLibraries('''
+    await _assertImportLibrary('''
 library test;
 
 class A {}
@@ -125,7 +125,7 @@
   }
 
   test_importLibrary_dart_beforeDart() async {
-    await _assertImportLibraries('''
+    await _assertImportLibrary('''
 import 'dart:aaa';
 import 'dart:ccc';
 ''', ['dart:bbb'], '''
@@ -136,7 +136,7 @@
   }
 
   test_importLibrary_dart_beforeDart_first() async {
-    await _assertImportLibraries('''
+    await _assertImportLibrary('''
 import 'dart:bbb';
 ''', ['dart:aaa'], '''
 import 'dart:aaa';
@@ -145,7 +145,7 @@
   }
 
   test_importLibrary_dart_beforePackage() async {
-    await _assertImportLibraries('''
+    await _assertImportLibrary('''
 import 'package:foo/foo.dart';
 ''', ['dart:async'], '''
 import 'dart:async';
@@ -155,7 +155,7 @@
   }
 
   test_importLibrary_noDirectives_docComment() async {
-    await _assertImportLibraries('''
+    await _assertImportLibrary('''
 /// Documentation comment.
 /// Continues.
 void main() {}
@@ -169,7 +169,7 @@
   }
 
   test_importLibrary_noDirectives_hashBang() async {
-    await _assertImportLibraries('''
+    await _assertImportLibrary('''
 #!/bin/dart
 
 void main() {}
@@ -183,7 +183,7 @@
   }
 
   test_importLibrary_noDirectives_lineComment() async {
-    await _assertImportLibraries('''
+    await _assertImportLibrary('''
 // Not documentation comment.
 // Continues.
 
@@ -199,7 +199,7 @@
   }
 
   test_importLibrary_package_afterDart() async {
-    await _assertImportLibraries('''
+    await _assertImportLibrary('''
 import 'dart:async';
 ''', ['package:aaa/aaa.dart'], '''
 import 'dart:async';
@@ -209,7 +209,7 @@
   }
 
   test_importLibrary_package_afterPackage() async {
-    await _assertImportLibraries('''
+    await _assertImportLibrary('''
 import 'package:aaa/a1.dart';
 
 import 'foo.dart';
@@ -222,7 +222,7 @@
   }
 
   test_importLibrary_package_afterPackage_leadingComment() async {
-    await _assertImportLibraries('''
+    await _assertImportLibrary('''
 // comment
 import 'package:aaa/a1.dart';
 
@@ -237,7 +237,7 @@
   }
 
   test_importLibrary_package_afterPackage_trailingComment() async {
-    await _assertImportLibraries('''
+    await _assertImportLibrary('''
 import 'package:aaa/a1.dart'; // comment
 
 import 'foo.dart';
@@ -250,7 +250,7 @@
   }
 
   test_importLibrary_package_beforePackage() async {
-    await _assertImportLibraries('''
+    await _assertImportLibrary('''
 import 'package:aaa/a1.dart';
 import 'package:aaa/a3.dart';
 
@@ -265,7 +265,7 @@
   }
 
   test_importLibrary_package_beforePackage_first() async {
-    await _assertImportLibraries('''
+    await _assertImportLibrary('''
 import 'package:aaa/a2.dart';
 
 import 'foo.dart';
@@ -278,7 +278,7 @@
   }
 
   test_importLibrary_package_beforePackage_leadingComments() async {
-    await _assertImportLibraries('''
+    await _assertImportLibrary('''
 // comment a2
 import 'package:aaa/a2.dart';
 
@@ -293,7 +293,7 @@
   }
 
   test_importLibrary_package_beforePackage_trailingComments() async {
-    await _assertImportLibraries('''
+    await _assertImportLibrary('''
 import 'package:aaa/a2.dart'; // comment a2
 
 import 'foo.dart';
@@ -306,7 +306,7 @@
   }
 
   test_importLibrary_package_beforeRelative() async {
-    await _assertImportLibraries('''
+    await _assertImportLibrary('''
 import 'foo.dart';
 ''', ['package:aaa/aaa.dart'], '''
 import 'package:aaa/aaa.dart';
@@ -316,7 +316,7 @@
   }
 
   test_importLibrary_relative_afterDart() async {
-    await _assertImportLibraries('''
+    await _assertImportLibrary('''
 import 'dart:async';
 ''', ['aaa.dart'], '''
 import 'dart:async';
@@ -326,7 +326,7 @@
   }
 
   test_importLibrary_relative_afterPackage() async {
-    await _assertImportLibraries('''
+    await _assertImportLibrary('''
 import 'package:foo/foo.dart';
 ''', ['aaa.dart'], '''
 import 'package:foo/foo.dart';
@@ -336,7 +336,7 @@
   }
 
   test_importLibrary_relative_beforeRelative() async {
-    await _assertImportLibraries('''
+    await _assertImportLibrary('''
 import 'dart:async';
 
 import 'package:foo/foo.dart';
@@ -355,7 +355,7 @@
   }
 
   test_importLibrary_relative_beforeRelative_first() async {
-    await _assertImportLibraries('''
+    await _assertImportLibrary('''
 import 'dart:async';
 
 import 'package:foo/foo.dart';
@@ -372,7 +372,7 @@
   }
 
   test_importLibrary_relative_last() async {
-    await _assertImportLibraries('''
+    await _assertImportLibrary('''
 import 'dart:async';
 
 import 'package:foo/foo.dart';
@@ -1734,6 +1734,32 @@
     expect(edit.replacement, equalsIgnoringWhitespace(''));
   }
 
+  test_writeType_function() async {
+    await _assertWriteType('int Function(double a, String b)');
+  }
+
+  @failingTest
+  test_writeType_function_generic() async {
+    // TODO(scheglov) Fails because T/U are considered invisible.
+    await _assertWriteType('T Function<T, U>(T a, U b)');
+  }
+
+  test_writeType_function_noReturnType() async {
+    await _assertWriteType('Function()');
+  }
+
+  test_writeType_function_parameters_named() async {
+    await _assertWriteType('int Function(int a, {int b, int c})');
+  }
+
+  test_writeType_function_parameters_noName() async {
+    await _assertWriteType('int Function(double, String)');
+  }
+
+  test_writeType_function_parameters_positional() async {
+    await _assertWriteType('int Function(int a, [int b, int c])');
+  }
+
   test_writeType_genericType() async {
     String path = provider.convertPath('/test.dart');
     String content = 'class A {} class B<E> {}';
@@ -1806,6 +1832,33 @@
     expect(values, contains('C'));
   }
 
+  test_writeType_groupName_invalidType() async {
+    String path = provider.convertPath('/test.dart');
+    String content = 'class A<T> {}';
+    addSource(path, content);
+
+    InterfaceType typeA = await _getType(path, 'A');
+    DartType typeT = typeA.typeParameters.single.type;
+
+    var builder = new DartChangeBuilder(session);
+    await builder.addFileEdit(path, (builder) {
+      builder.addInsertion(content.length, (builder) {
+        // "T" cannot be written, because we are outside of "A".
+        // So, we also should not create linked groups.
+        builder.writeType(typeT, groupName: 'type');
+      });
+    });
+    expect(builder.sourceChange.linkedEditGroups, isEmpty);
+  }
+
+  test_writeType_interface_typeArguments() async {
+    await _assertWriteType('Map<int, List<String>>');
+  }
+
+  test_writeType_interface_typeArguments_allDynamic() async {
+    await _assertWriteType('Map');
+  }
+
   test_writeType_null() async {
     String path = provider.convertPath('/test.dart');
     String content = 'class A {}';
@@ -1821,6 +1874,56 @@
     expect(edit.replacement, equalsIgnoringWhitespace(''));
   }
 
+  test_writeType_prefixGenerator() async {
+    String aPath = provider.convertPath('/a.dart');
+    String bPath = provider.convertPath('/b.dart');
+
+    addSource(aPath, r'''
+class A1 {}
+class A2 {}
+''');
+    addSource(bPath, r'''
+class B {}
+''');
+
+    String path = provider.convertPath('/test.dart');
+    String content = '';
+    addSource(path, content);
+
+    ClassElement a1 = await _getClassElement(aPath, 'A1');
+    ClassElement a2 = await _getClassElement(aPath, 'A2');
+    ClassElement b = await _getClassElement(bPath, 'B');
+
+    int nextPrefixIndex = 0;
+    String prefixGenerator(_) {
+      return '_prefix${nextPrefixIndex++}';
+    }
+
+    var builder = new DartChangeBuilder(session);
+    await builder.addFileEdit(path, (builder) {
+      builder.addInsertion(content.length - 1, (builder) {
+        builder.writeType(a1.type);
+        builder.write(' a1; ');
+
+        builder.writeType(a2.type);
+        builder.write(' a2; ');
+
+        builder.writeType(b.type);
+        builder.write(' b;');
+      });
+    }, importPrefixGenerator: prefixGenerator);
+    List<SourceEdit> edits = getEdits(builder);
+    expect(edits, hasLength(2));
+    expect(
+        edits[0].replacement,
+        equalsIgnoringWhitespace(
+            "import 'a.dart' as _prefix0; import 'b.dart' as _prefix1;"));
+    expect(
+        edits[1].replacement,
+        equalsIgnoringWhitespace(
+            '_prefix0.A1 a1; _prefix0.A2 a2; _prefix1.B b;'));
+  }
+
   test_writeType_required_dynamic() async {
     String path = provider.convertPath('/test.dart');
     String content = 'class A {}';
@@ -1890,6 +1993,15 @@
     expect(edit.replacement, equalsIgnoringWhitespace('A'));
   }
 
+  test_writeType_typedef_typeArguments() async {
+    await _assertWriteType('F<int, String>',
+        declarations: 'typedef void F<T, U>(T t, U u);');
+  }
+
+  test_writeType_void() async {
+    await _assertWriteType('void Function()');
+  }
+
   test_writeTypes_empty() async {
     String path = provider.convertPath('/test.dart');
     String content = 'class A {}';
@@ -1955,18 +2067,15 @@
     expect(edit.replacement, equalsIgnoringWhitespace('implements A, B'));
   }
 
-  Future<Null> _assertImportLibraries(
+  Future<Null> _assertImportLibrary(
       String initialCode, List<String> newUris, String expectedCode) async {
     String path = provider.convertPath('/test.dart');
     addSource(path, initialCode);
     DartChangeBuilderImpl builder = new DartChangeBuilder(session);
     await builder.addFileEdit(path, (DartFileEditBuilder builder) {
-      Iterable<_MockSource> sources = newUris.map((newUri) {
-        String path =
-            newUri.contains(':') ? null : provider.convertPath('/$newUri');
-        return new _MockSource(path, Uri.parse(newUri));
-      });
-      builder.importLibraries(sources);
+      for (String newUri in newUris) {
+        builder.importLibrary(Uri.parse(newUri));
+      }
     });
 
     String resultCode = initialCode;
@@ -2044,6 +2153,23 @@
     }
   }
 
+  Future<void> _assertWriteType(String typeCode, {String declarations}) async {
+    String path = provider.convertPath('/test.dart');
+    String content = (declarations ?? '') + '$typeCode v;';
+    addSource(path, content);
+
+    var f = await _getTopLevelAccessorElement(path, 'v');
+
+    var builder = new DartChangeBuilder(session);
+    await builder.addFileEdit(path, (builder) {
+      builder.addInsertion(content.length - 1, (builder) {
+        builder.writeType(f.returnType);
+      });
+    });
+    SourceEdit edit = getEdit(builder);
+    expect(edit.replacement, typeCode);
+  }
+
   Future<ClassElement> _getClassElement(String path, String name) async {
     UnitElementResult result = await driver.getUnitElement(path);
     return result.element.getType(name);
@@ -2055,7 +2181,7 @@
     return result.element.accessors.firstWhere((v) => v.name == name);
   }
 
-  Future<DartType> _getType(String path, String name) async {
+  Future<InterfaceType> _getType(String path, String name) async {
     ClassElement classElement = await _getClassElement(path, name);
     return classElement.type;
   }
@@ -2168,16 +2294,3 @@
         unorderedEquals(['Object', 'A', 'B', 'C']));
   }
 }
-
-class _MockSource implements Source {
-  @override
-  final String fullName;
-
-  @override
-  final Uri uri;
-
-  _MockSource(this.fullName, this.uri);
-
-  @override
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
-}
diff --git a/pkg/analyzer_plugin/tool/spec/common_types_spec.html b/pkg/analyzer_plugin/tool/spec/common_types_spec.html
index 648c033..7e30303 100644
--- a/pkg/analyzer_plugin/tool/spec/common_types_spec.html
+++ b/pkg/analyzer_plugin/tool/spec/common_types_spec.html
@@ -6,7 +6,7 @@
 </head>
 <body>
 <h1>Common Types</h1>
-<version>1.0.0</version>
+<version>1.0.1</version>
 <p>
   This document contains a specification of the types that are common between
   the analysis server wire protocol and the analysis server plugin wire
@@ -533,11 +533,12 @@
       An enumeration of the kinds of folding regions.
     </p>
     <enum>
-      <value><code>COMMENT</code></value>
-      <value><code>CLASS_MEMBER</code></value>
+      <value><code>ANNOTATIONS</code></value>
+      <value><code>CLASS_BODY</code></value>
       <value><code>DIRECTIVES</code></value>
       <value><code>DOCUMENTATION_COMMENT</code></value>
-      <value><code>TOP_LEVEL_DECLARATION</code></value>
+      <value><code>FILE_HEADER</code></value>
+      <value><code>FUNCTION_BODY</code></value>
     </enum>
   </type>
   <type name="FoldingRegion">
diff --git a/pkg/async_helper/lib/async_helper.dart b/pkg/async_helper/lib/async_helper.dart
index 1c9c10e..46360f9 100644
--- a/pkg/async_helper/lib/async_helper.dart
+++ b/pkg/async_helper/lib/async_helper.dart
@@ -23,14 +23,7 @@
 
 library async_helper;
 
-// TODO(kustermann): This is problematic because we rely on a working
-// 'dart:isolate' (i.e. it is in particular problematic with dart2js).
-// It would be nice if we could use a different mechanism for different
-// runtimes.
-import 'dart:isolate';
-
 bool _initialized = false;
-ReceivePort _port = null;
 int _asyncLevel = 0;
 
 Exception _buildException(String msg) {
@@ -49,7 +42,6 @@
   if (!_initialized) {
     print('unittest-suite-wait-for-done');
     _initialized = true;
-    _port = new ReceivePort();
   }
   _asyncLevel += count;
 }
@@ -66,8 +58,6 @@
   }
   _asyncLevel--;
   if (_asyncLevel == 0) {
-    _port.close();
-    _port = null;
     print('unittest-suite-success');
   }
 }
diff --git a/pkg/compiler/lib/src/apiimpl.dart b/pkg/compiler/lib/src/apiimpl.dart
index 1ad4fc81..cd2101a 100644
--- a/pkg/compiler/lib/src/apiimpl.dart
+++ b/pkg/compiler/lib/src/apiimpl.dart
@@ -17,14 +17,11 @@
 import 'common.dart';
 import 'compiler.dart';
 import 'diagnostics/messages.dart' show Message;
-import 'elements/elements.dart' as elements;
 import 'environment.dart';
-import 'library_loader.dart';
 import 'io/source_file.dart';
 import 'options.dart' show CompilerOptions;
 import 'platform_configuration.dart' as platform_configuration;
 import 'resolved_uri_translator.dart';
-import 'script.dart';
 
 /// Implements the [Compiler] using a [api.CompilerInput] for supplying the
 /// sources.
@@ -34,10 +31,6 @@
   api.CompilerDiagnostics handler;
   Packages packages;
 
-  bool get mockableLibraryUsed => resolvedUriTranslator.isSet
-      ? resolvedUriTranslator.mockableLibraryUsed
-      : false;
-
   ForwardingResolvedUriTranslator resolvedUriTranslator;
 
   GenericTask userHandlerTask;
@@ -73,86 +66,6 @@
         null, null, null, null, message, api.Diagnostic.VERBOSE_INFO);
   }
 
-  /// Report [exception] reading [uri]. Use [element] and [node] to compute
-  /// the error location.
-  void _reportReadError(
-      Uri uri, elements.Element element, Spannable node, exception) {
-    if (element == null || node == null) {
-      reporter.reportErrorMessage(new SourceSpan(uri, 0, 0),
-          MessageKind.READ_SELF_ERROR, {'uri': uri, 'exception': exception});
-    } else {
-      reporter.withCurrentElement(element, () {
-        reporter.reportErrorMessage(node, MessageKind.READ_URI_ERROR,
-            {'uri': uri, 'exception': exception});
-      });
-    }
-  }
-
-  /**
-   * Reads the script designated by [readableUri].
-   */
-  Future<Script> readScript(Uri readableUri, [Spannable node]) {
-    if (!readableUri.isAbsolute) {
-      if (node == null) node = NO_LOCATION_SPANNABLE;
-      reporter.internalError(
-          node, 'Relative uri $readableUri provided to readScript(Uri).');
-    }
-
-    // We need to store the current element since we are reporting read errors
-    // asynchronously and therefore need to restore the current element for
-    // [node] to be valid.
-    elements.Element element = currentElement;
-
-    Uri resourceUri = translateUri(node, readableUri);
-    if (resourceUri == null) return _synthesizeScript(readableUri);
-    if (resourceUri.scheme == 'dart-ext') {
-      reporter.withCurrentElement(element, () {
-        reporter.reportErrorMessage(node, MessageKind.DART_EXT_NOT_SUPPORTED);
-      });
-      return _synthesizeScript(readableUri);
-    }
-
-    // TODO(johnniwinther): Wrap the result from [provider] in a specialized
-    // [Future] to ensure that we never execute an asynchronous action without
-    // setting up the current element of the compiler.
-    return new Future.sync(
-            () => callUserProvider(resourceUri, api.InputKind.UTF8))
-        .then((api.Input sourceFile) {
-      // We use [readableUri] as the URI for the script since need to preserve
-      // the scheme in the script because [Script.uri] is used for resolving
-      // relative URIs mentioned in the script. See the comment on
-      // [LibraryLoader] for more details.
-      return new Script(readableUri, resourceUri, sourceFile);
-    }).catchError((error) {
-      _reportReadError(readableUri, element, node, error);
-      return _synthesizeScript(readableUri);
-    });
-  }
-
-  Future<Script> _synthesizeScript(Uri readableUri) {
-    return new Future.value(new Script.synthetic(readableUri));
-  }
-
-  Future<Binary> readBinary(Uri resourceUri, [Spannable node]) {
-    if (!resourceUri.isAbsolute) {
-      if (node == null) node = NO_LOCATION_SPANNABLE;
-      reporter.internalError(
-          node, 'Relative uri $resourceUri provided to readBinary(Uri).');
-    }
-
-    // We need to store the current element since we are reporting read errors
-    // asynchronously and therefore need to restore the current element for
-    // [node] to be valid.
-    elements.Element element = currentElement;
-
-    return new Future.sync(
-            () => callUserProvider(resourceUri, api.InputKind.binary))
-        .catchError((error) {
-      _reportReadError(resourceUri, element, node, error);
-      return new Binary(resourceUri, null);
-    });
-  }
-
   /**
    * Translates a readable URI into a resource URI.
    *
@@ -176,21 +89,6 @@
     });
   }
 
-  Future<elements.LibraryElement> analyzeUri(Uri uri,
-      {bool skipLibraryWithPartOfTag: true}) {
-    Future setupFuture = new Future.value();
-    if (resolvedUriTranslator.isNotSet) {
-      setupFuture = setupFuture.then((_) => setupSdk());
-    }
-    if (packages == null) {
-      setupFuture = setupFuture.then((_) => setupPackages(uri));
-    }
-    return setupFuture.then((_) {
-      return super
-          .analyzeUri(uri, skipLibraryWithPartOfTag: skipLibraryWithPartOfTag);
-    });
-  }
-
   Future setupPackages(Uri uri) {
     if (options.packageRoot != null) {
       // Use "non-file" packages because the file version requires a [Directory]
@@ -229,8 +127,7 @@
             .load(options.platformConfigUri, provider)
             .then((Map<String, Uri> mapping) {
           resolvedUriTranslator.resolvedUriTranslator =
-              new ResolvedUriTranslator(
-                  mapping, reporter, options.platformConfigUri);
+              new ResolvedUriTranslator(mapping);
         });
       });
     }
@@ -314,9 +211,6 @@
     }
   }
 
-  bool get isMockCompilation =>
-      mockableLibraryUsed && options.allowMockCompilation;
-
   void callUserHandler(Message message, Uri uri, int begin, int end,
       String text, api.Diagnostic kind) {
     try {
@@ -348,11 +242,6 @@
       rethrow;
     }
   }
-
-  Uri resolvePatchUri(String libraryName) {
-    return LibraryLoaderTask.resolvePatchUri(
-        libraryName, options.platformConfigUri);
-  }
 }
 
 class _Environment implements Environment {
diff --git a/pkg/compiler/lib/src/closure.dart b/pkg/compiler/lib/src/closure.dart
index 869ed63..a4ad683 100644
--- a/pkg/compiler/lib/src/closure.dart
+++ b/pkg/compiler/lib/src/closure.dart
@@ -2,27 +2,10 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-import 'package:front_end/src/fasta/scanner.dart' show Token;
-
-import 'common/names.dart' show Identifiers;
-import 'common/resolution.dart' show ParsingContext, Resolution;
 import 'common/tasks.dart' show CompilerTask, Measurer;
 import 'common.dart';
-import 'compiler.dart' show Compiler;
-import 'constants/expressions.dart';
-import 'elements/elements.dart';
 import 'elements/entities.dart';
-import 'elements/entity_utils.dart' as utils;
-import 'elements/modelx.dart'
-    show BaseFunctionElementX, ClassElementX, ElementX;
-import 'elements/resolution_types.dart';
 import 'elements/types.dart';
-import 'elements/visitor.dart' show ElementVisitor;
-import 'js_backend/js_backend.dart' show JavaScriptBackend;
-import 'js_backend/runtime_types.dart';
-import 'resolution/tree_elements.dart' show TreeElements;
-import 'tree/tree.dart';
-import 'util/util.dart';
 import 'world.dart' show ClosedWorldRefiner;
 
 // TODO(johnniwinther,efortuna): Split [ClosureConversionTask] from
@@ -249,293 +232,6 @@
   bool get isClosure => false;
 }
 
-class ClosureTask extends ClosureConversionTask<Node> {
-  Map<Node, CapturedScopeImpl> _closureInfoMap = <Node, CapturedScopeImpl>{};
-  Map<MemberElement, ClosureClassMap> _closureMemberMappingCache =
-      <MemberElement, ClosureClassMap>{};
-  Map<FunctionExpression, ClosureClassMap> _closureNodeMappingCache =
-      <FunctionExpression, ClosureClassMap>{};
-  Compiler compiler;
-  ClosureTask(Compiler compiler)
-      : compiler = compiler,
-        super(compiler.measurer);
-
-  String get name => "Closure Simplifier";
-
-  DiagnosticReporter get reporter => compiler.reporter;
-
-  void convertClosures(Iterable<MemberEntity> processedEntities,
-      ClosedWorldRefiner closedWorldRefiner) {
-    createClosureClasses(closedWorldRefiner);
-  }
-
-  CapturedScope _getCapturedScope(Node node) {
-    var value = _closureInfoMap[node];
-    return value == null ? const CapturedScope() : value;
-  }
-
-  CapturedScope getCapturedScope(covariant MemberElement member) {
-    ResolvedAst resolvedAst = member.resolvedAst;
-    if (resolvedAst.kind != ResolvedAstKind.PARSED)
-      return const CapturedScope();
-    return _getCapturedScope(resolvedAst.node);
-  }
-
-  ScopeInfo getScopeInfo(MemberEntity member) {
-    return _getMemberMapping(member);
-  }
-
-  ClosureRepresentationInfo getClosureInfoForMember(MemberEntity member) {
-    return _getMemberMapping(member);
-  }
-
-  ClosureRepresentationInfo getClosureInfo(covariant FunctionExpression node) {
-    return _getClosureMapping(node);
-  }
-
-  CapturedLoopScope getCapturedLoopScope(Node loopNode) {
-    var value = _closureInfoMap[loopNode];
-    return value == null ? const CapturedLoopScope() : value;
-  }
-
-  /// Returns the [ClosureClassMap] computed for [element].
-  ClosureClassMap _getMemberMapping(MemberElement element) {
-    return measure(() {
-      if (element.isGenerativeConstructorBody) {
-        ConstructorBodyElement constructorBody = element;
-        element = constructorBody.constructor;
-      }
-      ClosureClassMap closureClassMap = _closureMemberMappingCache[element];
-      assert(closureClassMap != null,
-          failedAt(element, "No ClosureClassMap computed for ${element}."));
-      return closureClassMap;
-    });
-  }
-
-  /// Returns the [ClosureClassMap] computed for [node].
-  ClosureClassMap _getClosureMapping(FunctionExpression node) {
-    return measure(() {
-      ClosureClassMap closureClassMap = _closureNodeMappingCache[node];
-      assert(closureClassMap != null,
-          failedAt(node, "No ClosureClassMap computed for ${node}."));
-      return closureClassMap;
-    });
-  }
-
-  /// Create [ClosureClassMap]s for all live members.
-  void createClosureClasses(ClosedWorldRefiner closedWorldRefiner) {
-    compiler.enqueuer.resolution.processedEntities
-        .forEach((MemberEntity _element) {
-      MemberElement element = _element;
-      ResolvedAst resolvedAst = element.resolvedAst;
-      if (element.isAbstract) return;
-      if (element.isField &&
-          !element.isInstanceMember &&
-          resolvedAst.body == null) {
-        // Skip top-level/static fields without an initializer.
-        return;
-      }
-      computeClosureToClassMapping(element, closedWorldRefiner);
-    });
-  }
-
-  ClosureClassMap computeClosureToClassMapping(
-      MemberElement element, ClosedWorldRefiner closedWorldRefiner) {
-    return measure(() {
-      ClosureClassMap cached = _closureMemberMappingCache[element];
-      if (cached != null) return cached;
-      if (element.resolvedAst.kind != ResolvedAstKind.PARSED) {
-        return _closureMemberMappingCache[element] = new ClosureClassMap(
-            null, null, null, new ThisLocalVariable(element));
-      }
-      return reporter.withCurrentElement(element.implementation, () {
-        Node node = element.resolvedAst.node;
-        TreeElements elements = element.resolvedAst.elements;
-
-        ClosureTranslator translator = new ClosureTranslator(
-            compiler,
-            closedWorldRefiner,
-            elements,
-            _closureMemberMappingCache,
-            _closureNodeMappingCache,
-            _closureInfoMap);
-
-        // The translator will store the computed closure-mappings inside the
-        // cache. One for given node and one for each nested closure.
-        if (node is FunctionExpression) {
-          translator.translateFunction(element, node);
-        } else if (element.isSynthesized) {
-          reporter.internalError(
-              element, "Unexpected synthesized element: $element");
-          _closureMemberMappingCache[element] = new ClosureClassMap(
-              null, null, null, new ThisLocalVariable(element));
-        } else {
-          assert(element.isField,
-              failedAt(element, "Expected $element to be a field."));
-          Node initializer = element.resolvedAst.body;
-          if (initializer != null) {
-            // The lazy initializer of a static.
-            translator.translateLazyInitializer(element, node, initializer);
-          } else {
-            assert(
-                element.isInstanceMember,
-                failedAt(
-                    element,
-                    "Expected $element (${element.runtimeType}) "
-                    "to be an instance field."));
-            _closureMemberMappingCache[element] = new ClosureClassMap(
-                null, null, null, new ThisLocalVariable(element));
-          }
-        }
-        assert(_closureMemberMappingCache[element] != null,
-            failedAt(element, "No ClosureClassMap computed for ${element}."));
-        return _closureMemberMappingCache[element];
-      });
-    });
-  }
-}
-
-// TODO(ahe): These classes continuously cause problems.  We need to
-// find a more general solution.
-class ClosureFieldElement extends ElementX
-    implements FieldElement, PrivatelyNamedJSEntity {
-  /// The [BoxLocal] or [LocalElement] being accessed through the field.
-  final Local local;
-
-  ClosureFieldElement(String name, this.local, ClosureClassElement enclosing)
-      : super(name, ElementKind.FIELD, enclosing);
-
-  /// Use [closureClass] instead.
-  @deprecated
-  get enclosingElement => super.enclosingElement;
-
-  ClosureClassElement get closureClass => super.enclosingElement;
-
-  MemberElement get memberContext => closureClass.methodElement.memberContext;
-
-  @override
-  Local get declaredEntity => local;
-
-  @override
-  Entity get rootOfScope => closureClass;
-
-  bool get hasNode => false;
-
-  VariableDefinitions get node {
-    throw failedAt(local, 'Should not access node of ClosureFieldElement.');
-  }
-
-  bool get hasResolvedAst => hasTreeElements;
-
-  ResolvedAst get resolvedAst {
-    return new ParsedResolvedAst(this, null, null, treeElements,
-        memberContext.compilationUnit.script.resourceUri);
-  }
-
-  Expression get initializer {
-    throw failedAt(
-        local, 'Should not access initializer of ClosureFieldElement.');
-  }
-
-  bool get isInstanceMember => true;
-  bool get isAssignable => false;
-
-  ResolutionDartType computeType(Resolution resolution) => type;
-
-  ResolutionDartType get type {
-    if (local is LocalElement) {
-      LocalElement element = local;
-      return element.type;
-    }
-    return const ResolutionDynamicType();
-  }
-
-  String toString() => "ClosureFieldElement($name)";
-
-  accept(ElementVisitor visitor, arg) {
-    return visitor.visitClosureFieldElement(this, arg);
-  }
-
-  AnalyzableElement get analyzableElement =>
-      closureClass.methodElement.analyzableElement;
-
-  @override
-  List<MethodElement> get nestedClosures => const <MethodElement>[];
-
-  @override
-  bool get hasConstant => false;
-
-  @override
-  ConstantExpression get constant => null;
-}
-
-// TODO(ahe): These classes continuously cause problems.  We need to find
-// a more general solution.
-class ClosureClassElement extends ClassElementX {
-  ResolutionInterfaceType rawType;
-  ResolutionInterfaceType thisType;
-  ResolutionFunctionType callType;
-
-  /// Node that corresponds to this closure, used for source position.
-  final FunctionExpression node;
-
-  /**
-   * The element for the declaration of the function expression.
-   */
-  final LocalFunctionElement methodElement;
-
-  final List<ClosureFieldElement> _closureFields = <ClosureFieldElement>[];
-
-  ClosureClassElement(
-      this.node, String name, Compiler compiler, LocalFunctionElement closure)
-      : this.methodElement = closure,
-        super(
-            name,
-            closure.compilationUnit,
-            // By assigning a fresh class-id we make sure that the hashcode
-            // is unique, but also emit closure classes after all other
-            // classes (since the emitter sorts classes by their id).
-            compiler.idGenerator.getNextFreeId(),
-            STATE_DONE) {
-    ClassElement superclass = compiler.resolution.commonElements.closureClass;
-    superclass.ensureResolved(compiler.resolution);
-    supertype = superclass.thisType;
-    interfaces = const Link<ResolutionDartType>();
-    thisType = rawType = new ResolutionInterfaceType(this);
-    allSupertypesAndSelf =
-        superclass.allSupertypesAndSelf.extendClass(thisType);
-    callType = methodElement.type;
-  }
-
-  MethodElement get callMethod => methodElement.callMethod;
-
-  Iterable<ClosureFieldElement> get closureFields => _closureFields;
-
-  void addField(ClosureFieldElement field, DiagnosticReporter listener) {
-    _closureFields.add(field);
-    addMember(field, listener);
-  }
-
-  bool get hasNode => true;
-
-  bool get isClosure => true;
-
-  Token get position => node.getBeginToken();
-
-  Node parseNode(ParsingContext parsing) => node;
-
-  // A [ClosureClassElement] is nested inside a function or initializer in terms
-  // of [enclosingElement], but still has to be treated as a top-level
-  // element.
-  bool get isTopLevel => true;
-
-  get enclosingElement => methodElement;
-
-  accept(ElementVisitor visitor, arg) {
-    return visitor.visitClosureClassElement(this, arg);
-  }
-}
-
 /// A local variable that contains the box object holding the [BoxFieldElement]
 /// fields.
 class BoxLocal extends Local {
@@ -549,73 +245,6 @@
   String toString() => 'BoxLocal($name)';
 }
 
-class BoxLocalVariable extends BoxLocal implements LocalVariable {
-  final MemberElement memberContext;
-
-  BoxLocalVariable(String name, this.memberContext) : super(name);
-
-  ExecutableElement get executableContext => memberContext;
-}
-
-// TODO(ngeoffray, ahe): These classes continuously cause problems.  We need to
-// find a more general solution.
-class BoxFieldElement extends ElementX
-    implements TypedElement, FieldElement, PrivatelyNamedJSEntity {
-  final LocalVariableElement variableElement;
-  final BoxLocalVariable box;
-
-  BoxFieldElement(String name, this.variableElement, BoxLocalVariable box)
-      : this.box = box,
-        super(name, ElementKind.FIELD, box.executableContext);
-
-  ResolutionDartType computeType(Resolution resolution) => type;
-
-  ResolutionDartType get type => variableElement.type;
-
-  @override
-  Local get declaredEntity => variableElement;
-
-  @override
-  Entity get rootOfScope => box;
-
-  accept(ElementVisitor visitor, arg) {
-    return visitor.visitBoxFieldElement(this, arg);
-  }
-
-  @override
-  bool get hasNode => false;
-
-  @override
-  bool get hasResolvedAst => false;
-
-  @override
-  Expression get initializer {
-    throw new UnsupportedError("BoxFieldElement.initializer");
-  }
-
-  @override
-  MemberElement get memberContext => box.memberContext;
-
-  @override
-  List<MethodElement> get nestedClosures => const <MethodElement>[];
-
-  @override
-  VariableDefinitions get node {
-    throw new UnsupportedError("BoxFieldElement.node");
-  }
-
-  @override
-  ResolvedAst get resolvedAst {
-    throw new UnsupportedError("BoxFieldElement.resolvedAst");
-  }
-
-  @override
-  bool get hasConstant => false;
-
-  @override
-  ConstantExpression get constant => null;
-}
-
 /// A local variable used encode the direct (uncaptured) references to [this].
 class ThisLocal extends Local {
   final ClassEntity enclosingClass;
@@ -631,906 +260,6 @@
   int get hashCode => enclosingClass.hashCode;
 }
 
-/// A local variable used encode the direct (uncaptured) references to [this].
-class ThisLocalVariable extends ThisLocal implements LocalVariable {
-  final MemberElement memberContext;
-
-  ThisLocalVariable(this.memberContext) : super(memberContext);
-
-  ExecutableElement get executableContext => memberContext;
-}
-
-/// Call method of a closure class.
-// ignore: STRONG_MODE_INVALID_METHOD_OVERRIDE_FROM_BASE
-class SynthesizedCallMethodElementX extends BaseFunctionElementX
-    implements MethodElement {
-  final LocalFunctionElement expression;
-  final FunctionExpression node;
-  final TreeElements treeElements;
-
-  SynthesizedCallMethodElementX(String name, LocalFunctionElement other,
-      ClosureClassElement enclosing, this.node, this.treeElements)
-      : expression = other,
-        super(name, other.kind, Modifiers.EMPTY, enclosing) {
-    asyncMarker = other.asyncMarker;
-    functionSignature = other.functionSignature;
-    expression.callMethod = this;
-  }
-
-  /// Use [closureClass] instead.
-  @deprecated
-  get enclosingElement => super.enclosingElement;
-
-  ClosureClassElement get closureClass => super.enclosingElement;
-
-  MemberElement get memberContext {
-    return closureClass.methodElement.memberContext;
-  }
-
-  SourceSpan get sourcePosition => expression.sourcePosition;
-
-  bool get hasNode => node != null;
-
-  FunctionExpression parseNode(ParsingContext parsing) => node;
-
-  AnalyzableElement get analyzableElement =>
-      closureClass.methodElement.analyzableElement;
-
-  bool get hasResolvedAst => true;
-
-  ResolvedAst get resolvedAst {
-    return new ParsedResolvedAst(this, node, node.body, treeElements,
-        expression.compilationUnit.script.resourceUri);
-  }
-
-  accept(ElementVisitor visitor, arg) {
-    return visitor.visitMethodElement(this, arg);
-  }
-}
-
-// The box-element for a scope, and the captured variables that need to be
-// stored in the box.
-class CapturedScopeImpl implements CapturedScope, CapturedLoopScope {
-  final BoxLocal boxElement;
-  final Map<Local, BoxFieldElement> capturedVariables;
-
-  // If the scope is attached to a [For] contains the variables that are
-  // declared in the initializer of the [For] and that need to be boxed.
-  // Otherwise contains the empty List.
-  List<Local> boxedLoopVariables = const <Local>[];
-
-  CapturedScopeImpl(this.boxElement, this.capturedVariables);
-
-  Local get context => boxElement;
-
-  bool get requiresContextBox => capturedVariables.keys.isNotEmpty;
-
-  void forEachBoxedVariable(f(Local local, FieldEntity field)) {
-    capturedVariables.forEach(f);
-  }
-
-  bool get hasBoxedLoopVariables => boxedLoopVariables.isNotEmpty;
-
-  bool isBoxed(Local variable) {
-    return capturedVariables.containsKey(variable);
-  }
-
-  void forEachCapturedVariable(
-      f(LocalVariableElement variable, BoxFieldElement boxField)) {
-    capturedVariables.forEach(f);
-  }
-
-  // Should not be called. Added to make the new interface happy.
-  bool localIsUsedInTryOrSync(Local variable) =>
-      throw new UnsupportedError("CapturedScopeImpl.localIsUsedInTryOrSync");
-
-  // Should not be called. Added to make the new interface happy.
-  Local get thisLocal =>
-      throw new UnsupportedError("CapturedScopeImpl.thisLocal");
-
-  String toString() {
-    String separator = '';
-    StringBuffer sb = new StringBuffer();
-    sb.write('CapturedScopeImpl(');
-    if (boxElement != null) {
-      sb.write('box=$boxElement');
-      separator = ',';
-    }
-    if (boxedLoopVariables.isNotEmpty) {
-      sb.write(separator);
-      sb.write('boxedLoopVariables=${boxedLoopVariables}');
-      separator = ',';
-    }
-    if (capturedVariables.isNotEmpty) {
-      sb.write(separator);
-      sb.write('capturedVariables=$capturedVariables');
-    }
-    sb.write(')');
-    return sb.toString();
-  }
-}
-
-class ClosureClassMap implements ClosureRepresentationInfo {
-  /// The local function element before any translation.
-  ///
-  /// Will be null for methods.
-  final LocalFunctionElement closureEntity;
-
-  /// The synthesized closure class for [closureEntity].
-  ///
-  /// The closureClassEntity will be null for methods that are not local
-  /// closures.
-  final ClosureClassElement closureClassEntity;
-
-  /// The synthesized `call` method of the [closureClassEntity].
-  ///
-  /// The callMethod will be null for methods that are not local closures.
-  final MethodElement callMethod;
-
-  /// The [thisLocal] makes handling 'this' easier by treating it like any
-  /// other argument. It is only set for instance-members.
-  final ThisLocal thisLocal;
-
-  /// Maps free locals, arguments, function elements, and box locals to
-  /// their locations.
-  final Map<Local, FieldEntity> freeVariableMap = new Map<Local, FieldEntity>();
-
-  /// Maps [Loop] and [FunctionExpression] nodes to their [CapturedScopeImpl] which
-  /// contains their box and the captured variables that are stored in the box.
-  /// This map will be empty if the method/closure of this [ClosureData] does
-  /// not contain any nested closure.
-  final Map<Node, CapturedScopeImpl> capturingScopes =
-      new Map<Node, CapturedScopeImpl>();
-
-  /// Set of [variable]s referenced in this scope that are used inside a
-  /// `try` block or a `sync*` generator (this is important to know because
-  /// boxing/redirection needs to happen for those local variables).
-  ///
-  /// Variables that are used in a try must be treated as boxed because the
-  /// control flow can be non-linear.
-  ///
-  /// Also parameters to a `sync*` generator must be boxed, because of the way
-  /// we rewrite sync* functions. See also comments in [useLocal].
-  // TODO(johnniwinther): Add variables to this only if the variable is mutated.
-  final Set<Local> localsUsedInTryOrSync = new Set<Local>();
-
-  ClosureClassMap(this.closureEntity, this.closureClassEntity, this.callMethod,
-      this.thisLocal);
-
-  List<Local> get createdFieldEntities {
-    List<Local> fields = <Local>[];
-    if (closureClassEntity == null) return const <Local>[];
-    closureClassEntity.closureFields.forEach((field) {
-      fields.add(field.local);
-    });
-    return fields;
-  }
-
-  @override
-  Local getLocalForField(covariant ClosureFieldElement field) => field.local;
-
-  void addFreeVariable(Local element) {
-    assert(freeVariableMap[element] == null);
-    freeVariableMap[element] = null;
-  }
-
-  Iterable<Local> get freeVariables => freeVariableMap.keys;
-
-  bool isFreeVariable(Local element) {
-    return freeVariableMap.containsKey(element);
-  }
-
-  void forEachFreeVariable(f(Local variable, FieldEntity field)) {
-    freeVariableMap.forEach(f);
-  }
-
-  FieldEntity get thisFieldEntity => freeVariableMap[thisLocal];
-
-  bool localIsUsedInTryOrSync(Local variable) =>
-      localsUsedInTryOrSync.contains(variable);
-
-  Local getLocalVariableForClosureField(ClosureFieldElement field) {
-    return field.local;
-  }
-
-  bool get isClosure => closureEntity != null;
-
-  bool capturingScopesBox(Local variable) {
-    return capturingScopes.values.any((scope) {
-      return scope.boxedLoopVariables.contains(variable);
-    });
-  }
-
-  bool isVariableBoxed(Local variable) {
-    FieldEntity copy = freeVariableMap[variable];
-    if (copy is BoxFieldElement) {
-      return true;
-    }
-    return capturingScopesBox(variable);
-  }
-
-  void forEachBoxedVariable(
-      void f(LocalVariableElement local, BoxFieldElement field)) {
-    freeVariableMap.forEach((variable, copy) {
-      if (!isVariableBoxed(variable)) return;
-      f(variable, copy);
-    });
-    capturingScopes.values.forEach((CapturedScopeImpl scope) {
-      scope.forEachCapturedVariable(f);
-    });
-  }
-
-  bool isBoxed(Local local) {
-    bool variableIsBoxed = false;
-    forEachBoxedVariable((LocalVariableElement element, BoxFieldElement field) {
-      if (element == local) variableIsBoxed = true;
-    });
-    return variableIsBoxed;
-  }
-}
-
-class ClosureTranslator extends Visitor {
-  final Compiler compiler;
-  final ClosedWorldRefiner closedWorldRefiner;
-  final TreeElements elements;
-  int closureFieldCounter = 0;
-  int boxedFieldCounter = 0;
-  bool inTryStatement = false;
-
-  final Map<MemberElement, ClosureClassMap> memberMappingCache;
-  final Map<FunctionExpression, ClosureClassMap> nodeMappingCache;
-  final Map<Node, CapturedScopeImpl> closureInfo;
-
-  // Map of captured variables. Initially they will map to `null`. If
-  // a variable needs to be boxed then the scope declaring the variable
-  // will update this to mapping to the capturing [BoxFieldElement].
-  Map<Local, BoxFieldElement> _capturedVariableMapping =
-      new Map<Local, BoxFieldElement>();
-
-  // List of encountered closures.
-  List<FunctionExpression> closures = <FunctionExpression>[];
-
-  // The local variables that have been declared in the current scope.
-  List<LocalVariableElement> scopeVariables;
-
-  // Keep track of the mutated local variables so that we don't need to box
-  // non-mutated variables.
-  Set<LocalVariableElement> mutatedVariables = new Set<LocalVariableElement>();
-
-  MemberElement outermostElement;
-  ExecutableElement executableContext;
-
-  // The closureData of the currentFunctionElement.
-  ClosureClassMap closureData;
-
-  bool insideClosure = false;
-
-  ClosureTranslator(this.compiler, this.closedWorldRefiner, this.elements,
-      this.memberMappingCache, this.nodeMappingCache, this.closureInfo);
-
-  DiagnosticReporter get reporter => compiler.reporter;
-
-  RuntimeTypesNeed get rtiNeed => closedWorldRefiner.closedWorld.rtiNeed;
-
-  /// Generate a unique name for the [id]th closure field, with proposed name
-  /// [name].
-  ///
-  /// The result is used as the name of [ClosureFieldElement]s, and must
-  /// therefore be unique to avoid breaking an invariant in the element model
-  /// (classes cannot declare multiple fields with the same name).
-  ///
-  /// Also, the names should be distinct from real field names to prevent
-  /// clashes with selectors for those fields.
-  ///
-  /// These names are not used in generated code, just as element name.
-  String getClosureVariableName(String name, int id) {
-    return "_captured_${name}_$id";
-  }
-
-  /// Generate a unique name for the [id]th box field, with proposed name
-  /// [name].
-  ///
-  /// The result is used as the name of [BoxFieldElement]s, and must
-  /// therefore be unique to avoid breaking an invariant in the element model
-  /// (classes cannot declare multiple fields with the same name).
-  ///
-  /// Also, the names should be distinct from real field names to prevent
-  /// clashes with selectors for those fields.
-  ///
-  /// These names are not used in generated code, just as element name.
-  String getBoxFieldName(int id) {
-    return "_box_$id";
-  }
-
-  bool isCapturedVariable(Local element) {
-    return _capturedVariableMapping.containsKey(element);
-  }
-
-  void addCapturedVariable(Node node, Local variable) {
-    if (_capturedVariableMapping[variable] != null) {
-      reporter.internalError(node, 'In closure analyzer.');
-    }
-    _capturedVariableMapping[variable] = null;
-  }
-
-  void setCapturedVariableBoxField(Local variable, BoxFieldElement boxField) {
-    assert(isCapturedVariable(variable));
-    _capturedVariableMapping[variable] = boxField;
-  }
-
-  BoxFieldElement getCapturedVariableBoxField(Local variable) {
-    return _capturedVariableMapping[variable];
-  }
-
-  void translateFunction(Element element, FunctionExpression node) {
-    // For constructors the [element] and the [:elements[node]:] may differ.
-    // The [:elements[node]:] always points to the generative-constructor
-    // element, whereas the [element] might be the constructor-body element.
-    visit(node); // [visitFunctionExpression] will call [visitInvokable].
-    // When variables need to be boxed their [_capturedVariableMapping] is
-    // updated, but we delay updating the similar freeVariableMapping in the
-    // closure datas that capture these variables.
-    // The closures don't have their fields (in the closure class) set, either.
-    updateClosures();
-  }
-
-  void translateLazyInitializer(
-      FieldElement element, VariableDefinitions node, Expression initializer) {
-    visitInvokable(element, node, () {
-      visit(initializer);
-    });
-    updateClosures();
-  }
-
-  // This function runs through all of the existing closures and updates their
-  // free variables to the boxed value. It also adds the field-elements to the
-  // class representing the closure.
-  void updateClosures() {
-    for (FunctionExpression closure in closures) {
-      // The captured variables that need to be stored in a field of the closure
-      // class.
-      Set<Local> fieldCaptures = new Set<Local>();
-      Set<BoxLocal> boxes = new Set<BoxLocal>();
-      ClosureClassMap data = nodeMappingCache[closure];
-      // We get a copy of the keys and iterate over it, to avoid modifications
-      // to the map while iterating over it.
-      Iterable<Local> freeVariables = data.freeVariables.toList();
-      freeVariables.forEach((Local fromElement) {
-        assert(data.isFreeVariable(fromElement));
-        assert(data.freeVariableMap[fromElement] == null);
-        assert(isCapturedVariable(fromElement));
-        BoxFieldElement boxFieldElement =
-            getCapturedVariableBoxField(fromElement);
-        if (boxFieldElement == null) {
-          assert(fromElement is! BoxLocal);
-          // The variable has not been boxed.
-          fieldCaptures.add(fromElement);
-        } else {
-          // A boxed element.
-          data.freeVariableMap[fromElement] = boxFieldElement;
-          boxes.add(boxFieldElement.box);
-        }
-      });
-      ClosureClassElement closureClass = data.closureClassEntity;
-      assert(closureClass != null || (fieldCaptures.isEmpty && boxes.isEmpty));
-
-      void addClosureField(Local local, String name) {
-        ClosureFieldElement closureField =
-            new ClosureFieldElement(name, local, closureClass);
-        closureClass.addField(closureField, reporter);
-        data.freeVariableMap[local] = closureField;
-      }
-
-      // Add the box elements first so we get the same ordering.
-      // TODO(sra): What is the canonical order of multiple boxes?
-      for (BoxLocal capturedElement in boxes) {
-        addClosureField(capturedElement, capturedElement.name);
-      }
-
-      /// Comparator for locals. Position boxes before elements.
-      int compareLocals(a, b) {
-        if (a is Element && b is Element) {
-          return Elements.compareByPosition(a, b);
-        } else if (a is Element) {
-          return 1;
-        } else if (b is Element) {
-          return -1;
-        } else {
-          return a.name.compareTo(b.name);
-        }
-      }
-
-      for (Local capturedLocal in fieldCaptures.toList()..sort(compareLocals)) {
-        int id = closureFieldCounter++;
-        String name = getClosureVariableName(capturedLocal.name, id);
-        addClosureField(capturedLocal, name);
-      }
-    }
-  }
-
-  void useLocal(Local variable) {
-    // If the element is not declared in the current function and the element
-    // is not the closure itself we need to mark the element as free variable.
-    // Note that the check on [insideClosure] is not just an
-    // optimization: factories have type parameters as function
-    // parameters, and type parameters are declared in the class, not
-    // the factory.
-    bool inCurrentContext(LocalVariable variable) {
-      return variable == executableContext ||
-          variable.executableContext == executableContext;
-    }
-
-    if (insideClosure && !inCurrentContext(variable)) {
-      closureData.addFreeVariable(variable);
-    } else if (inTryStatement) {
-      // Don't mark the this-element or a self-reference. This would complicate
-      // things in the builder.
-      // Note that nested (named) functions are immutable.
-      if (variable != closureData.thisLocal &&
-          variable != closureData.closureEntity &&
-          variable is! TypeVariableLocal) {
-        closureData.localsUsedInTryOrSync.add(variable);
-      }
-    } else if (variable is LocalParameterElement &&
-        variable.functionDeclaration.asyncMarker == AsyncMarker.SYNC_STAR) {
-      // Parameters in a sync* function are shared between each Iterator created
-      // by the Iterable returned by the function, therefore they must be boxed.
-      closureData.localsUsedInTryOrSync.add(variable);
-    }
-  }
-
-  void useTypeVariableAsLocal(ResolutionTypeVariableType typeVariable) {
-    useLocal(new TypeVariableLocalVariable(
-        typeVariable, outermostElement, outermostElement.memberContext));
-  }
-
-  void declareLocal(LocalVariableElement element) {
-    scopeVariables.add(element);
-  }
-
-  void registerNeedsThis() {
-    if (closureData.thisLocal != null) {
-      useLocal(closureData.thisLocal);
-    }
-  }
-
-  visit(Node node) => node.accept(this);
-
-  visitNode(Node node) => node.visitChildren(this);
-
-  visitVariableDefinitions(VariableDefinitions node) {
-    if (node.type != null) {
-      visit(node.type);
-    }
-    for (Link<Node> link = node.definitions.nodes;
-        !link.isEmpty;
-        link = link.tail) {
-      Node definition = link.head;
-      LocalElement element = elements[definition];
-      assert(element != null);
-      if (!element.isInitializingFormal) {
-        declareLocal(element);
-      }
-      // We still need to visit the right-hand sides of the init-assignments.
-      // For SendSets don't visit the left again. Otherwise it would be marked
-      // as mutated.
-      if (definition is Send) {
-        Send assignment = definition;
-        Node arguments = assignment.argumentsNode;
-        if (arguments != null) {
-          visit(arguments);
-        }
-      } else {
-        visit(definition);
-      }
-    }
-  }
-
-  visitTypeAnnotation(TypeAnnotation node) {
-    MemberElement member = executableContext.memberContext;
-    ResolutionDartType type = elements.getType(node);
-    // TODO(karlklose,johnniwinther): if the type is null, the annotation is
-    // from a parameter which has been analyzed before the method has been
-    // resolved and the result has been thrown away.
-    if (compiler.options.enableTypeAssertions &&
-        type != null &&
-        type.containsTypeVariables) {
-      if (insideClosure && member.isFactoryConstructor) {
-        // This is a closure in a factory constructor.  Since there is no
-        // [:this:], we have to mark the type arguments as free variables to
-        // capture them in the closure.
-        type.forEachTypeVariable((ResolutionTypeVariableType variable) {
-          useTypeVariableAsLocal(variable);
-        });
-      }
-      if (member.isInstanceMember && !member.isField) {
-        // In checked mode, using a type variable in a type annotation may lead
-        // to a runtime type check that needs to access the type argument and
-        // therefore the closure needs a this-element, if it is not in a field
-        // initializer; field initializers are evaluated in a context where
-        // the type arguments are available in locals.
-        registerNeedsThis();
-      }
-    }
-  }
-
-  visitIdentifier(Identifier node) {
-    if (node.isThis()) {
-      registerNeedsThis();
-    } else {
-      Element element = elements[node];
-      if (element != null && element.isTypeVariable) {
-        if (outermostElement.isConstructor || outermostElement.isField) {
-          TypeVariableElement typeVariable = element;
-          useTypeVariableAsLocal(typeVariable.type);
-        } else {
-          registerNeedsThis();
-        }
-      }
-    }
-    node.visitChildren(this);
-  }
-
-  visitSend(Send node) {
-    Element element = elements[node];
-    if (Elements.isLocal(element)) {
-      LocalElement localElement = element;
-      useLocal(localElement);
-    } else if (element != null && element.isTypeVariable) {
-      TypeVariableElement variable = element;
-      analyzeType(variable.type);
-    } else if (node.receiver == null &&
-        Elements.isInstanceSend(node, elements)) {
-      registerNeedsThis();
-    } else if (node.isSuperCall) {
-      registerNeedsThis();
-    } else if (node.isTypeTest || node.isTypeCast) {
-      TypeAnnotation annotation = node.typeAnnotationFromIsCheckOrCast;
-      ResolutionDartType type = elements.getType(annotation);
-      analyzeType(type);
-    } else if (node.isTypeTest) {
-      ResolutionDartType type =
-          elements.getType(node.typeAnnotationFromIsCheckOrCast);
-      analyzeType(type);
-    } else if (node.isTypeCast) {
-      ResolutionDartType type = elements.getType(node.arguments.head);
-      analyzeType(type);
-    }
-    node.visitChildren(this);
-  }
-
-  visitSendSet(SendSet node) {
-    Element element = elements[node];
-    if (Elements.isLocal(element)) {
-      mutatedVariables.add(element);
-      if (compiler.options.enableTypeAssertions) {
-        TypedElement typedElement = element;
-        analyzeTypeVariables(typedElement.type);
-      }
-    }
-    super.visitSendSet(node);
-  }
-
-  visitNewExpression(NewExpression node) {
-    ResolutionDartType type = elements.getType(node);
-    analyzeType(type);
-    node.visitChildren(this);
-  }
-
-  visitLiteralList(LiteralList node) {
-    ResolutionDartType type = elements.getType(node);
-    analyzeType(type);
-    node.visitChildren(this);
-  }
-
-  visitLiteralMap(LiteralMap node) {
-    ResolutionDartType type = elements.getType(node);
-    analyzeType(type);
-    node.visitChildren(this);
-  }
-
-  void analyzeTypeVariables(ResolutionDartType type) {
-    type.forEachTypeVariable((ResolutionTypeVariableType typeVariable) {
-      // Field initializers are inlined and access the type variable as
-      // normal parameters.
-      if (!outermostElement.isField && !outermostElement.isConstructor) {
-        registerNeedsThis();
-      } else {
-        useTypeVariableAsLocal(typeVariable);
-      }
-    });
-  }
-
-  void analyzeType(ResolutionDartType type) {
-    // TODO(johnniwinther): Find out why this can be null.
-    if (type == null) return;
-    if (outermostElement.isClassMember &&
-        rtiNeed.classNeedsTypeArguments(outermostElement.enclosingClass)) {
-      if (outermostElement.isConstructor || outermostElement.isField) {
-        analyzeTypeVariables(type);
-      } else if (outermostElement.isInstanceMember) {
-        if (type.containsTypeVariables) {
-          registerNeedsThis();
-        }
-      }
-    }
-  }
-
-  // If variables that are declared in the [node] scope are captured and need
-  // to be boxed create a box-element and update the [capturingScopes] in the
-  // current [closureData].
-  // The boxed variables are updated in the [capturedVariableMapping].
-  void attachCapturedScopeVariables(Node node) {
-    BoxLocalVariable box = null;
-    Map<LocalVariableElement, BoxFieldElement> scopeMapping =
-        new Map<LocalVariableElement, BoxFieldElement>();
-
-    void boxCapturedVariable(LocalVariableElement variable) {
-      if (isCapturedVariable(variable)) {
-        if (box == null) {
-          // TODO(floitsch): construct better box names.
-          String boxName = getBoxFieldName(closureFieldCounter++);
-          box = new BoxLocalVariable(boxName, executableContext.memberContext);
-        }
-        String elementName = variable.name;
-        String boxedName =
-            getClosureVariableName(elementName, boxedFieldCounter++);
-        // TODO(kasperl): Should this be a FieldElement instead?
-        BoxFieldElement boxed = new BoxFieldElement(boxedName, variable, box);
-        scopeMapping[variable] = boxed;
-        setCapturedVariableBoxField(variable, boxed);
-      }
-    }
-
-    for (LocalVariableElement variable in scopeVariables) {
-      // No need to box non-assignable elements.
-      if (!variable.isAssignable) continue;
-      if (!mutatedVariables.contains(variable)) continue;
-      boxCapturedVariable(variable);
-    }
-    if (!scopeMapping.isEmpty) {
-      CapturedScopeImpl scope = new CapturedScopeImpl(box, scopeMapping);
-      closureData.capturingScopes[node] = scope;
-      assert(closureInfo[node] == null);
-      closureInfo[node] = scope;
-    }
-  }
-
-  void inNewScope(Node node, Function action) {
-    List<LocalVariableElement> oldScopeVariables = scopeVariables;
-    scopeVariables = <LocalVariableElement>[];
-    action();
-    attachCapturedScopeVariables(node);
-    mutatedVariables.removeAll(scopeVariables);
-    scopeVariables = oldScopeVariables;
-  }
-
-  visitLoop(Loop node) {
-    inNewScope(node, () {
-      node.visitChildren(this);
-    });
-  }
-
-  visitFor(For node) {
-    List<LocalVariableElement> boxedLoopVariables = <LocalVariableElement>[];
-    inNewScope(node, () {
-      // First visit initializer and update so we can easily check if a loop
-      // variable was captured in one of these subexpressions.
-      if (node.initializer != null) visit(node.initializer);
-      if (node.update != null) visit(node.update);
-
-      // Loop variables that have not been captured yet can safely be flagged as
-      // non-mutated, because no nested function can observe the mutation.
-      if (node.initializer is VariableDefinitions) {
-        VariableDefinitions definitions = node.initializer;
-        definitions.definitions.nodes.forEach((Node node) {
-          LocalVariableElement local = elements[node];
-          if (!isCapturedVariable(local)) {
-            mutatedVariables.remove(local);
-          }
-        });
-      }
-
-      // Visit condition and body.
-      // This must happen after the above, so any loop variables mutated in the
-      // condition or body are indeed flagged as mutated.
-      if (node.conditionStatement != null) visit(node.conditionStatement);
-      if (node.body != null) visit(node.body);
-
-      // See if we have declared loop variables that need to be boxed.
-      if (node.initializer == null) return;
-      VariableDefinitions definitions =
-          node.initializer.asVariableDefinitions();
-      if (definitions == null) return;
-      for (Link<Node> link = definitions.definitions.nodes;
-          !link.isEmpty;
-          link = link.tail) {
-        Node definition = link.head;
-        LocalVariableElement element = elements[definition];
-        // Non-mutated variables should not be boxed.  The mutatedVariables set
-        // gets cleared when 'inNewScope' returns, so check it here.
-        if (isCapturedVariable(element) && mutatedVariables.contains(element)) {
-          boxedLoopVariables.add(element);
-        }
-      }
-    });
-    CapturedScopeImpl scopeData = closureData.capturingScopes[node];
-    if (scopeData == null) return;
-    scopeData.boxedLoopVariables = boxedLoopVariables;
-  }
-
-  /** Returns a non-unique name for the given closure element. */
-  String computeClosureName(Element element) {
-    Link<String> parts = const Link<String>();
-    String ownName = element.name;
-    if (ownName == null || ownName == "") {
-      parts = parts.prepend("closure");
-    } else {
-      parts = parts.prepend(ownName);
-    }
-    for (Element enclosingElement = element.enclosingElement;
-        enclosingElement != null &&
-            (enclosingElement.kind == ElementKind.GENERATIVE_CONSTRUCTOR_BODY ||
-                enclosingElement.kind == ElementKind.GENERATIVE_CONSTRUCTOR ||
-                enclosingElement.kind == ElementKind.CLASS ||
-                enclosingElement.kind == ElementKind.FUNCTION ||
-                enclosingElement.kind == ElementKind.GETTER ||
-                enclosingElement.kind == ElementKind.SETTER);
-        enclosingElement = enclosingElement.enclosingElement) {
-      // TODO(johnniwinther): Simplify computed names.
-      if (enclosingElement.isGenerativeConstructor ||
-          enclosingElement.isGenerativeConstructorBody ||
-          enclosingElement.isFactoryConstructor) {
-        ConstructorElement constructor = enclosingElement;
-        parts = parts.prepend(utils.reconstructConstructorName(constructor));
-      } else {
-        String surroundingName =
-            Elements.operatorNameToIdentifier(enclosingElement.name);
-        parts = parts.prepend(surroundingName);
-      }
-      // A generative constructors's parent is the class; the class name is
-      // already part of the generative constructor's name.
-      if (enclosingElement.kind == ElementKind.GENERATIVE_CONSTRUCTOR) break;
-    }
-    StringBuffer sb = new StringBuffer();
-    parts.printOn(sb, '_');
-    return sb.toString();
-  }
-
-  JavaScriptBackend get backend => compiler.backend;
-
-  ClosureClassMap globalizeClosure(
-      FunctionExpression node, LocalFunctionElement element) {
-    String closureName = computeClosureName(element);
-    ClosureClassElement globalizedElement =
-        new ClosureClassElement(node, closureName, compiler, element);
-    MethodElement callElement = new SynthesizedCallMethodElementX(
-        Identifiers.call, element, globalizedElement, node, elements);
-    // Extend [globalizedElement] as an instantiated class in the closed world.
-    closedWorldRefiner.registerClosureClass(globalizedElement);
-    backend.mirrorsDataBuilder.maybeMarkClosureAsNeededForReflection(
-        globalizedElement, callElement, element);
-    MemberElement enclosing = element.memberContext;
-    enclosing.nestedClosures.add(callElement);
-    globalizedElement.addMember(callElement, reporter);
-    globalizedElement.computeAllClassMembers(compiler.resolution);
-    // The nested function's 'this' is the same as the one for the outer
-    // function. It could be [null] if we are inside a static method.
-    ThisLocal thisElement = closureData.thisLocal;
-
-    return new ClosureClassMap(
-        element, globalizedElement, callElement, thisElement);
-  }
-
-  void visitInvokable(
-      ExecutableElement element, Node node, void visitChildren()) {
-    bool oldInsideClosure = insideClosure;
-    Element oldFunctionElement = executableContext;
-    ClosureClassMap oldClosureData = closureData;
-
-    insideClosure = outermostElement != null;
-    LocalFunctionElement closure;
-    executableContext = element;
-    bool needsRti = false;
-    if (insideClosure) {
-      closure = element;
-      closures.add(node);
-      nodeMappingCache[node] = closureData = globalizeClosure(node, closure);
-      needsRti = compiler.options.enableTypeAssertions ||
-          rtiNeed.localFunctionNeedsSignature(closure);
-    } else {
-      outermostElement = element;
-      ThisLocal thisElement = null;
-      if (element.isInstanceMember || element.isGenerativeConstructor) {
-        MemberElement member = element;
-        thisElement = new ThisLocalVariable(member);
-      }
-      closureData = new ClosureClassMap(null, null, null, thisElement);
-      memberMappingCache[element] = closureData;
-      memberMappingCache[element.declaration] = closureData;
-      if (element is MethodElement) {
-        needsRti = compiler.options.enableTypeAssertions ||
-            rtiNeed.methodNeedsSignature(element);
-      }
-    }
-    if (closureData.callMethod != null) {
-      memberMappingCache[closureData.callMethod] = closureData;
-    }
-
-    inNewScope(node, () {
-      // If the method needs RTI, or checked mode is set, we need to
-      // escape the potential type variables used in that closure.
-      if (needsRti) {
-        analyzeTypeVariables(element.type);
-      }
-
-      visitChildren();
-    });
-
-    ClosureClassMap savedClosureData = closureData;
-    bool savedInsideClosure = insideClosure;
-
-    // Restore old values.
-    insideClosure = oldInsideClosure;
-    closureData = oldClosureData;
-    executableContext = oldFunctionElement;
-
-    // Mark all free variables as captured and use them in the outer function.
-    Iterable<Local> freeVariables = savedClosureData.freeVariables;
-    assert(freeVariables.isEmpty || savedInsideClosure);
-    for (Local freeVariable in freeVariables) {
-      addCapturedVariable(node, freeVariable);
-      useLocal(freeVariable);
-    }
-  }
-
-  visitFunctionExpression(FunctionExpression node) {
-    Element element = elements[node];
-
-    if (element.isRegularParameter) {
-      // TODO(ahe): This is a hack. This method should *not* call
-      // visitChildren.
-      return node.name.accept(this);
-    }
-
-    visitInvokable(element, node, () {
-      // TODO(ahe): This is problematic. The backend should not repeat
-      // the work of the resolver. It is the resolver's job to create
-      // parameters, etc. Other phases should only visit statements.
-      if (node.parameters != null) node.parameters.accept(this);
-      if (node.initializers != null) node.initializers.accept(this);
-      if (node.body != null) node.body.accept(this);
-    });
-  }
-
-  visitTryStatement(TryStatement node) {
-    // TODO(ngeoffray): implement finer grain state.
-    bool oldInTryStatement = inTryStatement;
-    inTryStatement = true;
-    node.visitChildren(this);
-    inTryStatement = oldInTryStatement;
-  }
-
-  visitCatchBlock(CatchBlock node) {
-    if (node.type != null) {
-      // The "on T" clause may contain type variables.
-      analyzeType(elements.getType(node.type));
-    }
-    if (node.formals != null) {
-      node.formals.visitChildren(this);
-    }
-    node.block.accept(this);
-  }
-
-  visitAsyncForIn(AsyncForIn node) {
-    // An `await for` loop is enclosed in an implicit try-finally.
-    bool oldInTryStatement = inTryStatement;
-    inTryStatement = true;
-    visitLoop(node);
-    inTryStatement = oldInTryStatement;
-  }
-}
-
 /// A type variable as a local variable.
 class TypeVariableLocal implements Local {
   final TypeVariableType typeVariable;
@@ -1555,16 +284,6 @@
   }
 }
 
-class TypeVariableLocalVariable extends TypeVariableLocal
-    implements LocalVariable {
-  final ExecutableElement executableContext;
-  final MemberElement memberContext;
-
-  TypeVariableLocalVariable(
-      TypeVariableType typeVariable, this.executableContext, this.memberContext)
-      : super(typeVariable);
-}
-
 ///
 /// Move the below classes to a JS model eventually.
 ///
diff --git a/pkg/compiler/lib/src/common/backend_api.dart b/pkg/compiler/lib/src/common/backend_api.dart
index 0ab7475..5c38952 100644
--- a/pkg/compiler/lib/src/common/backend_api.dart
+++ b/pkg/compiler/lib/src/common/backend_api.dart
@@ -5,31 +5,8 @@
 library dart2js.backend_api;
 
 import '../common/resolution.dart' show ResolutionImpact;
-import '../constants/expressions.dart' show ConstantExpression;
-import '../elements/resolution_types.dart'
-    show ResolutionDartType, ResolutionInterfaceType;
-import '../tree/tree.dart' show Node;
 import '../universe/world_impact.dart' show WorldImpact;
 
-/// Interface for resolving native data for a target specific element.
-abstract class NativeRegistry {
-  /// Registers [nativeData] as part of the resolution impact.
-  void registerNativeData(dynamic nativeData);
-}
-
-/// Interface for resolving calls to foreign functions.
-abstract class ForeignResolver {
-  /// Returns the constant expression of [node], or `null` if [node] is not
-  /// a constant expression.
-  ConstantExpression getConstant(Node node);
-
-  /// Registers [type] as instantiated.
-  void registerInstantiatedType(ResolutionInterfaceType type);
-
-  /// Resolves [typeName] to a type in the context of [node].
-  ResolutionDartType resolveTypeFromString(Node node, String typeName);
-}
-
 /// Target-specific transformation for resolution world impacts.
 ///
 /// This processes target-agnostic [ResolutionImpact]s and creates [WorldImpact]
diff --git a/pkg/compiler/lib/src/common/names.dart b/pkg/compiler/lib/src/common/names.dart
index 327c9e5..5d1116c 100644
--- a/pkg/compiler/lib/src/common/names.dart
+++ b/pkg/compiler/lib/src/common/names.dart
@@ -222,10 +222,6 @@
   static final Uri dart__foreign_helper =
       new Uri(scheme: 'dart', path: '_foreign_helper');
 
-  /// The URI for 'dart:_js_mirrors'.
-  static final Uri dart__js_mirrors =
-      new Uri(scheme: 'dart', path: '_js_mirrors');
-
   /// The URI for 'dart:_js_names'.
   static final Uri dart__js_names = new Uri(scheme: 'dart', path: '_js_names');
 
@@ -233,10 +229,6 @@
   static final Uri dart__js_embedded_names =
       new Uri(scheme: 'dart', path: '_js_embedded_names');
 
-  /// The URI for 'dart:_isolate_helper'.
-  static final Uri dart__isolate_helper =
-      new Uri(scheme: 'dart', path: '_isolate_helper');
-
   /// The URI for 'package:js'.
   static final Uri package_js = new Uri(scheme: 'package', path: 'js/js.dart');
 }
diff --git a/pkg/compiler/lib/src/common/resolution.dart b/pkg/compiler/lib/src/common/resolution.dart
index 3965ba8..b0eb1ac 100644
--- a/pkg/compiler/lib/src/common/resolution.dart
+++ b/pkg/compiler/lib/src/common/resolution.dart
@@ -4,64 +4,10 @@
 
 library dart2js.common.resolution;
 
-import '../common.dart';
-import '../compile_time_constants.dart';
 import '../constants/expressions.dart' show ConstantExpression;
-import '../constants/values.dart' show ConstantValue;
-import '../common_elements.dart' show CommonElements, ElementEnvironment;
-import '../elements/resolution_types.dart' show ResolutionDartType, Types;
-import '../elements/elements.dart'
-    show
-        ClassElement,
-        Element,
-        ExecutableElement,
-        FunctionElement,
-        FunctionSignature,
-        LibraryElement,
-        MemberElement,
-        MetadataAnnotation,
-        MethodElement,
-        ResolvedAst,
-        TypedefElement;
 import '../elements/entities.dart';
-import '../enqueue.dart' show ResolutionEnqueuer;
-import '../id_generator.dart';
-import '../js_backend/backend.dart' show JavaScriptBackend;
-import '../mirrors_used.dart';
-import '../options.dart' show CompilerOptions;
-import '../parser/element_listener.dart' show ScannerOptions;
-import '../parser/parser_task.dart';
-import '../scanner/scanner_task.dart';
-import '../patch_parser.dart';
-import '../resolution/resolution.dart';
-import '../tree/tree.dart' show Send, TypeAnnotation;
-import '../universe/call_structure.dart' show CallStructure;
 import '../universe/world_impact.dart' show WorldImpact;
 import '../universe/feature.dart';
-import 'backend_api.dart';
-import 'work.dart' show WorkItem;
-
-/// [WorkItem] used exclusively by the [ResolutionEnqueuer].
-abstract class ResolutionWorkItem implements WorkItem {
-  factory ResolutionWorkItem(Resolution resolution, MemberElement element) =
-      _ResolutionWorkItem;
-}
-
-class _ResolutionWorkItem extends WorkItem implements ResolutionWorkItem {
-  bool _isAnalyzed = false;
-  final MemberElement element;
-  final Resolution resolution;
-
-  _ResolutionWorkItem(this.resolution, this.element);
-
-  WorldImpact run() {
-    assert(!_isAnalyzed,
-        failedAt(element, 'Element ${element} has already been analyzed'));
-    WorldImpact impact = resolution.computeWorldImpact(element);
-    _isAnalyzed = true;
-    return impact;
-  }
-}
 
 class ResolutionImpact extends WorldImpact {
   const ResolutionImpact();
@@ -76,190 +22,3 @@
 
   Iterable<dynamic> get nativeData => const <dynamic>[];
 }
-
-/// Interface defining target-specific behavior for resolution.
-abstract class Target {
-  /// Returns `true` if [library] is a target specific library whose members
-  /// have special treatment, such as being allowed to extends blacklisted
-  /// classes or members being eagerly resolved.
-  bool isTargetSpecificLibrary(LibraryElement element);
-
-  /// Resolve target specific information for [element] and register it with
-  /// [registry].
-  void resolveNativeMember(MemberElement element, NativeRegistry registry) {}
-
-  /// Processes [element] for resolution and returns the [MethodElement] that
-  /// defines the implementation of [element].
-  MethodElement resolveExternalFunction(MethodElement element) => element;
-
-  /// Called when resolving a call to a foreign function. If a non-null value
-  /// is returned, this is stored as native data for [node] in the resolved
-  /// AST.
-  dynamic resolveForeignCall(Send node, Element element,
-      CallStructure callStructure, ForeignResolver resolver) {
-    return null;
-  }
-
-  /// Returns `true` if [element] is a default implementation of `noSuchMethod`
-  /// used by the target.
-  bool isDefaultNoSuchMethod(MethodElement element);
-
-  /// Returns the default superclass for the given [element] in this target.
-  ClassElement defaultSuperclass(ClassElement element);
-
-  /// Returns `true` if [element] is a native class, that is, that the
-  /// corresponding entity already exists in the target language.
-  bool isNativeClass(ClassEntity element) => false;
-
-  /// Returns `true` if [element] is a foreign element, that is, that the
-  /// backend has specialized handling for the element.
-  bool isForeign(Element element) => false;
-
-  /// Returns `true` if this target supports async/await.
-  bool get supportsAsyncAwait => true;
-}
-
-// TODO(johnniwinther): Rename to `Resolver` or `ResolverContext`.
-abstract class Resolution {
-  ParsingContext get parsingContext;
-  DiagnosticReporter get reporter;
-  ElementEnvironment get elementEnvironment;
-  CommonElements get commonElements;
-  Types get types;
-  Target get target;
-  ResolverTask get resolver;
-  ResolutionEnqueuer get enqueuer;
-  CompilerOptions get options;
-  IdGenerator get idGenerator;
-  ConstantEnvironment get constants;
-  MirrorUsageAnalyzerTask get mirrorUsageAnalyzerTask;
-
-  /// Whether internally we computed the constant for the [proxy] variable
-  /// defined in dart:core (used only for testing).
-  // TODO(sigmund): delete, we need a better way to test this.
-  bool get wasProxyConstantComputedTestingOnly;
-
-  /// If set to `true` resolution caches will not be cleared. Use this only for
-  /// testing.
-  bool retainCachesForTesting;
-
-  void resolveTypedef(TypedefElement typdef);
-  void resolveClass(ClassElement cls);
-  void resolveMetadataAnnotation(MetadataAnnotation metadataAnnotation);
-  FunctionSignature resolveSignature(FunctionElement function);
-  ResolutionDartType resolveTypeAnnotation(
-      Element element, TypeAnnotation node);
-
-  /// Returns `true` if [element] has been resolved.
-  bool hasBeenResolved(Element element);
-
-  /// Resolve [element] if it has not already been resolved.
-  void ensureResolved(Element element);
-
-  /// Ensure the resolution of all members of [element].
-  void ensureClassMembers(ClassElement element);
-
-  /// Registers that [element] has a compile time error.
-  ///
-  /// The error itself is given in [message].
-  void registerCompileTimeError(Element element, DiagnosticMessage message);
-
-  ResolutionWorkItem createWorkItem(MemberElement element);
-
-  /// Returns `true` if [element] as a fully computed [ResolvedAst].
-  bool hasResolvedAst(ExecutableElement element);
-
-  /// Returns the `ResolvedAst` for the [element].
-  ResolvedAst getResolvedAst(ExecutableElement element);
-
-  /// Returns `true` if the [ResolutionImpact] for [element] is cached.
-  bool hasResolutionImpact(MemberElement element);
-
-  /// Returns the precomputed [ResolutionImpact] for [element].
-  ResolutionImpact getResolutionImpact(MemberElement element);
-
-  /// Returns the [ResolvedAst] for [element], computing it if necessary.
-  ResolvedAst computeResolvedAst(MemberElement element);
-
-  /// Returns the precomputed [WorldImpact] for [element].
-  WorldImpact getWorldImpact(MemberElement element);
-
-  /// Computes the [WorldImpact] for [element].
-  WorldImpact computeWorldImpact(MemberElement element);
-
-  WorldImpact transformResolutionImpact(
-      MemberElement element, ResolutionImpact resolutionImpact);
-
-  /// Removes the [WorldImpact] for [element] from the resolution cache. Later
-  /// calls to [getWorldImpact] or [computeWorldImpact] returns an empty impact.
-  void uncacheWorldImpact(MemberElement element);
-
-  /// Removes the [WorldImpact]s for all [Element]s in the resolution cache. ,
-  /// Later calls to [getWorldImpact] or [computeWorldImpact] returns an empty
-  /// impact.
-  void emptyCache();
-
-  /// Returns `true` if [value] is the top-level [proxy] annotation from the
-  /// core library.
-  bool isProxyConstant(ConstantValue value);
-
-  // TODO(het): Remove this once we move to the kernel-based frontend. This is
-  // an escape hatch for types that can't be added to an impact. For example,
-  // resolving a method signature will register the classes seen in the
-  // signature.
-  @deprecated
-  void registerClass(ClassEntity cls);
-}
-
-/// A container of commonly used dependencies for tasks that involve parsing.
-abstract class ParsingContext {
-  factory ParsingContext(
-      DiagnosticReporter reporter,
-      ParserTask parser,
-      ScannerTask scanner,
-      PatchParserTask patchParser,
-      JavaScriptBackend backend) = _ParsingContext;
-
-  DiagnosticReporter get reporter;
-  ParserTask get parser;
-  ScannerTask get scanner;
-  PatchParserTask get patchParser;
-
-  /// Use [patchParser] directly instead.
-  @deprecated
-  void parsePatchClass(ClassElement cls);
-
-  /// Use [parser] and measure directly instead.
-  @deprecated
-  measure(f());
-
-  /// Get the [ScannerOptions] to scan the given [element].
-  ScannerOptions getScannerOptionsFor(Element element);
-}
-
-class _ParsingContext implements ParsingContext {
-  final DiagnosticReporter reporter;
-  final ParserTask parser;
-  final ScannerTask scanner;
-  final PatchParserTask patchParser;
-  final JavaScriptBackend backend;
-
-  _ParsingContext(
-      this.reporter, this.parser, this.scanner, this.patchParser, this.backend);
-
-  @override
-  measure(f()) => parser.measure(f);
-
-  @override
-  void parsePatchClass(ClassElement cls) {
-    patchParser.measure(() {
-      if (cls.isPatch) {
-        patchParser.parsePatchClassNode(cls);
-      }
-    });
-  }
-
-  @override
-  ScannerOptions getScannerOptionsFor(Element element) => new ScannerOptions(
-      canUseNative: backend.canLibraryUseNative(element.library));
-}
diff --git a/pkg/compiler/lib/src/common_elements.dart b/pkg/compiler/lib/src/common_elements.dart
index ff7d0d7..0e83adc 100644
--- a/pkg/compiler/lib/src/common_elements.dart
+++ b/pkg/compiler/lib/src/common_elements.dart
@@ -137,10 +137,6 @@
   LibraryEntity get foreignLibrary =>
       _foreignLibrary ??= _env.lookupLibrary(Uris.dart__foreign_helper);
 
-  LibraryEntity _isolateHelperLibrary;
-  LibraryEntity get isolateHelperLibrary =>
-      _isolateHelperLibrary ??= _env.lookupLibrary(Uris.dart__isolate_helper);
-
   /// Reference to the internal library to lookup functions to always inline.
   LibraryEntity _internalLibrary;
   LibraryEntity get internalLibrary => _internalLibrary ??=
@@ -599,19 +595,6 @@
       _asyncStarStreamControllerFactory ??=
           _findAsyncHelperFunction('_makeAsyncStarStreamController');
 
-  // From dart:mirrors
-  FunctionEntity _findMirrorsFunction(String name) {
-    LibraryEntity library = _env.lookupLibrary(Uris.dart__js_mirrors);
-    if (library == null) return null;
-    return _env.lookupLibraryMember(library, name, required: true);
-  }
-
-  /// Holds the method "disableTreeShaking" in js_mirrors when
-  /// dart:mirrors has been loaded.
-  FunctionEntity _disableTreeShakingMarker;
-  FunctionEntity get disableTreeShakingMarker =>
-      _disableTreeShakingMarker ??= _findMirrorsFunction('disableTreeShaking');
-
   /// Holds the method "preserveNames" in js_mirrors when
   /// dart:mirrors has been loaded.
   FunctionEntity _preserveNamesMarker;
@@ -625,19 +608,6 @@
     return _preserveNamesMarker;
   }
 
-  /// Holds the method "preserveMetadata" in js_mirrors when
-  /// dart:mirrors has been loaded.
-  FunctionEntity _preserveMetadataMarker;
-  FunctionEntity get preserveMetadataMarker =>
-      _preserveMetadataMarker ??= _findMirrorsFunction('preserveMetadata');
-
-  /// Holds the method "preserveLibraryNames" in js_mirrors when
-  /// dart:mirrors has been loaded.
-  FunctionEntity _preserveLibraryNamesMarker;
-  FunctionEntity get preserveLibraryNamesMarker =>
-      _preserveLibraryNamesMarker ??=
-          _findMirrorsFunction('preserveLibraryNames');
-
   // From dart:_interceptors
   ClassEntity _findInterceptorsClass(String name) =>
       _findClass(interceptorsLibrary, name);
@@ -1442,8 +1412,6 @@
       ClassEntity cls, List<DartType> typeArguments);
 
   /// Returns the `dynamic` type.
-  // TODO(johnniwinther): Remove this when `ResolutionDynamicType` is no longer
-  // needed.
   DartType get dynamicType;
 
   /// Returns the 'raw type' of [cls]. That is, the instantiation of [cls]
diff --git a/pkg/compiler/lib/src/compile_time_constants.dart b/pkg/compiler/lib/src/compile_time_constants.dart
index 8a93589..9055af7 100644
--- a/pkg/compiler/lib/src/compile_time_constants.dart
+++ b/pkg/compiler/lib/src/compile_time_constants.dart
@@ -4,1459 +4,27 @@
 
 library dart2js.compile_time_constant_evaluator;
 
-import 'common/resolution.dart' show Resolution;
 import 'common/tasks.dart' show CompilerTask, Measurer;
-import 'common.dart';
-import 'compiler.dart' show Compiler;
-import 'constant_system_dart.dart';
 import 'constants/constant_system.dart';
-import 'constants/constructors.dart';
-import 'constants/evaluation.dart';
-import 'constants/expressions.dart';
-import 'constants/values.dart';
-import 'common_elements.dart' show CommonElements;
-import 'elements/elements.dart';
-import 'elements/types.dart' show DartTypes;
-import 'elements/modelx.dart' show ConstantVariableMixin;
-import 'elements/operators.dart';
-import 'elements/resolution_types.dart';
-import 'resolution/tree_elements.dart' show TreeElements;
-import 'resolution/deferred_load.dart' show AstDeferredLoadTask;
-import 'tree/tree.dart';
-import 'universe/call_structure.dart' show CallStructure;
-import 'util/util.dart' show Link;
+import 'elements/entities.dart';
 
 /// A [ConstantEnvironment] provides access for constants compiled for variable
 /// initializers.
 abstract class ConstantEnvironment {
   /// The [ConstantSystem] used by this environment.
   ConstantSystem get constantSystem;
-
-  /// Returns `true` if a value has been computed for [expression].
-  bool hasConstantValue(ConstantExpression expression);
-
-  /// Returns the constant value computed for [expression].
-  // TODO(johnniwinther): Support directly evaluation of [expression].
-  ConstantValue getConstantValue(ConstantExpression expression);
-
-  /// Returns the constant value for the initializer of [element].
-  @deprecated
-  ConstantValue getConstantValueForVariable(VariableElement element);
-}
-
-/// A class that can compile and provide constants for variables, nodes and
-/// metadata.
-abstract class ConstantCompiler extends ConstantEnvironment {
-  /// Compiles the compile-time constant for the initializer of [element], or
-  /// reports an error if the initializer is not a compile-time constant.
-  ///
-  /// Depending on implementation, the constant compiler might also compute
-  /// the compile-time constant for the backend interpretation of constants.
-  ///
-  /// The returned constant is always of the frontend interpretation.
-  ConstantExpression compileConstant(VariableElement element);
-
-  /// Computes the compile-time constant for the variable initializer,
-  /// if possible.
-  ConstantExpression compileVariable(VariableElement element);
-
-  /// Compiles the constant for [node].
-  ///
-  /// Reports an error if [node] is not a compile-time constant and
-  /// [enforceConst].
-  ///
-  /// If `!enforceConst`, then if [node] is a "runtime constant" (for example
-  /// a reference to a deferred constant) it will be returned - otherwise null
-  /// is returned.
-  ///
-  /// Depending on implementation, the constant compiler might also compute
-  /// the constant for the backend interpretation of constants.
-  ///
-  /// The returned constant is always of the frontend interpretation.
-  ConstantExpression compileNode(Node node, TreeElements elements,
-      {bool enforceConst: true});
-
-  /// Compiles the compile-time constant for the value [metadata], or reports an
-  /// error if the value is not a compile-time constant.
-  ///
-  /// Depending on implementation, the constant compiler might also compute
-  /// the compile-time constant for the backend interpretation of constants.
-  ///
-  /// The returned constant is always of the frontend interpretation.
-  ConstantExpression compileMetadata(
-      MetadataAnnotation metadata, Node node, TreeElements elements);
-
-  /// Evaluates [constant] and caches the result.
-  // TODO(johnniwinther): Remove when all constants are evaluated.
-  void evaluate(ConstantExpression constant);
 }
 
 /// A [BackendConstantEnvironment] provides access to constants needed for
 /// backend implementation.
 abstract class BackendConstantEnvironment extends ConstantEnvironment {
-  /// Returns the compile-time constant value associated with [node].
-  ///
-  /// Depending on implementation, the constant might be stored in [elements].
-  ConstantValue getConstantValueForNode(Node node, TreeElements elements);
-
-  /// Returns the compile-time constant associated with [node].
-  ///
-  /// Depending on implementation, the constant might be stored in [elements].
-  ConstantExpression getConstantForNode(Node node, TreeElements elements);
-
-  /// Returns the compile-time constant value of [metadata].
-  ConstantValue getConstantValueForMetadata(MetadataAnnotation metadata);
-
   /// Register that [element] needs lazy initialization.
-  void registerLazyStatic(FieldElement element);
+  void registerLazyStatic(FieldEntity element);
 }
 
 /// Interface for the task that compiles the constant environments for the
 /// frontend and backend interpretation of compile-time constants.
 abstract class ConstantCompilerTask extends CompilerTask
-    implements ConstantCompiler {
+    implements ConstantEnvironment {
   ConstantCompilerTask(Measurer measurer) : super(measurer);
-
-  /// Copy all cached constant values from [task].
-  ///
-  /// This is a hack to support reuse cached compilers in memory_compiler.
-  // TODO(johnniwinther): Remove this when values are computed from the
-  // expressions.
-  void copyConstantValues(ConstantCompilerTask task);
-}
-
-/**
- * The [ConstantCompilerBase] is provides base implementation for compilation of
- * compile-time constants for both the Dart and JavaScript interpretation of
- * constants. It keeps track of compile-time constants for initializations of
- * global and static fields, and default values of optional parameters.
- */
-abstract class ConstantCompilerBase implements ConstantCompiler {
-  final Compiler compiler;
-  final ConstantSystem constantSystem;
-
-  /**
-   * Contains the initial values of fields and default values of parameters.
-   *
-   * Must contain all static and global initializations of const fields.
-   *
-   * May contain eagerly compiled initial values for statics and instance
-   * fields (if those are compile-time constants).
-   *
-   * May contain default parameter values of optional arguments.
-   *
-   * Invariant: The keys in this map are declarations.
-   */
-  // TODO(johnniwinther): Make this purely internal when no longer used by
-  // poi/forget_element_test.
-  final Map<VariableElement, ConstantExpression> initialVariableValues =
-      new Map<VariableElement, ConstantExpression>();
-
-  /** The set of variable elements that are in the process of being computed. */
-  final Set<VariableElement> pendingVariables = new Set<VariableElement>();
-
-  final Map<ConstantExpression, ConstantValue> constantValueMap =
-      <ConstantExpression, ConstantValue>{};
-
-  ConstantCompilerBase(this.compiler, this.constantSystem);
-
-  DiagnosticReporter get reporter => compiler.reporter;
-
-  CommonElements get commonElements => compiler.resolution.commonElements;
-
-  @override
-  @deprecated
-  ConstantValue getConstantValueForVariable(VariableElement element) {
-    ConstantExpression constant = initialVariableValues[element.declaration];
-    // TODO(johnniwinther): Support eager evaluation of the constant.
-    return constant != null ? getConstantValue(constant) : null;
-  }
-
-  ConstantExpression compileConstant(VariableElement element) {
-    return internalCompileVariable(element, true, true);
-  }
-
-  @override
-  void evaluate(ConstantExpression constant) {
-    constantValueMap.putIfAbsent(constant, () {
-      return constant.evaluate(
-          new AstEvaluationEnvironment(compiler), constantSystem);
-    });
-  }
-
-  ConstantExpression compileVariable(VariableElement element) {
-    return internalCompileVariable(element, false, true);
-  }
-
-  /// Compile [element] into a constant expression. If [isConst] is true,
-  /// then [element] is a constant variable. If [checkType] is true, then
-  /// report an error if [element] does not typecheck.
-  ConstantExpression internalCompileVariable(
-      VariableElement element, bool isConst, bool checkType) {
-    if (initialVariableValues.containsKey(element.declaration)) {
-      ConstantExpression result = initialVariableValues[element.declaration];
-      return result;
-    }
-    if (element.hasConstant) {
-      if (element.constant != null) {
-        assert(
-            hasConstantValue(element.constant),
-            failedAt(
-                element,
-                "Constant expression has not been evaluated: "
-                "${element.constant.toStructuredText()}."));
-      }
-      return element.constant;
-    }
-    AstElement currentElement = element.analyzableElement;
-    return reporter.withCurrentElement(element, () {
-      // TODO(johnniwinther): Avoid this eager analysis.
-      compiler.resolution.ensureResolved(currentElement.declaration);
-
-      ConstantExpression constant = compileVariableWithDefinitions(
-          element, currentElement.resolvedAst.elements,
-          isConst: isConst, checkType: checkType);
-      return constant;
-    });
-  }
-
-  /**
-   * Returns the a compile-time constant if the variable could be compiled
-   * eagerly. If the variable needs to be initialized lazily returns `null`.
-   * If the variable is `const` but cannot be compiled eagerly reports an
-   * error.
-   */
-  ConstantExpression compileVariableWithDefinitions(
-      ConstantVariableMixin element, TreeElements definitions,
-      {bool isConst: false, bool checkType: true}) {
-    Node node = element.node;
-    if (pendingVariables.contains(element)) {
-      if (isConst) {
-        reporter.reportErrorMessage(
-            node, MessageKind.CYCLIC_COMPILE_TIME_CONSTANTS);
-        ConstantExpression expression = new ErroneousConstantExpression();
-        constantValueMap[expression] = constantSystem.createNull();
-        return expression;
-      }
-      return null;
-    }
-    pendingVariables.add(element);
-
-    Expression initializer = element.initializer;
-    ConstantExpression expression;
-    if (initializer == null) {
-      // No initial value.
-      expression = new NullConstantExpression();
-      constantValueMap[expression] = constantSystem.createNull();
-    } else {
-      expression = compileNodeWithDefinitions(initializer, definitions,
-          isConst: isConst);
-      if (compiler.options.enableTypeAssertions &&
-          checkType &&
-          expression != null &&
-          element.isField) {
-        ResolutionDartType elementType = element.type;
-        ConstantValue value = getConstantValue(expression);
-        if (elementType.isMalformed && !value.isNull) {
-          if (isConst) {
-            // TODO(johnniwinther): Check that it is possible to reach this
-            // point in a situation where `elementType is! MalformedType`.
-            if (elementType is MalformedType) {
-              ErroneousElement element = elementType.element;
-              reporter.reportErrorMessage(
-                  node, element.messageKind, element.messageArguments);
-            }
-          } else {
-            // We need to throw an exception at runtime.
-            expression = null;
-          }
-        } else {
-          ResolutionDartType constantType = value.getType(commonElements);
-          if (!constantSystem.isSubtype(
-              compiler.resolution.types, constantType, elementType)) {
-            if (isConst) {
-              reporter.reportErrorMessage(node, MessageKind.NOT_ASSIGNABLE,
-                  {'fromType': constantType, 'toType': elementType});
-            } else {
-              // If the field cannot be lazily initialized, we will throw
-              // the exception at runtime.
-              expression = null;
-            }
-          }
-        }
-      }
-    }
-    if (expression != null) {
-      element.constant = expression;
-      initialVariableValues[element.declaration] = expression;
-    } else {
-      assert(
-          !isConst,
-          failedAt(
-              element, "Variable $element does not compile to a constant."));
-    }
-    pendingVariables.remove(element);
-    return expression;
-  }
-
-  void cacheConstantValue(ConstantExpression expression, ConstantValue value) {
-    constantValueMap[expression] = value;
-  }
-
-  ConstantExpression compileNodeWithDefinitions(
-      Node node, TreeElements definitions,
-      {bool isConst: true}) {
-    assert(node != null);
-    CompileTimeConstantEvaluator evaluator = new CompileTimeConstantEvaluator(
-        this, definitions, compiler,
-        isConst: isConst);
-    AstConstant constant = evaluator.evaluate(node);
-    if (constant != null) {
-      cacheConstantValue(constant.expression, constant.value);
-      return constant.expression;
-    }
-    return null;
-  }
-
-  bool hasConstantValue(ConstantExpression expression) {
-    return constantValueMap.containsKey(expression);
-  }
-
-  @override
-  ConstantValue getConstantValue(ConstantExpression expression) {
-    assert(
-        expression != null,
-        failedAt(CURRENT_ELEMENT_SPANNABLE,
-            "ConstantExpression is null in getConstantValue."));
-    ConstantValue value = constantValueMap[expression];
-    if (value == null &&
-        expression != null &&
-        expression.kind == ConstantExpressionKind.ERRONEOUS) {
-      // TODO(johnniwinther): When the Dart constant system sees a constant
-      // expression as erroneous but the JavaScript constant system finds it ok
-      // we have store a constant value for the erroneous constant expression.
-      // Ensure the computed constant expressions are always the same; that only
-      // the constant values may be different.
-      value = new NullConstantValue();
-    }
-    return value;
-  }
-
-  ConstantExpression compileNode(Node node, TreeElements elements,
-      {bool enforceConst: true}) {
-    return compileNodeWithDefinitions(node, elements, isConst: enforceConst);
-  }
-
-  ConstantExpression compileMetadata(
-      MetadataAnnotation metadata, Node node, TreeElements elements) {
-    return compileNodeWithDefinitions(node, elements);
-  }
-}
-
-/// [ConstantCompiler] that uses the Dart semantics for the compile-time
-/// constant evaluation.
-class DartConstantCompiler extends ConstantCompilerBase {
-  DartConstantCompiler(Compiler compiler)
-      : super(compiler, const DartConstantSystem());
-
-  ConstantExpression getConstantForNode(Node node, TreeElements definitions) {
-    return definitions.getConstant(node);
-  }
-
-  ConstantExpression compileNodeWithDefinitions(
-      Node node, TreeElements definitions,
-      {bool isConst: true}) {
-    ConstantExpression constant = definitions.getConstant(node);
-    if (constant != null && hasConstantValue(constant)) {
-      return constant;
-    }
-    constant =
-        super.compileNodeWithDefinitions(node, definitions, isConst: isConst);
-    if (constant != null) {
-      definitions.setConstant(node, constant);
-    }
-    return constant;
-  }
-}
-
-// TODO(johnniwinther): Decouple the creation of [ConstExp] and [Constant] from
-// front-end AST in order to reuse the evaluation for the shared front-end.
-class CompileTimeConstantEvaluator extends Visitor<AstConstant> {
-  bool isEvaluatingConstant;
-  final ConstantCompilerBase handler;
-  final TreeElements elements;
-  final Compiler compiler;
-
-  Element get context => elements.analyzedElement;
-
-  CompileTimeConstantEvaluator(this.handler, this.elements, this.compiler,
-      {bool isConst: false})
-      : this.isEvaluatingConstant = isConst;
-
-  ConstantSystem get constantSystem => handler.constantSystem;
-  Resolution get resolution => compiler.resolution;
-  CommonElements get commonElements => resolution.commonElements;
-  DiagnosticReporter get reporter => compiler.reporter;
-
-  AstConstant evaluate(Node node) {
-    // TODO(johnniwinther): should there be a visitErrorNode?
-    if (node is ErrorNode) return new ErroneousAstConstant(context, node);
-    AstConstant result = node.accept(this);
-    assert(!isEvaluatingConstant || result != null,
-        failedAt(node, "No AstConstant computed for the node."));
-    return result;
-  }
-
-  AstConstant evaluateConstant(Node node) {
-    bool oldIsEvaluatingConstant = isEvaluatingConstant;
-    isEvaluatingConstant = true;
-    AstConstant result = node.accept(this);
-    isEvaluatingConstant = oldIsEvaluatingConstant;
-    assert(result != null,
-        failedAt(node, "No AstConstant computed for the node."));
-    return result;
-  }
-
-  AstConstant visitNode(Node node) {
-    return signalNotCompileTimeConstant(node);
-  }
-
-  AstConstant visitLiteralBool(LiteralBool node) {
-    return new AstConstant(
-        context,
-        node,
-        new BoolConstantExpression(node.value),
-        constantSystem.createBool(node.value));
-  }
-
-  AstConstant visitLiteralDouble(LiteralDouble node) {
-    return new AstConstant(
-        context,
-        node,
-        new DoubleConstantExpression(node.value),
-        constantSystem.createDouble(node.value));
-  }
-
-  AstConstant visitLiteralInt(LiteralInt node) {
-    return new AstConstant(context, node, new IntConstantExpression(node.value),
-        constantSystem.createInt(node.value));
-  }
-
-  AstConstant visitLiteralList(LiteralList node) {
-    if (!node.isConst) {
-      return signalNotCompileTimeConstant(node);
-    }
-    List<ConstantExpression> argumentExpressions = <ConstantExpression>[];
-    List<ConstantValue> argumentValues = <ConstantValue>[];
-    for (Link<Node> link = node.elements.nodes;
-        !link.isEmpty;
-        link = link.tail) {
-      AstConstant argument = evaluateConstant(link.head);
-      if (argument == null || argument.isError) {
-        return argument;
-      }
-      argumentExpressions.add(argument.expression);
-      argumentValues.add(argument.value);
-    }
-    ResolutionInterfaceType type = elements.getType(node);
-    return new AstConstant(
-        context,
-        node,
-        new ListConstantExpression(type, argumentExpressions),
-        constantSystem.createList(type, argumentValues));
-  }
-
-  AstConstant visitLiteralMap(LiteralMap node) {
-    if (!node.isConst) {
-      return signalNotCompileTimeConstant(node);
-    }
-    List<ConstantExpression> keyExpressions = <ConstantExpression>[];
-    List<ConstantExpression> valueExpressions = <ConstantExpression>[];
-    List<ConstantValue> keyValues = <ConstantValue>[];
-    Map<ConstantValue, ConstantValue> map = <ConstantValue, ConstantValue>{};
-    for (Link<Node> link = node.entries.nodes;
-        !link.isEmpty;
-        link = link.tail) {
-      LiteralMapEntry entry = link.head;
-      AstConstant key = evaluateConstant(entry.key);
-      if (key == null || key.isError) {
-        return key;
-      }
-      AstConstant value = evaluateConstant(entry.value);
-      if (value == null || value.isError) {
-        return value;
-      }
-      if (!map.containsKey(key.value)) {
-        keyValues.add(key.value);
-      } else {
-        reporter.reportWarningMessage(
-            entry.key, MessageKind.EQUAL_MAP_ENTRY_KEY);
-      }
-      keyExpressions.add(key.expression);
-      valueExpressions.add(value.expression);
-      map[key.value] = value.value;
-    }
-    ResolutionInterfaceType type = elements.getType(node);
-    return new AstConstant(
-        context,
-        node,
-        new MapConstantExpression(type, keyExpressions, valueExpressions),
-        constantSystem.createMap(
-            resolution.commonElements, type, keyValues, map.values.toList()));
-  }
-
-  AstConstant visitLiteralNull(LiteralNull node) {
-    return new AstConstant(context, node, new NullConstantExpression(),
-        constantSystem.createNull());
-  }
-
-  AstConstant visitLiteralString(LiteralString node) {
-    String text = node.dartString.slowToString();
-    return new AstConstant(context, node, new StringConstantExpression(text),
-        constantSystem.createString(text));
-  }
-
-  AstConstant visitStringJuxtaposition(StringJuxtaposition node) {
-    AstConstant left = evaluate(node.first);
-    AstConstant right = evaluate(node.second);
-    if (left == null || left.isError) {
-      return left;
-    }
-    if (right == null || right.isError) {
-      return right;
-    }
-    StringConstantValue leftValue = left.value;
-    StringConstantValue rightValue = right.value;
-    return new AstConstant(
-        context,
-        node,
-        new ConcatenateConstantExpression([left.expression, right.expression]),
-        constantSystem
-            .createString(leftValue.stringValue + rightValue.stringValue));
-  }
-
-  AstConstant visitStringInterpolation(StringInterpolation node) {
-    List<ConstantExpression> subexpressions = <ConstantExpression>[];
-    AstConstant initialString = evaluate(node.string);
-    if (initialString == null || initialString.isError) {
-      return initialString;
-    }
-    subexpressions.add(initialString.expression);
-    StringBuffer sb = new StringBuffer();
-    StringConstantValue initialStringValue = initialString.value;
-    sb.write(initialStringValue.stringValue);
-    for (StringInterpolationPart part in node.parts) {
-      AstConstant subexpression = evaluate(part.expression);
-      if (subexpression == null || subexpression.isError) {
-        return subexpression;
-      }
-      subexpressions.add(subexpression.expression);
-      ConstantValue expression = subexpression.value;
-      if (expression.isPrimitive) {
-        if (expression is IntConstantValue) {
-          sb.write(expression.intValue);
-        } else if (expression is DoubleConstantValue) {
-          sb.write(expression.doubleValue);
-        } else if (expression is StringConstantValue) {
-          sb.write(expression.stringValue);
-        } else if (expression is BoolConstantValue) {
-          sb.write(expression.boolValue);
-        } else if (expression is NullConstantValue) {
-          sb.write(null);
-        }
-      } else {
-        // TODO(johnniwinther): Specialize message to indicated that the problem
-        // is not constness but the types of the const expressions.
-        return signalNotCompileTimeConstant(part.expression);
-      }
-      AstConstant partString = evaluate(part.string);
-      if (partString == null) return null;
-      subexpressions.add(partString.expression);
-      StringConstantValue partStringValue = partString.value;
-      sb.write(partStringValue.stringValue);
-    }
-    return new AstConstant(
-        context,
-        node,
-        new ConcatenateConstantExpression(subexpressions),
-        constantSystem.createString(sb.toString()));
-  }
-
-  AstConstant visitLiteralSymbol(LiteralSymbol node) {
-    ResolutionInterfaceType type = commonElements.symbolImplementationType;
-    String text = node.slowNameString;
-    List<AstConstant> arguments = <AstConstant>[
-      new AstConstant(context, node, new StringConstantExpression(text),
-          constantSystem.createString(text))
-    ];
-    ConstructorElement constructor =
-        resolution.commonElements.symbolConstructorTarget;
-    AstConstant constant = createConstructorInvocation(
-        node, type, constructor, CallStructure.ONE_ARG,
-        normalizedArguments: arguments);
-    return new AstConstant(
-        context, node, new SymbolConstantExpression(text), constant.value);
-  }
-
-  ConstantValue makeTypeConstant(ResolutionDartType elementType) {
-    return constantSystem.createType(resolution.commonElements, elementType);
-  }
-
-  /// Returns true if the prefix of the send resolves to a deferred import
-  /// prefix.
-  bool isDeferredUse(Send send) {
-    if (send == null) return false;
-    AstDeferredLoadTask deferredLoadTask = compiler.deferredLoadTask;
-    return deferredLoadTask.deferredImportElement(send, elements) != null;
-  }
-
-  AstConstant visitIdentifier(Identifier node) {
-    Element element = elements[node];
-    if (Elements.isClass(element) || Elements.isTypedef(element)) {
-      TypeDeclarationElement typeDeclarationElement = element;
-      ResolutionDartType type = typeDeclarationElement.rawType;
-      return new AstConstant(
-          element,
-          node,
-          new TypeConstantExpression(type, typeDeclarationElement.name),
-          makeTypeConstant(type));
-    }
-    return signalNotCompileTimeConstant(node);
-  }
-
-  // TODO(floitsch): provide better error-messages.
-  AstConstant visitSend(Send send) {
-    Element element = elements[send];
-    if (send.isPropertyAccess) {
-      AstConstant result;
-      if (Elements.isStaticOrTopLevelFunction(element)) {
-        MethodElement function = element;
-        function.computeType(resolution);
-        result = new AstConstant(
-            context,
-            send,
-            new FunctionConstantExpression(function, function.type),
-            new FunctionConstantValue(function, function.type));
-      } else if (Elements.isStaticOrTopLevelField(element)) {
-        ConstantExpression elementExpression;
-        if (element.isConst) {
-          elementExpression = handler.compileConstant(element);
-        } else if (element.isFinal && !isEvaluatingConstant) {
-          elementExpression = handler.compileVariable(element);
-        }
-        if (elementExpression != null) {
-          FieldElement field = element;
-          result = new AstConstant(
-              context,
-              send,
-              new FieldConstantExpression(field),
-              handler.getConstantValue(elementExpression));
-        }
-      } else if (Elements.isClass(element) || Elements.isTypedef(element)) {
-        assert(elements.isTypeLiteral(send));
-        ResolutionDartType elementType = elements.getTypeLiteralType(send);
-        result = new AstConstant(
-            context,
-            send,
-            new TypeConstantExpression(elementType, element.name),
-            makeTypeConstant(elementType));
-      } else if (send.receiver != null) {
-        if (send.selector.asIdentifier().source == "length") {
-          AstConstant left = evaluate(send.receiver);
-          if (left != null && left.value.isString) {
-            StringConstantValue stringConstantValue = left.value;
-            String string = stringConstantValue.stringValue;
-            IntConstantValue length = constantSystem.createInt(string.length);
-            result = new AstConstant(context, send,
-                new StringLengthConstantExpression(left.expression), length);
-          }
-        }
-        // Fall through to error handling.
-      } else if (!Elements.isUnresolved(element) &&
-          element.isVariable &&
-          element.isConst) {
-        LocalVariableElement local = element;
-        ConstantExpression variableExpression = handler.compileConstant(local);
-        if (variableExpression != null) {
-          result = new AstConstant(
-              context,
-              send,
-              new LocalVariableConstantExpression(local),
-              handler.getConstantValue(variableExpression));
-        }
-      }
-      if (result == null) {
-        return signalNotCompileTimeConstant(send);
-      }
-      if (isDeferredUse(send)) {
-        if (isEvaluatingConstant) {
-          reporter.reportErrorMessage(
-              send, MessageKind.DEFERRED_COMPILE_TIME_CONSTANT);
-        }
-        AstDeferredLoadTask deferredLoadTask = compiler.deferredLoadTask;
-        ImportElement import =
-            deferredLoadTask.deferredImportElement(send, elements);
-        result = new AstConstant(
-            context,
-            send,
-            new DeferredConstantExpression(result.expression, import),
-            new DeferredConstantValue(result.value, import));
-        compiler.deferredLoadTask
-            .registerConstantDeferredUse(result.value, import);
-      }
-      return result;
-    } else if (send.isCall) {
-      if (element == resolution.commonElements.identicalFunction &&
-          send.argumentCount() == 2) {
-        AstConstant left = evaluate(send.argumentsNode.nodes.head);
-        AstConstant right = evaluate(send.argumentsNode.nodes.tail.head);
-        if (left == null || right == null) {
-          return null;
-        }
-        ConstantValue result =
-            constantSystem.identity.fold(left.value, right.value);
-        if (result != null) {
-          return new AstConstant(
-              context,
-              send,
-              new IdenticalConstantExpression(
-                  left.expression, right.expression),
-              result);
-        }
-      }
-      return signalNotCompileTimeConstant(send);
-    } else if (send.isPrefix) {
-      assert(send.isOperator);
-      AstConstant receiverConstant = evaluate(send.receiver);
-      if (receiverConstant == null || receiverConstant.isError) {
-        return receiverConstant;
-      }
-      Operator node = send.selector;
-      UnaryOperator operator = UnaryOperator.parse(node.source);
-      UnaryOperation operation = constantSystem.lookupUnary(operator);
-      if (operation == null) {
-        reporter.internalError(send.selector, "Unexpected operator.");
-      }
-      ConstantValue folded = operation.fold(receiverConstant.value);
-      if (folded == null) {
-        return signalNotCompileTimeConstant(send);
-      }
-      return new AstConstant(
-          context,
-          send,
-          new UnaryConstantExpression(operator, receiverConstant.expression),
-          folded);
-    } else if (send.isOperator && !send.isPostfix) {
-      assert(send.argumentCount() == 1);
-      AstConstant left = evaluate(send.receiver);
-      AstConstant right = evaluate(send.argumentsNode.nodes.head);
-      if (left == null || left.isError) {
-        return left;
-      }
-      if (right == null || right.isError) {
-        return right;
-      }
-      ConstantValue leftValue = left.value;
-      ConstantValue rightValue = right.value;
-      Operator node = send.selector.asOperator();
-      BinaryOperator operator = BinaryOperator.parse(node.source);
-      ConstantValue folded = null;
-      // operator is null when `node=="is"`
-      if (operator != null) {
-        switch (operator.kind) {
-          case BinaryOperatorKind.EQ:
-            if (leftValue.isPrimitive && rightValue.isPrimitive) {
-              folded = constantSystem.equal.fold(leftValue, rightValue);
-            }
-            break;
-          case BinaryOperatorKind.NOT_EQ:
-            if (leftValue.isPrimitive && rightValue.isPrimitive) {
-              BoolConstantValue areEquals =
-                  constantSystem.equal.fold(leftValue, rightValue);
-              if (areEquals == null) {
-                folded = null;
-              } else {
-                folded = areEquals.negate();
-              }
-            }
-            break;
-          default:
-            BinaryOperation operation = constantSystem.lookupBinary(operator);
-            if (operation != null) {
-              folded = operation.fold(leftValue, rightValue);
-            }
-        }
-      }
-      if (folded == null) {
-        return signalNotCompileTimeConstant(send);
-      }
-      return new AstConstant(
-          context,
-          send,
-          new BinaryConstantExpression(
-              left.expression, operator, right.expression),
-          folded);
-    }
-    return signalNotCompileTimeConstant(send);
-  }
-
-  AstConstant visitConditional(Conditional node) {
-    AstConstant condition = evaluate(node.condition);
-    if (condition == null || condition.isError) {
-      return condition;
-    } else if (!condition.value.isBool) {
-      ResolutionDartType conditionType =
-          condition.value.getType(commonElements);
-      if (isEvaluatingConstant) {
-        reporter.reportErrorMessage(node.condition, MessageKind.NOT_ASSIGNABLE,
-            {'fromType': conditionType, 'toType': commonElements.boolType});
-        return new ErroneousAstConstant(context, node);
-      }
-      return null;
-    }
-    AstConstant thenExpression = evaluate(node.thenExpression);
-    AstConstant elseExpression = evaluate(node.elseExpression);
-    if (thenExpression == null || thenExpression.isError) {
-      return thenExpression;
-    }
-    if (elseExpression == null || elseExpression.isError) {
-      return elseExpression;
-    }
-    BoolConstantValue boolCondition = condition.value;
-    return new AstConstant(
-        context,
-        node,
-        new ConditionalConstantExpression(condition.expression,
-            thenExpression.expression, elseExpression.expression),
-        boolCondition.boolValue ? thenExpression.value : elseExpression.value);
-  }
-
-  AstConstant visitSendSet(SendSet node) {
-    return signalNotCompileTimeConstant(node);
-  }
-
-  /**
-   * Returns the normalized list of constant arguments that are passed to the
-   * constructor including both the concrete arguments and default values for
-   * omitted optional arguments.
-   *
-   * Invariant: [target] must be an implementation element.
-   */
-  List<AstConstant> evaluateArgumentsToConstructor(
-      Node node,
-      CallStructure callStructure,
-      Link<Node> arguments,
-      ConstructorElement target,
-      {AstConstant compileArgument(Node node)}) {
-    assert(target.isImplementation, failedAt(node));
-
-    AstConstant compileDefaultValue(VariableElement element) {
-      ConstantExpression constant = handler.compileConstant(element);
-      return new AstConstant.fromDefaultValue(
-          element, constant, handler.getConstantValue(constant));
-    }
-
-    target.computeType(resolution);
-
-    if (!callStructure.signatureApplies(target.parameterStructure)) {
-      String name = Elements.constructorNameForDiagnostics(
-          target.enclosingClass.name, target.name);
-      reporter.reportErrorMessage(node,
-          MessageKind.INVALID_CONSTRUCTOR_ARGUMENTS, {'constructorName': name});
-
-      return new List<AstConstant>.filled(
-          target.functionSignature.parameterCount,
-          new ErroneousAstConstant(context, node));
-    }
-    return Elements.makeArgumentsList<AstConstant>(
-        callStructure, arguments, target, compileArgument, compileDefaultValue);
-  }
-
-  AstConstant visitNewExpression(NewExpression node) {
-    if (!node.isConst) {
-      return signalNotCompileTimeConstant(node);
-    }
-
-    Send send = node.send;
-    ConstructorElement constructor = elements[send];
-    if (Elements.isUnresolved(constructor)) {
-      return signalNotCompileTimeConstant(node);
-    }
-
-    // Deferred types can not be used in const instance creation expressions.
-    // Check if the constructor comes from a deferred library.
-    if (isDeferredUse(node.send.selector.asSend())) {
-      return signalNotCompileTimeConstant(node,
-          message: MessageKind.DEFERRED_COMPILE_TIME_CONSTANT_CONSTRUCTION);
-    }
-
-    ResolutionInterfaceType type = elements.getType(node);
-    CallStructure callStructure = elements.getSelector(send).callStructure;
-
-    return createConstructorInvocation(node, type, constructor, callStructure,
-        arguments: node.send.arguments);
-  }
-
-  AstConstant createConstructorInvocation(
-      Node node,
-      ResolutionInterfaceType type,
-      ConstructorElement constructor,
-      CallStructure callStructure,
-      {Link<Node> arguments,
-      List<AstConstant> normalizedArguments}) {
-    // TODO(ahe): This is nasty: we must eagerly analyze the
-    // constructor to ensure the redirectionTarget has been computed
-    // correctly.  Find a way to avoid this.
-    resolution.ensureResolved(constructor.declaration);
-
-    // The redirection chain of this element may not have been resolved through
-    // a post-process action, so we have to make sure it is done here.
-    compiler.resolver.resolveRedirectionChain(constructor, node);
-
-    bool isInvalid = false;
-    ResolutionInterfaceType constructedType = type;
-    ConstructorElement implementation;
-    if (constructor.isRedirectingFactory) {
-      if (constructor.isEffectiveTargetMalformed) {
-        isInvalid = true;
-      } else {
-        constructedType = constructor.computeEffectiveTargetType(type);
-        ConstructorElement target = constructor.effectiveTarget;
-        // The constructor must be an implementation to ensure that field
-        // initializers are handled correctly.
-        implementation = target.implementation;
-      }
-    } else {
-      // The constructor must be an implementation to ensure that field
-      // initializers are handled correctly.
-      implementation = constructor.implementation;
-      isInvalid = implementation.isMalformed;
-      if (implementation.isGenerativeConstructor &&
-          constructor.enclosingClass.isAbstract) {
-        isInvalid = true;
-      }
-    }
-    if (isInvalid) {
-      return signalNotCompileTimeConstant(node);
-    }
-
-    List<AstConstant> concreteArguments;
-    if (arguments != null) {
-      Map<Node, AstConstant> concreteArgumentMap = <Node, AstConstant>{};
-      for (Link<Node> link = arguments; !link.isEmpty; link = link.tail) {
-        Node argument = link.head;
-        NamedArgument namedArgument = argument.asNamedArgument();
-        if (namedArgument != null) {
-          argument = namedArgument.expression;
-        }
-        concreteArgumentMap[argument] = evaluateConstant(argument);
-      }
-
-      normalizedArguments = evaluateArgumentsToConstructor(
-          node, callStructure, arguments, implementation,
-          compileArgument: (node) => concreteArgumentMap[node]);
-      concreteArguments = concreteArgumentMap.values.toList();
-    } else {
-      assert(normalizedArguments != null);
-      concreteArguments = normalizedArguments;
-    }
-    if (constructor.isFromEnvironmentConstructor) {
-      return createFromEnvironmentConstant(node, constructedType, constructor,
-          callStructure, normalizedArguments, concreteArguments);
-    } else {
-      return makeConstructedConstant(
-          compiler,
-          handler,
-          context,
-          node,
-          type,
-          constructor,
-          constructedType,
-          implementation,
-          callStructure,
-          concreteArguments,
-          normalizedArguments);
-    }
-  }
-
-  AstConstant createFromEnvironmentConstant(
-      Node node,
-      ResolutionInterfaceType type,
-      ConstructorElement constructor,
-      CallStructure callStructure,
-      List<AstConstant> normalizedArguments,
-      List<AstConstant> concreteArguments) {
-    dynamic firstArgument = normalizedArguments[0].value;
-    ConstantValue defaultValue = normalizedArguments[1].value;
-
-    if (firstArgument.isNull) {
-      return reportNotCompileTimeConstant(
-          normalizedArguments[0].node, MessageKind.NULL_NOT_ALLOWED);
-    }
-
-    if (!firstArgument.isString) {
-      ResolutionDartType type = defaultValue.getType(commonElements);
-      return reportNotCompileTimeConstant(
-          normalizedArguments[0].node,
-          MessageKind.NOT_ASSIGNABLE,
-          {'fromType': type, 'toType': commonElements.stringType});
-    }
-
-    if (constructor.isIntFromEnvironmentConstructor &&
-        !(defaultValue.isNull || defaultValue.isInt)) {
-      ResolutionDartType type = defaultValue.getType(commonElements);
-      return reportNotCompileTimeConstant(
-          normalizedArguments[1].node,
-          MessageKind.NOT_ASSIGNABLE,
-          {'fromType': type, 'toType': commonElements.intType});
-    }
-
-    if (constructor.isBoolFromEnvironmentConstructor &&
-        !(defaultValue.isNull || defaultValue.isBool)) {
-      ResolutionDartType type = defaultValue.getType(commonElements);
-      return reportNotCompileTimeConstant(
-          normalizedArguments[1].node,
-          MessageKind.NOT_ASSIGNABLE,
-          {'fromType': type, 'toType': commonElements.boolType});
-    }
-
-    if (constructor.isStringFromEnvironmentConstructor &&
-        !(defaultValue.isNull || defaultValue.isString)) {
-      ResolutionDartType type = defaultValue.getType(commonElements);
-      return reportNotCompileTimeConstant(
-          normalizedArguments[1].node,
-          MessageKind.NOT_ASSIGNABLE,
-          {'fromType': type, 'toType': commonElements.stringType});
-    }
-
-    String name = firstArgument.stringValue;
-    String value = compiler.fromEnvironment(name);
-
-    AstConstant createEvaluatedConstant(ConstantValue value) {
-      ConstantExpression expression;
-      ConstantExpression name = concreteArguments[0].expression;
-      ConstantExpression defaultValue;
-      if (concreteArguments.length > 1) {
-        defaultValue = concreteArguments[1].expression;
-      }
-      if (constructor.isIntFromEnvironmentConstructor) {
-        expression =
-            new IntFromEnvironmentConstantExpression(name, defaultValue);
-      } else if (constructor.isBoolFromEnvironmentConstructor) {
-        expression =
-            new BoolFromEnvironmentConstantExpression(name, defaultValue);
-      } else if (constructor.isStringFromEnvironmentConstructor) {
-        expression =
-            new StringFromEnvironmentConstantExpression(name, defaultValue);
-      }
-      assert(expression != null);
-      return new AstConstant(context, node, expression, value);
-    }
-
-    if (value == null) {
-      return createEvaluatedConstant(defaultValue);
-    } else if (constructor.isIntFromEnvironmentConstructor) {
-      int number = int.parse(value, onError: (_) => null);
-      return createEvaluatedConstant(
-          (number == null) ? defaultValue : constantSystem.createInt(number));
-    } else if (constructor.isBoolFromEnvironmentConstructor) {
-      if (value == 'true') {
-        return createEvaluatedConstant(constantSystem.createBool(true));
-      } else if (value == 'false') {
-        return createEvaluatedConstant(constantSystem.createBool(false));
-      } else {
-        return createEvaluatedConstant(defaultValue);
-      }
-    } else {
-      assert(constructor.isStringFromEnvironmentConstructor);
-      return createEvaluatedConstant(constantSystem.createString(value));
-    }
-  }
-
-  static AstConstant makeConstructedConstant(
-      Compiler compiler,
-      ConstantCompilerBase handler,
-      Element context,
-      Node node,
-      ResolutionInterfaceType type,
-      ConstructorElement constructor,
-      ResolutionInterfaceType constructedType,
-      ConstructorElement target,
-      CallStructure callStructure,
-      List<AstConstant> concreteArguments,
-      List<AstConstant> normalizedArguments) {
-    if (target.isRedirectingFactory) {
-      // This happens in case of cyclic redirection.
-      assert(
-          compiler.compilationFailed,
-          failedAt(
-              node,
-              "makeConstructedConstant can only be called with the "
-              "effective target: $constructor"));
-      return new ErroneousAstConstant(context, node);
-    }
-    assert(
-        callStructure.signatureApplies(constructor.parameterStructure) ||
-            compiler.compilationFailed,
-        failedAt(
-            node,
-            "Call structure $callStructure does not apply to constructor "
-            "$constructor."));
-
-    ConstructorEvaluator evaluator =
-        new ConstructorEvaluator(constructedType, target, handler, compiler);
-    evaluator.evaluateConstructorFieldValues(normalizedArguments);
-    Map<FieldElement, AstConstant> fieldConstants =
-        evaluator.buildFieldConstants(target.enclosingClass);
-    Map<FieldElement, ConstantValue> fieldValues =
-        <FieldElement, ConstantValue>{};
-    fieldConstants.forEach((FieldElement field, AstConstant astConstant) {
-      fieldValues[field] = astConstant.value;
-    });
-    for (AstConstant fieldValue in fieldConstants.values) {
-      if (fieldValue.isError) {
-        return fieldValue;
-      }
-    }
-    return new AstConstant(
-        context,
-        node,
-        new ConstructedConstantExpression(type, constructor, callStructure,
-            concreteArguments.map((e) => e.expression).toList()),
-        new ConstructedConstantValue(constructedType, fieldValues));
-  }
-
-  AstConstant visitParenthesizedExpression(ParenthesizedExpression node) {
-    return node.expression.accept(this);
-  }
-
-  AstConstant reportNotCompileTimeConstant(Node node, MessageKind message,
-      [Map arguments = const {}]) {
-    reporter.reportErrorMessage(node, message, arguments);
-    return new AstConstant(context, node, new ErroneousConstantExpression(),
-        new NullConstantValue());
-  }
-
-  AstConstant signalNotCompileTimeConstant(Node node,
-      {MessageKind message: MessageKind.NOT_A_COMPILE_TIME_CONSTANT,
-      Map arguments: const {}}) {
-    if (isEvaluatingConstant) {
-      return reportNotCompileTimeConstant(node, message, arguments);
-    }
-    // Else we don't need to do anything. The final handler is only
-    // optimistically trying to compile constants. So it is normal that we
-    // sometimes see non-compile time constants.
-    // Simply return [:null:] which is used to propagate a failing
-    // compile-time compilation.
-    return null;
-  }
-}
-
-class ConstructorEvaluator extends CompileTimeConstantEvaluator {
-  final ResolutionInterfaceType constructedType;
-  final ConstructorElement constructor;
-  final Map<Element, AstConstant> definitions;
-  final Map<Element, AstConstant> fieldValues;
-  final ResolvedAst resolvedAst;
-
-  /**
-   * Documentation wanted -- johnniwinther
-   *
-   * Invariant: [constructor] must be an implementation element.
-   */
-  ConstructorEvaluator(
-      ResolutionInterfaceType this.constructedType,
-      ConstructorElement constructor,
-      ConstantCompiler handler,
-      Compiler compiler)
-      : this.constructor = constructor,
-        this.definitions = new Map<Element, AstConstant>(),
-        this.fieldValues = new Map<Element, AstConstant>(),
-        this.resolvedAst =
-            compiler.resolution.computeResolvedAst(constructor.declaration),
-        super(handler, null, compiler, isConst: true) {
-    assert(constructor.isImplementation, failedAt(constructor));
-  }
-
-  @override
-  Element get context => resolvedAst.element;
-
-  @override
-  TreeElements get elements => resolvedAst.elements;
-
-  AstConstant visitSend(Send send) {
-    Element element = elements[send];
-    if (Elements.isLocal(element)) {
-      AstConstant constant = definitions[element];
-      if (constant == null) {
-        reporter.internalError(send, "Local variable without value.");
-      }
-      return constant;
-    }
-    return super.visitSend(send);
-  }
-
-  void potentiallyCheckType(TypedElement element, AstConstant constant) {
-    if (compiler.options.enableTypeAssertions) {
-      ResolutionDartType elementType =
-          element.type.substByContext(constructedType);
-      ResolutionDartType constantType = constant.value.getType(commonElements);
-      if (!constantSystem.isSubtype(
-          compiler.resolution.types, constantType, elementType)) {
-        reporter.withCurrentElement(constant.element, () {
-          reporter.reportErrorMessage(constant.node, MessageKind.NOT_ASSIGNABLE,
-              {'fromType': constantType, 'toType': elementType});
-        });
-      }
-    }
-  }
-
-  void updateFieldValue(Node node, TypedElement element, AstConstant constant) {
-    potentiallyCheckType(element, constant);
-    fieldValues[element] = constant;
-  }
-
-  /**
-   * Given the arguments (a list of constants) assigns them to the parameters,
-   * updating the definitions map. If the constructor has field-initializer
-   * parameters (like [:this.x:]), also updates the [fieldValues] map.
-   */
-  void assignArgumentsToParameters(List<AstConstant> arguments) {
-    if (constructor.isMalformed) return;
-    // Assign arguments to parameters.
-    FunctionSignature signature = constructor.functionSignature;
-    int index = 0;
-    signature.orderedForEachParameter((_parameter) {
-      ParameterElement parameter = _parameter;
-      AstConstant argument = arguments[index++];
-      Node node = parameter.node;
-      if (parameter.isInitializingFormal) {
-        InitializingFormalElement initializingFormal = parameter;
-        updateFieldValue(node, initializingFormal.fieldElement, argument);
-      } else {
-        potentiallyCheckType(parameter, argument);
-      }
-      definitions[parameter] = argument;
-    });
-  }
-
-  void evaluateSuperOrRedirectSend(List<AstConstant> compiledArguments,
-      CallStructure callStructure, ConstructorElement targetConstructor) {
-    ResolutionInterfaceType type =
-        constructedType.asInstanceOf(targetConstructor.enclosingClass);
-    ConstructorEvaluator evaluator =
-        new ConstructorEvaluator(type, targetConstructor, handler, compiler);
-    evaluator.evaluateConstructorFieldValues(compiledArguments);
-    // Copy over the fieldValues from the super/redirect-constructor.
-    // No need to go through [updateFieldValue] because the
-    // assignments have already been checked in checked mode.
-    evaluator.fieldValues.forEach((key, value) => fieldValues[key] = value);
-  }
-
-  /**
-   * Runs through the initializers of the given [constructor] and updates
-   * the [fieldValues] map.
-   */
-  void evaluateConstructorInitializers() {
-    ResolvedAst resolvedAst = constructor.resolvedAst;
-    if (resolvedAst.kind != ResolvedAstKind.PARSED) {
-      List<AstConstant> compiledArguments = <AstConstant>[];
-
-      Function compileArgument = (element) => definitions[element];
-      Function compileConstant = handler.compileConstant;
-      FunctionElement target = constructor.definingConstructor.implementation;
-      Elements.addForwardingElementArgumentsToList(constructor,
-          compiledArguments, target, compileArgument, compileConstant);
-      CallStructure callStructure = new CallStructure(
-          target.functionSignature.parameterCount, target.type.namedParameters);
-      evaluateSuperOrRedirectSend(compiledArguments, callStructure, target);
-      return;
-    }
-    FunctionExpression functionNode = resolvedAst.node;
-    NodeList initializerList = functionNode.initializers;
-
-    bool foundSuperOrRedirect = false;
-
-    if (initializerList != null) {
-      for (Link<Node> link = initializerList.nodes;
-          !link.isEmpty;
-          link = link.tail) {
-        assert(link.head is Send);
-        if (link.head is! SendSet) {
-          // A super initializer or constructor redirection.
-          Send call = link.head;
-          FunctionElement target = elements[call];
-          if (!target.isMalformed) {
-            CallStructure callStructure =
-                elements.getSelector(call).callStructure;
-            List<AstConstant> compiledArguments =
-                evaluateArgumentsToConstructor(
-                    call, callStructure, call.arguments, target,
-                    compileArgument: evaluateConstant);
-            evaluateSuperOrRedirectSend(
-                compiledArguments, callStructure, target);
-          }
-          foundSuperOrRedirect = true;
-        } else {
-          // A field initializer.
-          SendSet init = link.head;
-          Link<Node> initArguments = init.arguments;
-          assert(!initArguments.isEmpty && initArguments.tail.isEmpty);
-          AstConstant fieldValue = evaluate(initArguments.head);
-          updateFieldValue(init, elements[init], fieldValue);
-        }
-      }
-    }
-
-    if (!foundSuperOrRedirect) {
-      // No super initializer found. Try to find the default constructor if
-      // the class is not Object.
-      ClassElement enclosingClass = constructor.enclosingClass;
-      ClassElement superClass = enclosingClass.superclass;
-      if (!enclosingClass.isObject) {
-        assert(superClass != null);
-        assert(superClass.isResolved);
-
-        FunctionElement targetConstructor =
-            superClass.lookupDefaultConstructor();
-        // If we do not find a default constructor, an error was reported
-        // already and compilation will fail anyway. So just ignore that case.
-        if (targetConstructor != null) {
-          CallStructure callStructure = CallStructure.NO_ARGS;
-          List<AstConstant> compiledArguments = evaluateArgumentsToConstructor(
-              functionNode,
-              callStructure,
-              const Link<Node>(),
-              targetConstructor);
-          evaluateSuperOrRedirectSend(
-              compiledArguments, callStructure, targetConstructor);
-        }
-      }
-    }
-  }
-
-  /**
-   * Simulates the execution of the [constructor] with the given
-   * [arguments] to obtain the field values that need to be passed to the
-   * native JavaScript constructor.
-   */
-  void evaluateConstructorFieldValues(List<AstConstant> arguments) {
-    if (constructor.isMalformed) return;
-    reporter.withCurrentElement(constructor, () {
-      assignArgumentsToParameters(arguments);
-      evaluateConstructorInitializers();
-    });
-  }
-
-  /// Builds a normalized list of the constant values for each field in the
-  /// inheritance chain of [classElement].
-  Map<FieldElement, AstConstant> buildFieldConstants(
-      ClassElement classElement) {
-    Map<FieldElement, AstConstant> fieldConstants =
-        <FieldElement, AstConstant>{};
-    classElement.implementation.forEachInstanceField(
-        (ClassElement enclosing, FieldElement field) {
-      AstConstant fieldValue = fieldValues[field];
-      if (fieldValue == null) {
-        // Use the default value.
-        ConstantExpression fieldExpression =
-            handler.internalCompileVariable(field, true, false);
-        fieldValue = new AstConstant.fromDefaultValue(
-            field, fieldExpression, handler.getConstantValue(fieldExpression));
-        // TODO(het): If the field value doesn't typecheck due to the type
-        // variable in the constructor invocation, then report the error on the
-        // invocation rather than the field.
-        potentiallyCheckType(field, fieldValue);
-      }
-      fieldConstants[field] = fieldValue;
-    }, includeSuperAndInjectedMembers: true);
-    return fieldConstants;
-  }
-}
-
-/// A constant created from the front-end AST.
-///
-/// [element] and [node] point to the source location of the constant.
-/// [expression] holds the symbolic constant expression and [value] its constant
-/// value.
-///
-/// This class differs from [ConstantExpression] in that it is coupled to the
-/// front-end AST whereas [ConstantExpression] is only coupled to the element
-/// model.
-class AstConstant {
-  final Element element;
-  final Node node;
-  final ConstantExpression expression;
-  final ConstantValue value;
-
-  AstConstant(this.element, this.node, this.expression, this.value);
-
-  factory AstConstant.fromDefaultValue(VariableElement element,
-      ConstantExpression constant, ConstantValue value) {
-    return new AstConstant(
-        element,
-        element.initializer != null ? element.initializer : element.node,
-        constant,
-        value);
-  }
-
-  bool get isError => expression.kind == ConstantExpressionKind.ERRONEOUS;
-
-  String toString() => expression.toString();
-}
-
-/// A synthetic constant used to recover from errors.
-class ErroneousAstConstant extends AstConstant {
-  ErroneousAstConstant(Element element, Node node)
-      : super(
-            element,
-            node,
-            // TODO(johnniwinther): Return a [NonConstantValue] instead.
-            new ErroneousConstantExpression(),
-            new NullConstantValue());
-}
-
-class AstEvaluationEnvironment extends EvaluationEnvironmentBase {
-  final Compiler _compiler;
-
-  AstEvaluationEnvironment(this._compiler, {bool constantRequired: true})
-      : super(CURRENT_ELEMENT_SPANNABLE, constantRequired: constantRequired);
-
-  @override
-  CommonElements get commonElements => _compiler.resolution.commonElements;
-
-  @override
-  DartTypes get types => _compiler.resolution.types;
-
-  @override
-  String readFromEnvironment(String name) {
-    return _compiler.fromEnvironment(name);
-  }
-
-  @override
-  ResolutionDartType substByContext(
-      ResolutionDartType base, ResolutionInterfaceType target) {
-    return base.substByContext(target);
-  }
-
-  @override
-  ConstantConstructor getConstructorConstant(ConstructorElement constructor) {
-    return constructor.constantConstructor;
-  }
-
-  @override
-  ConstantExpression getFieldConstant(FieldElement field) {
-    return field.constant;
-  }
-
-  @override
-  ConstantExpression getLocalConstant(LocalVariableElement local) {
-    return local.constant;
-  }
-
-  @override
-  DiagnosticReporter get reporter => _compiler.reporter;
-
-  @override
-  bool get enableAssertions => _compiler.options.enableUserAssertions;
 }
diff --git a/pkg/compiler/lib/src/compiler.dart b/pkg/compiler/lib/src/compiler.dart
index dde70dd..a62b1a9 100644
--- a/pkg/compiler/lib/src/compiler.dart
+++ b/pkg/compiler/lib/src/compiler.dart
@@ -10,59 +10,29 @@
 import 'backend_strategy.dart';
 import 'common/names.dart' show Selectors;
 import 'common/names.dart' show Uris;
-import 'common/resolution.dart'
-    show
-        ParsingContext,
-        Resolution,
-        ResolutionWorkItem,
-        ResolutionImpact,
-        Target;
 import 'common/tasks.dart' show CompilerTask, GenericTask, Measurer;
 import 'common/work.dart' show WorkItem;
 import 'common.dart';
 import 'compile_time_constants.dart';
-import 'constants/values.dart';
-import 'common_elements.dart' show CommonElements, ElementEnvironment;
+import 'common_elements.dart' show ElementEnvironment;
 import 'deferred_load.dart' show DeferredLoadTask, OutputUnitData;
 import 'diagnostics/code_location.dart';
 import 'diagnostics/diagnostic_listener.dart' show DiagnosticReporter;
-import 'diagnostics/invariant.dart' show REPORT_EXCESS_RESOLUTION;
 import 'diagnostics/messages.dart' show Message, MessageTemplate;
 import 'dump_info.dart' show DumpInfoTask;
-import 'elements/elements.dart';
 import 'elements/entities.dart';
-import 'elements/resolution_types.dart' show ResolutionDartType, Types;
 import 'enqueue.dart' show Enqueuer, EnqueueTask, ResolutionEnqueuer;
 import 'environment.dart';
 import 'frontend_strategy.dart';
-import 'id_generator.dart';
 import 'io/source_information.dart' show SourceInformation;
-import 'io/source_file.dart' show Binary;
 import 'js_backend/backend.dart' show JavaScriptBackend;
 import 'kernel/kernel_backend_strategy.dart';
 import 'kernel/kernel_strategy.dart';
-import 'library_loader.dart'
-    show
-        ElementScanner,
-        LibraryLoader,
-        LibraryLoaderTask,
-        LoadedLibraries,
-        ScriptLoader;
-import 'mirrors_used.dart' show MirrorUsageAnalyzerTask;
+import 'library_loader.dart' show LibraryLoaderTask, LoadedLibraries;
 import 'null_compiler_output.dart' show NullCompilerOutput, NullSink;
 import 'options.dart' show CompilerOptions, DiagnosticOptions;
-import 'parser/diet_parser_task.dart' show DietParserTask;
-import 'parser/parser_task.dart' show ParserTask;
-import 'patch_parser.dart' show PatchParserTask;
-import 'resolution/resolution.dart' show ResolverTask;
-import 'resolution/resolution_strategy.dart';
-import 'resolved_uri_translator.dart';
-import 'scanner/scanner_task.dart' show ScannerTask;
-import 'script.dart' show Script;
 import 'ssa/nodes.dart' show HInstruction;
-import 'package:front_end/src/fasta/scanner.dart' show StringToken, Token;
-import 'tree/tree.dart' show Node, TypeAnnotation;
-import 'typechecker.dart' show TypeCheckerTask;
+import 'package:front_end/src/fasta/scanner.dart' show StringToken;
 import 'types/types.dart' show GlobalTypeInferenceTask;
 import 'universe/selector.dart' show Selector;
 import 'universe/world_builder.dart'
@@ -70,7 +40,6 @@
 import 'universe/use.dart' show StaticUse, TypeUse;
 import 'universe/world_impact.dart'
     show ImpactStrategy, WorldImpact, WorldImpactBuilderImpl;
-import 'util/util.dart' show Link;
 import 'world.dart' show ClosedWorld, ClosedWorldRefiner;
 
 typedef CompilerDiagnosticReporter MakeReporterFunction(
@@ -81,14 +50,11 @@
 
   api.CompilerInput get provider;
 
-  final IdGenerator idGenerator = new IdGenerator();
   FrontendStrategy frontendStrategy;
   BackendStrategy backendStrategy;
   CompilerDiagnosticReporter _reporter;
-  CompilerResolution _resolution;
   Map<Entity, WorldImpact> _impactCache;
   ImpactCacheDeleter _impactCacheDeleter;
-  ParsingContext _parsingContext;
 
   ImpactStrategy impactStrategy = const ImpactStrategy();
 
@@ -108,17 +74,13 @@
 
   List<Uri> librariesToAnalyzeWhenRun;
 
-  ResolvedUriTranslator get resolvedUriTranslator;
-
   Uri mainLibraryUri;
 
   ClosedWorld backendClosedWorldForTesting;
 
   DiagnosticReporter get reporter => _reporter;
-  Resolution get resolution => _resolution;
   Map<Entity, WorldImpact> get impactCache => _impactCache;
   ImpactCacheDeleter get impactCacheDeleter => _impactCacheDeleter;
-  ParsingContext get parsingContext => _parsingContext;
 
   // TODO(zarah): Remove this map and incorporate compile-time errors
   // in the model.
@@ -135,13 +97,7 @@
   Entity get currentElement => _reporter.currentElement;
 
   List<CompilerTask> tasks;
-  ScannerTask scanner;
-  DietParserTask dietParser;
-  ParserTask parser;
-  PatchParserTask patchParser;
   LibraryLoaderTask libraryLoader;
-  ResolverTask resolver;
-  TypeCheckerTask checker;
   GlobalTypeInferenceTask globalInference;
   JavaScriptBackend backend;
   CodegenWorldBuilder _codegenWorldBuilder;
@@ -154,7 +110,6 @@
 
   EnqueueTask enqueuer;
   DeferredLoadTask deferredLoadTask;
-  MirrorUsageAnalyzerTask mirrorUsageAnalyzerTask;
   DumpInfoTask dumpInfoTask;
 
   bool get hasCrashed => _reporter.hasCrashed;
@@ -206,36 +161,18 @@
     enqueuer = backend.makeEnqueuer();
 
     tasks = [
-      dietParser = new DietParserTask(idGenerator, backend, reporter, measurer),
-      scanner = createScannerTask(),
-      patchParser = new PatchParserTask(this),
-      libraryLoader = frontendStrategy.createLibraryLoader(
-          resolvedUriTranslator,
-          new _ScriptLoader(this),
-          provider,
-          new _ElementScanner(scanner),
-          resolvePatchUri,
-          patchParser,
-          environment,
-          reporter,
-          measurer),
-      parser = new ParserTask(this),
-      resolver = createResolverTask(),
-      checker = new TypeCheckerTask(this),
+      libraryLoader =
+          frontendStrategy.createLibraryLoader(provider, reporter, measurer),
+      kernelFrontEndTask,
       globalInference = new GlobalTypeInferenceTask(this),
       constants = backend.constantCompilerTask,
       deferredLoadTask = frontendStrategy.createDeferredLoadTask(this),
-      mirrorUsageAnalyzerTask = new MirrorUsageAnalyzerTask(this),
       // [enqueuer] is created earlier because it contains the resolution world
       // objects needed by other tasks.
       enqueuer,
       dumpInfoTask = new DumpInfoTask(this),
       selfTask,
     ];
-    tasks.add(kernelFrontEndTask);
-
-    _parsingContext =
-        new ParsingContext(reporter, parser, scanner, patchParser, backend);
 
     tasks.addAll(backend.tasks);
   }
@@ -251,26 +188,9 @@
         useNewSourceInfo: options.useNewSourceInfo);
   }
 
-  /// Creates the scanner task.
-  ///
-  /// Override this to mock the scanner for testing.
-  ScannerTask createScannerTask() =>
-      new ScannerTask(dietParser, reporter, measurer);
-
-  /// Creates the resolution object.
-  ///
-  /// Override this to mock resolution for testing.
-  Resolution createResolution() => new CompilerResolution(this);
-
-  /// Creates the resolver task.
-  ///
-  /// Override this to mock the resolver for testing.
-  ResolverTask createResolverTask() {
-    return new ResolverTask(resolution, backend.constantCompilerTask, measurer);
-  }
-
   ResolutionWorldBuilder get resolutionWorldBuilder =>
       enqueuer.resolution.worldBuilder;
+
   CodegenWorldBuilder get codegenWorldBuilder {
     assert(
         _codegenWorldBuilder != null,
@@ -302,63 +222,6 @@
         });
       });
 
-  /// Compute the set of distinct import chains to the library at [uri] within
-  /// [loadedLibraries].
-  ///
-  /// The chains are strings of the form
-  ///
-  ///       <main-uri> => <intermediate-uri1> => <intermediate-uri2> => <uri>
-  ///
-  Set<String> computeImportChainsFor(LoadedLibraries loadedLibraries, Uri uri) {
-    // TODO(johnniwinther): Move computation of dependencies to the library
-    // loader.
-    Set<String> importChains = new Set<String>();
-    // The maximum number of full imports chains to process.
-    final int chainLimit = 10000;
-    // The maximum number of imports chains to show.
-    final int compactChainLimit = options.verbose ? 20 : 10;
-    int chainCount = 0;
-    loadedLibraries.forEachImportChain(uri,
-        callback: (Link<Uri> importChainReversed) {
-      Link<CodeLocation> compactImportChain = const Link<CodeLocation>();
-      CodeLocation currentCodeLocation =
-          new UriLocation(importChainReversed.head);
-      compactImportChain = compactImportChain.prepend(currentCodeLocation);
-      for (Link<Uri> link = importChainReversed.tail;
-          !link.isEmpty;
-          link = link.tail) {
-        Uri uri = link.head;
-        if (!currentCodeLocation.inSameLocation(uri)) {
-          currentCodeLocation =
-              options.verbose ? new UriLocation(uri) : new CodeLocation(uri);
-          compactImportChain = compactImportChain.prepend(currentCodeLocation);
-        }
-      }
-      String importChain = compactImportChain.map((CodeLocation codeLocation) {
-        return codeLocation.relativize(
-            (loadedLibraries.rootLibrary as LibraryElement).canonicalUri);
-      }).join(' => ');
-
-      if (!importChains.contains(importChain)) {
-        if (importChains.length > compactChainLimit) {
-          importChains.add('...');
-          return false;
-        } else {
-          importChains.add(importChain);
-        }
-      }
-
-      chainCount++;
-      if (chainCount > chainLimit) {
-        // Assume there are more import chains.
-        importChains.add('...');
-        return false;
-      }
-      return true;
-    });
-    return importChains;
-  }
-
   /// This method is called when all new libraries loaded through
   /// [LibraryLoader.loadLibrary] has been loaded and their imports/exports
   /// have been computed.
@@ -384,12 +247,6 @@
     return loadedLibraries;
   }
 
-  /**
-   * Get an [Uri] pointing to a patch for the dart: library with
-   * the given path. Returns null if there is no patch.
-   */
-  Uri resolvePatchUri(String dartLibraryPath);
-
   Future runInternal(Uri uri) async {
     mainLibraryUri = uri;
     // TODO(ahe): This prevents memory leaks when invoking the compiler
@@ -433,30 +290,6 @@
     compileLoadedLibraries(mainApp);
   }
 
-  /// Analyze all members of the library in [libraryUri].
-  ///
-  /// If [skipLibraryWithPartOfTag] is `true`, member analysis is skipped if the
-  /// library has a `part of` tag, assuming it is a part and not a library.
-  ///
-  /// This operation assumes an unclosed resolution queue and is only supported
-  /// when the '--analyze-main' option is used.
-  Future<LibraryElement> analyzeUri(Uri libraryUri,
-      {bool skipLibraryWithPartOfTag: true}) async {
-    phase = PHASE_RESOLVING;
-    assert(options.analyzeMain);
-    reporter.log('Analyzing $libraryUri (${options.buildId})');
-    LoadedLibraries loadedLibraries = await libraryLoader
-        .loadLibrary(libraryUri, skipFileWithPartOfTag: true);
-    if (loadedLibraries == null) return null;
-    processLoadedLibraries(loadedLibraries);
-    LibraryElement library = loadedLibraries.rootLibrary;
-    ResolutionEnqueuer resolutionEnqueuer = startResolution();
-    resolutionEnqueuer.applyImpact(computeImpactForLibrary(library));
-    emptyQueue(resolutionEnqueuer, onProgress: showResolutionProgress);
-    resolutionEnqueuer.logSummary(reporter.log);
-    return library;
-  }
-
   /// Starts the resolution phase, creating the [ResolutionEnqueuer] if not
   /// already created.
   ///
@@ -609,66 +442,17 @@
       impactBuilder.registerStaticUse(new StaticUse.directUse(element));
     }
 
-    void registerStaticElementUse(Element element) {
-      MemberElement member = element;
-      impactBuilder.registerStaticUse(new StaticUse.directUse(member));
-    }
+    ElementEnvironment elementEnvironment = frontendStrategy.elementEnvironment;
 
-    void registerElement(Element element) {
-      if (element.isClass) {
-        ClassElement cls = element;
-        cls.ensureResolved(resolution);
-        cls.forEachLocalMember(registerStaticElementUse);
-        impactBuilder.registerTypeUse(new TypeUse.instantiation(cls.rawType));
-      } else if (element.isTypedef) {
-        TypedefElement typedef = element;
-        typedef.ensureResolved(resolution);
-      } else {
-        registerStaticElementUse(element);
-      }
-    }
-
-    if (library is LibraryElement) {
-      library.implementation.forEachLocalMember(registerElement);
-
-      library.imports.forEach((ImportElement import) {
-        if (import.isDeferred) {
-          // `import.prefix` and `loadLibrary` may be `null` when the deferred
-          // import has compile-time errors.
-          GetterElement loadLibrary = import.prefix?.loadLibrary;
-          if (loadLibrary != null) {
-            registerStaticUse(loadLibrary);
-          }
-        }
-      });
-    } else {
-      ElementEnvironment elementEnvironment =
-          frontendStrategy.elementEnvironment;
-
-      elementEnvironment.forEachLibraryMember(library, registerStaticUse);
-      elementEnvironment.forEachClass(library, (ClassEntity cls) {
-        impactBuilder.registerTypeUse(
-            new TypeUse.instantiation(elementEnvironment.getRawType(cls)));
-        elementEnvironment.forEachLocalClassMember(cls, registerStaticUse);
-      });
-    }
+    elementEnvironment.forEachLibraryMember(library, registerStaticUse);
+    elementEnvironment.forEachClass(library, (ClassEntity cls) {
+      impactBuilder.registerTypeUse(
+          new TypeUse.instantiation(elementEnvironment.getRawType(cls)));
+      elementEnvironment.forEachLocalClassMember(cls, registerStaticUse);
+    });
     return impactBuilder;
   }
 
-  // Resolves metadata on library elements.  This is necessary in order to
-  // resolve metadata classes referenced only from metadata on library tags.
-  // TODO(ahe): Figure out how to do this lazily.
-  void resolveLibraryMetadata() {
-    assert(frontendStrategy.commonElements.mirrorsLibrary != null);
-    for (LibraryElement library in libraryLoader.libraries) {
-      if (library.metadata != null) {
-        for (MetadataAnnotation metadata in library.metadata) {
-          metadata.ensureResolved(resolution);
-        }
-      }
-    }
-  }
-
   /**
    * Empty the [enqueuer] queue.
    */
@@ -716,27 +500,6 @@
     for (Enqueuer enqueuer in [resolutionEnqueuer, codegenEnqueuer]) {
       enqueuer.checkQueueIsEmpty();
     }
-    if (!REPORT_EXCESS_RESOLUTION) return;
-    var resolved = new Set.from(resolutionEnqueuer.processedEntities);
-    for (MemberEntity e in codegenEnqueuer.processedEntities) {
-      resolved.remove(e);
-    }
-    for (MemberEntity e in new Set.from(resolved)) {
-      if (e.isField) {
-        resolved.remove(e);
-      }
-      if (e.isConstructor && (e as ConstructorEntity).isGenerativeConstructor) {
-        resolved.remove(e);
-      }
-      if (backend.isTargetSpecificLibrary(e.library)) {
-        resolved.remove(e);
-      }
-    }
-    reporter.log('Excess resolution work: ${resolved.length}.');
-    for (MemberEntity e in resolved) {
-      reporter.reportWarningMessage(e, MessageKind.GENERIC,
-          {'text': 'Warning: $e resolved but not compiled.'});
-    }
   }
 
   void showResolutionProgress(Enqueuer enqueuer) {
@@ -783,29 +546,6 @@
     registerCompileTimeError(currentElement, message);
   }
 
-  /**
-   * Reads the script specified by the [readableUri].
-   *
-   * See [LibraryLoader] for terminology on URIs.
-   */
-  Future<Script> readScript(Uri readableUri, [Spannable node]) {
-    throw failedAt(node, 'Compiler.readScript not implemented.');
-  }
-
-  Future<Binary> readBinary(Uri readableUri, [Spannable node]) {
-    throw failedAt(node, 'Compiler.readBinary not implemented.');
-  }
-
-  Element lookupElementIn(ScopeContainerElement container, String name) {
-    Element element = container.localLookup(name);
-    if (element == null) {
-      throw 'Could not find $name in $container';
-    }
-    return element;
-  }
-
-  bool get isMockCompilation => false;
-
   /// Helper for determining whether the current element is declared within
   /// 'user code'.
   ///
@@ -883,8 +623,6 @@
       return element.library.canonicalUri;
     } else if (element is MemberEntity) {
       return element.library.canonicalUri;
-    } else if (element is Element) {
-      return element.library.canonicalUri;
     }
     return null;
   }
@@ -1123,22 +861,6 @@
     }
   }
 
-  // TODO(johnniwinther): Move this to the parser listeners.
-  @override
-  SourceSpan spanFromToken(Token token) {
-    if (compiler.frontendStrategy is ResolutionFrontEndStrategy) {
-      ResolutionFrontEndStrategy strategy = compiler.frontendStrategy;
-      return strategy.spanFromToken(currentElement, token);
-    }
-    throw 'No error location.';
-  }
-
-  Element _elementFromHInstruction(HInstruction instruction) {
-    return instruction.sourceElement is Element
-        ? instruction.sourceElement
-        : null;
-  }
-
   internalError(Spannable spannable, reason) {
     String message = tryToString(reason);
     reportDiagnosticInternal(
@@ -1168,9 +890,7 @@
     if (node is Entity) {
       element = node;
     } else if (node is HInstruction) {
-      element = _elementFromHInstruction(node);
-    } else if (node is MetadataAnnotation) {
-      element = node.annotatedElement;
+      element = node.sourceElement;
     }
     return element != null ? element : currentElement;
   }
@@ -1238,258 +958,6 @@
   }
 }
 
-// TODO(johnniwinther): Move [ResolverTask] here.
-class CompilerResolution implements Resolution, ImpactCacheDeleter {
-  final Compiler _compiler;
-  final Map<Element, ResolutionImpact> _resolutionImpactCache =
-      <Element, ResolutionImpact>{};
-  final Map<Entity, WorldImpact> _worldImpactCache = <Entity, WorldImpact>{};
-  bool retainCachesForTesting = false;
-  Types _types;
-
-  CompilerResolution(this._compiler) {
-    _types = new Types(this);
-  }
-
-  @override
-  DiagnosticReporter get reporter => _compiler.reporter;
-
-  @override
-  ParsingContext get parsingContext => _compiler.parsingContext;
-
-  @override
-  ElementEnvironment get elementEnvironment =>
-      _compiler.frontendStrategy.elementEnvironment;
-
-  @override
-  CommonElements get commonElements =>
-      _compiler.frontendStrategy.commonElements;
-
-  @override
-  Types get types => _types;
-
-  @override
-  Target get target => _compiler.backend.target;
-
-  @override
-  ResolverTask get resolver => _compiler.resolver;
-
-  @override
-  ResolutionEnqueuer get enqueuer => _compiler.enqueuer.resolution;
-
-  @override
-  CompilerOptions get options => _compiler.options;
-
-  @override
-  IdGenerator get idGenerator => _compiler.idGenerator;
-
-  @override
-  ConstantEnvironment get constants => _compiler.constants;
-
-  @override
-  MirrorUsageAnalyzerTask get mirrorUsageAnalyzerTask =>
-      _compiler.mirrorUsageAnalyzerTask;
-
-  LibraryElement get coreLibrary =>
-      _compiler.frontendStrategy.commonElements.coreLibrary;
-
-  @override
-  bool get wasProxyConstantComputedTestingOnly => _proxyConstant != null;
-
-  @override
-  void resolveClass(ClassElement cls) {
-    _compiler.resolver.resolveClass(cls);
-  }
-
-  @override
-  void resolveTypedef(TypedefElement typdef) {
-    _compiler.resolver.resolve(typdef);
-  }
-
-  @override
-  void resolveMetadataAnnotation(MetadataAnnotation metadataAnnotation) {
-    _compiler.resolver.resolveMetadataAnnotation(metadataAnnotation);
-  }
-
-  @override
-  FunctionSignature resolveSignature(FunctionElement function) {
-    return _compiler.resolver.resolveSignature(function);
-  }
-
-  @override
-  ResolutionDartType resolveTypeAnnotation(
-      Element element, TypeAnnotation node) {
-    return _compiler.resolver.resolveTypeAnnotation(element, node);
-  }
-
-  @override
-  void ensureResolved(Element element) {
-    computeWorldImpact(element);
-  }
-
-  @override
-  void ensureClassMembers(ClassElement element) {
-    _compiler.resolver.checkClass(element);
-  }
-
-  @override
-  void registerCompileTimeError(Element element, DiagnosticMessage message) =>
-      _compiler.registerCompileTimeError(element, message);
-
-  @override
-  bool hasResolvedAst(ExecutableElement element) {
-    assert(element.isDeclaration,
-        failedAt(element, "Element $element must be the declaration."));
-    return hasBeenResolved(element.memberContext.declaration) &&
-        element.hasResolvedAst;
-  }
-
-  @override
-  ResolvedAst getResolvedAst(ExecutableElement element) {
-    assert(element.isDeclaration,
-        failedAt(element, "Element $element must be the declaration."));
-    assert(hasResolvedAst(element),
-        failedAt(element, "ResolvedAst not available for $element."));
-    return element.resolvedAst;
-  }
-
-  @override
-  ResolvedAst computeResolvedAst(Element element) {
-    ensureResolved(element);
-    return getResolvedAst(element);
-  }
-
-  @override
-  bool hasResolutionImpact(Element element) {
-    assert(element.isDeclaration,
-        failedAt(element, "Element $element must be the declaration."));
-    return _resolutionImpactCache.containsKey(element);
-  }
-
-  @override
-  ResolutionImpact getResolutionImpact(Element element) {
-    assert(element.isDeclaration,
-        failedAt(element, "Element $element must be the declaration."));
-    ResolutionImpact resolutionImpact = _resolutionImpactCache[element];
-    assert(resolutionImpact != null,
-        failedAt(element, "ResolutionImpact not available for $element."));
-    return resolutionImpact;
-  }
-
-  @override
-  WorldImpact getWorldImpact(Element element) {
-    assert(element.isDeclaration,
-        failedAt(element, "Element $element must be the declaration."));
-    WorldImpact worldImpact = _worldImpactCache[element];
-    assert(worldImpact != null,
-        failedAt(element, "WorldImpact not computed for $element."));
-    return worldImpact;
-  }
-
-  @override
-  WorldImpact computeWorldImpact(Element element) {
-    return _compiler.selfTask.measureSubtask("Resolution.computeWorldImpact",
-        () {
-      assert(
-          element.impliesType ||
-              element.isField ||
-              element.isFunction ||
-              element.isConstructor ||
-              element.isGetter ||
-              element.isSetter,
-          failedAt(element, 'Unexpected element kind: ${element.kind}'));
-      // `true ==` prevents analyzer type inference from strengthening element
-      // to AnalyzableElement which incompatible with some down-cast to ElementX
-      // uses.
-      // TODO(29712): Can this be made to work as we expect?
-      assert(true == element is AnalyzableElement,
-          failedAt(element, 'Element $element is not analyzable.'));
-      assert(element.isDeclaration,
-          failedAt(element, "Element $element must be the declaration."));
-      return _worldImpactCache.putIfAbsent(element, () {
-        assert(_compiler.parser != null);
-        Node tree = _compiler.parser.parse(element);
-        assert(!element.isSynthesized || tree == null, failedAt(element));
-        ResolutionImpact resolutionImpact = _compiler.resolver.resolve(element);
-
-        if (retainCachesForTesting) {
-          // [ResolutionImpact] is currently only used by serialization. The
-          // enqueuer uses the [WorldImpact] which is always cached.
-          // TODO(johnniwinther): Align these use cases better; maybe only
-          // cache [ResolutionImpact] and let the enqueuer transform it into
-          // a [WorldImpact].
-          _resolutionImpactCache[element] = resolutionImpact;
-        }
-        if (tree != null && !_compiler.options.analyzeSignaturesOnly) {
-          // TODO(het): don't do this if suppressWarnings is on, currently we
-          // have to do it because the typechecker also sets types
-          // Only analyze nodes with a corresponding [TreeElements].
-          _compiler.checker.check(element);
-        }
-        return transformResolutionImpact(element, resolutionImpact);
-      });
-    });
-  }
-
-  @override
-  WorldImpact transformResolutionImpact(
-      Element element, ResolutionImpact resolutionImpact) {
-    WorldImpact worldImpact = _compiler.backend.impactTransformer
-        .transformResolutionImpact(resolutionImpact);
-    _worldImpactCache[element] = worldImpact;
-    return worldImpact;
-  }
-
-  @override
-  void uncacheWorldImpact(covariant Element element) {
-    assert(element.isDeclaration,
-        failedAt(element, "Element $element must be the declaration."));
-    if (retainCachesForTesting) return;
-    assert(_worldImpactCache[element] != null,
-        failedAt(element, "WorldImpact not computed for $element."));
-    _worldImpactCache[element] = const WorldImpact();
-    _resolutionImpactCache.remove(element);
-  }
-
-  @override
-  void emptyCache() {
-    if (retainCachesForTesting) return;
-    for (Element element in _worldImpactCache.keys) {
-      _worldImpactCache[element] = const WorldImpact();
-    }
-    _resolutionImpactCache.clear();
-  }
-
-  @override
-  bool hasBeenResolved(Element element) {
-    return _worldImpactCache.containsKey(element);
-  }
-
-  @override
-  ResolutionWorkItem createWorkItem(MemberElement element) {
-    return new ResolutionWorkItem(this, element);
-  }
-
-  ConstantValue _proxyConstant;
-
-  @override
-  bool isProxyConstant(ConstantValue value) {
-    FieldElement field = coreLibrary.find('proxy');
-    if (field == null) return false;
-    if (!hasBeenResolved(field)) return false;
-    if (_proxyConstant == null) {
-      _proxyConstant = constants
-          .getConstantValue(resolver.constantCompiler.compileConstant(field));
-    }
-    return _proxyConstant == value;
-  }
-
-  @override
-  void registerClass(ClassEntity cls) {
-    enqueuer.worldBuilder.registerClass(cls);
-  }
-}
-
 class _MapImpactCacheDeleter implements ImpactCacheDeleter {
   final Map<Entity, WorldImpact> _impactCache;
   _MapImpactCacheDeleter(this._impactCache);
@@ -1507,24 +975,6 @@
   }
 }
 
-class _ScriptLoader implements ScriptLoader {
-  Compiler compiler;
-  _ScriptLoader(this.compiler);
-
-  Future<Script> readScript(Uri uri, [Spannable spannable]) =>
-      compiler.readScript(uri, spannable);
-
-  Future<Binary> readBinary(Uri uri, [Spannable spannable]) =>
-      compiler.readBinary(uri, spannable);
-}
-
-class _ElementScanner implements ElementScanner {
-  ScannerTask scanner;
-  _ElementScanner(this.scanner);
-  void scanLibrary(LibraryElement library) => scanner.scanLibrary(library);
-  void scanUnit(CompilationUnitElement unit) => scanner.scan(unit);
-}
-
 class _EmptyEnvironment implements Environment {
   const _EmptyEnvironment();
 
diff --git a/pkg/compiler/lib/src/constants/constant_constructors.dart b/pkg/compiler/lib/src/constants/constant_constructors.dart
deleted file mode 100644
index 288c063..0000000
--- a/pkg/compiler/lib/src/constants/constant_constructors.dart
+++ /dev/null
@@ -1,369 +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.
-
-// TODO(johnniwinther): Remove this library when all constant constructors are
-// computed during resolution.
-library dart2js.constants.constant_constructors;
-
-import '../common.dart';
-import '../elements/elements.dart';
-import '../elements/operators.dart';
-import '../elements/resolution_types.dart';
-import '../resolution/semantic_visitor.dart';
-import '../resolution/send_resolver.dart' show DeclarationResolverMixin;
-import '../resolution/send_structure.dart';
-import '../resolution/tree_elements.dart' show TreeElements;
-import '../tree/tree.dart';
-import '../universe/call_structure.dart' show CallStructure;
-import 'constructors.dart';
-import 'expressions.dart';
-
-ConstantConstructor computeConstantConstructor(ResolvedAst resolvedAst) {
-  ConstantConstructorComputer visitor =
-      new ConstantConstructorComputer(resolvedAst.elements);
-  return resolvedAst.node.accept(visitor);
-}
-
-class ConstantConstructorComputer extends SemanticVisitor
-    with
-        SemanticDeclarationResolvedMixin,
-        DeclarationResolverMixin,
-        GetBulkMixin,
-        SetBulkMixin,
-        ErrorBulkMixin,
-        InvokeBulkMixin,
-        IndexSetBulkMixin,
-        CompoundBulkMixin,
-        SetIfNullBulkMixin,
-        UnaryBulkMixin,
-        BaseBulkMixin,
-        BinaryBulkMixin,
-        PrefixBulkMixin,
-        PostfixBulkMixin,
-        NewBulkMixin,
-        InitializerBulkMixin,
-        FunctionBulkMixin,
-        VariableBulkMixin
-    implements SemanticDeclarationVisitor, SemanticSendVisitor {
-  final Map<FieldElement, ConstantExpression> fieldMap =
-      <FieldElement, ConstantExpression>{};
-  final Map<dynamic /*int|String*/, ConstantExpression> defaultValues =
-      <dynamic /*int|String*/, ConstantExpression>{};
-
-  ConstantConstructorComputer(TreeElements elements) : super(elements);
-
-  SemanticDeclarationVisitor get declVisitor => this;
-
-  SemanticSendVisitor get sendVisitor => this;
-
-  ClassElement get currentClass => currentConstructor.enclosingClass;
-
-  ConstructorElement get currentConstructor => elements.analyzedElement;
-
-  apply(Node node, [_]) => node.accept(this);
-
-  visitNode(Node node) {
-    internalError(node, 'Unhandled node $node: ${node.toDebugString()}');
-  }
-
-  @override
-  bulkHandleNode(Node node, String template, _) {
-    internalError(node, template.replaceFirst('#', '$node'));
-  }
-
-  internalError(Spannable node, String message) {
-    throw new UnsupportedError(message);
-  }
-
-  ConstantConstructor visitGenerativeConstructorDeclaration(
-      FunctionExpression node,
-      ConstructorElement constructor,
-      NodeList parameters,
-      NodeList initializers,
-      Node body,
-      _) {
-    applyParameters(parameters, _);
-    ConstructedConstantExpression constructorInvocation =
-        applyInitializers(node, _);
-    constructor.enclosingClass.forEachInstanceField((_, FieldElement field) {
-      if (!fieldMap.containsKey(field)) {
-        fieldMap[field] = field.constant;
-      }
-    });
-    return new GenerativeConstantConstructor(
-        currentClass.thisType,
-        defaultValues,
-        fieldMap,
-        const <AssertConstantExpression>[],
-        constructorInvocation);
-  }
-
-  ConstantConstructor visitRedirectingGenerativeConstructorDeclaration(
-      FunctionExpression node,
-      ConstructorElement constructor,
-      NodeList parameters,
-      NodeList initializers,
-      _) {
-    applyParameters(parameters, _);
-    ConstructedConstantExpression constructorInvocation =
-        applyInitializers(node, _);
-    return new RedirectingGenerativeConstantConstructor(
-        defaultValues, constructorInvocation);
-  }
-
-  ConstantConstructor visitRedirectingFactoryConstructorDeclaration(
-      FunctionExpression node,
-      ConstructorElement constructor,
-      NodeList parameters,
-      ResolutionInterfaceType redirectionType,
-      ConstructorElement redirectionTarget,
-      _) {
-    List<String> argumentNames = [];
-    List<ConstantExpression> arguments = [];
-    int index = 0;
-    for (ParameterElement parameter in constructor.parameters) {
-      if (parameter.isNamed) {
-        String name = parameter.name;
-        argumentNames.add(name);
-        arguments.add(new NamedArgumentReference(name));
-      } else {
-        arguments.add(new PositionalArgumentReference(index));
-      }
-      index++;
-    }
-    CallStructure callStructure = new CallStructure(index, argumentNames);
-
-    return new RedirectingFactoryConstantConstructor(
-        new ConstructedConstantExpression(
-            redirectionType, redirectionTarget, callStructure, arguments));
-  }
-
-  @override
-  visitFactoryConstructorDeclaration(FunctionExpression node,
-      ConstructorElement constructor, NodeList parameters, Node body, _) {
-    // TODO(johnniwinther): Handle constant constructors with errors.
-    internalError(node, "Factory constructor cannot be constant: $node.");
-  }
-
-  applyParameters(NodeList parameters, _) {
-    computeParameterStructures(parameters).forEach((s) => s.dispatch(this, _));
-  }
-
-  visitParameterDeclaration(VariableDefinitions node, Node definition,
-      ParameterElement parameter, int index, _) {
-    // Do nothing.
-  }
-
-  visitOptionalParameterDeclaration(
-      VariableDefinitions node,
-      Node definition,
-      ParameterElement parameter,
-      ConstantExpression defaultValue,
-      int index,
-      _) {
-    assert(defaultValue != null, failedAt(node));
-    defaultValues[index] = defaultValue;
-  }
-
-  visitNamedParameterDeclaration(VariableDefinitions node, Node definition,
-      ParameterElement parameter, ConstantExpression defaultValue, _) {
-    assert(defaultValue != null, failedAt(node));
-    String name = parameter.name;
-    defaultValues[name] = defaultValue;
-  }
-
-  visitInitializingFormalDeclaration(VariableDefinitions node, Node definition,
-      InitializingFormalElement parameter, int index, _) {
-    fieldMap[parameter.fieldElement] = new PositionalArgumentReference(index);
-  }
-
-  visitOptionalInitializingFormalDeclaration(
-      VariableDefinitions node,
-      Node definition,
-      InitializingFormalElement parameter,
-      ConstantExpression defaultValue,
-      int index,
-      _) {
-    assert(defaultValue != null, failedAt(node));
-    defaultValues[index] = defaultValue;
-    fieldMap[parameter.fieldElement] = new PositionalArgumentReference(index);
-  }
-
-  visitNamedInitializingFormalDeclaration(
-      VariableDefinitions node,
-      Node definition,
-      InitializingFormalElement parameter,
-      ConstantExpression defaultValue,
-      _) {
-    assert(defaultValue != null, failedAt(node));
-    String name = parameter.name;
-    defaultValues[name] = defaultValue;
-    fieldMap[parameter.fieldElement] = new NamedArgumentReference(name);
-  }
-
-  /// Apply this visitor to the constructor [initializers].
-  ConstructedConstantExpression applyInitializers(
-      FunctionExpression constructor, _) {
-    ConstructedConstantExpression constructorInvocation;
-    InitializersStructure initializers =
-        computeInitializersStructure(constructor);
-    for (InitializerStructure structure in initializers.initializers) {
-      if (structure.isConstructorInvoke) {
-        constructorInvocation = structure.dispatch(this, _);
-      } else {
-        structure.dispatch(this, _);
-      }
-    }
-    return constructorInvocation;
-  }
-
-  visitFieldInitializer(SendSet node, FieldElement field, Node initializer, _) {
-    fieldMap[field] = apply(initializer);
-  }
-
-  visitParameterGet(Send node, ParameterElement parameter, _) {
-    if (parameter.isNamed) {
-      return new NamedArgumentReference(parameter.name);
-    } else {
-      return new PositionalArgumentReference(
-          parameter.functionDeclaration.parameters.indexOf(parameter));
-    }
-  }
-
-  ConstructedConstantExpression visitSuperConstructorInvoke(
-      Send node,
-      ConstructorElement superConstructor,
-      ResolutionInterfaceType type,
-      NodeList arguments,
-      CallStructure callStructure,
-      _) {
-    List<ConstantExpression> argumentExpression =
-        arguments.nodes.map((a) => apply(a)).toList();
-    return new ConstructedConstantExpression(
-        type, superConstructor, callStructure, argumentExpression);
-  }
-
-  ConstructedConstantExpression visitImplicitSuperConstructorInvoke(
-      FunctionExpression node,
-      ConstructorElement superConstructor,
-      ResolutionInterfaceType type,
-      _) {
-    return new ConstructedConstantExpression(type, superConstructor,
-        CallStructure.NO_ARGS, const <ConstantExpression>[]);
-  }
-
-  ConstructedConstantExpression visitThisConstructorInvoke(
-      Send node,
-      ConstructorElement thisConstructor,
-      NodeList arguments,
-      CallStructure callStructure,
-      _) {
-    List<ConstantExpression> argumentExpression =
-        arguments.nodes.map((a) => apply(a)).toList();
-    return new ConstructedConstantExpression(currentClass.thisType,
-        thisConstructor, callStructure, argumentExpression);
-  }
-
-  @override
-  ConstantExpression visitBinary(
-      Send node, Node left, BinaryOperator operator, Node right, _) {
-    return new BinaryConstantExpression(apply(left), operator, apply(right));
-  }
-
-  @override
-  ConstantExpression visitEquals(Send node, Node left, Node right, _) {
-    return new BinaryConstantExpression(
-        apply(left), BinaryOperator.EQ, apply(right));
-  }
-
-  @override
-  ConstantExpression visitNotEquals(Send node, Node left, Node right, _) {
-    return new BinaryConstantExpression(
-        apply(left), BinaryOperator.NOT_EQ, apply(right));
-  }
-
-  @override
-  ConstantExpression visitUnary(
-      Send node, UnaryOperator operator, Node expression, _) {
-    return new UnaryConstantExpression(operator, apply(expression));
-  }
-
-  @override
-  ConstantExpression visitStaticFieldGet(Send node, FieldElement field, _) {
-    return new FieldConstantExpression(field);
-  }
-
-  @override
-  ConstantExpression visitTopLevelFunctionGet(
-      Send node, MethodElement method, _) {
-    return new FunctionConstantExpression(method, method.type);
-  }
-
-  @override
-  ConstantExpression visitTopLevelFieldGet(Send node, FieldElement field, _) {
-    return new FieldConstantExpression(field);
-  }
-
-  @override
-  ConstantExpression visitLiteralInt(LiteralInt node) {
-    return new IntConstantExpression(node.value);
-  }
-
-  @override
-  ConstantExpression visitLiteralDouble(LiteralDouble node) {
-    return new DoubleConstantExpression(node.value);
-  }
-
-  @override
-  ConstantExpression visitLiteralBool(LiteralBool node) {
-    return new BoolConstantExpression(node.value);
-  }
-
-  @override
-  ConstantExpression visitLiteralNull(LiteralNull node) {
-    return new NullConstantExpression();
-  }
-
-  @override
-  ConstantExpression visitLiteralString(LiteralString node) {
-    return new StringConstantExpression(node.dartString.slowToString());
-  }
-
-  @override
-  ConstantExpression visitConditional(Conditional node) {
-    return new ConditionalConstantExpression(apply(node.condition),
-        apply(node.thenExpression), apply(node.elseExpression));
-  }
-
-  @override
-  ConstantExpression visitParenthesizedExpression(
-      ParenthesizedExpression node) {
-    return apply(node.expression);
-  }
-
-  @override
-  ConstantExpression visitTopLevelFunctionInvoke(
-      Send node,
-      MethodElement function,
-      NodeList arguments,
-      CallStructure callStructure,
-      _) {
-    if (function.name != 'identical' || !function.library.isDartCore) {
-      throw new UnsupportedError("Unexpected function call: $function");
-    }
-    return new IdenticalConstantExpression(
-        apply(arguments.nodes.head), apply(arguments.nodes.tail.head));
-  }
-
-  @override
-  ConstantExpression visitNamedArgument(NamedArgument node) {
-    return apply(node.expression);
-  }
-
-  @override
-  ConstantExpression visitIfNull(Send node, Node left, Node right, _) {
-    return new BinaryConstantExpression(
-        apply(left), BinaryOperator.IF_NULL, apply(right));
-  }
-}
diff --git a/pkg/compiler/lib/src/deferred_load.dart b/pkg/compiler/lib/src/deferred_load.dart
index 1ccd493..2064ae8 100644
--- a/pkg/compiler/lib/src/deferred_load.dart
+++ b/pkg/compiler/lib/src/deferred_load.dart
@@ -19,8 +19,6 @@
         InstantiationConstantValue,
         TypeConstantValue;
 import 'elements/types.dart';
-import 'elements/elements.dart'
-    show AstElement, ClassElement, Element, MethodElement, LocalFunctionElement;
 import 'elements/entities.dart';
 import 'kernel/kelements.dart' show KLocalFunction;
 import 'universe/use.dart';
@@ -190,11 +188,6 @@
   /// Adds the results to [elements] and [constants].
   void _collectAllElementsAndConstantsResolvedFrom(Entity element,
       Set<Entity> elements, Set<ConstantValue> constants, isMirrorUsage) {
-    if (element is Element && element.isMalformed) {
-      // Malformed elements are ignored.
-      return;
-    }
-
     /// Collects all direct dependencies of [element].
     ///
     /// The collected dependent elements and constants are are added to
@@ -206,19 +199,13 @@
         return;
       }
 
-      // TODO(johnniwinther): Remove this when [AbstractFieldElement] has been
-      // removed.
-      if (element is Element && element is! AstElement) return;
-      Entity analyzableElement =
-          element is Element ? element.analyzableElement.declaration : element;
-
       // TODO(sigurdm): We want to be more specific about this - need a better
       // way to query "liveness".
-      if (!compiler.resolutionWorldBuilder.isMemberUsed(analyzableElement)) {
+      if (!compiler.resolutionWorldBuilder.isMemberUsed(element)) {
         return;
       }
-      _collectDependenciesFromImpact(analyzableElement, elements);
-      collectConstantsInBody(analyzableElement, constants);
+      _collectDependenciesFromImpact(element, elements);
+      collectConstantsInBody(element, constants);
     }
 
     if (element is FunctionEntity) {
@@ -238,13 +225,12 @@
         collectDependencies(element);
       }
 
-      ClassEntity cls = element is ClassElement ? element.declaration : element;
-      ClassEntity impl = cls is ClassElement ? cls.implementation : cls;
+      ClassEntity cls = element;
       elementEnvironment.forEachLocalClassMember(cls, addLiveInstanceMember);
-      elementEnvironment.forEachSupertype(impl, (InterfaceType type) {
+      elementEnvironment.forEachSupertype(cls, (InterfaceType type) {
         _collectTypeDependencies(type, elements);
       });
-      elements.add(impl);
+      elements.add(cls);
     } else if (element is MemberEntity &&
         (element.isStatic || element.isTopLevel || element.isConstructor)) {
       elements.add(element);
@@ -255,10 +241,8 @@
       // constructor, not the class itself.  We must add all the
       // instance members of the constructor's class.
       ClassEntity cls = element.enclosingClass;
-      ClassEntity implementation =
-          cls is ClassElement ? cls.implementation : cls;
       _collectAllElementsAndConstantsResolvedFrom(
-          implementation, elements, constants, isMirrorUsage);
+          cls, elements, constants, isMirrorUsage);
     }
 
     // Other elements, in particular instance members, are ignored as
@@ -474,8 +458,6 @@
       } else if (element is KLocalFunction) {
         // TODO(sigmund): consider adding `Local.library`
         library = element.memberContext.library;
-      } else if (element is LocalFunctionElement) {
-        library = element.library;
       } else {
         assert(false, "Unexpected entity: ${element.runtimeType}");
       }
@@ -691,12 +673,10 @@
       // information.
       for (MemberEntity element
           in closedWorld.backendUsage.globalFunctionDependencies) {
-        element = element is MethodElement ? element.implementation : element;
         queue.addElement(element, importSets.mainSet);
       }
       for (ClassEntity element
           in closedWorld.backendUsage.globalClassDependencies) {
-        element = element is ClassElement ? element.implementation : element;
         queue.addElement(element, importSets.mainSet);
       }
 
@@ -1162,26 +1142,8 @@
     // TODO(johnniwinther): Support use of entities by splitting maps by
     // entity kind.
     if (!isProgramSplit) return mainOutputUnit;
-    entity = entity is Element ? entity.implementation : entity;
     OutputUnit unit = _entityToUnit[entity];
     if (unit != null) return unit;
-    if (entity is Element) {
-      Element element = entity;
-      while (!_entityToUnit.containsKey(element)) {
-        // TODO(21051): workaround: it looks like we output annotation constants
-        // for classes that we don't include in the output. This seems to happen
-        // when we have reflection but can see that some classes are not needed.
-        // We still add the annotation but don't run through it below (where we
-        // assign every element to its output unit).
-        if (element.enclosingElement == null) {
-          _entityToUnit[element] = mainOutputUnit;
-          break;
-        }
-        element = element.enclosingElement.implementation;
-      }
-      return _entityToUnit[element];
-    }
-
     if (entity is MemberEntity && entity.isInstanceMember) {
       return outputUnitForEntity(entity.enclosingClass);
     }
diff --git a/pkg/compiler/lib/src/diagnostics/diagnostic_listener.dart b/pkg/compiler/lib/src/diagnostics/diagnostic_listener.dart
index 0e4d08d..e44df31 100644
--- a/pkg/compiler/lib/src/diagnostics/diagnostic_listener.dart
+++ b/pkg/compiler/lib/src/diagnostics/diagnostic_listener.dart
@@ -4,7 +4,6 @@
 
 library dart2js.diagnostic_listener;
 
-import 'package:front_end/src/fasta/scanner.dart' show Token;
 import '../elements/entities.dart';
 import '../options.dart' show DiagnosticOptions;
 import 'messages.dart';
@@ -26,12 +25,6 @@
   /// tokens can be found within the tokens of the current element.
   SourceSpan spanFromSpannable(Spannable node);
 
-  /// Creates a [SourceSpan] for [token] in scope of the current element.
-  ///
-  /// In checked mode we assert that the token can be found within the tokens
-  /// of the current element.
-  SourceSpan spanFromToken(Token token);
-
   void reportErrorMessage(Spannable spannable, MessageKind messageKind,
       [Map arguments = const {}]) {
     reportError(createMessage(spannable, messageKind, arguments));
diff --git a/pkg/compiler/lib/src/diagnostics/invariant.dart b/pkg/compiler/lib/src/diagnostics/invariant.dart
index bdfc7f2..11b446c 100644
--- a/pkg/compiler/lib/src/diagnostics/invariant.dart
+++ b/pkg/compiler/lib/src/diagnostics/invariant.dart
@@ -6,12 +6,6 @@
 
 import 'spannable.dart';
 
-/**
- * If true, print a warning for each method that was resolved, but not
- * compiled.
- */
-const bool REPORT_EXCESS_RESOLUTION = false;
-
 /// Flag that can be used in assertions to assert that a code path is only
 /// executed as part of development.
 ///
diff --git a/pkg/compiler/lib/src/diagnostics/source_span.dart b/pkg/compiler/lib/src/diagnostics/source_span.dart
index 638a923..3fffc29 100644
--- a/pkg/compiler/lib/src/diagnostics/source_span.dart
+++ b/pkg/compiler/lib/src/diagnostics/source_span.dart
@@ -4,8 +4,6 @@
 
 library dart2js.diagnostics.source_span;
 
-import 'package:front_end/src/fasta/scanner.dart' show Token;
-import '../tree/tree.dart' show Node;
 import 'spannable.dart' show Spannable;
 
 class SourceSpan implements Spannable {
@@ -15,21 +13,6 @@
 
   const SourceSpan(this.uri, this.begin, this.end);
 
-  factory SourceSpan.fromNode(Uri uri, Node node) {
-    return new SourceSpan.fromTokens(
-        uri, node.getBeginToken(), node.getPrefixEndToken());
-  }
-
-  factory SourceSpan.fromTokens(Uri uri, Token begin, Token end) {
-    final beginOffset = begin.charOffset;
-    final endOffset = end.charOffset + end.charCount;
-
-    // [begin] and [end] might be the same for the same empty token. This
-    // happens for instance when scanning '$$'.
-    assert(endOffset >= beginOffset);
-    return new SourceSpan(uri, beginOffset, endOffset);
-  }
-
   int get hashCode {
     return 13 * uri.hashCode + 17 * begin.hashCode + 19 * end.hashCode;
   }
diff --git a/pkg/compiler/lib/src/dump_info.dart b/pkg/compiler/lib/src/dump_info.dart
index 251dacd..75010fd 100644
--- a/pkg/compiler/lib/src/dump_info.dart
+++ b/pkg/compiler/lib/src/dump_info.dart
@@ -17,15 +17,12 @@
 import 'compiler.dart' show Compiler;
 import 'constants/values.dart' show ConstantValue, InterceptorConstantValue;
 import 'deferred_load.dart' show OutputUnit;
-import 'elements/elements.dart';
 import 'elements/entities.dart';
 import 'js/js.dart' as jsAst;
 import 'js_backend/js_backend.dart' show JavaScriptBackend;
+import 'types/masks.dart';
 import 'types/types.dart'
-    show
-        GlobalTypeInferenceElementResult,
-        GlobalTypeInferenceMemberResult,
-        TypeMask;
+    show GlobalTypeInferenceElementResult, GlobalTypeInferenceMemberResult;
 import 'universe/world_builder.dart'
     show CodegenWorldBuilder, ReceiverConstraint;
 import 'universe/world_impact.dart'
@@ -179,8 +176,6 @@
 
   ClassInfo visitClass(ClassEntity clazz) {
     // Omit class if it is not needed.
-    if (!_hasClassBeenResolved(clazz)) return null;
-
     ClassInfo classInfo = new ClassInfo(
         name: clazz.name,
         isAbstract: clazz.isAbstract,
@@ -385,10 +380,6 @@
     }
     return _infoFromOutputUnit(outputUnit);
   }
-
-  bool _hasClassBeenResolved(ClassEntity cls) {
-    return compiler.backend.mirrorsData.isClassResolved(cls);
-  }
 }
 
 class Selection {
@@ -451,9 +442,6 @@
   }
 
   void reportInlined(FunctionEntity element, MemberEntity inlinedFrom) {
-    assert(!(element is MethodElement && !element.isDeclaration));
-    assert(!(inlinedFrom is MemberElement && !inlinedFrom.isDeclaration));
-
     inlineCount.putIfAbsent(element, () => 0);
     inlineCount[element] += 1;
     inlineMap.putIfAbsent(inlinedFrom, () => new List<Entity>());
diff --git a/pkg/compiler/lib/src/elements/common.dart b/pkg/compiler/lib/src/elements/common.dart
deleted file mode 100644
index 6990e6a..0000000
--- a/pkg/compiler/lib/src/elements/common.dart
+++ /dev/null
@@ -1,678 +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.
-
-/// Mixins that implement convenience methods on [Element] subclasses.
-
-library elements.common;
-
-import '../common/names.dart' show Identifiers, Names, Uris;
-import '../common_elements.dart' show CommonElements;
-import '../util/util.dart' show Link;
-import 'entities.dart';
-import 'elements.dart';
-import 'names.dart';
-import 'types.dart';
-import 'resolution_types.dart'
-    show ResolutionDartType, ResolutionInterfaceType, ResolutionFunctionType;
-
-abstract class ElementCommon implements Element {
-  @override
-  bool get isLibrary => kind == ElementKind.LIBRARY;
-
-  @override
-  bool get isCompilationUnit => kind == ElementKind.COMPILATION_UNIT;
-
-  @override
-  bool get isPrefix => kind == ElementKind.PREFIX;
-
-  @override
-  bool get isClass => kind == ElementKind.CLASS;
-
-  @override
-  bool get isTypeVariable => kind == ElementKind.TYPE_VARIABLE;
-
-  @override
-  bool get isTypedef => kind == ElementKind.TYPEDEF;
-
-  @override
-  bool get isFunction => kind == ElementKind.FUNCTION;
-
-  @override
-  bool get isAccessor => isGetter || isSetter;
-
-  @override
-  bool get isGetter => kind == ElementKind.GETTER;
-
-  @override
-  bool get isSetter => kind == ElementKind.SETTER;
-
-  @override
-  bool get isConstructor => isGenerativeConstructor || isFactoryConstructor;
-
-  @override
-  bool get isGenerativeConstructor =>
-      kind == ElementKind.GENERATIVE_CONSTRUCTOR;
-
-  @override
-  bool get isGenerativeConstructorBody =>
-      kind == ElementKind.GENERATIVE_CONSTRUCTOR_BODY;
-
-  bool get isFactoryConstructor => kind == ElementKind.FACTORY_CONSTRUCTOR;
-
-  @override
-  bool get isVariable => kind == ElementKind.VARIABLE;
-
-  @override
-  bool get isField => kind == ElementKind.FIELD;
-
-  @override
-  bool get isAbstractField => kind == ElementKind.ABSTRACT_FIELD;
-
-  @override
-  bool get isRegularParameter => kind == ElementKind.PARAMETER;
-
-  @override
-  bool get isInitializingFormal => kind == ElementKind.INITIALIZING_FORMAL;
-
-  @override
-  bool get isError => kind == ElementKind.ERROR;
-
-  @override
-  bool get isAmbiguous => kind == ElementKind.AMBIGUOUS;
-
-  @override
-  bool get isMalformed => false;
-
-  @override
-  bool get isWarnOnUse => kind == ElementKind.WARN_ON_USE;
-
-  @override
-  bool get impliesType => (kind.category & ElementCategory.IMPLIES_TYPE) != 0;
-
-  @override
-  bool get isAssignable {
-    if (isFinal || isConst) return false;
-    if (isFunction || isGetter || isConstructor) return false;
-    return true;
-  }
-
-  @override
-  Element get declaration => this;
-
-  @override
-  Element get implementation => this;
-
-  @override
-  bool get isDeclaration => true;
-
-  @override
-  bool get isPatched => false;
-
-  @override
-  bool get isPatch => false;
-
-  @override
-  bool get isImplementation => true;
-
-  @override
-  bool get isInjected => !isPatch && implementationLibrary.isPatch;
-
-  @override
-  Element get patch {
-    throw new UnsupportedError('patch is not supported on $this');
-  }
-
-  @override
-  Element get origin {
-    throw new UnsupportedError('origin is not supported on $this');
-  }
-
-  @override
-  ClassElement get contextClass {
-    ClassElement cls;
-    for (Element e = this; e != null; e = e.enclosingElement) {
-      if (e.isClass) {
-        // Record [e] instead of returning it directly. We need the last class
-        // in the chain since the first classes might be closure classes.
-        cls = e.declaration;
-      }
-    }
-    return cls;
-  }
-
-  @override
-  Element get outermostEnclosingMemberOrTopLevel {
-    // TODO(lrn): Why is this called "Outermost"?
-    // TODO(johnniwinther): Clean up this method: This method does not return
-    // the outermost for elements in closure classes, but some call-sites rely
-    // on that behavior.
-    for (Element e = this; e != null; e = e.enclosingElement) {
-      if (e.isClassMember || e.isTopLevel) {
-        return e;
-      }
-    }
-    return null;
-  }
-
-  Element get enclosingClassOrCompilationUnit {
-    for (Element e = this; e != null; e = e.enclosingElement) {
-      if (e.isClass || e.isCompilationUnit) return e;
-    }
-    return null;
-  }
-}
-
-abstract class LibraryElementCommon implements LibraryElement {
-  @override
-  bool get isDartCore => canonicalUri == Uris.dart_core;
-
-  @override
-  bool get isPlatformLibrary => canonicalUri.scheme == 'dart';
-
-  @override
-  bool get isPackageLibrary => canonicalUri.scheme == 'package';
-
-  @override
-  bool get isInternalLibrary =>
-      isPlatformLibrary && canonicalUri.path.startsWith('_');
-
-  String get name {
-    if (hasLibraryName) {
-      return libraryName;
-    } else {
-      // Use the file name as script name.
-      String path = canonicalUri.path;
-      return path.substring(path.lastIndexOf('/') + 1);
-    }
-  }
-}
-
-abstract class CompilationUnitElementCommon implements CompilationUnitElement {}
-
-abstract class ClassElementCommon implements ClassElement {
-  @override
-  Link<InterfaceType> get allSupertypes => allSupertypesAndSelf.supertypes;
-
-  @override
-  int get hierarchyDepth => allSupertypesAndSelf.maxDepth;
-
-  @override
-  ResolutionInterfaceType asInstanceOf(ClassElement cls) {
-    if (cls == this) return thisType;
-    return allSupertypesAndSelf.asInstanceOf(cls, cls.hierarchyDepth);
-  }
-
-  @override
-  ConstructorElement lookupConstructor(String name) {
-    Element result = localLookup(name);
-    return result != null && result.isConstructor ? result : null;
-  }
-
-  /**
-   * Find the first member in the class chain with the given [memberName].
-   *
-   * This method is NOT to be used for resolving
-   * unqualified sends because it does not implement the scoping
-   * rules, where library scope comes before superclass scope.
-   *
-   * When called on the implementation element both members declared in the
-   * origin and the patch class are returned.
-   */
-  MemberElement lookupByName(Name memberName, {ClassElement stopAt}) {
-    return internalLookupByName(memberName,
-        isSuperLookup: false, stopAtSuperclass: stopAt);
-  }
-
-  MemberElement lookupSuperByName(Name memberName) {
-    return internalLookupByName(memberName, isSuperLookup: true);
-  }
-
-  MemberElement internalLookupByName(Name memberName,
-      {bool isSuperLookup, ClassElement stopAtSuperclass}) {
-    String name = memberName.text;
-    bool isPrivate = memberName.isPrivate;
-    LibraryElement library = memberName.library;
-    for (ClassElement current = isSuperLookup ? superclass : this;
-        current != null && current != stopAtSuperclass;
-        current = current.superclass) {
-      Element member = current.lookupLocalMember(name);
-      if (member == null && current.isPatched) {
-        // Doing lookups on selectors is done after resolution, so it
-        // is safe to look in the patch class.
-        member = current.patch.lookupLocalMember(name);
-      }
-      if (member == null) continue;
-      // Private members from a different library are not visible.
-      if (isPrivate && !identical(library, member.library)) continue;
-      // Static members are not inherited.
-      if (member.isStatic && !identical(this, current)) continue;
-      // If we find an abstract field we have to make sure that it has
-      // the getter or setter part we're actually looking
-      // for. Otherwise, we continue up the superclass chain.
-      if (member.isAbstractField) {
-        AbstractFieldElement field = member;
-        GetterElement getter = field.getter;
-        SetterElement setter = field.setter;
-        if (memberName.isSetter) {
-          // Abstract members can be defined in a super class.
-          if (setter != null && !setter.isAbstract) {
-            return setter;
-          }
-        } else {
-          if (getter != null && !getter.isAbstract) {
-            return getter;
-          }
-        }
-        // Abstract members can be defined in a super class.
-      } else if (!member.isAbstract && !member.isMalformed) {
-        return member;
-      }
-    }
-    return null;
-  }
-
-  /**
-   * Find the first member in the class chain with the given
-   * [memberName]. This method is NOT to be used for resolving
-   * unqualified sends because it does not implement the scoping
-   * rules, where library scope comes before superclass scope.
-   */
-  @override
-  Element lookupMember(String memberName) {
-    Element localMember = lookupLocalMember(memberName);
-    return localMember == null ? lookupSuperMember(memberName) : localMember;
-  }
-
-  @override
-  Link<Element> get constructors {
-    // TODO(ajohnsen): See if we can avoid this method at some point.
-    Link<Element> result = const Link<Element>();
-    // TODO(johnniwinther): Should we include injected constructors?
-    forEachMember((_, Element member) {
-      if (member.isConstructor) result = result.prepend(member);
-    });
-    return result;
-  }
-
-  /**
-   * Lookup super members for the class. This will ignore constructors.
-   */
-  @override
-  Element lookupSuperMember(String memberName) {
-    return lookupSuperMemberInLibrary(memberName, library);
-  }
-
-  /**
-   * Lookup super members for the class that is accessible in [library].
-   * This will ignore constructors.
-   */
-  @override
-  Element lookupSuperMemberInLibrary(
-      String memberName, LibraryElement library) {
-    bool isPrivate = Name.isPrivateName(memberName);
-    for (ClassElement s = superclass; s != null; s = s.superclass) {
-      // Private members from a different library are not visible.
-      if (isPrivate && !identical(library, s.library)) continue;
-      Element e = s.lookupLocalMember(memberName);
-      if (e == null) continue;
-      // Static members are not inherited.
-      if (e.isStatic) continue;
-      return e;
-    }
-    return null;
-  }
-
-  /**
-   * Lookup local members in the class. This will ignore constructors.
-   */
-  @override
-  Element lookupLocalMember(String memberName) {
-    var result = localLookup(memberName);
-    if (result != null && result.isConstructor) return null;
-    return result;
-  }
-
-  /**
-   * Runs through all members of this class.
-   *
-   * The enclosing class is passed to the callback. This is useful when
-   * [includeSuperAndInjectedMembers] is [:true:].
-   *
-   * When called on an implementation element both the members in the origin
-   * and patch class are included.
-   */
-  // TODO(johnniwinther): Clean up lookup to get rid of the include predicates.
-  @override
-  void forEachMember(void f(ClassElement enclosingClass, Element member),
-      {includeBackendMembers: false, includeSuperAndInjectedMembers: false}) {
-    bool includeInjectedMembers = includeSuperAndInjectedMembers || isPatch;
-    ClassElement classElement = declaration;
-    do {
-      // Iterate through the members in textual order, which requires
-      // to reverse the data structure [localMembers] we created.
-      // Textual order may be important for certain operations, for
-      // example when emitting the initializers of fields.
-      classElement.forEachLocalMember((e) => f(classElement, e));
-      if (includeBackendMembers) {
-        classElement.forEachConstructorBody((e) => f(classElement, e));
-      }
-      if (includeInjectedMembers) {
-        if (classElement.isPatched) {
-          classElement.patch.forEachLocalMember((e) {
-            if (!e.isPatch) f(classElement, e);
-          });
-        }
-      }
-      classElement =
-          includeSuperAndInjectedMembers ? classElement.superclass : null;
-    } while (classElement != null);
-  }
-
-  /**
-   * Runs through all instance-field members of this class.
-   *
-   * The enclosing class is passed to the callback. This is useful when
-   * [includeSuperAndInjectedMembers] is [:true:].
-   *
-   * When called on the implementation element both the fields declared in the
-   * origin and in the patch are included.
-   */
-  @override
-  void forEachInstanceField(
-      void f(ClassElement enclosingClass, FieldElement field),
-      {bool includeSuperAndInjectedMembers: false}) {
-    // Filters so that [f] is only invoked with instance fields.
-    void fieldFilter(ClassElement enclosingClass, Element member) {
-      if (member.isInstanceMember && member.kind == ElementKind.FIELD) {
-        f(enclosingClass, member);
-      }
-    }
-
-    forEachMember(fieldFilter,
-        includeSuperAndInjectedMembers: includeSuperAndInjectedMembers);
-  }
-
-  /// Similar to [forEachInstanceField] but visits static fields.
-  @override
-  void forEachStaticField(void f(ClassElement enclosingClass, Element field)) {
-    // Filters so that [f] is only invoked with static fields.
-    void fieldFilter(ClassElement enclosingClass, Element member) {
-      if (!member.isInstanceMember && member.kind == ElementKind.FIELD) {
-        f(enclosingClass, member);
-      }
-    }
-
-    forEachMember(fieldFilter);
-  }
-
-  /**
-   * Returns true if the [fieldMember] shadows another field.  The given
-   * [fieldMember] must be a member of this class, i.e. if there is a field of
-   * the same name in the superclass chain.
-   *
-   * This method also works if the [fieldMember] is private.
-   */
-  @override
-  bool hasFieldShadowedBy(FieldElement fieldMember) {
-    assert(fieldMember.isField);
-    String fieldName = fieldMember.name;
-    bool isPrivate = Name.isPrivateName(fieldName);
-    LibraryElement memberLibrary = fieldMember.library;
-    ClassElement lookupClass = this.superclass;
-    while (lookupClass != null) {
-      Element foundMember = lookupClass.lookupLocalMember(fieldName);
-      if (foundMember != null) {
-        if (foundMember.isField) {
-          if (!isPrivate || memberLibrary == foundMember.library) {
-            // Private fields can only be shadowed by a field declared in the
-            // same library.
-            return true;
-          }
-        }
-      }
-      lookupClass = lookupClass.superclass;
-    }
-    return false;
-  }
-
-  @override
-  bool implementsInterface(ClassElement interface) {
-    return this != interface &&
-        allSupertypesAndSelf.asInstanceOf(
-                interface, interface.hierarchyDepth) !=
-            null;
-  }
-
-  @override
-  bool implementsFunction(CommonElements commonElements) {
-    return asInstanceOf(commonElements.functionClass) != null ||
-        callType != null;
-  }
-
-  @override
-  bool isSubclassOf(ClassElement cls) {
-    // Use [declaration] for both [this] and [cls], because
-    // declaration classes hold the superclass hierarchy.
-    cls = cls.declaration;
-    for (ClassElement s = declaration; s != null; s = s.superclass) {
-      if (identical(s, cls)) return true;
-    }
-    return false;
-  }
-
-  ResolutionFunctionType get callType {
-    MemberSignature member = lookupInterfaceMember(Names.call);
-    return member != null && member.isMethod ? member.type : null;
-  }
-
-  @override
-  bool get isNamedMixinApplication {
-    return isMixinApplication && !isUnnamedMixinApplication;
-  }
-
-  // backendMembers are members that have been added by the backend to simplify
-  // compilation. They don't have any user-side counter-part.
-  List<ConstructorBodyElement> constructorBodies = <ConstructorBodyElement>[];
-
-  bool get hasConstructorBodies => !constructorBodies.isEmpty;
-
-  void addConstructorBody(ConstructorBodyElement member) {
-    // TODO(ngeoffray): Deprecate this method.
-    assert(member.isGenerativeConstructorBody);
-    constructorBodies.add(member);
-  }
-
-  /// Lookup a synthetic element created by the backend.
-  ConstructorBodyElement lookupConstructorBody(String memberName) {
-    for (ConstructorBodyElement element in constructorBodies) {
-      if (element.name == memberName) {
-        return element;
-      }
-    }
-    return null;
-  }
-
-  void forEachConstructorBody(void f(ConstructorBodyElement member)) {
-    constructorBodies.forEach(f);
-  }
-}
-
-abstract class FunctionSignatureCommon implements FunctionSignature {
-  ParameterStructure _parameterStructure;
-
-  ResolutionDartType get returnType => type.returnType;
-
-  void forEachRequiredParameter(void function(FormalElement parameter)) {
-    requiredParameters.forEach(function);
-  }
-
-  void forEachOptionalParameter(void function(FormalElement parameter)) {
-    optionalParameters.forEach(function);
-  }
-
-  void forEachParameter(void function(FormalElement parameter)) {
-    forEachRequiredParameter(function);
-    forEachOptionalParameter(function);
-  }
-
-  void orderedForEachParameter(void function(FormalElement parameter)) {
-    forEachRequiredParameter(function);
-    orderedOptionalParameters.forEach(function);
-  }
-
-  int get parameterCount => requiredParameterCount + optionalParameterCount;
-
-  /**
-   * Check whether a function with this signature can be used instead of a
-   * function with signature [signature] without causing a `noSuchMethod`
-   * exception/call.
-   */
-  bool isCompatibleWith(FunctionSignature signature) {
-    if (optionalParametersAreNamed) {
-      if (!signature.optionalParametersAreNamed) {
-        return requiredParameterCount == signature.parameterCount;
-      }
-      // If both signatures have named parameters, then they must have
-      // the same number of required parameters, and the names in
-      // [signature] must all be in [:this:].
-      if (requiredParameterCount != signature.requiredParameterCount) {
-        return false;
-      }
-      Set<String> names =
-          optionalParameters.map((Element element) => element.name).toSet();
-      for (Element namedParameter in signature.optionalParameters) {
-        if (!names.contains(namedParameter.name)) {
-          return false;
-        }
-      }
-    } else {
-      if (signature.optionalParametersAreNamed) return false;
-      // There must be at least as many arguments as in the other signature, but
-      // this signature must not have more required parameters.  Having more
-      // optional parameters is not a problem, they simply are never provided
-      // by call sites of a call to a method with the other signature.
-      int otherTotalCount = signature.parameterCount;
-      return requiredParameterCount <= otherTotalCount &&
-          parameterCount >= otherTotalCount;
-    }
-    return true;
-  }
-
-  ParameterStructure get parameterStructure {
-    if (_parameterStructure == null) {
-      int requiredParameters = requiredParameterCount;
-      int positionalParameters;
-      List<String> namedParameters;
-      if (optionalParametersAreNamed) {
-        namedParameters = type.namedParameters;
-        positionalParameters = requiredParameters;
-      } else {
-        namedParameters = const <String>[];
-        positionalParameters = requiredParameters + optionalParameterCount;
-      }
-      _parameterStructure = new ParameterStructure(
-          requiredParameters, positionalParameters, namedParameters, 0);
-    }
-    return _parameterStructure;
-  }
-}
-
-abstract class MixinApplicationElementCommon
-    implements MixinApplicationElement {
-  Link<ConstructorElement> get constructors {
-    throw new UnsupportedError('Unimplemented $this.constructors');
-  }
-
-  FunctionElement _lookupLocalConstructor(String name) {
-    for (Link<Element> link = constructors; !link.isEmpty; link = link.tail) {
-      if (link.head.name == name) return link.head;
-    }
-    return null;
-  }
-
-  @override
-  Element localLookup(String name) {
-    Element constructor = _lookupLocalConstructor(name);
-    if (constructor != null) return constructor;
-    if (mixin == null) return null;
-    Element mixedInElement = mixin.localLookup(name);
-    if (mixedInElement == null) return null;
-    return mixedInElement.isInstanceMember ? mixedInElement : null;
-  }
-
-  @override
-  void forEachLocalMember(void f(Element member)) {
-    constructors.forEach(f);
-    if (mixin != null)
-      mixin.forEachLocalMember((Element mixedInElement) {
-        if (mixedInElement.isInstanceMember) f(mixedInElement);
-      });
-  }
-}
-
-abstract class AbstractFieldElementCommon implements AbstractFieldElement {
-  @override
-  bool get isInstanceMember {
-    return isClassMember && !isStatic;
-  }
-
-  @override
-  bool get isAbstract {
-    return getter != null && getter.isAbstract ||
-        setter != null && setter.isAbstract;
-  }
-}
-
-enum _FromEnvironmentState {
-  NOT,
-  BOOL,
-  INT,
-  STRING,
-}
-
-abstract class ConstructorElementCommon implements ConstructorElement {
-  LibraryElement get library;
-
-  _FromEnvironmentState _fromEnvironmentState;
-
-  _FromEnvironmentState get fromEnvironmentState {
-    if (_fromEnvironmentState == null) {
-      _fromEnvironmentState = _FromEnvironmentState.NOT;
-      if (name == Identifiers.fromEnvironment && library.isDartCore) {
-        switch (enclosingClass.name) {
-          case 'bool':
-            _fromEnvironmentState = _FromEnvironmentState.BOOL;
-            break;
-          case 'int':
-            _fromEnvironmentState = _FromEnvironmentState.INT;
-            break;
-          case 'String':
-            _fromEnvironmentState = _FromEnvironmentState.STRING;
-            break;
-        }
-      }
-    }
-    return _fromEnvironmentState;
-  }
-
-  @override
-  bool get isFromEnvironmentConstructor {
-    return fromEnvironmentState != _FromEnvironmentState.NOT;
-  }
-
-  @override
-  bool get isIntFromEnvironmentConstructor {
-    return fromEnvironmentState == _FromEnvironmentState.INT;
-  }
-
-  @override
-  bool get isBoolFromEnvironmentConstructor {
-    return fromEnvironmentState == _FromEnvironmentState.BOOL;
-  }
-
-  @override
-  bool get isStringFromEnvironmentConstructor {
-    return fromEnvironmentState == _FromEnvironmentState.STRING;
-  }
-}
diff --git a/pkg/compiler/lib/src/elements/elements.dart b/pkg/compiler/lib/src/elements/elements.dart
deleted file mode 100644
index c282f29..0000000
--- a/pkg/compiler/lib/src/elements/elements.dart
+++ /dev/null
@@ -1,1931 +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.
-
-library elements;
-
-import 'package:front_end/src/fasta/scanner.dart'
-    show Token, isUserDefinableOperator, isMinusOperator;
-
-import '../common.dart';
-import '../common/resolution.dart' show Resolution;
-import '../common_elements.dart' show CommonElements;
-import '../constants/constructors.dart';
-import '../constants/expressions.dart';
-import '../ordered_typeset.dart' show OrderedTypeSet;
-import '../resolution/scope.dart' show Scope;
-import '../resolution/tree_elements.dart' show TreeElements;
-import '../script.dart';
-import '../tree/tree.dart' hide AsyncModifier;
-import '../universe/call_structure.dart';
-import '../util/util.dart';
-import '../world.dart' show ClosedWorld;
-import 'entities.dart';
-import 'entity_utils.dart' as utils;
-import 'jumps.dart';
-import 'names.dart';
-import 'resolution_types.dart';
-import 'types.dart';
-import 'visitor.dart' show ElementVisitor;
-
-const int STATE_NOT_STARTED = 0;
-const int STATE_STARTED = 1;
-const int STATE_DONE = 2;
-
-class ElementCategory {
-  /**
-   * Represents things that we don't expect to find when looking in a
-   * scope.
-   */
-  static const int NONE = 0;
-
-  /** Field, parameter, or variable. */
-  static const int VARIABLE = 1;
-
-  /** Function, method, or foreign function. */
-  static const int FUNCTION = 2;
-
-  static const int CLASS = 4;
-
-  static const int PREFIX = 8;
-
-  /** Constructor or factory. */
-  static const int FACTORY = 16;
-
-  static const int ALIAS = 32;
-
-  static const int SUPER = 64;
-
-  /** Type variable */
-  static const int TYPE_VARIABLE = 128;
-
-  static const int IMPLIES_TYPE = CLASS | ALIAS | TYPE_VARIABLE;
-}
-
-class ElementKind {
-  final String id;
-  final int category;
-
-  const ElementKind(String this.id, this.category);
-
-  static const ElementKind VARIABLE =
-      const ElementKind('variable', ElementCategory.VARIABLE);
-  static const ElementKind PARAMETER =
-      const ElementKind('parameter', ElementCategory.VARIABLE);
-  // Parameters in constructors that directly initialize fields. For example:
-  // [:A(this.field):].
-  static const ElementKind INITIALIZING_FORMAL =
-      const ElementKind('initializing_formal', ElementCategory.VARIABLE);
-  static const ElementKind FUNCTION =
-      const ElementKind('function', ElementCategory.FUNCTION);
-  static const ElementKind CLASS =
-      const ElementKind('class', ElementCategory.CLASS);
-  static const ElementKind GENERATIVE_CONSTRUCTOR =
-      const ElementKind('generative_constructor', ElementCategory.FACTORY);
-  static const ElementKind FACTORY_CONSTRUCTOR =
-      const ElementKind('factory_constructor', ElementCategory.FACTORY);
-  static const ElementKind FIELD =
-      const ElementKind('field', ElementCategory.VARIABLE);
-  static const ElementKind GENERATIVE_CONSTRUCTOR_BODY =
-      const ElementKind('generative_constructor_body', ElementCategory.NONE);
-  static const ElementKind COMPILATION_UNIT =
-      const ElementKind('compilation_unit', ElementCategory.NONE);
-  static const ElementKind GETTER =
-      const ElementKind('getter', ElementCategory.NONE);
-  static const ElementKind SETTER =
-      const ElementKind('setter', ElementCategory.NONE);
-  static const ElementKind TYPE_VARIABLE =
-      const ElementKind('type_variable', ElementCategory.TYPE_VARIABLE);
-  static const ElementKind ABSTRACT_FIELD =
-      const ElementKind('abstract_field', ElementCategory.VARIABLE);
-  static const ElementKind LIBRARY =
-      const ElementKind('library', ElementCategory.NONE);
-  static const ElementKind IMPORT =
-      const ElementKind('import', ElementCategory.NONE);
-  static const ElementKind EXPORT =
-      const ElementKind('export', ElementCategory.NONE);
-  static const ElementKind PREFIX =
-      const ElementKind('prefix', ElementCategory.PREFIX);
-  static const ElementKind TYPEDEF =
-      const ElementKind('typedef', ElementCategory.ALIAS);
-
-  static const ElementKind AMBIGUOUS =
-      const ElementKind('ambiguous', ElementCategory.NONE);
-  static const ElementKind WARN_ON_USE =
-      const ElementKind('warn_on_use', ElementCategory.NONE);
-  static const ElementKind ERROR =
-      const ElementKind('error', ElementCategory.NONE);
-
-  toString() => id;
-}
-
-/**
- * A declared element of a program.
- *
- * The declared elements of a program include classes, methods,
- * fields, variables, parameters, etc.
- *
- * Sometimes it makes sense to construct "synthetic" elements that
- * have not been declared anywhere in a program, for example, there
- * are elements corresponding to "dynamic", "null", and unresolved
- * references.
- *
- * Elements are distinct from types ([ResolutionDartType]). For example, there
- * is one declaration of the class List, but several related types,
- * for example, List, List<int>, List<String>, etc.
- *
- * Elements are distinct from AST nodes ([Node]), and there normally is a
- * one-to-one correspondence between an AST node and an element
- * (except that not all kinds of AST nodes have an associated
- * element).
- *
- * AST nodes represent precisely what is written in source code, for
- * example, when a user writes "class MyClass {}", the corresponding
- * AST node does not have a superclass. On the other hand, the
- * corresponding element (once fully resolved) will record the
- * information about the implicit superclass as defined by the
- * language semantics.
- *
- * Generally, the contents of a method are represented as AST nodes
- * without additional elements, but things like local functions, local
- * variables, and labels have a corresponding element.
- *
- * We generally say that scanning, parsing, resolution, and type
- * checking comprise the "front-end" of the compiler. The "back-end"
- * includes things like SSA graph construction, optimizations, and
- * code generation.
- *
- * The front-end data structures are designed to be reusable by
- * several back-ends.  For example, we may want to support emitting
- * minified Dart and JavaScript code in one go.  Also, we're planning
- * on adding an incremental compilation server that should be able to
- * reuse elements between compilations.  So to keep things simple, it
- * is best if the backends avoid setting state directly in elements.
- * It is better to keep such state in a table on the side.
- */
-abstract class Element implements Entity {
-  String get name;
-  ElementKind get kind;
-  Element get enclosingElement;
-  Iterable<MetadataAnnotation> get metadata;
-
-  /// `true` if this element is a library.
-  bool get isLibrary;
-
-  /// `true` if this element is an import declaration.
-  bool get isImport => kind == ElementKind.IMPORT;
-
-  /// `true` if this element is an export declaration.
-  bool get isExport => kind == ElementKind.EXPORT;
-
-  /// `true` if this element is a compilation unit.
-  bool get isCompilationUnit;
-
-  /// `true` if this element is defines the scope of prefix used by one or
-  /// more import declarations.
-  bool get isPrefix;
-
-  /// `true` if this element is a class declaration or a mixin application.
-  bool get isClass;
-
-  /// `true` if this element is a type variable declaration.
-  bool get isTypeVariable;
-
-  /// `true` if this element is a typedef declaration.
-  bool get isTypedef;
-
-  /// `true` if this element is a top level function, static or instance
-  /// method, local function or closure defined by a function expression.
-  ///
-  /// This property is `true` for operator methods but `false` for getter and
-  /// setter methods, and generative and factory constructors.
-  ///
-  /// See also [isConstructor], [isGenerativeConstructor], and
-  /// [isFactoryConstructor] for constructor properties, and [isAccessor],
-  /// [isGetter] and [isSetter] for getter/setter properties.
-  bool get isFunction;
-
-  /// `true` if this element is an operator method.
-  bool get isOperator;
-
-  /// `true` if this element is an accessor, that is either an explicit
-  /// getter or an explicit setter.
-  bool get isAccessor;
-
-  /// `true` if this element is an explicit getter method.
-  bool get isGetter;
-
-  /// `true` if this element is an explicit setter method.
-  bool get isSetter;
-
-  /// `true` if this element is a generative or factory constructor.
-  bool get isConstructor;
-
-  /// `true` if this element is a generative constructor, potentially
-  /// redirecting.
-  bool get isGenerativeConstructor;
-
-  /// `true` if this element is the body of a generative constructor.
-  ///
-  /// This is a synthetic element kind used only by the JavaScript backend.
-  bool get isGenerativeConstructorBody;
-
-  /// `true` if this element is a factory constructor,
-  /// potentially redirecting.
-  bool get isFactoryConstructor;
-
-  /// `true` if this element is a local variable.
-  bool get isVariable;
-
-  /// `true` if this element is a top level variable, static or instance field.
-  bool get isField;
-
-  /// `true` if this element is the abstract field implicitly defined by an
-  /// explicit getter and/or setter.
-  bool get isAbstractField;
-
-  /// `true` if this element is a formal parameter from a constructor,
-  /// a method, a typedef declaration, or from an inlined function typed
-  /// parameter.
-  ///
-  /// This property is `false` if this element is an initializing formal.
-  /// See [isInitializingFormal].
-  bool get isRegularParameter;
-
-  /// `true` if this element is an initializing formal of constructor, that
-  /// is a formal of the form `this.foo`.
-  bool get isInitializingFormal;
-
-  /// `true` if this element is a formal parameter, either regular or
-  /// initializing.
-  bool get isParameter => isRegularParameter || isInitializingFormal;
-
-  /// `true` if this element represents a resolution error.
-  bool get isError;
-
-  /// `true` if this element represents an ambiguous name.
-  ///
-  /// Ambiguous names occur when two imports/exports contain different entities
-  /// by the same name. If an ambiguous name is resolved an warning or error
-  /// is produced.
-  bool get isAmbiguous;
-
-  /// True if there has been errors during resolution or parsing of this
-  /// element.
-  bool get isMalformed;
-
-  /// `true` if this element represents an entity whose access causes one or
-  /// more warnings.
-  bool get isWarnOnUse;
-
-  bool get isClosure;
-
-  /// `true` if the element is a (static or instance) member of a class.
-  ///
-  /// Members are constructors, methods and fields.
-  bool get isClassMember;
-
-  /// `true` if the element is a nonstatic member of a class.
-  ///
-  /// Instance members are methods and fields but not constructors.
-  bool get isInstanceMember;
-
-  /// Returns true if this [Element] is a top level element.
-  /// That is, if it is not defined within the scope of a class.
-  ///
-  /// This means whether the enclosing element is a compilation unit.
-  /// With the exception of [ClosureClassElement] that is considered top level
-  /// as all other classes.
-  bool get isTopLevel;
-  bool get isAssignable;
-
-  bool get isDeferredLoaderGetter;
-
-  /// True if the element is declared in a patch library but has no
-  /// corresponding declaration in the origin library.
-  bool get isInjected;
-
-  /// `true` if this element is a constructor, top level or local variable,
-  /// or static field that is declared `const`.
-  bool get isConst;
-
-  /// `true` if this element is a top level or local variable, static or
-  /// instance field, or parameter that is declared `final`.
-  bool get isFinal;
-
-  /// `true` if this element is a method, getter, setter or field that
-  /// is declared `static`.
-  bool get isStatic;
-
-  /// `true` if this element is local element, that is, a local variable,
-  /// local function or parameter.
-  bool get isLocal;
-
-  bool get impliesType;
-
-  /// The character offset of the declaration of this element within its
-  /// compilation unit, if available.
-  ///
-  /// This is used to sort the elements.
-  int get sourceOffset;
-
-  // TODO(johnniwinther): Remove this.
-  Token get position;
-
-  /// The position of the declaration of this element, if available.
-  SourceSpan get sourcePosition;
-
-  CompilationUnitElement get compilationUnit;
-  LibraryElement get library;
-  LibraryElement get implementationLibrary;
-  ClassElement get enclosingClass;
-  Element get enclosingClassOrCompilationUnit;
-  Element get outermostEnclosingMemberOrTopLevel;
-
-  // TODO(johnniwinther): Replace uses of this with [enclosingClass] when
-  // [ClosureClassElement] has been removed.
-  /// The enclosing class that defines the type environment for this element.
-  ClassElement get contextClass;
-
-  FunctionElement asFunctionElement();
-
-  /// Is [:true:] if this element has a corresponding patch.
-  ///
-  /// If [:true:] this element has a non-null [patch] field.
-  ///
-  /// See [:patch_parser.dart:] for a description of the terminology.
-  bool get isPatched;
-
-  /// Is [:true:] if this element is a patch.
-  ///
-  /// If [:true:] this element has a non-null [origin] field.
-  ///
-  /// See [:patch_parser.dart:] for a description of the terminology.
-  bool get isPatch;
-
-  /// Is [:true:] if this element defines the implementation for the entity of
-  /// this element.
-  ///
-  /// See [:patch_parser.dart:] for a description of the terminology.
-  bool get isImplementation;
-
-  /// Is [:true:] if this element introduces the entity of this element.
-  ///
-  /// See [:patch_parser.dart:] for a description of the terminology.
-  bool get isDeclaration;
-
-  /// Returns the element which defines the implementation for the entity of
-  /// this element.
-  ///
-  /// See [:patch_parser.dart:] for a description of the terminology.
-  Element get implementation;
-
-  /// Returns the element which introduces the entity of this element.
-  ///
-  /// See [:patch_parser.dart:] for a description of the terminology.
-  Element get declaration;
-
-  /// Returns the patch for this element if this element is patched.
-  ///
-  /// See [:patch_parser.dart:] for a description of the terminology.
-  Element get patch;
-
-  /// Returns the origin for this element if this element is a patch.
-  ///
-  /// See [:patch_parser.dart:] for a description of the terminology.
-  Element get origin;
-
-  bool get isSynthesized;
-  bool get isMixinApplication;
-
-  bool get isAbstract;
-
-  Scope buildScope();
-
-  // TODO(johnniwinther): Move this to [AstElement].
-  /// Returns the [Element] that holds the [TreeElements] for this element.
-  AnalyzableElement get analyzableElement;
-
-  accept(ElementVisitor visitor, arg);
-}
-
-class Elements {
-  static bool isUnresolved(Element e) {
-    return e == null || e.isMalformed;
-  }
-
-  static bool isError(Element e) {
-    return e != null && e.isError;
-  }
-
-  static bool isMalformed(Element e) {
-    return e != null && e.isMalformed;
-  }
-
-  /// Unwraps [element] reporting any warnings attached to it, if any.
-  static Element unwrap(
-      Element element, DiagnosticReporter listener, Spannable spannable) {
-    if (element != null && element.isWarnOnUse) {
-      WarnOnUseElement wrappedElement = element;
-      element = wrappedElement.unwrap(listener, spannable);
-    }
-    return element;
-  }
-
-  static bool isClass(Element e) => e != null && e.kind == ElementKind.CLASS;
-  static bool isTypedef(Element e) {
-    return e != null && e.kind == ElementKind.TYPEDEF;
-  }
-
-  static bool isLocal(Element element) {
-    return !Elements.isUnresolved(element) && element.isLocal;
-  }
-
-  static bool isInstanceField(Element element) {
-    return !Elements.isUnresolved(element) &&
-        element.isInstanceMember &&
-        (identical(element.kind, ElementKind.FIELD) ||
-            identical(element.kind, ElementKind.GETTER) ||
-            identical(element.kind, ElementKind.SETTER));
-  }
-
-  static bool isStaticOrTopLevel(Element element) {
-    // TODO(johnniwinther): Clean this up. This currently returns true for a
-    // PartialConstructorElement, SynthesizedConstructorElementX, and
-    // TypeVariableElementX though neither `element.isStatic` nor
-    // `element.isTopLevel` is true.
-    if (Elements.isUnresolved(element)) return false;
-    if (element.isStatic || element.isTopLevel) return true;
-    return !element.isAmbiguous &&
-        !element.isInstanceMember &&
-        !element.isPrefix &&
-        element.enclosingElement != null &&
-        (element.enclosingElement.kind == ElementKind.CLASS ||
-            element.enclosingElement.kind == ElementKind.COMPILATION_UNIT ||
-            element.enclosingElement.kind == ElementKind.LIBRARY ||
-            element.enclosingElement.kind == ElementKind.PREFIX);
-  }
-
-  static bool isInStaticContext(Element element) {
-    if (isUnresolved(element)) return true;
-    if (element.enclosingElement.isClosure) {
-      dynamic closureClass = element.enclosingElement;
-      // ignore: UNDEFINED_GETTER
-      element = closureClass.methodElement;
-    }
-    Element outer = element.outermostEnclosingMemberOrTopLevel;
-    if (isUnresolved(outer)) return true;
-    if (outer.isTopLevel) return true;
-    if (outer.isGenerativeConstructor) return false;
-    if (outer.isInstanceMember) return false;
-    return true;
-  }
-
-  static bool hasAccessToTypeVariable(
-      Element element, TypeVariableElement typeVariable) {
-    GenericElement declaration = typeVariable.typeDeclaration;
-    if (declaration is FunctionElement || declaration is ParameterElement) {
-      return true;
-    }
-    Element outer = element.outermostEnclosingMemberOrTopLevel;
-    return (outer != null && outer.isFactoryConstructor) ||
-        !isInStaticContext(element);
-  }
-
-  static bool isStaticOrTopLevelField(Element element) {
-    return isStaticOrTopLevel(element) &&
-        (identical(element.kind, ElementKind.FIELD) ||
-            identical(element.kind, ElementKind.GETTER) ||
-            identical(element.kind, ElementKind.SETTER));
-  }
-
-  static bool isStaticOrTopLevelFunction(Element element) {
-    return isStaticOrTopLevel(element) && element.isFunction;
-  }
-
-  static bool isInstanceMethod(Element element) {
-    return !Elements.isUnresolved(element) &&
-        element.isInstanceMember &&
-        (identical(element.kind, ElementKind.FUNCTION));
-  }
-
-  static bool isInstanceSend(Send send, TreeElements elements) {
-    Element element = elements[send];
-    if (element == null) return !isClosureSend(send, element);
-    return isInstanceMethod(element) ||
-        isInstanceField(element) ||
-        (send.isConditional && !element.isStatic);
-  }
-
-  static bool isClosureSend(Send send, Element element) {
-    if (send.isPropertyAccess) return false;
-    if (send.receiver != null) return false;
-    Node selector = send.selector;
-    // this().
-    if (selector.isThis()) return true;
-    // (o)() or foo()().
-    if (element == null && selector.asIdentifier() == null) return true;
-    if (element == null) return false;
-    // foo() with foo a local or a parameter.
-    return isLocal(element);
-  }
-
-  static String reconstructConstructorNameSourceString(FunctionEntity element) {
-    if (element.name == '') {
-      return element.enclosingClass.name;
-    } else {
-      return utils.reconstructConstructorName(element);
-    }
-  }
-
-  static String constructorNameForDiagnostics(
-      String className, String constructorName) {
-    String classNameString = className;
-    String constructorNameString = constructorName;
-    return (constructorName == '')
-        ? classNameString
-        : "$classNameString.$constructorNameString";
-  }
-
-  /// Returns `true` if [name] is the name of an operator method.
-  static bool isOperatorName(String name) {
-    return name == 'unary-' || isUserDefinableOperator(name);
-  }
-
-  /**
-   * Map an operator-name to a valid JavaScript identifier.
-   *
-   * For non-operator names, this method just returns its input.
-   *
-   * The results returned from this method are guaranteed to be valid
-   * JavaScript identifiers, except it may include reserved words for
-   * non-operator names.
-   */
-  static String operatorNameToIdentifier(String name) {
-    if (name == null) {
-      return name;
-    } else if (name == '==') {
-      return r'operator$eq';
-    } else if (name == '~') {
-      return r'operator$not';
-    } else if (name == '[]') {
-      return r'operator$index';
-    } else if (name == '[]=') {
-      return r'operator$indexSet';
-    } else if (name == '*') {
-      return r'operator$mul';
-    } else if (name == '/') {
-      return r'operator$div';
-    } else if (name == '%') {
-      return r'operator$mod';
-    } else if (name == '~/') {
-      return r'operator$tdiv';
-    } else if (name == '+') {
-      return r'operator$add';
-    } else if (name == '<<') {
-      return r'operator$shl';
-    } else if (name == '>>') {
-      return r'operator$shr';
-    } else if (name == '>=') {
-      return r'operator$ge';
-    } else if (name == '>') {
-      return r'operator$gt';
-    } else if (name == '<=') {
-      return r'operator$le';
-    } else if (name == '<') {
-      return r'operator$lt';
-    } else if (name == '&') {
-      return r'operator$and';
-    } else if (name == '^') {
-      return r'operator$xor';
-    } else if (name == '|') {
-      return r'operator$or';
-    } else if (name == '-') {
-      return r'operator$sub';
-    } else if (name == 'unary-') {
-      return r'operator$negate';
-    } else {
-      return name;
-    }
-  }
-
-  static String constructOperatorNameOrNull(String op, bool isUnary) {
-    if (isMinusOperator(op)) {
-      return isUnary ? 'unary-' : op;
-    } else if (isUserDefinableOperator(op) || op == '??') {
-      return op;
-    } else {
-      return null;
-    }
-  }
-
-  static String constructOperatorName(String op, bool isUnary) {
-    String operatorName = constructOperatorNameOrNull(op, isUnary);
-    if (operatorName == null)
-      throw 'Unhandled operator: $op';
-    else
-      return operatorName;
-  }
-
-  static String mapToUserOperatorOrNull(String op) {
-    if (identical(op, '!=')) return '==';
-    if (identical(op, '*=')) return '*';
-    if (identical(op, '/=')) return '/';
-    if (identical(op, '%=')) return '%';
-    if (identical(op, '~/=')) return '~/';
-    if (identical(op, '+=')) return '+';
-    if (identical(op, '-=')) return '-';
-    if (identical(op, '<<=')) return '<<';
-    if (identical(op, '>>=')) return '>>';
-    if (identical(op, '&=')) return '&';
-    if (identical(op, '^=')) return '^';
-    if (identical(op, '|=')) return '|';
-    if (identical(op, '??=')) return '??';
-
-    return null;
-  }
-
-  /// If `true`, members are sorted using their implementation fileUri.
-  ///
-  /// This is used for ensuring equivalent output order when testing against
-  /// .dill.
-  // TODO(johnniwinther): Remove this when patching correctly stores origin and
-  // patch file uris (issue 31579)
-  static bool useCFEOrder = false;
-
-  /// A `compareTo` function that places [Element]s in a consistent order based
-  /// on the source code order.
-  static int compareByPosition(Element a, Element b) {
-    if (identical(a, b)) return 0;
-    if (useCFEOrder) {
-      if (a is MethodElement) {
-        a = a.implementation;
-      }
-      if (b is MethodElement) {
-        b = b.implementation;
-      }
-    }
-    int r = utils.compareLibrariesUris(
-        a.library.canonicalUri, b.library.canonicalUri);
-    if (r != 0) return r;
-    Uri aUri = a.compilationUnit.script.readableUri;
-    Uri bUri = b.compilationUnit.script.readableUri;
-    r = utils.compareSourceUris(aUri, bUri);
-    if (r != 0) return r;
-    return utils.compareEntities(a, a.sourceOffset, -1, b, b.sourceOffset, -1);
-  }
-
-  static List<E> sortedByPosition<E extends Element>(Iterable<E> elements) {
-    return elements.toList()..sort(compareByPosition);
-  }
-
-  static bool isFixedListConstructorCall(
-      ConstructorEntity element, Send node, CommonElements commonElements) {
-    return commonElements.isUnnamedListConstructor(element) &&
-        node.isCall &&
-        !node.arguments.isEmpty &&
-        node.arguments.tail.isEmpty;
-  }
-
-  static bool isGrowableListConstructorCall(
-      ConstructorEntity element, Send node, CommonElements commonElements) {
-    return commonElements.isUnnamedListConstructor(element) &&
-        node.isCall &&
-        node.arguments.isEmpty;
-  }
-
-  static bool isFilledListConstructorCall(
-      ConstructorEntity element, Send node, CommonElements commonElements) {
-    return commonElements.isFilledListConstructor(element) &&
-        node.isCall &&
-        !node.arguments.isEmpty &&
-        !node.arguments.tail.isEmpty &&
-        node.arguments.tail.tail.isEmpty;
-  }
-
-  static bool isConstructorOfTypedArraySubclass(
-      Element element, ClosedWorld closedWorld) {
-    if (closedWorld.commonElements.typedDataLibrary == null) return false;
-    if (!element.isConstructor) return false;
-    ConstructorElement constructor = element.implementation;
-    constructor = constructor.effectiveTarget;
-    ClassElement cls = constructor.enclosingClass;
-    return cls.library == closedWorld.commonElements.typedDataLibrary &&
-        closedWorld.nativeData.isNativeClass(cls) &&
-        closedWorld.isSubtypeOf(
-            cls, closedWorld.commonElements.typedDataClass) &&
-        closedWorld.isSubtypeOf(cls, closedWorld.commonElements.listClass) &&
-        constructor.name == '';
-  }
-
-  static bool switchStatementHasContinue(
-      SwitchStatement node, TreeElements elements) {
-    for (SwitchCase switchCase in node.cases) {
-      for (Node labelOrCase in switchCase.labelsAndCases) {
-        Node label = labelOrCase.asLabel();
-        if (label != null) {
-          LabelDefinition labelElement = elements.getLabelDefinition(label);
-          if (labelElement != null && labelElement.isContinueTarget) {
-            return true;
-          }
-        }
-      }
-    }
-    return false;
-  }
-
-  static bool isUnusedLabel(LabeledStatement node, TreeElements elements) {
-    Node body = node.statement;
-    JumpTarget element = elements.getTargetDefinition(body);
-    // Labeled statements with no element on the body have no breaks.
-    // A different target statement only happens if the body is itself
-    // a break or continue for a different target. In that case, this
-    // label is also always unused.
-    return element == null || element.statement != body;
-  }
-
-  /**
-   * Returns a `List` with the evaluated arguments in the normalized order.
-   *
-   * [compileDefaultValue] is a function that returns a compiled constant
-   * of an optional argument that is not in [compiledArguments].
-   *
-   * Precondition: `callStructure.signatureApplies(element.type)`.
-   *
-   * Invariant: [element] must be the implementation element.
-   */
-  static List<T> makeArgumentsList<T>(
-      CallStructure callStructure,
-      Link<Node> arguments,
-      FunctionElement element,
-      T compileArgument(Node argument),
-      T compileDefaultValue(ParameterElement element)) {
-    assert(element.isImplementation, failedAt(element));
-    List<T> result = <T>[];
-
-    FunctionSignature parameters = element.functionSignature;
-    parameters.forEachRequiredParameter((_) {
-      result.add(compileArgument(arguments.head));
-      arguments = arguments.tail;
-    });
-
-    if (!parameters.optionalParametersAreNamed) {
-      parameters.forEachOptionalParameter((_element) {
-        ParameterElement element = _element;
-        if (!arguments.isEmpty) {
-          result.add(compileArgument(arguments.head));
-          arguments = arguments.tail;
-        } else {
-          result.add(compileDefaultValue(element));
-        }
-      });
-    } else {
-      // Visit named arguments and add them into a temporary list.
-      List compiledNamedArguments = [];
-      for (; !arguments.isEmpty; arguments = arguments.tail) {
-        NamedArgument namedArgument = arguments.head;
-        compiledNamedArguments.add(compileArgument(namedArgument.expression));
-      }
-      // Iterate over the optional parameters of the signature, and try to
-      // find them in [compiledNamedArguments]. If found, we use the
-      // value in the temporary list, otherwise the default value.
-      parameters.orderedOptionalParameters.forEach((_element) {
-        ParameterElement element = _element;
-        int foundIndex = callStructure.namedArguments.indexOf(element.name);
-        if (foundIndex != -1) {
-          result.add(compiledNamedArguments[foundIndex]);
-        } else {
-          result.add(compileDefaultValue(element));
-        }
-      });
-    }
-    return result;
-  }
-
-  /**
-   * Fills [list] with the arguments in the order expected by
-   * [callee], and where [caller] is a synthesized element
-   *
-   * [compileArgument] is a function that returns a compiled version
-   * of a parameter of [callee].
-   *
-   * [compileConstant] is a function that returns a compiled constant
-   * of an optional argument that is not in the parameters of [callee].
-   *
-   * Returns [:true:] if the signature of the [caller] matches the
-   * signature of the [callee], [:false:] otherwise.
-   */
-  static bool addForwardingElementArgumentsToList<T>(
-      ConstructorElement caller,
-      List<T> list,
-      ConstructorElement callee,
-      T compileArgument(ParameterElement element),
-      T compileConstant(ParameterElement element)) {
-    assert(
-        !callee.isMalformed,
-        failedAt(
-            caller,
-            "Cannot compute arguments to malformed constructor: "
-            "$caller calling $callee."));
-
-    FunctionSignature signature = caller.functionSignature;
-    Map<Node, ParameterElement> mapping = <Node, ParameterElement>{};
-
-    // TODO(ngeoffray): This is a hack that fakes up AST nodes, so
-    // that we can call [addArgumentsToList].
-    Link<Node> computeCallNodesFromParameters() {
-      LinkBuilder<Node> builder = new LinkBuilder<Node>();
-      signature.forEachRequiredParameter((_element) {
-        ParameterElement element = _element;
-        Node node = element.node;
-        mapping[node] = element;
-        builder.addLast(node);
-      });
-      if (signature.optionalParametersAreNamed) {
-        signature.forEachOptionalParameter((_element) {
-          ParameterElement element = _element;
-          mapping[element.initializer] = element;
-          builder.addLast(new NamedArgument(null, null, element.initializer));
-        });
-      } else {
-        signature.forEachOptionalParameter((_element) {
-          ParameterElement element = _element;
-          Node node = element.node;
-          mapping[node] = element;
-          builder.addLast(node);
-        });
-      }
-      return builder.toLink();
-    }
-
-    T internalCompileArgument(Node node) {
-      return compileArgument(mapping[node]);
-    }
-
-    Link<Node> nodes = computeCallNodesFromParameters();
-
-    // Synthesize a structure for the call.
-    // TODO(ngeoffray): Should the resolver do it instead?
-    CallStructure callStructure = new CallStructure(
-        signature.parameterCount, signature.type.namedParameters);
-    if (!callStructure.signatureApplies(signature.parameterStructure)) {
-      return false;
-    }
-    list.addAll(makeArgumentsList<T>(callStructure, nodes, callee,
-        internalCompileArgument, compileConstant));
-
-    return true;
-  }
-}
-
-/// An element representing an erroneous resolution.
-///
-/// An [ErroneousElement] is used instead of `null` to provide additional
-/// information about the error that caused the element to be unresolvable
-/// or otherwise invalid.
-///
-/// Accessing any field or calling any method defined on [ErroneousElement]
-/// except [isError] will currently throw an exception. (This might
-/// change when we actually want more information on the erroneous element,
-/// e.g., the name of the element we were trying to resolve.)
-///
-/// Code that cannot not handle an [ErroneousElement] should use
-/// `Element.isUnresolved(element)` to check for unresolvable elements instead
-/// of `element == null`.
-// ignore: STRONG_MODE_INVALID_METHOD_OVERRIDE_FROM_BASE
-abstract class ErroneousElement extends Element implements ConstructorElement {
-  MessageKind get messageKind;
-  Map get messageArguments;
-  String get message;
-}
-
-/// An [Element] whose usage should cause one or more warnings.
-abstract class WarnOnUseElement extends Element {
-  /// The element whose usage cause a warning.
-  Element get wrappedElement;
-
-  /// Reports the attached warning and returns the wrapped element.
-  /// [usageSpannable] is used to report messages on the reference of
-  /// [wrappedElement].
-  Element unwrap(DiagnosticReporter listener, Spannable usageSpannable);
-}
-
-/// An ambiguous element represents multiple elements accessible by the same
-/// name.
-///
-/// Ambiguous elements are created during handling of import/export scopes. If
-/// an ambiguous element is encountered during resolution a warning/error is
-/// reported.
-abstract class AmbiguousElement extends Element {
-  MessageKind get messageKind;
-  Map get messageArguments;
-  Element get existingElement;
-  Element get newElement;
-
-  /// Compute the info messages associated with an error/warning on [context].
-  List<DiagnosticMessage> computeInfos(
-      Element context, DiagnosticReporter listener);
-}
-
-// TODO(kasperl): This probably shouldn't be called an element. It's
-// just an interface shared by classes and libraries.
-abstract class ScopeContainerElement implements Element {
-  Element localLookup(String elementName);
-
-  void forEachLocalMember(f(Element element));
-}
-
-abstract class CompilationUnitElement extends Element {
-  /// Use [library] instead.
-  @deprecated
-  get enclosingElement;
-
-  Script get script;
-
-  void forEachLocalMember(f(Element element));
-}
-
-abstract class ImportElement extends Element implements ImportEntity {
-  Uri get uri;
-  LibraryElement get importedLibrary;
-  LibraryElement get enclosingLibrary => library;
-  bool get isDeferred;
-  PrefixElement get prefix;
-  String get name;
-  // TODO(johnniwinther): Remove this when no longer needed in source mirrors.
-  Import get node;
-}
-
-abstract class ExportElement extends Element {
-  Uri get uri;
-  LibraryElement get exportedLibrary;
-  // TODO(johnniwinther): Remove this when no longer needed in source mirrors.
-  Export get node;
-}
-
-abstract class LibraryElement extends Element
-    implements ScopeContainerElement, AnalyzableElement, LibraryEntity {
-  /**
-   * The canonical uri for this library.
-   *
-   * For user libraries the canonical uri is the script uri. For platform
-   * libraries the canonical uri is of the form [:dart:x:].
-   */
-  Uri get canonicalUri;
-
-  /// Returns `true` if this library is 'dart:core'.
-  bool get isDartCore;
-
-  CompilationUnitElement get entryCompilationUnit;
-  Link<CompilationUnitElement> get compilationUnits;
-
-  /// The import declarations in this library, including the implicit import of
-  /// 'dart:core', if present.
-  Iterable<ImportElement> get imports;
-
-  /// The export declarations in this library.
-  Iterable<ExportElement> get exports;
-
-  /**
-   * [:true:] if this library is part of the platform, that is, its canonical
-   * uri has the scheme 'dart'.
-   */
-  bool get isPlatformLibrary;
-
-  /**
-   * [:true:] if this library is from a package, that is, its canonical uri has
-   * the scheme 'package'.
-   */
-  bool get isPackageLibrary;
-
-  /**
-   * [:true:] if this library is a platform library whose path starts with
-   * an underscore.
-   */
-  bool get isInternalLibrary;
-
-  bool get exportsHandled;
-
-  LibraryElement get implementation;
-
-  Element find(String elementName);
-  Element findLocal(String elementName);
-  Element findExported(String elementName);
-  void forEachExport(f(Element element));
-
-  /// Calls [f] for each [Element] imported into this library.
-  void forEachImport(f(Element element));
-
-  /// Returns the imports that import element into this library.
-  Iterable<ImportElement> getImportsFor(Element element);
-
-  /// `true` if this library has name as given through a library tag.
-  bool get hasLibraryName;
-
-  /// The library name, which is either the name given in the library tag
-  /// or the empty string if there is no library tag.
-  String get libraryName;
-
-  /// Returns the library name (as defined by the library tag) or for scripts
-  /// (which have no library tag) the script file name.
-  ///
-  /// Note: the returned filename is still escaped ("a%20b.dart" instead of
-  /// "a b.dart").
-  String get name;
-}
-
-/// The implicit scope defined by a import declaration with a prefix clause.
-abstract class PrefixElement extends Element {
-  Element lookupLocalMember(String memberName);
-
-  void forEachLocalMember(void f(Element member));
-
-  /// Is true if this prefix belongs to a deferred import.
-  bool get isDeferred;
-
-  /// Import that declared this deferred prefix.
-  ImportElement get deferredImport;
-
-  /// The `loadLibrary` getter implicitly defined on deferred prefixes.
-  GetterElement get loadLibrary;
-}
-
-/// A type alias definition.
-abstract class TypedefElement extends Element
-    implements
-        AstElement,
-        TypeDeclarationElement,
-        FunctionTypedElement,
-        TypedefEntity {
-  /// The type defined by this typedef with the type variables as its type
-  /// arguments.
-  ///
-  /// For instance `F<T>` for `typedef void F<T>(T t)`.
-  ResolutionTypedefType get thisType;
-
-  /// The type defined by this typedef with `dynamic` as its type arguments.
-  ///
-  /// For instance `F<dynamic>` for `typedef void F<T>(T t)`.
-  ResolutionTypedefType get rawType;
-
-  /// The type, function type if well-defined, for which this typedef is an
-  /// alias.
-  ///
-  /// For instance `(int)->void` for `typedef void F(int)`.
-  ResolutionDartType get alias;
-
-  void checkCyclicReference(Resolution resolution);
-}
-
-/// An executable element is an element that can hold code.
-///
-/// These elements variables (fields, parameters and locals), which can hold
-/// code in their initializer, and functions (including methods and
-/// constructors), which can hold code in their body.
-abstract class ExecutableElement extends Element
-    implements TypedElement, AstElement {
-  /// The outermost member that contains this element.
-  ///
-  /// For top level, static or instance members, the member context is the
-  /// element itself. For parameters, local variables and nested closures, the
-  /// member context is the top level, static or instance member in which it is
-  /// defined.
-  MemberElement get memberContext;
-}
-
-/// A top-level, static or instance field or method, or a constructor.
-///
-/// A [MemberElement] is the outermost executable element for any executable
-/// context.
-abstract class MemberElement extends Element
-    implements ExecutableElement, MemberEntity {
-  /// The local functions defined within this member.
-  List<MethodElement> get nestedClosures;
-
-  /// The name of this member, taking privacy into account.
-  Name get memberName;
-}
-
-/// A local function, variable, parameter or synthesized local.
-abstract class LocalVariable implements Local {
-  /// The context in which this local is defined.
-  ExecutableElement get executableContext;
-
-  /// The outermost member that contains this element.
-  ///
-  /// For top level, static or instance members, the member context is the
-  /// element itself. For parameters, local variables and nested closures, the
-  /// member context is the top level, static or instance member in which it is
-  /// defined.
-  MemberElement get memberContext;
-}
-
-/// A function, variable or parameter defined in an executable context.
-abstract class LocalElement extends Element
-    implements AstElement, TypedElement, LocalVariable {
-  ExecutableElement get executableContext;
-}
-
-/// A top level, static or instance field, a formal parameter or local variable.
-abstract class VariableElement extends ExecutableElement {
-  @override
-  VariableDefinitions get node;
-
-  Expression get initializer;
-
-  bool get hasConstant;
-
-  /// The constant expression defining the (initial) value of the variable.
-  ///
-  /// If the variable is `const` the value is always non-null, possibly an
-  /// [ErroneousConstantExpression], otherwise, the value is null when the
-  /// initializer isn't a constant expression.
-  ConstantExpression get constant;
-}
-
-/// A variable or parameter that is local to an executable context.
-///
-/// The executable context is the [ExecutableElement] in which this variable
-/// is defined.
-abstract class LocalVariableElement extends VariableElement
-    implements LocalElement {}
-
-/// A top-level, static or instance field.
-abstract class FieldElement extends VariableElement
-    implements MemberElement, FieldEntity {}
-
-/// A parameter-like element of a function signature.
-///
-/// If the function signature comes from a typedef or an inline function-typed
-/// parameter (e.g. the parameter 'f' in `method(void f())`), then its
-/// parameters are not real parameters in that they can take no argument and
-/// hold no value. Such parameter-like elements are modeled by [FormalElement].
-///
-/// If the function signature comes from a function or constructor, its
-/// parameters are real parameters and are modeled by [ParameterElement].
-abstract class FormalElement extends Element
-    implements FunctionTypedElement, TypedElement, AstElement {
-  /// Use [functionDeclaration] instead.
-  @deprecated
-  get enclosingElement;
-
-  /// The function, typedef or inline function-typed parameter on which
-  /// this parameter is declared.
-  FunctionTypedElement get functionDeclaration;
-
-  VariableDefinitions get node;
-
-  /// Whether the parameter is unnamed in a function type.
-  bool get isUnnamed;
-}
-
-/// A formal parameter of a function or constructor.
-///
-/// Normal parameter that introduce a local variable are modeled by
-/// [LocalParameterElement] whereas initializing formals, that is parameter of
-/// the form `this.x`, are modeled by [InitializingFormalElement].
-abstract class ParameterElement extends Element
-    implements VariableElement, FormalElement, LocalElement {
-  /// Use [functionDeclaration] instead.
-  @deprecated
-  get enclosingElement;
-
-  /// The function on which this parameter is declared.
-  FunctionElement get functionDeclaration;
-
-  /// `true` if this parameter is named.
-  bool get isNamed;
-
-  /// `true` if this parameter is optional.
-  bool get isOptional;
-}
-
-/// A formal parameter on a function or constructor that introduces a local
-/// variable in the scope of the function or constructor.
-abstract class LocalParameterElement extends ParameterElement
-    implements LocalVariableElement {}
-
-/// A formal parameter in a constructor that directly initializes a field.
-///
-/// For example: `A(this.field)`.
-abstract class InitializingFormalElement extends LocalParameterElement {
-  /// The field initialized by this initializing formal.
-  FieldElement get fieldElement;
-
-  /// The function on which this parameter is declared.
-  ConstructorElement get functionDeclaration;
-}
-
-/**
- * A synthetic element which holds a getter and/or a setter.
- *
- * This element unifies handling of fields and getters/setters.  When
- * looking at code like "foo.x", we don't have to look for both a
- * field named "x", a getter named "x", and a setter named "x=".
- */
-abstract class AbstractFieldElement extends Element {
-  GetterElement get getter;
-  SetterElement get setter;
-}
-
-abstract class FunctionSignature {
-  ResolutionFunctionType get type;
-  ResolutionDartType get returnType;
-  List<ResolutionDartType> get typeVariables;
-  List<FormalElement> get requiredParameters;
-  List<FormalElement> get optionalParameters;
-
-  int get requiredParameterCount;
-  int get optionalParameterCount;
-  bool get optionalParametersAreNamed;
-  bool get hasOptionalParameters;
-
-  int get parameterCount;
-  List<FormalElement> get orderedOptionalParameters;
-
-  void forEachParameter(void function(FormalElement parameter));
-  void forEachRequiredParameter(void function(FormalElement parameter));
-  void forEachOptionalParameter(void function(FormalElement parameter));
-
-  void orderedForEachParameter(void function(FormalElement parameter));
-
-  bool isCompatibleWith(FunctionSignature constructorSignature);
-
-  ParameterStructure get parameterStructure;
-}
-
-/// A top level, static or instance method, constructor, local function, or
-/// closure (anonymous local function).
-abstract class FunctionElement extends Element
-    implements
-        AstElement,
-        TypedElement,
-        FunctionTypedElement,
-        ExecutableElement,
-        GenericElement {
-  FunctionExpression get node;
-
-  FunctionElement get patch;
-  FunctionElement get origin;
-
-  bool get hasFunctionSignature;
-
-  /// The parameters of this function.
-  List<ParameterElement> get parameters;
-
-  /// The type of this function.
-  ResolutionFunctionType get type;
-
-  /// The synchronous/asynchronous marker on this function.
-  AsyncMarker get asyncMarker;
-
-  /// `true` if this function is external.
-  ///
-  /// Patched methods are _not_ external, but [isMarkedExternal] is `true`.
-  bool get isExternal;
-
-  /// `true` if this function is marked as external.
-  ///
-  /// If the function is implemented through a patch [isExternal] is `false`.
-  bool get isMarkedExternal;
-
-  /// The structure of the function parameters.
-  ParameterStructure get parameterStructure;
-}
-
-/// A getter or setter.
-abstract class AccessorElement extends MethodElement {
-  /// Used to retrieve a link to the abstract field element representing this
-  /// element.
-  AbstractFieldElement get abstractField;
-}
-
-/// A getter.
-abstract class GetterElement extends AccessorElement {
-  /// The setter corresponding to this getter, if any.
-  SetterElement get setter;
-}
-
-/// A setter.
-abstract class SetterElement extends AccessorElement {
-  /// The getter corresponding to this setter, if any.
-  GetterElement get getter;
-}
-
-/// A top level, static or instance function.
-abstract class MethodElement extends FunctionElement
-    implements MemberElement, FunctionEntity {}
-
-/// A local function or closure (anonymous local function).
-abstract class LocalFunctionElement extends FunctionElement
-    implements LocalElement {
-  /// The synthesized 'call' method created for this local function during
-  /// closure conversion.
-  MethodElement callMethod;
-}
-
-/// A constructor.
-abstract class ConstructorElement extends MethodElement
-    implements ConstructorEntity {
-  /// Returns `true` if [effectiveTarget] has been computed for this
-  /// constructor.
-  bool get hasEffectiveTarget;
-
-  /// The effective target of this constructor, that is the non-redirecting
-  /// constructor that is called on invocation of this constructor.
-  ///
-  /// Consider for instance this hierarchy:
-  ///
-  ///     class C { factory C.c() = D.d; }
-  ///     class D { factory D.d() = E.e2; }
-  ///     class E { E.e1();
-  ///               E.e2() : this.e1(); }
-  ///
-  /// The effective target of both `C.c`, `D.d`, and `E.e2` is `E.e2`, and the
-  /// effective target of `E.e1` is `E.e1` itself.
-  ConstructorElement get effectiveTarget;
-
-  /// The immediate redirection target of a redirecting factory constructor.
-  ///
-  /// Consider for instance this hierarchy:
-  ///
-  ///     class C { factory C() = D; }
-  ///     class D { factory D() = E; }
-  ///     class E { E(); }
-  ///
-  /// The immediate redirection target of `C` is `D` and the immediate
-  /// redirection target of `D` is `E`. `E` is not a redirecting factory
-  /// constructor so its immediate redirection target is `null`.
-  ConstructorElement get immediateRedirectionTarget;
-
-  /// The prefix of the immediateRedirectionTarget, if it is deferred.
-  /// [null] if it is not deferred.
-  PrefixElement get redirectionDeferredPrefix;
-
-  /// Is `true` if this constructor is a redirecting generative constructor.
-  bool get isRedirectingGenerative;
-
-  /// Is `true` if this constructor is a redirecting factory constructor.
-  bool get isRedirectingFactory;
-
-  /// Is `true` if this constructor is a redirecting factory constructor that is
-  /// part of a redirection cycle.
-  bool get isCyclicRedirection;
-
-  /// Is `true` if the effective target of this constructor is malformed.
-  ///
-  /// A constructor is considered malformed if any of the following applies:
-  ///
-  ///     * the constructor is undefined,
-  ///     * the type of the constructor is undefined,
-  ///     * the constructor is a redirecting factory and either
-  ///       - it is part of a redirection cycle,
-  ///       - the effective target is a generative constructor on an abstract
-  ///         class, or
-  ///       - this constructor is constant but the effective target is not,
-  ///       - the arguments to this constructor are incompatible with the
-  ///         parameters of the effective target.
-  bool get isEffectiveTargetMalformed;
-
-  /// Compute the type of the effective target of this constructor for an
-  /// instantiation site with type [:newType:].
-  /// May return a malformed type.
-  ResolutionDartType computeEffectiveTargetType(
-      ResolutionInterfaceType newType);
-
-  /// If this is a synthesized constructor [definingConstructor] points to
-  /// the generative constructor from which this constructor was created.
-  /// Otherwise [definingConstructor] is `null`.
-  ///
-  /// Consider for instance this hierarchy:
-  ///
-  ///     class C { C.c(a, {b});
-  ///     class D {}
-  ///     class E = C with D;
-  ///
-  /// Class `E` has a synthesized constructor, `E.c`, whose defining constructor
-  /// is `C.c`.
-  ConstructorElement get definingConstructor;
-
-  /// Returns `true` if this constructor is an implicit default constructor.
-  bool get isDefaultConstructor;
-
-  /// The constant constructor defining the binding of fields if `const`,
-  /// `null` otherwise.
-  ConstantConstructor get constantConstructor;
-
-  /// `true` if this constructor is one of `bool.fromEnvironment`,
-  /// `int.fromEnvironment`, or `String.fromEnvironment`.
-  bool get isFromEnvironmentConstructor;
-
-  /// `true` if this constructor is `int.fromEnvironment`.
-  bool get isIntFromEnvironmentConstructor;
-
-  /// `true` if this constructor is `bool.fromEnvironment`.
-  bool get isBoolFromEnvironmentConstructor;
-
-  /// `true` if this constructor is `String.fromEnvironment`.
-  bool get isStringFromEnvironmentConstructor;
-
-  /// Use [enclosingClass] instead.
-  @deprecated
-  get enclosingElement;
-}
-
-/// JavaScript backend specific element for the body of constructor.
-// TODO(johnniwinther): Remove this class from the element model.
-abstract class ConstructorBodyElement extends MethodElement
-    implements ConstructorBodyEntity {
-  ConstructorElement get constructor;
-}
-
-/// [GenericElement] defines the common interface for generic functions and
-/// [TypeDeclarationElement].
-abstract class GenericElement extends Element implements AstElement {
-  /// Do not use [computeType] outside of the resolver.
-  ///
-  /// Trying to access a type that has not been computed in resolution is an
-  /// error and calling [computeType] covers that error.
-  /// This method will go away!
-  @deprecated
-  ResolutionDartType computeType(Resolution resolution);
-
-  /**
-   * The type variables declared on this declaration. The type variables are not
-   * available until the type of the element has been computed through
-   * [computeType].
-   */
-  List<ResolutionDartType> get typeVariables;
-}
-
-/// [TypeDeclarationElement] defines the common interface for class/interface
-/// declarations and typedefs.
-abstract class TypeDeclarationElement extends GenericElement {
-  /// The name of this type declaration, taking privacy into account.
-  Name get memberName;
-
-  /// Do not use [computeType] outside of the resolver; instead retrieve the
-  /// type from the [thisType] or [rawType], depending on the use case.
-  ///
-  /// Trying to access a type that has not been computed in resolution is an
-  /// error and calling [computeType] covers that error.
-  /// This method will go away!
-  @deprecated
-  GenericType computeType(Resolution resolution);
-
-  /**
-   * The `this type` for this type declaration.
-   *
-   * The type of [:this:] is the generic type based on this element in which
-   * the type arguments are the declared type variables. For instance,
-   * [:List<E>:] for [:List:] and [:Map<K,V>:] for [:Map:].
-   *
-   * For a class declaration this is the type of [:this:].
-   */
-  GenericType get thisType;
-
-  /**
-   * The raw type for this type declaration.
-   *
-   * The raw type is the generic type base on this element in which the type
-   * arguments are all [dynamic]. For instance [:List<dynamic>:] for [:List:]
-   * and [:Map<dynamic,dynamic>:] for [:Map:]. For non-generic classes [rawType]
-   * is the same as [thisType].
-   *
-   * The [rawType] field is a canonicalization of the raw type and should be
-   * used to distinguish explicit and implicit uses of the [dynamic]
-   * type arguments. For instance should [:List:] be the [rawType] of the
-   * [:List:] class element whereas [:List<dynamic>:] should be its own
-   * instantiation of [ResolutionInterfaceType] with [:dynamic:] as type
-   * argument. Using this distinction, we can print the raw type with type
-   * arguments only when the input source has used explicit type arguments.
-   */
-  GenericType get rawType;
-
-  bool get isResolved;
-
-  void ensureResolved(Resolution resolution);
-}
-
-abstract class ClassElement extends TypeDeclarationElement
-    implements ScopeContainerElement, ClassEntity {
-  /// The length of the longest inheritance path from [:Object:].
-  int get hierarchyDepth;
-
-  ResolutionInterfaceType get rawType;
-  ResolutionInterfaceType get thisType;
-  ClassElement get superclass;
-
-  /// The direct supertype of this class.
-  ResolutionDartType get supertype;
-
-  /// Ordered set of all supertypes of this class including the class itself.
-  OrderedTypeSet get allSupertypesAndSelf;
-
-  /// A list of all supertypes of this class excluding the class itself.
-  Link<InterfaceType> get allSupertypes;
-
-  /// Returns the this type of this class as an instance of [cls].
-  ResolutionInterfaceType asInstanceOf(ClassElement cls);
-
-  /// A list of all direct superinterfaces of this class.
-  Link<ResolutionDartType> get interfaces;
-
-  bool get hasConstructor;
-  Link<Element> get constructors;
-
-  ClassElement get patch;
-  ClassElement get origin;
-  ClassElement get declaration;
-  ClassElement get implementation;
-
-  /// `true` if this class is an enum declaration.
-  bool get isEnumClass;
-
-  /// `true` if this class is a mixin application, either named or unnamed.
-  bool get isMixinApplication;
-
-  /// `true` if this class is a named mixin application, e.g.
-  ///
-  ///     class NamedMixinApplication = SuperClass with MixinClass;
-  ///
-  bool get isNamedMixinApplication;
-
-  /// `true` if this class is an unnamed mixin application, e.g. the synthesized
-  /// `SuperClass+MixinClass` mixin application class in:
-  ///
-  ///     class Class extends SuperClass with MixinClass {}
-  ///
-  bool get isUnnamedMixinApplication;
-
-  bool get hasConstructorBodies;
-  bool get hasLocalScopeMembers;
-
-  /// Returns `true` if this class is `Object` from dart:core.
-  bool get isObject;
-
-  /// Returns `true` if this class implements [Function] either by directly
-  /// implementing the interface or by providing a [call] method.
-  bool implementsFunction(CommonElements commonElements);
-
-  /// Returns `true` if this class extends [cls] directly or indirectly.
-  ///
-  /// This method is not to be used for checking type hierarchy and assignments,
-  /// because it does not take parameterized types into account.
-  bool isSubclassOf(ClassElement cls);
-
-  /// Returns `true` if this class explicitly implements [intrface].
-  ///
-  /// Note that, if [intrface] is the `Function` class, this method returns
-  /// false for a class that has a `call` method but does not explicitly
-  /// implement `Function`.
-  bool implementsInterface(ClassElement intrface);
-
-  bool hasFieldShadowedBy(FieldElement fieldMember);
-
-  /// Returns `true` if this class has a @proxy annotation.
-  bool get isProxy;
-
-  /// Returns `true` if the class hierarchy for this class contains errors.
-  bool get hasIncompleteHierarchy;
-
-  void addConstructorBody(ConstructorBodyElement element);
-
-  Element lookupMember(String memberName);
-
-  /// Looks up a class instance member declared or inherited in this class
-  /// using [memberName] to match the (private) name and getter/setter property.
-  ///
-  /// This method recursively visits superclasses until the member is found or
-  /// [stopAt] is reached.
-  MemberElement lookupByName(Name memberName, {ClassElement stopAt});
-  MemberElement lookupSuperByName(Name memberName);
-
-  Element lookupLocalMember(String memberName);
-  ConstructorBodyElement lookupConstructorBody(String memberName);
-  Element lookupSuperMember(String memberName);
-
-  Element lookupSuperMemberInLibrary(String memberName, LibraryElement library);
-
-  // TODO(johnniwinther): Clean up semantics. Can the default constructor take
-  // optional arguments? Must it be resolved?
-  ConstructorElement lookupDefaultConstructor();
-  ConstructorElement lookupConstructor(String name);
-
-  void forEachMember(void f(ClassElement enclosingClass, Element member),
-      {bool includeBackendMembers: false,
-      bool includeSuperAndInjectedMembers: false});
-
-  void forEachInstanceField(
-      void f(ClassElement enclosingClass, FieldElement field),
-      {bool includeSuperAndInjectedMembers: false});
-
-  /// Similar to [forEachInstanceField] but visits static fields.
-  void forEachStaticField(void f(ClassElement enclosingClass, Element field));
-
-  void forEachConstructorBody(void f(ConstructorBodyElement member));
-
-  /// Looks up the member [name] in this class.
-  Member lookupClassMember(Name name);
-
-  /// Calls [f] with each member of this class.
-  void forEachClassMember(f(Member member));
-
-  /// Looks up the member [name] in the interface of this class.
-  MemberSignature lookupInterfaceMember(Name name);
-
-  /// Calls [f] with each member of the interface of this class.
-  void forEachInterfaceMember(f(MemberSignature member));
-
-  /// Returns the type of the 'call' method in the interface of this class, or
-  /// `null` if the interface has no 'call' method.
-  ResolutionFunctionType get callType;
-}
-
-abstract class MixinApplicationElement extends ClassElement {
-  ClassElement get mixin;
-  ResolutionInterfaceType get mixinType;
-
-  /// If this is an unnamed mixin application [subclass] is the subclass for
-  /// which this mixin application is created.
-  ClassElement get subclass;
-}
-
-/// Enum declaration.
-abstract class EnumClassElement extends ClassElement {
-  /// The static fields implied by the enum values.
-  List<EnumConstantElement> get enumValues;
-}
-
-/// An enum constant value.
-abstract class EnumConstantElement extends FieldElement {
-  /// The enum that declared this constant.
-  EnumClassElement get enclosingClass;
-
-  /// The index of this constant within the values of the enum.
-  int get index;
-}
-
-/// The [Element] for a type variable declaration on a generic class or typedef.
-abstract class TypeVariableElement extends Element
-    implements AstElement, TypedElement, TypeVariableEntity {
-  /// The name of this type variable, taking privacy into account.
-  Name get memberName;
-
-  /// Use [typeDeclaration] instead.
-  @deprecated
-  get enclosingElement;
-
-  /// The class, typedef, function, method, or function typed parameter on
-  /// which this type variable is defined.
-  GenericElement get typeDeclaration;
-
-  /// The index of this type variable within its type declaration.
-  int get index;
-
-  /// The [type] defined by the type variable.
-  ResolutionTypeVariableType get type;
-
-  /// The upper bound on the type variable. If not explicitly declared, this is
-  /// `Object`.
-  ResolutionDartType get bound;
-}
-
-abstract class MetadataAnnotation implements Spannable {
-  /// The front-end constant of this metadata annotation.
-  ConstantExpression get constant;
-  Element get annotatedElement;
-  SourceSpan get sourcePosition;
-
-  bool get hasNode;
-  Node get node;
-
-  MetadataAnnotation ensureResolved(Resolution resolution);
-}
-
-/// An [Element] that has a type.
-abstract class TypedElement extends Element {
-  /// Do not use [computeType] outside of the resolver; instead retrieve the
-  /// type from  [type] property.
-  ///
-  /// Trying to access a type that has not been computed in resolution is an
-  /// error and calling [computeType] covers that error.
-  /// This method will go away!
-  @deprecated
-  ResolutionDartType computeType(Resolution resolution);
-
-  ResolutionDartType get type;
-}
-
-/// An [Element] that can define a function type.
-abstract class FunctionTypedElement extends Element implements GenericElement {
-  /// The function signature for the function type defined by this element,
-  /// if any.
-  FunctionSignature get functionSignature;
-}
-
-/// An [Element] that holds a [TreeElements] mapping.
-abstract class AnalyzableElement extends Element {
-  /// Return `true` if [treeElements] have been (partially) computed for this
-  /// element.
-  bool get hasTreeElements;
-
-  /// Returns the [TreeElements] that hold the resolution information for the
-  /// AST nodes of this element.
-  TreeElements get treeElements;
-}
-
-/// An [Element] that (potentially) has a node.
-///
-/// Synthesized elements may return `null` from [node].
-abstract class AstElement extends AnalyzableElement {
-  /// `true` if [node] is available and non-null.
-  bool get hasNode;
-
-  /// The AST node of this element.
-  Node get node;
-
-  /// `true` if [resolvedAst] is available.
-  bool get hasResolvedAst;
-
-  /// The defining AST node of this element with is corresponding
-  /// [TreeElements]. This is not available if [hasResolvedAst] is `false`.
-  ResolvedAst get resolvedAst;
-}
-
-/// Enum values for different ways of defining semantics for an element.
-enum ResolvedAstKind {
-  /// The semantics of the element is defined in terms of an AST with resolved
-  /// data mapped in [TreeElements].
-  PARSED,
-
-  /// The element is an implicit default constructor. No AST or [TreeElements]
-  /// are provided.
-  DEFAULT_CONSTRUCTOR,
-
-  /// The element is an implicit forwarding constructor on a mixin application.
-  /// No AST or [TreeElements] are provided.
-  FORWARDING_CONSTRUCTOR,
-
-  /// The element is the `loadLibrary` getter implicitly defined on a deferred
-  /// prefix.
-  DEFERRED_LOAD_LIBRARY,
-}
-
-/// [ResolvedAst] contains info that define the semantics of an element.
-abstract class ResolvedAst {
-  /// The element whose semantics is defined.
-  Element get element;
-
-  /// The kind of semantics definition used for this object.
-  ResolvedAstKind get kind;
-
-  /// The root AST node for the declaration of [element]. This only available if
-  /// [kind] is `ResolvedAstKind.PARSED`.
-  Node get node;
-
-  /// The AST node for the 'body' of [element].
-  ///
-  /// For functions and constructors this is the root AST node of the method
-  /// body, and for variables this is the root AST node of the initializer, if
-  /// available.
-  ///
-  /// This only available if [kind] is `ResolvedAstKind.PARSED`.
-  Node get body;
-
-  /// The [TreeElements] containing the resolution data for [node]. This only
-  /// available of [kind] is `ResolvedAstKind.PARSED`.
-  TreeElements get elements;
-
-  /// Returns the uri for the source file defining [node] and [body]. This
-  /// only available if [kind] is `ResolvedAstKind.PARSED`.
-  Uri get sourceUri;
-}
-
-/// [ResolvedAst] implementation used for elements whose semantics is defined in
-/// terms an AST and a [TreeElements].
-class ParsedResolvedAst implements ResolvedAst {
-  final Element element;
-  final Node node;
-  final Node body;
-  final TreeElements elements;
-  final Uri sourceUri;
-
-  ParsedResolvedAst(
-      this.element, this.node, this.body, this.elements, this.sourceUri);
-
-  ResolvedAstKind get kind => ResolvedAstKind.PARSED;
-
-  String toString() => '$kind:$element:$node';
-}
-
-/// [ResolvedAst] implementation used for synthesized elements whose semantics
-/// is not defined in terms an AST and a [TreeElements].
-class SynthesizedResolvedAst implements ResolvedAst {
-  final Element element;
-  final ResolvedAstKind kind;
-
-  SynthesizedResolvedAst(this.element, this.kind);
-
-  @override
-  TreeElements get elements {
-    throw new UnsupportedError('$this does not provide a TreeElements');
-  }
-
-  @override
-  Node get node {
-    throw new UnsupportedError('$this does not have a root AST node');
-  }
-
-  @override
-  Node get body {
-    throw new UnsupportedError('$this does not have a body AST node');
-  }
-
-  @override
-  Uri get sourceUri {
-    throw new UnsupportedError('$this does not have a source URI');
-  }
-
-  String toString() => '$kind:$element';
-}
-
-/// A [MemberSignature] is a member of an interface.
-///
-/// A signature is either a method or a getter or setter, possibly implicitly
-/// defined by a field declarations. Fields themselves are not members of an
-/// interface.
-///
-/// A [MemberSignature] may be defined by a member declaration or may be
-/// synthetized from a set of declarations.
-abstract class MemberSignature {
-  /// The name of this member.
-  Name get name;
-
-  /// The type of the member when accessed. For getters and setters this is the
-  /// return type and argument type, respectively. For methods the type is the
-  /// [functionType] defined by the return type and parameters.
-  ResolutionDartType get type;
-
-  /// The function type of the member. For a getter `Foo get foo` this is
-  /// `() -> Foo`, for a setter `void set foo(Foo _)` this is `(Foo) -> void`.
-  /// For methods the function type is defined by the return type and
-  /// parameters.
-  ResolutionFunctionType get functionType;
-
-  /// Returns `true` if this member is a getter, possibly implicitly defined by a
-  /// field declaration.
-  bool get isGetter;
-
-  /// Returns `true` if this member is a setter, possibly implicitly defined by a
-  /// field declaration.
-  bool get isSetter;
-
-  /// Returns `true` if this member is a method, that is neither a getter nor
-  /// setter.
-  bool get isMethod;
-
-  /// Returns an iterable of the declarations that define this member.
-  Iterable<Member> get declarations;
-}
-
-/// A [Member] is a member of a class, that is either a method or a getter or
-/// setter, possibly implicitly defined by a field declarations. Fields
-/// themselves are not members of a class.
-///
-/// A [Member] of a class also defines a signature which is a member of the
-/// corresponding interface type.
-///
-/// A [Member] is implicitly concrete. An abstract declaration only declares
-/// a signature in the interface of its class.
-///
-/// A [Member] is always declared by an [Element] which is accessibly through
-/// the [element] getter.
-abstract class Member extends MemberSignature {
-  /// The [Element] that declared this member, possibly implicitly in case of
-  /// a getter or setter defined by a field.
-  MemberElement get element;
-
-  /// The instance of the class that declared this member.
-  ///
-  /// For instance:
-  ///   class A<T> { T m() {} }
-  ///   class B<S> extends A<S> {}
-  /// The declarer of `m` in `A` is `A<T>` whereas the declarer of `m` in `B` is
-  /// `A<S>`.
-  ResolutionInterfaceType get declarer;
-
-  /// Returns `true` if this member is static.
-  bool get isStatic;
-
-  /// Returns `true` if this member is a getter or setter implicitly declared
-  /// by a field.
-  bool get isDeclaredByField;
-
-  /// Returns `true` if this member is abstract.
-  bool get isAbstract;
-
-  /// If abstract, [implementation] points to the overridden concrete member,
-  /// if any. Otherwise [implementation] points to the member itself.
-  Member get implementation;
-}
diff --git a/pkg/compiler/lib/src/elements/entity_utils.dart b/pkg/compiler/lib/src/elements/entity_utils.dart
index 03512a8..9b11b16 100644
--- a/pkg/compiler/lib/src/elements/entity_utils.dart
+++ b/pkg/compiler/lib/src/elements/entity_utils.dart
@@ -4,6 +4,9 @@
 
 library entity_utils;
 
+import 'package:front_end/src/fasta/scanner.dart'
+    show isUserDefinableOperator, isMinusOperator;
+
 import 'entities.dart';
 
 // Somewhat stable ordering for libraries using [Uri]s
@@ -89,3 +92,86 @@
     return '$className\$${element.name}';
   }
 }
+
+String reconstructConstructorNameSourceString(FunctionEntity element) {
+  if (element.name == '') {
+    return element.enclosingClass.name;
+  } else {
+    return reconstructConstructorName(element);
+  }
+}
+
+/**
+ * Map an operator-name to a valid JavaScript identifier.
+ *
+ * For non-operator names, this method just returns its input.
+ *
+ * The results returned from this method are guaranteed to be valid
+ * JavaScript identifiers, except it may include reserved words for
+ * non-operator names.
+ */
+String operatorNameToIdentifier(String name) {
+  if (name == null) {
+    return name;
+  } else if (name == '==') {
+    return r'operator$eq';
+  } else if (name == '~') {
+    return r'operator$not';
+  } else if (name == '[]') {
+    return r'operator$index';
+  } else if (name == '[]=') {
+    return r'operator$indexSet';
+  } else if (name == '*') {
+    return r'operator$mul';
+  } else if (name == '/') {
+    return r'operator$div';
+  } else if (name == '%') {
+    return r'operator$mod';
+  } else if (name == '~/') {
+    return r'operator$tdiv';
+  } else if (name == '+') {
+    return r'operator$add';
+  } else if (name == '<<') {
+    return r'operator$shl';
+  } else if (name == '>>') {
+    return r'operator$shr';
+  } else if (name == '>=') {
+    return r'operator$ge';
+  } else if (name == '>') {
+    return r'operator$gt';
+  } else if (name == '<=') {
+    return r'operator$le';
+  } else if (name == '<') {
+    return r'operator$lt';
+  } else if (name == '&') {
+    return r'operator$and';
+  } else if (name == '^') {
+    return r'operator$xor';
+  } else if (name == '|') {
+    return r'operator$or';
+  } else if (name == '-') {
+    return r'operator$sub';
+  } else if (name == 'unary-') {
+    return r'operator$negate';
+  } else {
+    return name;
+  }
+}
+
+String constructOperatorNameOrNull(String op, bool isUnary) {
+  if (isMinusOperator(op)) {
+    return isUnary ? 'unary-' : op;
+  } else if (isUserDefinableOperator(op) || op == '??') {
+    return op;
+  } else {
+    return null;
+  }
+}
+
+String constructOperatorName(String op, bool isUnary) {
+  String operatorName = constructOperatorNameOrNull(op, isUnary);
+  if (operatorName == null)
+    throw 'Unhandled operator: $op';
+  else
+    return operatorName;
+}
diff --git a/pkg/compiler/lib/src/elements/modelx.dart b/pkg/compiler/lib/src/elements/modelx.dart
deleted file mode 100644
index 9d137e9..0000000
--- a/pkg/compiler/lib/src/elements/modelx.dart
+++ /dev/null
@@ -1,3637 +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.
-
-library elements.modelx;
-
-import '../common.dart';
-import '../common/names.dart' show Identifiers;
-import '../common/resolution.dart' show Resolution, ParsingContext;
-import '../compiler.dart' show Compiler;
-import '../constants/constant_constructors.dart';
-import '../constants/constructors.dart';
-import '../constants/expressions.dart';
-import '../diagnostics/messages.dart' show MessageTemplate;
-import '../ordered_typeset.dart' show OrderedTypeSet;
-import '../resolution/class_members.dart' show ClassMemberMixin;
-import '../resolution/resolution.dart' show AnalyzableElementX;
-import '../resolution/scope.dart'
-    show ClassScope, LibraryScope, Scope, TypeDeclarationScope;
-import '../resolution/tree_elements.dart' show TreeElements;
-import '../resolution/typedefs.dart' show TypedefCyclicVisitor;
-import '../script.dart';
-import 'package:front_end/src/fasta/scanner.dart' show ErrorToken, Token;
-import 'package:front_end/src/fasta/scanner.dart' as Tokens show EOF_TOKEN;
-import '../tree/tree.dart';
-import '../util/util.dart';
-import 'common.dart';
-import 'elements.dart';
-import 'entities.dart';
-import 'jumps.dart';
-import 'names.dart';
-import 'resolution_types.dart';
-import 'visitor.dart' show ElementVisitor;
-
-/// Object that identifies a declaration site.
-///
-/// For most elements, this is the element itself, but for variable declarations
-/// where multi-declarations like `var a, b, c` are allowed, the declaration
-/// site is a separate object.
-// TODO(johnniwinther): Add [beginToken] and [endToken] getters.
-abstract class DeclarationSite {}
-
-abstract class ElementX extends Element with ElementCommon {
-  static int _elementHashCode = 0;
-  static int newHashCode() =>
-      _elementHashCode = (_elementHashCode + 1).toUnsigned(30);
-
-  final String name;
-  final ElementKind kind;
-  final Element enclosingElement;
-  final int hashCode = newHashCode();
-  List<MetadataAnnotation> metadataInternal;
-
-  ElementX(this.name, this.kind, this.enclosingElement) {
-    assert(isError || implementationLibrary != null);
-  }
-
-  Modifiers get modifiers => Modifiers.EMPTY;
-
-  Node parseNode(ParsingContext parsing) {
-    parsing.reporter.internalError(this, 'parseNode not implemented on $this.');
-    return null;
-  }
-
-  void set metadata(List<MetadataAnnotation> metadata) {
-    assert(metadataInternal == null);
-    for (MetadataAnnotationX annotation in metadata) {
-      assert(annotation.annotatedElement == null);
-      annotation.annotatedElement = this;
-    }
-    metadataInternal = metadata;
-  }
-
-  Iterable<MetadataAnnotation> get metadata {
-    if (isPatch && metadataInternal != null) {
-      if (origin.metadata.isEmpty) {
-        return metadataInternal;
-      } else {
-        return <MetadataAnnotation>[]
-          ..addAll(origin.metadata)
-          ..addAll(metadataInternal);
-      }
-    }
-    return metadataInternal != null
-        ? metadataInternal
-        : const <MetadataAnnotation>[];
-  }
-
-  bool get isClosure => false;
-  bool get isClassMember {
-    // Check that this element is defined in the scope of a Class.
-    return enclosingElement != null && enclosingElement.isClass;
-  }
-
-  bool get isInstanceMember => false;
-  bool get isDeferredLoaderGetter => false;
-
-  bool get isConst => modifiers.isConst;
-  bool get isFinal => modifiers.isFinal;
-  bool get isStatic => modifiers.isStatic;
-  bool get isOperator => Elements.isOperatorName(name);
-
-  bool get isSynthesized => false;
-
-  bool get isMixinApplication => false;
-
-  bool get isLocal => false;
-
-  // TODO(johnniwinther): This breaks for libraries (for which enclosing
-  // elements are null) and is invalid for top level variable declarations for
-  // which the enclosing element is a VariableDeclarations and not a compilation
-  // unit.
-  bool get isTopLevel {
-    return enclosingElement != null && enclosingElement.isCompilationUnit;
-  }
-
-  @override
-  int get sourceOffset => position?.charOffset;
-
-  Token get position => null;
-
-  SourceSpan get sourcePosition {
-    if (position == null) return null;
-    Uri uri = compilationUnit.script.resourceUri;
-    return new SourceSpan(uri, position.charOffset, position.charEnd);
-  }
-
-  Token findMyName(Token token) {
-    return findNameToken(token, isConstructor, name, enclosingElement.name);
-  }
-
-  static Token findNameToken(
-      Token token, bool isConstructor, String name, String enclosingClassName) {
-    // We search for the token that has the name of this element.
-    // For constructors, that doesn't work because they may have
-    // named formed out of multiple tokens (named constructors) so
-    // for those we search for the class name instead.
-    String needle = isConstructor ? enclosingClassName : name;
-    // The unary '-' operator has a special element name (specified).
-    if (needle == 'unary-') needle = '-';
-    for (Token t = token; Tokens.EOF_TOKEN != t.kind; t = t.next) {
-      if (t is! ErrorToken && needle == t.lexeme) return t;
-    }
-    return token;
-  }
-
-  CompilationUnitElement get compilationUnit {
-    Element element = this;
-    while (!element.isCompilationUnit) {
-      element = element.enclosingElement;
-    }
-    return element;
-  }
-
-  LibraryElement get library => enclosingElement.library;
-
-  Name get memberName => new Name(name, library);
-
-  LibraryElement get implementationLibrary {
-    Element element = this;
-    while (!identical(element.kind, ElementKind.LIBRARY)) {
-      element = element.enclosingElement;
-    }
-    return element;
-  }
-
-  ClassElement get enclosingClass {
-    for (Element e = this; e != null; e = e.enclosingElement) {
-      if (e.isClass) return e.declaration;
-    }
-    return null;
-  }
-
-  /**
-   * Creates the scope for this element.
-   */
-  Scope buildScope() => enclosingElement.buildScope();
-
-  String toString() {
-    // TODO(johnniwinther): Test for nullness of name, or make non-nullness an
-    // invariant for all element types?
-    var nameText = name != null ? name : '?';
-    if (enclosingElement != null && !isTopLevel) {
-      String holderName = enclosingElement.name != null
-          ? enclosingElement.name
-          : '${enclosingElement.kind}?';
-      return '$kind($holderName#${nameText})';
-    } else {
-      return '$kind(${nameText})';
-    }
-  }
-
-  FunctionElement asFunctionElement() => null;
-
-  bool get isAbstract => modifiers.isAbstract;
-
-  bool get hasTreeElements => analyzableElement.hasTreeElements;
-
-  TreeElements get treeElements => analyzableElement.treeElements;
-
-  AnalyzableElement get analyzableElement {
-    Element element = outermostEnclosingMemberOrTopLevel;
-    if (element.isAbstractField || element.isPrefix) return element.library;
-    return element;
-  }
-
-  DeclarationSite get declarationSite => null;
-
-  void reuseElement() {
-    throw "reuseElement isn't implemented on ${runtimeType}.";
-  }
-}
-
-class ErroneousElementX extends ElementX
-    with ConstructorElementCommon
-    implements ErroneousElement {
-  final MessageKind messageKind;
-  final Map messageArguments;
-
-  ErroneousElementX(
-      this.messageKind, this.messageArguments, String name, Element enclosing)
-      : super(name, ElementKind.ERROR, enclosing);
-
-  bool get isTopLevel => false;
-
-  bool get isSynthesized => true;
-
-  bool get isCyclicRedirection => false;
-
-  bool get isDefaultConstructor => false;
-
-  bool get isMalformed => true;
-
-  PrefixElement get redirectionDeferredPrefix => null;
-
-  AbstractFieldElement abstractField;
-
-  unsupported() {
-    throw 'unsupported operation on erroneous element';
-  }
-
-  get asyncMarker => AsyncMarker.SYNC;
-  Iterable<MetadataAnnotation> get metadata => unsupported();
-  bool get hasNode => false;
-  get node => unsupported();
-  get hasResolvedAst => false;
-  get resolvedAst => unsupported();
-  get type => unsupported();
-  get cachedNode => unsupported();
-  get functionSignature => unsupported();
-  get parameterStructure => unsupported();
-  get parameters => unsupported();
-  FunctionElement get patch => null;
-  FunctionElement get origin => this;
-  get immediateRedirectionTarget => unsupported();
-  get nestedClosures => unsupported();
-  get memberContext => unsupported();
-  get executableContext => unsupported();
-  get isExternal => unsupported();
-  get isMarkedExternal => unsupported();
-  get constantConstructor => null;
-
-  bool get isRedirectingGenerative => unsupported();
-  bool get isRedirectingFactory => unsupported();
-
-  computeType(Resolution resolution) => unsupported();
-
-  bool get hasFunctionSignature => false;
-
-  bool get hasEffectiveTarget => true;
-
-  get effectiveTarget => this;
-
-  computeEffectiveTargetType(ResolutionInterfaceType newType) => unsupported();
-
-  get definingConstructor => null;
-
-  FunctionElement asFunctionElement() => this;
-
-  String get message {
-    return MessageTemplate.TEMPLATES[messageKind]
-        .message(messageArguments)
-        .toString();
-  }
-
-  String toString() => '<$name: $message>';
-
-  accept(ElementVisitor visitor, arg) {
-    return visitor.visitErroneousElement(this, arg);
-  }
-
-  @override
-  get isEffectiveTargetMalformed {
-    throw new UnsupportedError("isEffectiveTargetMalformed");
-  }
-
-  @override
-  List<ResolutionDartType> get typeVariables => unsupported();
-}
-
-/// A constructor that was synthesized to recover from a compile-time error.
-class ErroneousConstructorElementX extends ErroneousElementX
-    with
-        PatchMixin<FunctionElement>,
-        AnalyzableElementX,
-        ConstantConstructorMixin
-    implements ConstructorElementX {
-  // TODO(ahe): Instead of subclassing [ErroneousElementX], this class should
-  // be more like [ErroneousFieldElementX]. In particular, its kind should be
-  // [ElementKind.GENERATIVE_CONSTRUCTOR], and it shouldn't throw as much.
-
-  ErroneousConstructorElementX(MessageKind messageKind, Map messageArguments,
-      String name, Element enclosing)
-      : super(messageKind, messageArguments, name, enclosing);
-
-  @override
-  bool get isRedirectingGenerative => false;
-
-  @override
-  bool isRedirectingGenerativeInternal;
-
-  void set isRedirectingGenerative(_) {
-    throw new UnsupportedError("isRedirectingGenerative");
-  }
-
-  @override
-  bool get isRedirectingFactory => false;
-
-  @override
-  get isMarkedNative {
-    throw new UnsupportedError("isMarkedNative");
-  }
-
-  @override
-  set isMarkedNative(_) {
-    throw new UnsupportedError("isMarkedNative=");
-  }
-
-  @override
-  get definingElement {
-    throw new UnsupportedError("definingElement");
-  }
-
-  @override
-  get asyncMarker {
-    throw new UnsupportedError("asyncMarker");
-  }
-
-  @override
-  set asyncMarker(_) {
-    throw new UnsupportedError("asyncMarker=");
-  }
-
-  @override
-  get _asyncMarker {
-    throw new UnsupportedError("_asyncMarker");
-  }
-
-  @override
-  set _asyncMarker(_) {
-    throw new UnsupportedError("_asyncMarker=");
-  }
-
-  @override
-  get effectiveTargetInternal {
-    throw new UnsupportedError("effectiveTargetInternal");
-  }
-
-  @override
-  set effectiveTargetInternal(_) {
-    throw new UnsupportedError("effectiveTargetInternal=");
-  }
-
-  @override
-  get _effectiveTargetType {
-    throw new UnsupportedError("_effectiveTargetType");
-  }
-
-  @override
-  set _effectiveTargetType(_) {
-    throw new UnsupportedError("_effectiveTargetType=");
-  }
-
-  @override
-  get effectiveTargetType {
-    throw new UnsupportedError("effectiveTargetType");
-  }
-
-  @override
-  get _isEffectiveTargetMalformed {
-    throw new UnsupportedError("_isEffectiveTargetMalformed");
-  }
-
-  @override
-  set _isEffectiveTargetMalformed(_) {
-    throw new UnsupportedError("_isEffectiveTargetMalformed=");
-  }
-
-  @override
-  get isEffectiveTargetMalformed {
-    throw new UnsupportedError("isEffectiveTargetMalformed");
-  }
-
-  @override
-  void setEffectiveTarget(ConstructorElement target, ResolutionDartType type,
-      {bool isMalformed: false}) {
-    throw new UnsupportedError("setEffectiveTarget");
-  }
-
-  @override
-  void _computeSignature(Resolution resolution) {
-    throw new UnsupportedError("_computeSignature");
-  }
-
-  @override
-  get typeCache {
-    throw new UnsupportedError("typeCache");
-  }
-
-  @override
-  set typeCache(_) {
-    throw new UnsupportedError("typeCache=");
-  }
-
-  @override
-  get immediateRedirectionTarget {
-    throw new UnsupportedError("immediateRedirectionTarget");
-  }
-
-  @override
-  get _immediateRedirectionTarget {
-    throw new UnsupportedError("_immediateRedirectionTarget");
-  }
-
-  @override
-  set _immediateRedirectionTarget(_) {
-    throw new UnsupportedError("_immediateRedirectionTarget=");
-  }
-
-  @override
-  setImmediateRedirectionTarget(a, b) {
-    throw new UnsupportedError("setImmediateRedirectionTarget");
-  }
-
-  @override
-  get _functionSignatureCache {
-    throw new UnsupportedError("functionSignatureCache");
-  }
-
-  @override
-  set _functionSignatureCache(_) {
-    throw new UnsupportedError("functionSignatureCache=");
-  }
-
-  @override
-  set functionSignature(_) {
-    throw new UnsupportedError("functionSignature=");
-  }
-
-  @override
-  get parameterStructure {
-    throw new UnsupportedError("parameterStructure");
-  }
-
-  @override
-  get nestedClosures {
-    throw new UnsupportedError("nestedClosures");
-  }
-
-  @override
-  set nestedClosures(_) {
-    throw new UnsupportedError("nestedClosures=");
-  }
-
-  @override
-  get _redirectionDeferredPrefix {
-    throw new UnsupportedError("_redirectionDeferredPrefix");
-  }
-
-  @override
-  set _redirectionDeferredPrefix(_) {
-    throw new UnsupportedError("_redirectionDeferredPrefix=");
-  }
-
-  // TODO(johnniwinther): Remove this.
-  ConstructorElementX get declaration => super.declaration;
-
-  // TODO(johnniwinther): Remove this.
-  ConstructorElementX get implementation => super.implementation;
-
-  // TODO(johnniwinther): Remove this.
-  ConstructorElementX get origin => super.origin;
-
-  // TODO(johnniwinther): Remove this.
-  ConstructorElementX get patch => super.patch;
-
-  ResolutionFunctionType computeType(Resolution resolution) =>
-      super.computeType(resolution);
-}
-
-/// A message attached to a [WarnOnUseElementX].
-class WrappedMessage {
-  /// The message position. If [:null:] the position of the reference to the
-  /// [WarnOnUseElementX] is used.
-  final SourceSpan sourceSpan;
-
-  /**
-   * The message to report on resolving a wrapped element.
-   */
-  final MessageKind messageKind;
-
-  /**
-   * The message arguments to report on resolving a wrapped element.
-   */
-  final Map messageArguments;
-
-  WrappedMessage(this.sourceSpan, this.messageKind, this.messageArguments);
-}
-
-class WarnOnUseElementX extends ElementX implements WarnOnUseElement {
-  /// Warning to report on resolving this element.
-  final WrappedMessage warning;
-
-  /// Info to report on resolving this element.
-  final WrappedMessage info;
-
-  /// The element whose usage cause a warning.
-  final Element wrappedElement;
-
-  WarnOnUseElementX(
-      this.warning, this.info, Element enclosingElement, Element wrappedElement)
-      : this.wrappedElement = wrappedElement,
-        super(wrappedElement.name, ElementKind.WARN_ON_USE, enclosingElement);
-
-  Element unwrap(DiagnosticReporter reporter, Spannable usageSpannable) {
-    dynamic unwrapped = wrappedElement;
-    if (warning != null) {
-      Spannable spannable = warning.sourceSpan;
-      if (spannable == null) spannable = usageSpannable;
-      DiagnosticMessage warningMessage = reporter.createMessage(
-          spannable, warning.messageKind, warning.messageArguments);
-      List<DiagnosticMessage> infos = <DiagnosticMessage>[];
-      if (info != null) {
-        Spannable spannable = info.sourceSpan;
-        if (spannable == null) spannable = usageSpannable;
-        infos.add(reporter.createMessage(
-            spannable, info.messageKind, info.messageArguments));
-      }
-      reporter.reportWarning(warningMessage, infos);
-    }
-    if (unwrapped.isWarnOnUse) {
-      unwrapped = unwrapped.unwrap(reporter, usageSpannable);
-    }
-    return unwrapped;
-  }
-
-  accept(ElementVisitor visitor, arg) {
-    return visitor.visitWarnOnUseElement(this, arg);
-  }
-}
-
-abstract class AmbiguousElementX extends ElementX implements AmbiguousElement {
-  /**
-   * The message to report on resolving this element.
-   */
-  final MessageKind messageKind;
-
-  /**
-   * The message arguments to report on resolving this element.
-   */
-  final Map messageArguments;
-
-  /**
-   * The first element that this ambiguous element might refer to.
-   */
-  final Element existingElement;
-
-  /**
-   * The second element that this ambiguous element might refer to.
-   */
-  final Element newElement;
-
-  AmbiguousElementX(this.messageKind, this.messageArguments,
-      Element enclosingElement, Element existingElement, Element newElement)
-      : this.existingElement = existingElement,
-        this.newElement = newElement,
-        super(existingElement.name, ElementKind.AMBIGUOUS, enclosingElement);
-
-  Setlet flatten() {
-    Element element = this;
-    var set = new Setlet();
-    while (element.isAmbiguous) {
-      AmbiguousElement ambiguous = element;
-      set.add(ambiguous.newElement);
-      element = ambiguous.existingElement;
-    }
-    set.add(element);
-    return set;
-  }
-
-  List<DiagnosticMessage> computeInfos(
-      Element context, DiagnosticReporter reporter) {
-    return const <DiagnosticMessage>[];
-  }
-
-  accept(ElementVisitor visitor, arg) {
-    return visitor.visitAmbiguousElement(this, arg);
-  }
-
-  bool get isTopLevel => false;
-
-  ResolutionDynamicType get type => const ResolutionDynamicType();
-}
-
-/// Element synthesized to diagnose an ambiguous import.
-class AmbiguousImportX extends AmbiguousElementX {
-  AmbiguousImportX(MessageKind messageKind, Map messageArguments,
-      Element enclosingElement, Element existingElement, Element newElement)
-      : super(messageKind, messageArguments, enclosingElement, existingElement,
-            newElement);
-
-  List<DiagnosticMessage> computeInfos(
-      Element context, DiagnosticReporter reporter) {
-    List<DiagnosticMessage> infos = <DiagnosticMessage>[];
-    Setlet ambiguousElements = flatten();
-    MessageKind code = (ambiguousElements.length == 1)
-        ? MessageKind.AMBIGUOUS_REEXPORT
-        : MessageKind.AMBIGUOUS_LOCATION;
-    LibraryElementX importer = context.library;
-    for (Element element in ambiguousElements) {
-      Map arguments = {'name': element.name};
-      infos.add(reporter.createMessage(element, code, arguments));
-      reporter.withCurrentElement(importer, () {
-        for (ImportElement import in importer.importers.getImports(element)) {
-          infos.add(reporter.createMessage(
-              import, MessageKind.IMPORTED_HERE, arguments));
-        }
-      });
-    }
-    return infos;
-  }
-}
-
-/// Element synthesized to recover from a duplicated member of an element.
-class DuplicatedElementX extends AmbiguousElementX {
-  DuplicatedElementX(MessageKind messageKind, Map messageArguments,
-      Element enclosingElement, Element existingElement, Element newElement)
-      : super(messageKind, messageArguments, enclosingElement, existingElement,
-            newElement);
-
-  bool get isMalformed => true;
-}
-
-class ScopeX {
-  final Map<String, Element> contents = new Map<String, Element>();
-
-  bool get isEmpty => contents.isEmpty;
-  Iterable<Element> get values => contents.values;
-
-  Element lookup(String name) {
-    return contents[name];
-  }
-
-  void add(Element element, DiagnosticReporter reporter) {
-    String name = element.name;
-    if (element.isAccessor) {
-      addAccessor(element, contents[name], reporter);
-    } else {
-      Element existing = contents.putIfAbsent(name, () => element);
-      if (!identical(existing, element)) {
-        reporter.reportError(
-            reporter.createMessage(
-                element, MessageKind.DUPLICATE_DEFINITION, {'name': name}),
-            <DiagnosticMessage>[
-              reporter.createMessage(
-                  existing, MessageKind.EXISTING_DEFINITION, {'name': name}),
-            ]);
-      }
-    }
-  }
-
-  /**
-   * Adds a definition for an [accessor] (getter or setter) to a scope.
-   * The definition binds to an abstract field that can hold both a getter
-   * and a setter.
-   *
-   * The abstract field is added once, for the first getter or setter, and
-   * reused if the other one is also added.
-   * The abstract field should not be treated as a proper member of the
-   * container, it's simply a way to return two results for one lookup.
-   * That is, the getter or setter does not have the abstract field as enclosing
-   * element, they are enclosed by the class or compilation unit, as is the
-   * abstract field.
-   */
-  void addAccessor(AccessorElementX accessor, Element existing,
-      DiagnosticReporter reporter) {
-    void reportError(Element other) {
-      reporter.reportError(
-          reporter.createMessage(accessor, MessageKind.DUPLICATE_DEFINITION,
-              {'name': accessor.name}),
-          <DiagnosticMessage>[
-            reporter.createMessage(other, MessageKind.EXISTING_DEFINITION,
-                {'name': accessor.name}),
-          ]);
-
-      contents[accessor.name] = new DuplicatedElementX(
-          MessageKind.DUPLICATE_DEFINITION,
-          {'name': accessor.name},
-          accessor.memberContext.enclosingElement,
-          other,
-          accessor);
-    }
-
-    if (existing != null) {
-      if (!identical(existing.kind, ElementKind.ABSTRACT_FIELD)) {
-        reportError(existing);
-        return;
-      } else {
-        AbstractFieldElementX field = existing;
-        accessor.abstractField = field;
-        if (accessor.isGetter) {
-          if (field.getter != null && field.getter != accessor) {
-            reportError(field.getter);
-            return;
-          }
-          field.getter = accessor;
-        } else {
-          assert(accessor.isSetter);
-          if (field.setter != null && field.setter != accessor) {
-            reportError(field.setter);
-            return;
-          }
-          field.setter = accessor;
-        }
-      }
-    } else {
-      Element container = accessor.enclosingClassOrCompilationUnit;
-      AbstractFieldElementX field =
-          new AbstractFieldElementX(accessor.name, container);
-      accessor.abstractField = field;
-      if (accessor.isGetter) {
-        field.getter = accessor;
-      } else {
-        field.setter = accessor;
-      }
-      add(field, reporter);
-    }
-  }
-}
-
-class CompilationUnitElementX extends ElementX
-    with CompilationUnitElementCommon
-    implements CompilationUnitElement {
-  final Script script;
-  PartOf partTag;
-  Link<Element> localMembers = const Link<Element>();
-
-  CompilationUnitElementX(Script script, LibraryElementX library)
-      : this.script = script,
-        super(script.name, ElementKind.COMPILATION_UNIT, library) {
-    library.addCompilationUnit(this);
-  }
-
-  @override
-  LibraryElementX get library => enclosingElement.declaration;
-
-  void set metadata(List<MetadataAnnotation> metadata) {
-    for (MetadataAnnotationX annotation in metadata) {
-      assert(annotation.annotatedElement == null);
-      annotation.annotatedElement = this;
-    }
-    // TODO(johnniwinther): Remove this work-around when import, export,
-    // part, and part-of declarations are elements.
-    if (metadataInternal == null) {
-      metadataInternal = <MetadataAnnotation>[];
-    }
-    metadataInternal.addAll(metadata);
-  }
-
-  void forEachLocalMember(f(Element element)) {
-    localMembers.forEach(f);
-  }
-
-  void addMember(Element element, DiagnosticReporter reporter) {
-    // Keep a list of top level members.
-    localMembers = localMembers.prepend(element);
-    // Provide the member to the library to build scope.
-    if (enclosingElement.isPatch) {
-      LibraryElementX library = implementationLibrary;
-      library.addMember(element, reporter);
-    } else {
-      library.addMember(element, reporter);
-    }
-  }
-
-  void setPartOf(PartOf tag, DiagnosticReporter reporter) {
-    LibraryElementX library = enclosingElement;
-    if (library.entryCompilationUnit == this) {
-      // This compilation unit is loaded as a library. The error is reported by
-      // the library loader.
-      partTag = tag;
-      return;
-    }
-    if (!localMembers.isEmpty) {
-      reporter.reportErrorMessage(tag, MessageKind.BEFORE_TOP_LEVEL);
-      return;
-    }
-    if (partTag != null) {
-      reporter.reportWarningMessage(tag, MessageKind.DUPLICATED_PART_OF);
-      return;
-    }
-    partTag = tag;
-    LibraryName libraryTag = library.libraryTag;
-
-    Expression libraryReference = tag.name;
-    if (libraryReference is LiteralString) {
-      // Name is a URI. Resolve and compare to library's URI.
-      String content = libraryReference.dartString.slowToString();
-      Uri uri = this.script.readableUri.resolve(content);
-      Uri expectedUri = library.canonicalUri;
-      // Also allow `string.dart` to refer to `dart:core` as `core.dart`.
-      if (library.isPlatformLibrary && !uri.isScheme("dart")) {
-        expectedUri = library.entryCompilationUnit.script.readableUri;
-      }
-      if (uri != expectedUri) {
-        // Consider finding a relative URI reference for the error message.
-        reporter.reportWarningMessage(tag.name,
-            MessageKind.LIBRARY_URI_MISMATCH, {'libraryUri': expectedUri});
-      }
-      return;
-    }
-    String actualName = tag.name.toString();
-    if (libraryTag != null) {
-      String expectedName = libraryTag.name.toString();
-      if (expectedName != actualName) {
-        reporter.reportWarningMessage(tag.name,
-            MessageKind.LIBRARY_NAME_MISMATCH, {'libraryName': expectedName});
-      }
-    } else {
-      reporter.reportWarning(
-          reporter.createMessage(library, MessageKind.MISSING_LIBRARY_NAME,
-              {'libraryName': actualName}),
-          <DiagnosticMessage>[
-            reporter.createMessage(
-                tag.name, MessageKind.THIS_IS_THE_PART_OF_TAG),
-          ]);
-    }
-  }
-
-  bool get hasMembers => !localMembers.isEmpty;
-
-  AnalyzableElement get analyzableElement => library;
-
-  accept(ElementVisitor visitor, arg) {
-    return visitor.visitCompilationUnitElement(this, arg);
-  }
-}
-
-/// Map from [Element] to the [ImportElement]s throught which it was imported.
-///
-/// This is used for error reporting and deferred loading.
-class Importers {
-  Map<Element, List<ImportElement>> importers =
-      new Map<Element, List<ImportElement>>();
-
-  /// Returns the list of [ImportElement]s through which [element] was
-  /// imported.
-  List<ImportElement> getImports(Element element) {
-    List<ImportElement> imports = importers[element];
-    return imports != null ? imports : const <ImportElement>[];
-  }
-
-  /// Returns the first [ImportElement] through which [element] was imported.
-  ImportElement getImport(Element element) => getImports(element).first;
-
-  /// Register [element] as imported through [import];
-  void registerImport(Element element, ImportElement import) {
-    importers.putIfAbsent(element, () => <ImportElement>[]).add(import);
-  }
-}
-
-class ImportScope {
-  /**
-   * Map for elements imported through import declarations.
-   *
-   * Addition to the map is performed by [addImport]. Lookup is done trough
-   * [find].
-   */
-  final Map<String, Element> importScope = new Map<String, Element>();
-
-  /**
-   * Adds [element] to the import scope of this library.
-   *
-   * If an element by the same name is already in the imported scope, an
-   * [ErroneousElement] will be put in the imported scope, allowing for
-   * detection of ambiguous uses of imported names.
-   */
-  void addImport(Element enclosingElement, Element element,
-      ImportElement import, DiagnosticReporter reporter) {
-    LibraryElementX library = enclosingElement.library;
-    Importers importers = library.importers;
-
-    String name = element.name;
-
-    // The loadLibrary function always shadows existing bindings to that name.
-    if (element.isDeferredLoaderGetter) {
-      importScope.remove(name);
-      // TODO(sigurdm): Print a hint.
-    }
-    Element existing = importScope.putIfAbsent(name, () => element);
-    importers.registerImport(element, import);
-
-    void registerWarnOnUseElement(ImportElement import, MessageKind messageKind,
-        Element hidingElement, Element hiddenElement) {
-      Uri hiddenUri = hiddenElement.library.canonicalUri;
-      Uri hidingUri = hidingElement.library.canonicalUri;
-      Element element = new WarnOnUseElementX(
-          new WrappedMessage(
-              null, // Report on reference to [hidingElement].
-              messageKind,
-              {'name': name, 'hiddenUri': hiddenUri, 'hidingUri': hidingUri}),
-          new WrappedMessage(reporter.spanFromSpannable(import),
-              MessageKind.IMPORTED_HERE, {'name': name}),
-          enclosingElement,
-          hidingElement);
-      importScope[name] = element;
-      importers.registerImport(element, import);
-    }
-
-    if (existing != element) {
-      ImportElement existingImport = importers.getImport(existing);
-      if (existing.library.isPlatformLibrary &&
-          !element.library.isPlatformLibrary) {
-        // [existing] is implicitly hidden.
-        registerWarnOnUseElement(
-            import, MessageKind.HIDDEN_IMPORT, element, existing);
-      } else if (!existing.library.isPlatformLibrary &&
-          element.library.isPlatformLibrary) {
-        // [element] is implicitly hidden.
-        if (import.isSynthesized) {
-          // [element] is imported implicitly (probably through dart:core).
-          registerWarnOnUseElement(existingImport,
-              MessageKind.HIDDEN_IMPLICIT_IMPORT, existing, element);
-        } else {
-          registerWarnOnUseElement(
-              import, MessageKind.HIDDEN_IMPORT, existing, element);
-        }
-      } else {
-        Element ambiguousElement = new AmbiguousImportX(
-            MessageKind.DUPLICATE_IMPORT,
-            {'name': name},
-            enclosingElement,
-            existing,
-            element);
-        importScope[name] = ambiguousElement;
-        importers.registerImport(ambiguousElement, import);
-        importers.registerImport(ambiguousElement, existingImport);
-      }
-    }
-  }
-
-  Element operator [](String name) => importScope[name];
-
-  void forEach(f(Element element)) => importScope.values.forEach(f);
-}
-
-abstract class LibraryDependencyElementX extends ElementX {
-  final LibraryDependency node;
-  final Uri uri;
-  LibraryElement libraryDependency;
-
-  LibraryDependencyElementX(CompilationUnitElement enclosingElement,
-      ElementKind kind, this.node, this.uri)
-      : super('', kind, enclosingElement);
-
-  @override
-  List<MetadataAnnotation> get metadata => node.metadata;
-
-  void set metadata(value) {
-    // The metadata is stored on [libraryDependency].
-    failedAt(this, 'Cannot set metadata on a import/export.');
-  }
-
-  @override
-  Token get position => node.getBeginToken();
-
-  SourceSpan get sourcePosition {
-    return new SourceSpan.fromNode(compilationUnit.script.resourceUri, node);
-  }
-
-  String toString() => '$kind($uri)';
-}
-
-class ImportElementX extends LibraryDependencyElementX
-    implements ImportElement {
-  PrefixElementX prefix;
-
-  ImportElementX(CompilationUnitElement enclosingElement, Import node, Uri uri)
-      : super(enclosingElement, ElementKind.IMPORT, node, uri);
-
-  @override
-  Import get node => super.node;
-
-  @override
-  LibraryElement get enclosingLibrary => library;
-
-  @override
-  LibraryElement get importedLibrary => libraryDependency;
-
-  @override
-  accept(ElementVisitor visitor, arg) => visitor.visitImportElement(this, arg);
-
-  @override
-  bool get isDeferred => node.isDeferred;
-
-  @override
-  String get name => prefix?.name;
-}
-
-class SyntheticImportElement extends ImportElementX {
-  SyntheticImportElement(CompilationUnitElement enclosingElement, Uri uri,
-      LibraryElement libraryDependency)
-      : super(enclosingElement, null, uri) {
-    this.libraryDependency = libraryDependency;
-  }
-
-  @override
-  Token get position => library.position;
-
-  @override
-  bool get isSynthesized => true;
-
-  @override
-  bool get isDeferred => false;
-
-  @override
-  List<MetadataAnnotation> get metadata => const <MetadataAnnotation>[];
-
-  @override
-  SourceSpan get sourcePosition => library.sourcePosition;
-}
-
-class ExportElementX extends LibraryDependencyElementX
-    implements ExportElement {
-  ExportElementX(CompilationUnitElement enclosingElement, Export node, Uri uri)
-      : super(enclosingElement, ElementKind.EXPORT, node, uri);
-
-  Export get node => super.node;
-
-  @override
-  LibraryElement get exportedLibrary => libraryDependency;
-
-  @override
-  accept(ElementVisitor visitor, arg) => visitor.visitExportElement(this, arg);
-}
-
-class LibraryElementX extends ElementX
-    with LibraryElementCommon, AnalyzableElementX, PatchMixin<LibraryElementX>
-    implements LibraryElement {
-  final Uri canonicalUri;
-
-  /// True if the constructing script was synthesized.
-  final bool isSynthesized;
-
-  CompilationUnitElement entryCompilationUnit;
-  Link<CompilationUnitElement> compilationUnits =
-      const Link<CompilationUnitElement>();
-  LinkBuilder<LibraryTag> tagsBuilder = new LinkBuilder<LibraryTag>();
-  List<LibraryTag> tagsCache;
-  LibraryName libraryTag;
-  Link<Element> localMembers = const Link<Element>();
-  final ScopeX localScope = new ScopeX();
-  final ImportScope importScope = new ImportScope();
-
-  /// A mapping from an imported element to the "import" tag.
-  final Importers importers = new Importers();
-
-  /**
-   * Link for elements exported either through export declarations or through
-   * declaration. This field should not be accessed directly but instead through
-   * the [exports] getter.
-   *
-   * [LibraryDependencyHandler] sets this field through [setExports] when the
-   * library is loaded.
-   */
-  Link<Element> slotForExports;
-
-  List<ImportElement> _imports = <ImportElement>[];
-  List<ExportElement> _exports = <ExportElement>[];
-
-  final Map<LibraryDependency, LibraryElement> tagMapping =
-      new Map<LibraryDependency, LibraryElement>();
-
-  final Map<String, MixinApplicationElementX> mixinApplicationCache =
-      <String, MixinApplicationElementX>{};
-
-  LibraryElementX(Script script, [Uri canonicalUri, LibraryElementX origin])
-      : this.canonicalUri =
-            ((canonicalUri == null) ? script.readableUri : canonicalUri),
-        this.isSynthesized = script.isSynthesized,
-        super(script.name, ElementKind.LIBRARY, null) {
-    entryCompilationUnit = new CompilationUnitElementX(script, this);
-    if (origin != null) {
-      origin.applyPatch(this);
-    }
-  }
-
-  Iterable<MetadataAnnotation> get metadata {
-    if (libraryTag != null) {
-      return libraryTag.metadata;
-    }
-    return const <MetadataAnnotation>[];
-  }
-
-  void set metadata(value) {
-    // The metadata is stored on [libraryTag].
-    failedAt(this, 'Cannot set metadata on Library');
-  }
-
-  CompilationUnitElement get compilationUnit => entryCompilationUnit;
-
-  AnalyzableElement get analyzableElement => this;
-
-  void addCompilationUnit(CompilationUnitElement element) {
-    compilationUnits = compilationUnits.prepend(element);
-  }
-
-  void addTag(LibraryTag tag, DiagnosticReporter reporter) {
-    if (tagsCache != null) {
-      reporter.internalError(
-          tag, "Library tags for $this have already been computed.");
-    }
-    tagsBuilder.addLast(tag);
-  }
-
-  Iterable<LibraryTag> get tags {
-    if (tagsCache == null) {
-      tagsCache = tagsBuilder.toList();
-      tagsBuilder = null;
-    }
-    return tagsCache;
-  }
-
-  void addImportDeclaration(ImportElement import) {
-    _imports.add(import);
-  }
-
-  Iterable<ImportElement> get imports => _imports;
-
-  void addExportDeclaration(ExportElement export) {
-    _exports.add(export);
-  }
-
-  Iterable<ExportElement> get exports => _exports;
-
-  /**
-   * Adds [element] to the import scope of this library.
-   *
-   * If an element by the same name is already in the imported scope, an
-   * [ErroneousElement] will be put in the imported scope, allowing for
-   * detection of ambiguous uses of imported names.
-   */
-  void addImport(
-      Element element, ImportElement import, DiagnosticReporter reporter) {
-    importScope.addImport(this, element, import, reporter);
-  }
-
-  void addMember(Element element, DiagnosticReporter reporter) {
-    localMembers = localMembers.prepend(element);
-    addToScope(element, reporter);
-  }
-
-  void addToScope(Element element, DiagnosticReporter reporter) {
-    localScope.add(element, reporter);
-  }
-
-  Element localLookup(String elementName) {
-    Element result = localScope.lookup(elementName);
-    if (result == null && isPatch) {
-      result = origin.localLookup(elementName);
-    }
-    return result;
-  }
-
-  /**
-   * Returns [:true:] if the export scope has already been computed for this
-   * library.
-   */
-  bool get exportsHandled => slotForExports != null;
-
-  /**
-   * Sets the export scope of this library. This method can only be called once.
-   */
-  void setExports(Iterable<Element> exportedElements) {
-    assert(!exportsHandled,
-        failedAt(this, 'Exports already set to $slotForExports on $this'));
-    assert(exportedElements != null, failedAt(this));
-    var builder = new LinkBuilder<Element>();
-    for (Element export in exportedElements) {
-      builder.addLast(export);
-    }
-    slotForExports = builder.toLink();
-  }
-
-  LibraryElement get library => isPatch ? origin : this;
-
-  /**
-   * Look up a top-level element in this library. The element could
-   * potentially have been imported from another library. Returns
-   * null if no such element exist and an [ErroneousElement] if multiple
-   * elements have been imported.
-   */
-  Element find(String elementName) {
-    Element result = localScope.lookup(elementName);
-    if (result != null) return result;
-    if (origin != null) {
-      result = origin.localScope.lookup(elementName);
-      if (result != null) return result;
-    }
-    result = importScope[elementName];
-    if (result != null) return result;
-    if (origin != null) {
-      result = origin.importScope[elementName];
-      if (result != null) return result;
-    }
-    return null;
-  }
-
-  /** Look up a top-level element in this library, but only look for
-    * non-imported elements. Returns null if no such element exist. */
-  Element findLocal(String elementName) {
-    // TODO((johnniwinther): How to handle injected elements in the patch
-    // library?
-    Element result = localScope.lookup(elementName);
-    if (result == null && isPatch) {
-      return origin.findLocal(elementName);
-    }
-    return result;
-  }
-
-  Element findExported(String elementName) {
-    assert(exportsHandled, failedAt(this, 'Exports not handled on $this'));
-    for (Link link = slotForExports; !link.isEmpty; link = link.tail) {
-      Element element = link.head;
-      if (element.name == elementName) return element;
-    }
-    return null;
-  }
-
-  void forEachExport(f(Element element)) {
-    assert(exportsHandled, failedAt(this, 'Exports not handled on $this'));
-    slotForExports.forEach((Element e) => f(e));
-  }
-
-  Iterable<ImportElement> getImportsFor(Element element) {
-    return importers.getImports(element);
-  }
-
-  void forEachImport(f(Element element)) => importScope.forEach(f);
-
-  void forEachLocalMember(f(Element element)) {
-    if (isPatch) {
-      // Patch libraries traverse both origin and injected members.
-      origin.localMembers.forEach(f);
-
-      void filterPatch(Element element) {
-        if (!element.isPatch) {
-          // Do not traverse the patch members.
-          f(element);
-        }
-      }
-
-      localMembers.forEach(filterPatch);
-    } else {
-      localMembers.forEach(f);
-    }
-  }
-
-  Iterable<Element> getNonPrivateElementsInScope() {
-    return localScope.values.where((Element element) {
-      // At this point [localScope] only contains members so we don't need
-      // to check for foreign or prefix elements.
-      return !Name.isPrivateName(element.name);
-    });
-  }
-
-  bool get hasLibraryName => libraryTag != null;
-
-  String get libraryName {
-    if (libraryTag == null) return '';
-    return libraryTag.name.toString();
-  }
-
-  Scope buildScope() => new LibraryScope(this);
-
-  String toString() {
-    if (origin != null) {
-      return 'patch library(${canonicalUri})';
-    } else if (patch != null) {
-      return 'origin library(${canonicalUri})';
-    } else {
-      return 'library(${canonicalUri})';
-    }
-  }
-
-  accept(ElementVisitor visitor, arg) {
-    return visitor.visitLibraryElement(this, arg);
-  }
-
-  // TODO(johnniwinther): Remove this.
-  LibraryElementX get declaration => super.declaration;
-
-  // TODO(johnniwinther): Remove this.
-  LibraryElementX get implementation => super.implementation;
-
-  // TODO(johnniwinther): Remove this.
-  LibraryElementX get origin => super.origin;
-
-  // TODO(johnniwinther): Remove this.
-  LibraryElementX get patch => super.patch;
-}
-
-class PrefixElementX extends ElementX implements PrefixElement {
-  Token firstPosition;
-
-  final ImportScope importScope = new ImportScope();
-
-  bool get isDeferred => deferredImport != null;
-
-  // Only needed for deferred imports.
-  final ImportElement deferredImport;
-
-  PrefixElementX(
-      String prefix, Element enclosing, this.firstPosition, this.deferredImport)
-      : super(prefix, ElementKind.PREFIX, enclosing);
-
-  bool get isTopLevel => false;
-
-  Element lookupLocalMember(String memberName) => importScope[memberName];
-
-  void forEachLocalMember(f(Element member)) => importScope.forEach(f);
-
-  ResolutionDartType computeType(Resolution resolution) =>
-      const ResolutionDynamicType();
-
-  Token get position => firstPosition;
-
-  void addImport(
-      Element element, ImportElement import, DiagnosticReporter reporter) {
-    importScope.addImport(this, element, import, reporter);
-  }
-
-  accept(ElementVisitor visitor, arg) {
-    return visitor.visitPrefixElement(this, arg);
-  }
-
-  @override
-  GetterElement get loadLibrary {
-    return isDeferred ? lookupLocalMember(Identifiers.loadLibrary) : null;
-  }
-
-  String toString() => '$kind($name)';
-}
-
-class TypedefElementX extends ElementX
-    with AstElementMixin, AnalyzableElementX, TypeDeclarationElementX
-    implements TypedefElement {
-  Typedef cachedNode;
-
-  /**
-   * The type annotation which defines this typedef.
-   */
-  ResolutionDartType aliasCache;
-
-  ResolutionDartType get alias {
-    assert(hasBeenCheckedForCycles,
-        failedAt(this, "$this has not been checked for cycles."));
-    return aliasCache;
-  }
-
-  /// [:true:] if the typedef has been checked for cyclic reference.
-  bool hasBeenCheckedForCycles = false;
-
-  int resolutionState = STATE_NOT_STARTED;
-
-  TypedefElementX(String name, Element enclosing)
-      : super(name, ElementKind.TYPEDEF, enclosing);
-
-  bool get hasNode => cachedNode != null;
-
-  Typedef get node {
-    assert(cachedNode != null,
-        failedAt(this, "Node has not been computed for $this."));
-    return cachedNode;
-  }
-
-  /**
-   * Function signature for a typedef of a function type. The signature is
-   * kept to provide full information about parameter names through the mirror
-   * system.
-   *
-   * The [functionSignature] is not available until the typedef element has been
-   * resolved.
-   */
-  FunctionSignature functionSignature;
-
-  ResolutionTypedefType computeType(Resolution resolution) {
-    if (thisTypeCache != null) return thisTypeCache;
-    Typedef node = parseNode(resolution.parsingContext);
-    setThisAndRawTypes(createTypeVariables(node.templateParameters));
-    ensureResolved(resolution);
-    return thisTypeCache;
-  }
-
-  void ensureResolved(Resolution resolution) {
-    if (resolutionState == STATE_NOT_STARTED) {
-      resolution.resolveTypedef(this);
-    }
-  }
-
-  ResolutionTypedefType createType(List<ResolutionDartType> typeArguments) {
-    return new ResolutionTypedefType(this, typeArguments);
-  }
-
-  Scope buildScope() {
-    return new TypeDeclarationScope(enclosingElement.buildScope(), this);
-  }
-
-  void checkCyclicReference(Resolution resolution) {
-    if (hasBeenCheckedForCycles) return;
-    TypedefCyclicVisitor visitor =
-        new TypedefCyclicVisitor(resolution.reporter, this);
-    computeType(resolution).accept(visitor, null);
-    hasBeenCheckedForCycles = true;
-  }
-
-  accept(ElementVisitor visitor, arg) {
-    return visitor.visitTypedefElement(this, arg);
-  }
-
-  // A typedef cannot be patched therefore defines itself.
-  AstElement get definingElement => this;
-
-  ResolutionTypedefType get thisType => super.thisType;
-
-  ResolutionTypedefType get rawType => super.rawType;
-}
-
-// This class holds common information for a list of variable or field
-// declarations. It contains the node, and the type. A [VariableElementX]
-// forwards its [computeType] and [parseNode] methods to this class.
-class VariableList implements DeclarationSite {
-  VariableDefinitions definitions;
-  ResolutionDartType type;
-  final Modifiers modifiers;
-  List<MetadataAnnotation> metadataInternal;
-
-  VariableList(Modifiers this.modifiers);
-
-  VariableList.node(VariableDefinitions node, this.type)
-      : this.definitions = node,
-        this.modifiers = node.modifiers {
-    assert(modifiers != null);
-  }
-
-  Iterable<MetadataAnnotation> get metadata {
-    return metadataInternal != null
-        ? metadataInternal
-        : const <MetadataAnnotation>[];
-  }
-
-  void set metadata(List<MetadataAnnotation> metadata) {
-    if (metadata.isEmpty) {
-      // For a multi declaration like:
-      //
-      //    @foo @bar var a, b, c
-      //
-      // the metadata list is reported through the declaration of `a`, and `b`
-      // and `c` report an empty list of metadata.
-      return;
-    }
-    assert(metadataInternal == null);
-    metadataInternal = metadata;
-  }
-
-  VariableDefinitions parseNode(Element element, ParsingContext parsing) {
-    return definitions;
-  }
-
-  ResolutionDartType computeType(Element element, Resolution resolution) =>
-      type;
-}
-
-abstract class ConstantVariableMixin implements VariableElement {
-  ConstantExpression constantCache;
-
-  // TODO(johnniwinther): Update the on `constant = ...` when evaluation of
-  // constant expression can handle references to unanalyzed constant variables.
-  @override
-  bool get hasConstant => false;
-
-  ConstantExpression get constant {
-    if (isPatch) {
-      ConstantVariableMixin originVariable = origin;
-      return originVariable.constant;
-    }
-    assert(!isConst || constantCache != null,
-        failedAt(this, "Constant has not been computed for $this."));
-    return constantCache;
-  }
-
-  void set constant(ConstantExpression value) {
-    if (isPatch) {
-      ConstantVariableMixin originVariable = origin;
-      originVariable.constant = value;
-      return;
-    }
-    if (constantCache != null &&
-        constantCache.kind == ConstantExpressionKind.ERRONEOUS) {
-      // TODO(johnniwinther): Find out why we sometimes compute a non-erroneous
-      // constant for a variable already known to be erroneous.
-      return;
-    }
-    if (constantCache != null && constantCache != value) {
-      // Allow setting the constant as erroneous. Constants computed during
-      // resolution are locally valid but might be effectively erroneous. For
-      // instance `a ? true : false` where a is `const a = m()`. Since `a` is
-      // declared to be constant, the conditional is assumed valid, but when
-      // computing the value we see that it isn't.
-      // TODO(johnniwinther): Remove this exception when all constant
-      // expressions are computed during resolution.
-      assert(
-          value == null || value.kind == ConstantExpressionKind.ERRONEOUS,
-          failedAt(
-              this,
-              "Constant has already been computed for $this. "
-              "Existing constant: "
-              "${constantCache != null ? constantCache.toStructuredText() : ''}"
-              ", New constant: "
-              "${value != null ? value.toStructuredText() : ''}."));
-    }
-    constantCache = value;
-  }
-}
-
-abstract class VariableElementX extends ElementX
-    with AstElementMixin, ConstantVariableMixin
-    implements VariableElement {
-  final Token token;
-  final VariableList variables;
-  VariableDefinitions definitionsCache;
-  Expression definitionCache;
-  Expression initializerCache;
-
-  Modifiers get modifiers => variables.modifiers;
-
-  VariableElementX(String name, ElementKind kind, Element enclosingElement,
-      VariableList variables, this.token)
-      : this.variables = variables,
-        super(name, kind, enclosingElement);
-
-  // TODO(johnniwinther): Ensure that the [TreeElements] for this variable hold
-  // the mappings for all its metadata.
-  Iterable<MetadataAnnotation> get metadata => variables.metadata;
-
-  void set metadata(List<MetadataAnnotation> metadata) {
-    for (MetadataAnnotationX annotation in metadata) {
-      assert(annotation.annotatedElement == null);
-      annotation.annotatedElement = this;
-    }
-    variables.metadata = metadata;
-  }
-
-  // A variable cannot be patched therefore defines itself.
-  AstElement get definingElement => this;
-
-  bool get hasNode => definitionsCache != null;
-
-  VariableDefinitions get node {
-    assert(definitionsCache != null,
-        failedAt(this, "Node has not been computed for $this."));
-    return definitionsCache;
-  }
-
-  /// Returns the node that defines this field.
-  ///
-  /// For instance in `var a, b = true`, the definitions nodes for fields 'a'
-  /// and 'b' are the nodes for `a` and `b = true`, respectively.
-  Expression get definition {
-    assert(definitionCache != null,
-        failedAt(this, "Definition node has not been computed for $this."));
-    return definitionCache;
-  }
-
-  Expression get initializer {
-    assert(definitionsCache != null,
-        failedAt(this, "Initializer has not been computed for $this."));
-    return initializerCache;
-  }
-
-  Node parseNode(ParsingContext parsing) {
-    if (definitionsCache != null) return definitionsCache;
-
-    VariableDefinitions definitions = variables.parseNode(this, parsing);
-    createDefinitions(definitions);
-    return definitionsCache;
-  }
-
-  void createDefinitions(VariableDefinitions definitions) {
-    assert(
-        definitionsCache == null,
-        failedAt(
-            this, "VariableDefinitions has already been computed for $this."));
-    for (Link<Node> link = definitions.definitions.nodes;
-        !link.isEmpty;
-        link = link.tail) {
-      Expression initializedIdentifier = link.head;
-      Identifier identifier = initializedIdentifier.asIdentifier();
-      if (identifier == null) {
-        SendSet sendSet = initializedIdentifier.asSendSet();
-        identifier = sendSet.selector.asIdentifier();
-        if (identical(name, identifier.source)) {
-          definitionCache = initializedIdentifier;
-          initializerCache = sendSet.arguments.first;
-        }
-      } else if (identical(name, identifier.source)) {
-        definitionCache = initializedIdentifier;
-      }
-    }
-    if (definitionCache == null) {
-      failedAt(definitionCache, "Could not find '$name'.");
-    }
-    definitionsCache = definitions;
-  }
-
-  ResolutionDartType computeType(Resolution resolution) {
-    if (variables.type != null) return variables.type;
-    // Call [parseNode] to ensure that [definitionsCache] and [initializerCache]
-    // are set as a consequence of calling [computeType].
-    parseNode(resolution.parsingContext);
-    return variables.computeType(this, resolution);
-  }
-
-  ResolutionDartType get type {
-    assert(variables.type != null,
-        failedAt(this, "Type has not been computed for $this."));
-    return variables.type;
-  }
-
-  bool get isInstanceMember => isClassMember && !isStatic;
-
-  // Note: cachedNode.beginToken will not be correct in all
-  // cases, for example, for function typed parameters.
-  Token get position => token;
-
-  DeclarationSite get declarationSite => variables;
-}
-
-class LocalVariableElementX extends VariableElementX
-    implements LocalVariableElement {
-  LocalVariableElementX(String name, ExecutableElement enclosingElement,
-      VariableList variables, Token token)
-      : super(name, ElementKind.VARIABLE, enclosingElement, variables, token) {
-    createDefinitions(variables.definitions);
-  }
-
-  ExecutableElement get executableContext => enclosingElement;
-
-  MemberElement get memberContext => executableContext.memberContext;
-
-  bool get isLocal => true;
-
-  accept(ElementVisitor visitor, arg) {
-    return visitor.visitLocalVariableElement(this, arg);
-  }
-}
-
-class FieldElementX extends VariableElementX
-    with AnalyzableElementX
-    implements FieldElement {
-  List<MethodElement> nestedClosures = new List<MethodElement>();
-
-  FieldElementX(
-      Identifier name, Element enclosingElement, VariableList variables)
-      : super(name.source, ElementKind.FIELD, enclosingElement, variables,
-            name.token);
-
-  accept(ElementVisitor visitor, arg) {
-    return visitor.visitFieldElement(this, arg);
-  }
-
-  MemberElement get memberContext => this;
-
-  void reuseElement() {
-    super.reuseElement();
-    nestedClosures.clear();
-  }
-
-  FieldElementX copyWithEnclosing(Element enclosingElement) {
-    return new FieldElementX(
-        new Identifier(token), enclosingElement, variables);
-  }
-}
-
-/// A field that was synthesized to recover from a compile-time error.
-class ErroneousFieldElementX extends ElementX
-    with ConstantVariableMixin
-    implements FieldElementX {
-  final VariableList variables;
-
-  ErroneousFieldElementX(Identifier name, Element enclosingElement)
-      : variables = new VariableList(Modifiers.EMPTY)
-          ..definitions = new VariableDefinitions(
-              null, Modifiers.EMPTY, new NodeList.singleton(name))
-          ..type = const ResolutionDynamicType(),
-        super(name.source, ElementKind.FIELD, enclosingElement);
-
-  VariableDefinitions get definitionsCache => variables.definitions;
-
-  set definitionsCache(VariableDefinitions _) {
-    throw new UnsupportedError("definitionsCache=");
-  }
-
-  bool get hasNode => true;
-
-  VariableDefinitions get node => definitionsCache;
-
-  bool get hasResolvedAst => false;
-
-  ResolvedAst get resolvedAst {
-    throw new UnsupportedError("resolvedAst");
-  }
-
-  ResolutionDynamicType get type => const ResolutionDynamicType();
-
-  Token get token => node.getBeginToken();
-
-  get definitionCache {
-    throw new UnsupportedError("definitionCache");
-  }
-
-  set definitionCache(_) {
-    throw new UnsupportedError("definitionCache=");
-  }
-
-  get initializerCache {
-    throw new UnsupportedError("initializerCache");
-  }
-
-  set initializerCache(_) {
-    throw new UnsupportedError("initializerCache=");
-  }
-
-  void createDefinitions(VariableDefinitions definitions) {
-    throw new UnsupportedError("createDefinitions");
-  }
-
-  get initializer => null;
-
-  get definition => null;
-
-  bool get isMalformed => true;
-
-  get nestedClosures {
-    throw new UnsupportedError("nestedClosures");
-  }
-
-  set nestedClosures(_) {
-    throw new UnsupportedError("nestedClosures=");
-  }
-
-  // TODO(ahe): Should this throw or do nothing?
-  accept(ElementVisitor visitor, arg) {
-    return visitor.visitFieldElement(this, arg);
-  }
-
-  // TODO(ahe): Should return the context of the error site?
-  MemberElement get memberContext => this;
-
-  // TODO(ahe): Should return the definingElement of the error site?
-  AstElement get definingElement => this;
-
-  void reuseElement() {
-    throw new UnsupportedError("reuseElement");
-  }
-
-  FieldElementX copyWithEnclosing(Element enclosingElement) {
-    throw new UnsupportedError("copyWithEnclosing");
-  }
-
-  ResolutionDartType computeType(Resolution resolution) => type;
-}
-
-/// [Element] for a parameter-like element.
-class FormalElementX extends ElementX
-    with AstElementMixin
-    implements FormalElement {
-  final VariableDefinitions definitions;
-  final Identifier identifier;
-  ResolutionDartType typeCache;
-
-  @override
-  List<ResolutionDartType> get typeVariables => functionSignature.typeVariables;
-
-  /**
-   * Function signature for a variable with a function type. The signature is
-   * kept to provide full information about parameter names through the mirror
-   * system.
-   */
-  FunctionSignature _functionSignatureCache;
-
-  FormalElementX(ElementKind elementKind, FunctionTypedElement enclosingElement,
-      this.definitions, Identifier identifier)
-      : this.identifier = identifier,
-        super(identifier.source, elementKind, enclosingElement);
-
-  FormalElementX.unnamed(ElementKind elementKind,
-      FunctionTypedElement enclosingElement, this.definitions)
-      : this.identifier = null,
-        super("<unnamed>", elementKind, enclosingElement);
-
-  /// Whether this is an unnamed parameter in a Function type.
-  bool get isUnnamed => identifier == null;
-
-  FunctionTypedElement get functionDeclaration => enclosingElement;
-
-  Modifiers get modifiers => definitions.modifiers;
-
-  Token get position => identifier.getBeginToken();
-
-  Node parseNode(ParsingContext parsing) => definitions;
-
-  ResolutionDartType computeType(Resolution resolution) {
-    assert(type != null,
-        failedAt(this, "Parameter type has not been set for $this."));
-    return type;
-  }
-
-  ResolutionDartType get type {
-    assert(typeCache != null,
-        failedAt(this, "Parameter type has not been set for $this."));
-    return typeCache;
-  }
-
-  FunctionSignature get functionSignature {
-    assert(_functionSignatureCache != null,
-        failedAt(this, "Parameter signature has not been computed for $this."));
-    return _functionSignatureCache;
-  }
-
-  void set functionSignature(FunctionSignature value) {
-    assert(
-        _functionSignatureCache == null,
-        failedAt(
-            this, "Parameter signature has already been computed for $this."));
-    _functionSignatureCache = value;
-    typeCache = _functionSignatureCache.type;
-  }
-
-  bool get hasNode => true;
-
-  VariableDefinitions get node => definitions;
-
-  ResolutionFunctionType get functionType => type;
-
-  accept(ElementVisitor visitor, arg) {
-    return visitor.visitFormalElement(this, arg);
-  }
-
-  // A parameter is defined by the declaration element.
-  AstElement get definingElement => declaration;
-}
-
-/// [Element] for a formal parameter.
-///
-/// A [ParameterElementX] can be patched. A parameter of an external method is
-/// patched with the corresponding parameter of the patch method. This is done
-/// to ensure that default values on parameters are computed once (on the
-/// origin parameter) but can be found through both the origin and the patch.
-abstract class ParameterElementX extends FormalElementX
-    with PatchMixin<ParameterElement>, ConstantVariableMixin
-    implements ParameterElement {
-  final Expression initializer;
-  final bool isOptional;
-  final bool isNamed;
-
-  ParameterElementX(
-      ElementKind elementKind,
-      FunctionElement functionDeclaration,
-      VariableDefinitions definitions,
-      Identifier identifier,
-      this.initializer,
-      {this.isOptional: false,
-      this.isNamed: false})
-      : super(elementKind, functionDeclaration, definitions, identifier);
-
-  FunctionElement get functionDeclaration => enclosingElement;
-
-  ExecutableElement get executableContext => enclosingElement;
-
-  MemberElement get memberContext => executableContext.memberContext;
-
-  accept(ElementVisitor visitor, arg) {
-    return visitor.visitParameterElement(this, arg);
-  }
-
-  bool get isLocal => true;
-
-  String toString() {
-    if (isPatched) {
-      return 'origin ${super.toString()}';
-    } else if (isPatch) {
-      return 'patch ${super.toString()}';
-    }
-    return super.toString();
-  }
-}
-
-class LocalParameterElementX extends ParameterElementX
-    implements LocalParameterElement {
-  LocalParameterElementX(
-      FunctionElement functionDeclaration,
-      VariableDefinitions definitions,
-      Identifier identifier,
-      Expression initializer,
-      {bool isOptional: false,
-      bool isNamed: false})
-      : super(ElementKind.PARAMETER, functionDeclaration, definitions,
-            identifier, initializer,
-            isOptional: isOptional, isNamed: isNamed);
-}
-
-/// Parameters in constructors that directly initialize fields. For example:
-/// `A(this.field)`.
-class InitializingFormalElementX extends ParameterElementX
-    implements InitializingFormalElement {
-  final FieldElement fieldElement;
-
-  InitializingFormalElementX(
-      ConstructorElement constructorDeclaration,
-      VariableDefinitions variables,
-      Identifier identifier,
-      Expression initializer,
-      this.fieldElement,
-      {bool isOptional: false,
-      bool isNamed: false})
-      : super(ElementKind.INITIALIZING_FORMAL, constructorDeclaration,
-            variables, identifier, initializer,
-            isOptional: isOptional, isNamed: isNamed);
-
-  accept(ElementVisitor visitor, arg) {
-    return visitor.visitFieldParameterElement(this, arg);
-  }
-
-  MemberElement get memberContext => enclosingElement;
-
-  @override
-  bool get isFinal => true;
-
-  @override
-  bool get isLocal => true;
-
-  ConstructorElement get functionDeclaration => super.functionDeclaration;
-}
-
-// ignore: strong_mode_invalid_method_override_from_base
-class ErroneousInitializingFormalElementX extends ParameterElementX
-    implements InitializingFormalElementX {
-  final ErroneousFieldElementX fieldElement;
-
-  ErroneousInitializingFormalElementX(
-      Identifier identifier, Element enclosingElement)
-      : this.fieldElement =
-            new ErroneousFieldElementX(identifier, enclosingElement),
-        super(ElementKind.INITIALIZING_FORMAL, enclosingElement, null,
-            identifier, null);
-
-  VariableDefinitions get definitions => fieldElement.node;
-
-  MemberElement get memberContext => enclosingElement;
-
-  bool get isLocal => false;
-
-  bool get isMalformed => true;
-
-  ResolutionDynamicType get type => const ResolutionDynamicType();
-
-  ConstructorElement get functionDeclaration => super.functionDeclaration;
-}
-
-class AbstractFieldElementX extends ElementX
-    with AbstractFieldElementCommon
-    implements AbstractFieldElement {
-  GetterElementX getter;
-  SetterElementX setter;
-
-  AbstractFieldElementX(String name, Element enclosing)
-      : super(name, ElementKind.ABSTRACT_FIELD, enclosing);
-
-  ResolutionDartType computeType(Compiler compiler) {
-    throw "internal error: AbstractFieldElement has no type";
-  }
-
-  Node parseNode(ParsingContext parsing) {
-    throw "internal error: AbstractFieldElement has no node";
-  }
-
-  Token get position {
-    // The getter and setter may be defined in two different
-    // compilation units.  However, we know that one of them is
-    // non-null and defined in the same compilation unit as the
-    // abstract element.
-    // TODO(lrn): No we don't know that if the element from the same
-    // compilation unit is patched.
-    //
-    // We need to make sure that the position returned is relative to
-    // the compilation unit of the abstract element.
-    if (getter != null && identical(getter.compilationUnit, compilationUnit)) {
-      return getter.position;
-    } else {
-      return setter.position;
-    }
-  }
-
-  Modifiers get modifiers {
-    // The resolver ensures that the flags match (ignoring abstract).
-    if (getter != null) {
-      return new Modifiers.withFlags(getter.modifiers.nodes,
-          getter.modifiers.flags | Modifiers.FLAG_ABSTRACT);
-    } else {
-      return new Modifiers.withFlags(setter.modifiers.nodes,
-          setter.modifiers.flags | Modifiers.FLAG_ABSTRACT);
-    }
-  }
-
-  accept(ElementVisitor visitor, arg) {
-    return visitor.visitAbstractFieldElement(this, arg);
-  }
-}
-
-// TODO(johnniwinther): [FunctionSignature] should be merged with
-// [FunctionType].
-class FunctionSignatureX extends FunctionSignatureCommon
-    implements FunctionSignature {
-  final List<ResolutionDartType> typeVariables;
-  final List<FormalElement> requiredParameters;
-  final List<FormalElement> optionalParameters;
-  final int requiredParameterCount;
-  final int optionalParameterCount;
-  final bool optionalParametersAreNamed;
-  final List<FormalElement> orderedOptionalParameters;
-  final ResolutionFunctionType type;
-  final bool hasOptionalParameters;
-
-  FunctionSignatureX(
-      {this.typeVariables: const <ResolutionDartType>[],
-      this.requiredParameters: const <FormalElement>[],
-      this.requiredParameterCount: 0,
-      List<Element> optionalParameters: const <FormalElement>[],
-      this.optionalParameterCount: 0,
-      this.optionalParametersAreNamed: false,
-      this.orderedOptionalParameters: const <FormalElement>[],
-      this.type})
-      : optionalParameters = optionalParameters,
-        hasOptionalParameters = !optionalParameters.isEmpty;
-}
-
-abstract class BaseFunctionElementX extends ElementX
-    with PatchMixin<FunctionElement>, AstElementMixin
-    implements FunctionElement {
-  ResolutionDartType typeCache;
-  final Modifiers modifiers;
-  bool isMarkedNative = false;
-
-  List<MethodElement> nestedClosures = new List<MethodElement>();
-
-  FunctionSignature _functionSignatureCache;
-
-  AsyncMarker _asyncMarker = AsyncMarker.SYNC;
-
-  BaseFunctionElementX(String name, ElementKind kind, Modifiers this.modifiers,
-      Element enclosing)
-      : super(name, kind, enclosing) {
-    assert(modifiers != null);
-  }
-
-  AsyncMarker get asyncMarker {
-    if (isPatched) {
-      return patch.asyncMarker;
-    }
-    return _asyncMarker;
-  }
-
-  void set asyncMarker(AsyncMarker value) {
-    if (isPatched) {
-      BaseFunctionElementX function = patch;
-      function.asyncMarker = value;
-    } else {
-      _asyncMarker = value;
-    }
-  }
-
-  bool get isMarkedExternal => modifiers.isExternal;
-
-  bool get isExternal => (isMarkedExternal && !isPatched) || isMarkedNative;
-
-  bool get isInstanceMember {
-    return isClassMember && !isConstructor && !isStatic;
-  }
-
-  ParameterStructure get parameterStructure =>
-      functionSignature.parameterStructure;
-
-  bool get hasFunctionSignature => _functionSignatureCache != null;
-
-  void _computeSignature(Resolution resolution) {
-    if (hasFunctionSignature) return;
-    functionSignature = resolution.resolveSignature(this);
-  }
-
-  FunctionSignature get functionSignature {
-    assert(hasFunctionSignature,
-        failedAt(this, "Function signature has not been computed for $this."));
-    return _functionSignatureCache;
-  }
-
-  void set functionSignature(FunctionSignature value) {
-    // TODO(johnniwinther): Strengthen the invariant to `!hasFunctionSignature`
-    // when checked mode checks are not enqueued eagerly.
-    assert(
-        !hasFunctionSignature || type == value.type,
-        failedAt(
-            this, "Function signature has already been computed for $this."));
-    _functionSignatureCache = value;
-    typeCache = _functionSignatureCache.type;
-  }
-
-  List<ParameterElement> get parameters {
-    // TODO(johnniwinther): Store the list directly, possibly by using List
-    // instead of Link in FunctionSignature.
-    List<ParameterElement> list = <ParameterElement>[];
-    functionSignature.forEachParameter((e) => list.add(e));
-    return list;
-  }
-
-  ResolutionFunctionType computeType(Resolution resolution) {
-    if (typeCache != null) return typeCache;
-    _computeSignature(resolution);
-    assert(typeCache != null,
-        failedAt(this, "Type cache expected to be set on $this."));
-    return typeCache;
-  }
-
-  ResolutionFunctionType get type {
-    assert(typeCache != null,
-        failedAt(this, "Type has not been computed for $this."));
-    return typeCache;
-  }
-
-  FunctionElement asFunctionElement() => this;
-
-  @override
-  Scope buildScope() => new TypeDeclarationScope(super.buildScope(), this);
-
-  String toString() {
-    if (isPatch) {
-      return 'patch ${super.toString()}';
-    } else if (isPatched) {
-      return 'origin ${super.toString()}';
-    } else {
-      return super.toString();
-    }
-  }
-
-  bool get isAbstract => false;
-
-  // A function is defined by the implementation element.
-  AstElement get definingElement => implementation;
-
-  @override
-  List<ResolutionDartType> get typeVariables => functionSignature.typeVariables;
-
-  // TODO(johnniwinther): Remove this.
-  FunctionElement get declaration => super.declaration;
-
-  // TODO(johnniwinther): Remove this.
-  FunctionElement get implementation => super.implementation;
-
-  // TODO(johnniwinther): Remove this.
-  FunctionElement get origin => super.origin;
-
-  // TODO(johnniwinther): Remove this.
-  FunctionElement get patch => super.patch;
-}
-
-abstract class FunctionElementX extends BaseFunctionElementX
-    with AnalyzableElementX
-    implements MethodElement {
-  FunctionElementX(
-      String name, ElementKind kind, Modifiers modifiers, Element enclosing)
-      : super(name, kind, modifiers, enclosing);
-
-  MemberElement get memberContext => this;
-
-  @override
-  SourceSpan get sourcePosition {
-    SourceSpan span = super.sourcePosition;
-    if (span != null && hasNode) {
-      FunctionExpression functionExpression = node.asFunctionExpression();
-      if (functionExpression != null) {
-        span = new SourceSpan.fromNode(span.uri, functionExpression);
-      }
-    }
-    return span;
-  }
-
-  void reuseElement() {
-    super.reuseElement();
-    nestedClosures.clear();
-    _functionSignatureCache = null;
-    typeCache = null;
-  }
-}
-
-abstract class MethodElementX extends FunctionElementX {
-  final bool hasBody;
-
-  MethodElementX(
-      String name,
-      ElementKind kind,
-      Modifiers modifiers,
-      Element enclosing,
-      // TODO(15101): Make this a named parameter.
-      this.hasBody)
-      : super(name, kind, modifiers, enclosing);
-
-  @override
-  bool get isAbstract {
-    return !modifiers.isExternal && !hasBody;
-  }
-
-  accept(ElementVisitor visitor, arg) {
-    return visitor.visitMethodElement(this, arg);
-  }
-}
-
-abstract class AccessorElementX extends MethodElementX
-    implements AccessorElement {
-  AbstractFieldElement abstractField;
-
-  AccessorElementX(String name, ElementKind kind, Modifiers modifiers,
-      Element enclosing, bool hasBody)
-      : super(name, kind, modifiers, enclosing, hasBody);
-}
-
-abstract class GetterElementX extends AccessorElementX
-    implements GetterElement {
-  GetterElementX(
-      String name, Modifiers modifiers, Element enclosing, bool hasBody)
-      : super(name, ElementKind.GETTER, modifiers, enclosing, hasBody);
-
-  accept(ElementVisitor visitor, arg) {
-    return visitor.visitGetterElement(this, arg);
-  }
-}
-
-abstract class SetterElementX extends AccessorElementX
-    implements SetterElement {
-  SetterElementX(
-      String name, Modifiers modifiers, Element enclosing, bool hasBody)
-      : super(name, ElementKind.SETTER, modifiers, enclosing, hasBody);
-
-  accept(ElementVisitor visitor, arg) {
-    return visitor.visitSetterElement(this, arg);
-  }
-}
-
-class LocalFunctionElementX extends BaseFunctionElementX
-    implements LocalFunctionElement {
-  final FunctionExpression node;
-
-  MethodElement callMethod;
-
-  LocalFunctionElementX(String name, FunctionExpression this.node,
-      ElementKind kind, Modifiers modifiers, ExecutableElement enclosing)
-      : super(name, kind, modifiers, enclosing);
-
-  ExecutableElement get executableContext => enclosingElement;
-
-  MemberElement get memberContext => executableContext.memberContext;
-
-  bool get hasNode => true;
-
-  FunctionExpression parseNode(ParsingContext parsing) => node;
-
-  Token get position {
-    // Use the name as position if this is not an unnamed closure.
-    if (node.name != null) {
-      return node.name.getBeginToken();
-    } else {
-      return node.getBeginToken();
-    }
-  }
-
-  bool get isLocal => true;
-
-  accept(ElementVisitor visitor, arg) {
-    return visitor.visitLocalFunctionElement(this, arg);
-  }
-}
-
-abstract class ConstantConstructorMixin implements ConstructorElement {
-  ConstantConstructor _constantConstructor;
-
-  ConstantConstructor get constantConstructor {
-    if (isPatch) {
-      ConstructorElement originConstructor = origin;
-      return originConstructor.constantConstructor;
-    }
-    if (!isConst || isFromEnvironmentConstructor) return null;
-    if (_constantConstructor == null) {
-      _constantConstructor = computeConstantConstructor(resolvedAst);
-    }
-    return _constantConstructor;
-  }
-
-  void set constantConstructor(ConstantConstructor value) {
-    if (isPatch) {
-      ConstantConstructorMixin originConstructor = origin;
-      originConstructor.constantConstructor = value;
-    } else {
-      assert(
-          isConst,
-          failedAt(
-              this,
-              "Constant constructor set on non-constant "
-              "constructor $this."));
-      assert(
-          !isFromEnvironmentConstructor,
-          failedAt(
-              this,
-              "Constant constructor set on fromEnvironment "
-              "constructor: $this."));
-      assert(
-          _constantConstructor == null || _constantConstructor == value,
-          failedAt(
-              this,
-              "Constant constructor already computed for $this:"
-              "Existing: $_constantConstructor, new: $value"));
-      _constantConstructor = value;
-    }
-  }
-
-  /// Returns the empty list of type variables by default.
-  @override
-  List<ResolutionDartType> get typeVariables => functionSignature.typeVariables;
-}
-
-abstract class ConstructorElementX extends FunctionElementX
-    with ConstantConstructorMixin, ConstructorElementCommon
-    implements ConstructorElement {
-  bool isRedirectingGenerativeInternal = false;
-
-  ConstructorElementX(
-      String name, ElementKind kind, Modifiers modifiers, Element enclosing)
-      : super(name, kind, modifiers, enclosing);
-
-  ConstructorElement _immediateRedirectionTarget;
-  PrefixElement _redirectionDeferredPrefix;
-
-  bool get isRedirectingGenerative {
-    if (isPatched) return patch.isRedirectingGenerative;
-    return isRedirectingGenerativeInternal;
-  }
-
-  bool get isRedirectingFactory => immediateRedirectionTarget != null;
-
-  // TODO(johnniwinther): This should also return true for cyclic redirecting
-  // generative constructors.
-  bool get isCyclicRedirection => effectiveTarget.isRedirectingFactory;
-
-  bool get isDefaultConstructor => false;
-
-  /// These fields are set by the post process queue when checking for cycles.
-  ConstructorElement effectiveTargetInternal;
-  ResolutionDartType _effectiveTargetType;
-  bool _isEffectiveTargetMalformed;
-
-  bool get hasEffectiveTarget {
-    if (isPatched) {
-      return patch.hasEffectiveTarget;
-    }
-    return effectiveTargetInternal != null;
-  }
-
-  void setImmediateRedirectionTarget(
-      ConstructorElement target, PrefixElement prefix) {
-    if (isPatched) {
-      patch.setImmediateRedirectionTarget(target, prefix);
-    } else {
-      assert(
-          _immediateRedirectionTarget == null,
-          failedAt(this,
-              "Immediate redirection target has already been set on $this."));
-      _immediateRedirectionTarget = target;
-      _redirectionDeferredPrefix = prefix;
-    }
-  }
-
-  ConstructorElement get immediateRedirectionTarget {
-    if (isPatched) {
-      return patch.immediateRedirectionTarget;
-    }
-    return _immediateRedirectionTarget;
-  }
-
-  PrefixElement get redirectionDeferredPrefix {
-    if (isPatched) {
-      return patch.redirectionDeferredPrefix;
-    }
-    return _redirectionDeferredPrefix;
-  }
-
-  void setEffectiveTarget(ConstructorElement target, ResolutionDartType type,
-      {bool isMalformed: false}) {
-    if (isPatched) {
-      patch.setEffectiveTarget(target, type, isMalformed: isMalformed);
-    } else {
-      assert(target != null,
-          failedAt(this, 'No effective target provided for $this.'));
-      assert(
-          effectiveTargetInternal == null,
-          failedAt(
-              this, 'Effective target has already been computed for $this.'));
-      assert(
-          !target.isMalformed || isMalformed,
-          failedAt(
-              this,
-              'Effective target is not marked as malformed for $this: '
-              'target=$target, type=$type, isMalformed: $isMalformed'));
-      assert(
-          isMalformed || type.isInterfaceType,
-          failedAt(
-              this,
-              'Effective target type is not an interface type for $this: '
-              'target=$target, type=$type, isMalformed: $isMalformed'));
-      effectiveTargetInternal = target;
-      _effectiveTargetType = type;
-      _isEffectiveTargetMalformed = isMalformed;
-    }
-  }
-
-  ConstructorElement get effectiveTarget {
-    if (isPatched) {
-      return patch.effectiveTarget;
-    }
-    if (isRedirectingFactory) {
-      assert(effectiveTargetInternal != null);
-      return effectiveTargetInternal;
-    }
-    return this;
-  }
-
-  ResolutionDartType get effectiveTargetType {
-    if (isPatched) {
-      return patch.effectiveTargetType;
-    }
-    assert(
-        _effectiveTargetType != null,
-        failedAt(this,
-            'Effective target type has not yet been computed for $this.'));
-    return _effectiveTargetType;
-  }
-
-  ResolutionDartType computeEffectiveTargetType(
-      ResolutionInterfaceType newType) {
-    if (isPatched) {
-      return patch.computeEffectiveTargetType(newType);
-    }
-    if (!isRedirectingFactory) return newType;
-    return effectiveTargetType.substByContext(newType);
-  }
-
-  bool get isEffectiveTargetMalformed {
-    if (isPatched) {
-      return patch.isEffectiveTargetMalformed;
-    }
-    if (!isRedirectingFactory) return false;
-    assert(_isEffectiveTargetMalformed != null,
-        failedAt(this, 'Malformedness has not yet been computed for $this.'));
-    return _isEffectiveTargetMalformed == true;
-  }
-
-  accept(ElementVisitor visitor, arg) {
-    return visitor.visitConstructorElement(this, arg);
-  }
-
-  ConstructorElement get definingConstructor => null;
-
-  ClassElement get enclosingClass => enclosingElement.declaration;
-
-  // TODO(johnniwinther): Remove this.
-  ConstructorElementX get declaration => super.declaration;
-
-  // TODO(johnniwinther): Remove this.
-  ConstructorElementX get implementation => super.implementation;
-
-  // TODO(johnniwinther): Remove this.
-  ConstructorElementX get origin => super.origin;
-
-  // TODO(johnniwinther): Remove this.
-  ConstructorElementX get patch => super.patch;
-}
-
-class DeferredLoaderGetterElementX extends GetterElementX {
-  final PrefixElement prefix;
-
-  DeferredLoaderGetterElementX(PrefixElement prefix)
-      : this.prefix = prefix,
-        super(Identifiers.loadLibrary, Modifiers.EMPTY, prefix, false) {
-    functionSignature =
-        new FunctionSignatureX(type: new ResolutionFunctionType(this));
-  }
-
-  bool get isClassMember => false;
-
-  bool get isSynthesized => true;
-
-  bool get isDeferredLoaderGetter => true;
-
-  bool get isTopLevel => true;
-
-  // By having position null, the enclosing elements location is printed in
-  // error messages.
-  Token get position => null;
-
-  FunctionExpression parseNode(ParsingContext parsing) => null;
-
-  bool get hasNode => false;
-
-  FunctionExpression get node => null;
-
-  bool get hasResolvedAst => true;
-
-  ResolvedAst get resolvedAst {
-    return new SynthesizedResolvedAst(
-        this, ResolvedAstKind.DEFERRED_LOAD_LIBRARY);
-  }
-
-  @override
-  SetterElement get setter => null;
-}
-
-class ConstructorBodyElementX extends BaseFunctionElementX
-    implements ConstructorBodyElement {
-  final ResolvedAst _resolvedAst;
-  final ConstructorElement constructor;
-
-  ConstructorBodyElementX(
-      ResolvedAst resolvedAst, ConstructorElement constructor)
-      : this._resolvedAst = resolvedAst,
-        this.constructor = constructor,
-        super(constructor.name, ElementKind.GENERATIVE_CONSTRUCTOR_BODY,
-            Modifiers.EMPTY, constructor.enclosingElement) {
-    functionSignature = constructor.functionSignature;
-  }
-
-  /// Returns the constructor body associated with the given constructor or
-  /// creates a new constructor body, if none can be found.
-  ///
-  /// Returns `null` if the constructor does not have a body.
-  static ConstructorBodyElementX createFromResolvedAst(
-      ResolvedAst constructorResolvedAst) {
-    ConstructorElement constructor =
-        constructorResolvedAst.element.implementation;
-    assert(constructor.isGenerativeConstructor);
-    if (constructorResolvedAst.kind != ResolvedAstKind.PARSED) return null;
-
-    FunctionExpression node = constructorResolvedAst.node;
-    // If we know the body doesn't have any code, we don't generate it.
-    if (!node.hasBody) return null;
-    if (node.hasEmptyBody) return null;
-    ClassElement classElement = constructor.enclosingClass;
-    ConstructorBodyElement bodyElement;
-    classElement.forEachConstructorBody((ConstructorBodyElement body) {
-      if (body.constructor == constructor) {
-        // TODO(kasperl): Find a way of stopping the iteration
-        // through the backend members.
-        bodyElement = body;
-      }
-    });
-    if (bodyElement == null) {
-      bodyElement =
-          new ConstructorBodyElementX(constructorResolvedAst, constructor);
-      classElement.addConstructorBody(bodyElement);
-
-      if (constructor.isPatch) {
-        // Create origin body element for patched constructors.
-        ConstructorBodyElementX patch = bodyElement;
-        ConstructorBodyElementX origin = new ConstructorBodyElementX(
-            constructorResolvedAst, constructor.origin);
-        origin.applyPatch(patch);
-        classElement.origin.addConstructorBody(bodyElement.origin);
-      }
-    }
-    assert(bodyElement.isGenerativeConstructorBody);
-    return bodyElement;
-  }
-
-  bool get hasNode => _resolvedAst.kind == ResolvedAstKind.PARSED;
-
-  FunctionExpression get node => _resolvedAst.node;
-
-  bool get hasResolvedAst => true;
-
-  ResolvedAst get resolvedAst {
-    if (_resolvedAst.kind == ResolvedAstKind.PARSED) {
-      return new ParsedResolvedAst(declaration, _resolvedAst.node,
-          _resolvedAst.body, _resolvedAst.elements, _resolvedAst.sourceUri);
-    } else {
-      return new SynthesizedResolvedAst(declaration, _resolvedAst.kind);
-    }
-  }
-
-  List<MetadataAnnotation> get metadata => constructor.metadata;
-
-  bool get isInstanceMember => true;
-
-  ResolutionFunctionType computeType(Resolution resolution) {
-    DiagnosticReporter reporter = resolution.reporter;
-    reporter.internalError(this, '$this.computeType.');
-    return null;
-  }
-
-  int get sourceOffset => constructor.sourceOffset;
-
-  Token get position => constructor.position;
-
-  Element get outermostEnclosingMemberOrTopLevel => constructor;
-
-  AnalyzableElement get analyzableElement => constructor.analyzableElement;
-
-  accept(ElementVisitor visitor, arg) {
-    return visitor.visitConstructorBodyElement(this, arg);
-  }
-
-  MemberElement get memberContext => constructor;
-}
-
-/**
- * A constructor that is not defined in the source code but rather implied by
- * the language semantics.
- *
- * This class is used to represent default constructors and forwarding
- * constructors for mixin applications.
- */
-class SynthesizedConstructorElementX extends ConstructorElementX {
-  final ConstructorElement definingConstructor;
-  ResolvedAst _resolvedAst;
-
-  SynthesizedConstructorElementX.notForDefault(
-      String name, this.definingConstructor, Element enclosing)
-      : super(name, ElementKind.GENERATIVE_CONSTRUCTOR, Modifiers.EMPTY,
-            enclosing) {
-    _resolvedAst = new SynthesizedResolvedAst(
-        this, ResolvedAstKind.FORWARDING_CONSTRUCTOR);
-  }
-
-  SynthesizedConstructorElementX.forDefault(
-      this.definingConstructor, Element enclosing)
-      : super('', ElementKind.GENERATIVE_CONSTRUCTOR, Modifiers.EMPTY,
-            enclosing) {
-    functionSignature = new FunctionSignatureX(
-        type: new ResolutionFunctionType.synthesized(
-            const ResolutionDynamicType()));
-    _resolvedAst =
-        new SynthesizedResolvedAst(this, ResolvedAstKind.DEFAULT_CONSTRUCTOR);
-  }
-
-  bool get isDefaultConstructor {
-    return _resolvedAst.kind == ResolvedAstKind.DEFAULT_CONSTRUCTOR;
-  }
-
-  FunctionExpression parseNode(ParsingContext parsing) => null;
-
-  bool get hasNode => false;
-
-  FunctionExpression get node => null;
-
-  Token get position => enclosingElement.position;
-
-  bool get isSynthesized => true;
-
-  bool get hasResolvedAst => true;
-
-  ResolvedAst get resolvedAst => _resolvedAst;
-
-  ResolutionFunctionType get type {
-    if (isDefaultConstructor) {
-      return super.type;
-    } else {
-      // TODO(johnniwinther): Ensure that the function type substitutes type
-      // variables correctly.
-      return definingConstructor.type;
-    }
-  }
-
-  void _computeSignature(Resolution resolution) {
-    if (hasFunctionSignature) return;
-    if (definingConstructor.isMalformed) {
-      functionSignature = new FunctionSignatureX(
-          type:
-              new ResolutionFunctionType.synthesized(enclosingClass.thisType));
-    }
-    // TODO(johnniwinther): Ensure that the function signature (and with it the
-    // function type) substitutes type variables correctly.
-    definingConstructor.computeType(resolution);
-    functionSignature = definingConstructor.functionSignature;
-  }
-
-  accept(ElementVisitor visitor, arg) {
-    return visitor.visitConstructorElement(this, arg);
-  }
-}
-
-abstract class TypeDeclarationElementX implements TypeDeclarationElement {
-  /**
-   * The `this type` for this type declaration.
-   *
-   * The type of [:this:] is the generic type based on this element in which
-   * the type arguments are the declared type variables. For instance,
-   * [:List<E>:] for [:List:] and [:Map<K,V>:] for [:Map:].
-   *
-   * For a class declaration this is the type of [:this:].
-   *
-   * This type is computed in [computeType].
-   */
-  GenericType thisTypeCache;
-
-  /**
-   * The raw type for this type declaration.
-   *
-   * The raw type is the generic type base on this element in which the type
-   * arguments are all [dynamic]. For instance [:List<dynamic>:] for [:List:]
-   * and [:Map<dynamic,dynamic>:] for [:Map:]. For non-generic classes [rawType]
-   * is the same as [thisType].
-   *
-   * The [rawType] field is a canonicalization of the raw type and should be
-   * used to distinguish explicit and implicit uses of the [dynamic]
-   * type arguments. For instance should [:List:] be the [rawType] of the
-   * [:List:] class element whereas [:List<dynamic>:] should be its own
-   * instantiation of [ResolutionInterfaceType] with [:dynamic:] as type
-   * argument. Using this distinction, we can print the raw type with type
-   * arguments only when the input source has used explicit type arguments.
-   *
-   * This type is computed together with [thisType] in [computeType].
-   */
-  GenericType rawTypeCache;
-
-  GenericType get thisType {
-    assert(thisTypeCache != null,
-        failedAt(this, 'This type has not been computed for $this'));
-    return thisTypeCache;
-  }
-
-  GenericType get rawType {
-    assert(rawTypeCache != null,
-        failedAt(this, 'Raw type has not been computed for $this'));
-    return rawTypeCache;
-  }
-
-  GenericType createType(List<ResolutionDartType> typeArguments);
-
-  void setThisAndRawTypes(List<ResolutionDartType> typeParameters) {
-    assert(thisTypeCache == null,
-        failedAt(this, "This type has already been set on $this."));
-    assert(rawTypeCache == null,
-        failedAt(this, "Raw type has already been set on $this."));
-    thisTypeCache = createType(typeParameters);
-    if (typeParameters.isEmpty) {
-      rawTypeCache = thisTypeCache;
-    } else {
-      List<ResolutionDartType> dynamicParameters =
-          new List.filled(typeParameters.length, const ResolutionDynamicType());
-      rawTypeCache = createType(dynamicParameters);
-    }
-  }
-
-  List<ResolutionDartType> get typeVariables => thisType.typeArguments;
-
-  /**
-   * Creates the type variables, their type and corresponding element, for the
-   * type variables declared in [parameter] on [element]. The bounds of the type
-   * variables are not set until [element] has been resolved.
-   */
-  List<ResolutionDartType> createTypeVariables(NodeList parameters) {
-    if (parameters == null) return const <ResolutionDartType>[];
-
-    // Create types and elements for type variable.
-    Link<Node> nodes = parameters.nodes;
-    List<ResolutionDartType> arguments =
-        new List.generate(nodes.slowLength(), (int index) {
-      TypeVariable node = nodes.head;
-      String variableName = node.name.source;
-      nodes = nodes.tail;
-      TypeVariableElementX variableElement =
-          new TypeVariableElementX(variableName, this, index, node);
-      ResolutionTypeVariableType variableType =
-          new ResolutionTypeVariableType(variableElement);
-      variableElement.typeCache = variableType;
-      return variableType;
-    }, growable: false);
-    return arguments;
-  }
-
-  bool get isResolved => resolutionState == STATE_DONE;
-
-  int get resolutionState;
-}
-
-abstract class BaseClassElementX extends ElementX
-    with
-        AstElementMixin,
-        AnalyzableElementX,
-        ClassElementCommon,
-        TypeDeclarationElementX,
-        PatchMixin<ClassElement>,
-        ClassMemberMixin
-    implements ClassElement {
-  final int id;
-
-  ResolutionInterfaceType supertype;
-  Link<ResolutionDartType> interfaces;
-  int supertypeLoadState;
-  int resolutionState;
-  bool isProxy = false;
-  bool hasIncompleteHierarchy = false;
-
-  OrderedTypeSet allSupertypesAndSelf;
-
-  BaseClassElementX(String name, Element enclosing, this.id, int initialState)
-      : supertypeLoadState = initialState,
-        resolutionState = initialState,
-        super(name, ElementKind.CLASS, enclosing);
-
-  int get hashCode => id;
-
-  bool get isUnnamedMixinApplication => false;
-
-  @override
-  bool get isEnumClass => false;
-
-  ResolutionInterfaceType computeType(Resolution resolution) {
-    if (isPatch) {
-      origin.computeType(resolution);
-      thisTypeCache = origin.thisType;
-      rawTypeCache = origin.rawType;
-    } else if (thisTypeCache == null) {
-      computeThisAndRawType(
-          resolution, computeTypeParameters(resolution.parsingContext));
-    }
-    return thisTypeCache;
-  }
-
-  void computeThisAndRawType(
-      Resolution resolution, List<ResolutionDartType> typeVariables) {
-    if (thisTypeCache == null) {
-      if (origin == null) {
-        setThisAndRawTypes(typeVariables);
-      } else {
-        thisTypeCache = origin.computeType(resolution);
-        rawTypeCache = origin.rawType;
-      }
-    }
-  }
-
-  @override
-  ResolutionInterfaceType createType(List<ResolutionDartType> typeArguments) {
-    return new ResolutionInterfaceType(this, typeArguments);
-  }
-
-  List<ResolutionDartType> computeTypeParameters(ParsingContext parsing);
-
-  bool get isObject {
-    assert(isResolved,
-        failedAt(this, "isObject has not been computed for $this."));
-    return supertype == null;
-  }
-
-  void ensureResolved(Resolution resolution) {
-    if (resolutionState == STATE_NOT_STARTED) {
-      resolution.resolveClass(this);
-      resolution.registerClass(this);
-    }
-  }
-
-  void setDefaultConstructor(
-      FunctionElement constructor, DiagnosticReporter reporter);
-
-  ConstructorElement lookupDefaultConstructor() {
-    ConstructorElement constructor = lookupConstructor("");
-    // This method might be called on constructors that have not been
-    // resolved. As we query the live world, we return `null` in such cases
-    // as no default constructor exists in the live world.
-    if (constructor != null &&
-        constructor.hasFunctionSignature &&
-        constructor.functionSignature.requiredParameterCount == 0) {
-      return constructor;
-    }
-    return null;
-  }
-
-  /**
-   * Returns the super class, if any.
-   *
-   * The returned element may not be resolved yet.
-   */
-  ClassElement get superclass {
-    assert(supertypeLoadState == STATE_DONE,
-        failedAt(this, "Superclass has not been computed for $this."));
-    return supertype == null ? null : supertype.element;
-  }
-
-  // A class declaration is defined by the declaration element.
-  AstElement get definingElement => declaration;
-
-  ResolutionInterfaceType get thisType => super.thisType;
-
-  ResolutionInterfaceType get rawType => super.rawType;
-
-  // TODO(johnniwinther): Remove this.
-  ClassElement get declaration => super.declaration;
-
-  // TODO(johnniwinther): Remove this.
-  ClassElement get implementation => super.implementation;
-
-  // TODO(johnniwinther): Remove this.
-  ClassElement get origin => super.origin;
-
-  // TODO(johnniwinther): Remove this.
-  ClassElement get patch => super.patch;
-}
-
-abstract class ClassElementX extends BaseClassElementX {
-  Link<Element> localMembersReversed = const Link<Element>();
-  final ScopeX localScope = new ScopeX();
-
-  Link<Element> localMembersCache;
-
-  Link<Element> get localMembers {
-    if (localMembersCache == null) {
-      localMembersCache = localMembersReversed.reverse();
-    }
-    return localMembersCache;
-  }
-
-  ClassElementX(String name, Element enclosing, int id, int initialState)
-      : super(name, enclosing, id, initialState);
-
-  bool get isMixinApplication => false;
-  bool get hasLocalScopeMembers => !localScope.isEmpty;
-
-  void addMember(Element element, DiagnosticReporter reporter) {
-    localMembersCache = null;
-    localMembersReversed = localMembersReversed.prepend(element);
-    addToScope(element, reporter);
-  }
-
-  void addToScope(Element element, DiagnosticReporter reporter) {
-    if (element.isField && element.name == name) {
-      reporter.reportErrorMessage(element, MessageKind.MEMBER_USES_CLASS_NAME);
-    }
-    localScope.add(element, reporter);
-  }
-
-  Element localLookup(String elementName) {
-    Element result = localScope.lookup(elementName);
-    if (result == null && isPatch) {
-      result = origin.localLookup(elementName);
-    }
-    return result;
-  }
-
-  void forEachLocalMember(void f(Element member)) {
-    localMembers.forEach(f);
-  }
-
-  bool get hasConstructor {
-    // Search in scope to be sure we search patched constructors.
-    for (var element in localScope.values) {
-      if (element.isConstructor) return true;
-    }
-    return false;
-  }
-
-  void setDefaultConstructor(
-      FunctionElement constructor, DiagnosticReporter reporter) {
-    // The default constructor, although synthetic, is part of a class' API.
-    addMember(constructor, reporter);
-  }
-
-  List<ResolutionDartType> computeTypeParameters(ParsingContext parsing) {
-    ClassNode node = parseNode(parsing);
-    return createTypeVariables(node.typeParameters);
-  }
-
-  Scope buildScope() => new ClassScope(enclosingElement.buildScope(), this);
-
-  String toString() {
-    if (origin != null) {
-      return 'patch ${super.toString()}';
-    } else if (patch != null) {
-      return 'origin ${super.toString()}';
-    } else {
-      return super.toString();
-    }
-  }
-}
-
-/// This element is used to encode an enum class.
-///
-/// For instance
-///
-///     enum A { b, c, }
-///
-/// is modelled as
-///
-///     class A {
-///       final int index;
-///
-///       const A(this.index);
-///
-///       String toString() {
-///         return const <int, A>{0: 'A.b', 1: 'A.c'}[index];
-///       }
-///
-///       static const A b = const A(0);
-///       static const A c = const A(1);
-///
-///       static const List<A> values = const <A>[b, c];
-///     }
-///
-///  where the `A` class is encoded using this element.
-///
-class EnumClassElementX extends ClassElementX
-    implements EnumClassElement, DeclarationSite {
-  final Enum node;
-  List<EnumConstantElement> _enumValues;
-
-  EnumClassElementX(String name, Element enclosing, int id, this.node)
-      : super(name, enclosing, id, STATE_NOT_STARTED);
-
-  @override
-  bool get hasNode => true;
-
-  @override
-  Token get position => node.name.token;
-
-  @override
-  bool get isEnumClass => true;
-
-  @override
-  Node parseNode(ParsingContext parsing) => node;
-
-  @override
-  accept(ElementVisitor visitor, arg) {
-    return visitor.visitEnumClassElement(this, arg);
-  }
-
-  List<ResolutionDartType> computeTypeParameters(ParsingContext parsing) =>
-      const <ResolutionDartType>[];
-
-  List<EnumConstantElement> get enumValues {
-    assert(_enumValues != null,
-        failedAt(this, "enumValues has not been computed for $this."));
-    return _enumValues;
-  }
-
-  void set enumValues(List<EnumConstantElement> values) {
-    assert(_enumValues == null,
-        failedAt(this, "enumValues has already been computed for $this."));
-    _enumValues = values;
-  }
-
-  @override
-  DeclarationSite get declarationSite => this;
-}
-
-/// This element is used to encode the implicit constructor in an enum class.
-///
-/// For instance
-///
-///     enum A { b, c, }
-///
-/// is modelled as
-///
-///     class A {
-///       final int index;
-///
-///       const A(this.index);
-///
-///       String toString() {
-///         return const <int, A>{0: 'A.b', 1: 'A.c'}[index];
-///       }
-///
-///       static const A b = const A(0);
-///       static const A c = const A(1);
-///
-///       static const List<A> values = const <A>[b, c];
-///     }
-///
-///  where the `const A(...)` constructor is encoded using this element.
-///
-class EnumConstructorElementX extends ConstructorElementX {
-  final FunctionExpression node;
-
-  EnumConstructorElementX(
-      EnumClassElementX enumClass, Modifiers modifiers, this.node)
-      : super(
-            '', // Name.
-            ElementKind.GENERATIVE_CONSTRUCTOR,
-            modifiers,
-            enumClass);
-
-  @override
-  bool get hasNode => true;
-
-  @override
-  FunctionExpression parseNode(ParsingContext parsing) => node;
-
-  @override
-  SourceSpan get sourcePosition => enclosingClass.sourcePosition;
-}
-
-/// This element is used to encode the implicit methods in an enum class.
-///
-/// For instance
-///
-///     enum A { b, c, }
-///
-/// is modelled as
-///
-///     class A {
-///       final int index;
-///
-///       const A(this.index);
-///
-///       String toString() {
-///         return const <int, A>{0: 'A.b', 1: 'A.c'}[index];
-///       }
-///
-///       static const A b = const A(0);
-///       static const A c = const A(1);
-///
-///       static const List<A> values = const <A>[b, c];
-///     }
-///
-///  where the `toString` method is encoded using this element.
-///
-class EnumMethodElementX extends MethodElementX {
-  final FunctionExpression node;
-
-  EnumMethodElementX(
-      String name, EnumClassElementX enumClass, Modifiers modifiers, this.node)
-      : super(name, ElementKind.FUNCTION, modifiers, enumClass, true);
-
-  @override
-  bool get hasNode => true;
-
-  @override
-  FunctionExpression parseNode(ParsingContext parsing) => node;
-
-  @override
-  SourceSpan get sourcePosition => enclosingClass.sourcePosition;
-}
-
-/// This element is used to encode the initializing formal of the implicit
-/// constructor in an enum class.
-///
-/// For instance
-///
-///     enum A { b, c, }
-///
-/// is modelled as
-///
-///     class A {
-///       final int index;
-///
-///       const A(this.index);
-///
-///       String toString() {
-///         return const <int, A>{0: 'A.b', 1: 'A.c'}[index];
-///       }
-///
-///       static const A b = const A(0);
-///       static const A c = const A(1);
-///
-///       static const List<A> values = const <A>[b, c];
-///     }
-///
-///  where the `this.index` formal is encoded using this element.
-///
-class EnumFormalElementX extends InitializingFormalElementX {
-  EnumFormalElementX(
-      ConstructorElement constructor,
-      VariableDefinitions variables,
-      Identifier identifier,
-      EnumFieldElementX fieldElement)
-      : super(constructor, variables, identifier, null, fieldElement) {
-    typeCache = fieldElement.type;
-  }
-
-  @override
-  SourceSpan get sourcePosition => enclosingClass.sourcePosition;
-}
-
-/// This element is used to encode the implicitly fields in an enum class.
-///
-/// For instance
-///
-///     enum A { b, c, }
-///
-/// is modelled as
-///
-///     class A {
-///       final int index;
-///
-///       const A(this.index);
-///
-///       String toString() {
-///         return const <int, A>{0: 'A.b', 1: 'A.c'}[index];
-///       }
-///
-///       static const A b = const A(0);
-///       static const A c = const A(1);
-///
-///       static const List<A> values = const <A>[b, c];
-///     }
-///
-///  where the `index` and `values` fields are encoded using this element.
-///
-class EnumFieldElementX extends FieldElementX {
-  EnumFieldElementX(Identifier name, EnumClassElementX enumClass,
-      VariableList variableList, Node definition,
-      [Expression initializer])
-      : super(name, enumClass, variableList) {
-    definitionsCache = new VariableDefinitions(
-        null, variableList.modifiers, new NodeList.singleton(definition));
-    initializerCache = initializer;
-    definitionCache = definition;
-  }
-
-  @override
-  SourceSpan get sourcePosition => enclosingClass.sourcePosition;
-}
-
-/// This element is used to encode the constant value in an enum class.
-///
-/// For instance
-///
-///     enum A { b, c, }
-///
-/// is modelled as
-///
-///     class A {
-///       final int index;
-///
-///       const A(this.index);
-///
-///       String toString() {
-///         return const <int, A>{0: 'A.b', 1: 'A.c'}[index];
-///       }
-///
-///       static const A b = const A(0);
-///       static const A c = const A(1);
-///
-///       static const List<A> values = const <A>[b, c];
-///     }
-///
-///  where the `b` and `c` fields are encoded using this element.
-///
-class EnumConstantElementX extends EnumFieldElementX
-    implements EnumConstantElement {
-  final int index;
-
-  EnumConstantElementX(
-      Identifier name,
-      EnumClassElementX enumClass,
-      VariableList variableList,
-      Node definition,
-      Expression initializer,
-      this.index)
-      : super(name, enumClass, variableList, definition, initializer);
-
-  @override
-  SourceSpan get sourcePosition {
-    return new SourceSpan(enclosingClass.sourcePosition.uri,
-        position.charOffset, position.charEnd);
-  }
-
-  EnumClassElement get enclosingClass => super.enclosingClass;
-}
-
-abstract class MixinApplicationElementX extends BaseClassElementX
-    with MixinApplicationElementCommon
-    implements MixinApplicationElement {
-  Link<ConstructorElement> constructors = new Link<ConstructorElement>();
-
-  ResolutionInterfaceType mixinType;
-
-  MixinApplicationElementX(String name, Element enclosing, int id)
-      : super(name, enclosing, id, STATE_NOT_STARTED);
-
-  ClassElement get mixin => mixinType != null ? mixinType.element : null;
-
-  bool get isMixinApplication => true;
-  bool get hasConstructor => !constructors.isEmpty;
-  bool get hasLocalScopeMembers => !constructors.isEmpty;
-
-  get patch => null;
-  get origin => null;
-
-  bool get hasNode => true;
-
-  Token get position => node.getBeginToken();
-
-  Node parseNode(ParsingContext parsing) => node;
-
-  void addMember(Element element, DiagnosticReporter reporter) {
-    throw new UnsupportedError("Cannot add member to $this.");
-  }
-
-  void addToScope(Element element, DiagnosticReporter reporter) {
-    reporter.internalError(this, 'Cannot add to scope of $this.');
-  }
-
-  void addConstructor(FunctionElement constructor) {
-    constructors = constructors.prepend(constructor);
-  }
-
-  void setDefaultConstructor(
-      FunctionElement constructor, DiagnosticReporter reporter) {
-    assert(!hasConstructor);
-    addConstructor(constructor);
-  }
-
-  List<ResolutionDartType> computeTypeParameters(ParsingContext parsing) {
-    NamedMixinApplication named = node.asNamedMixinApplication();
-    if (named == null) {
-      failedAt(
-          node,
-          "Type variables on unnamed mixin applications must be set on "
-          "creation.");
-    }
-    return createTypeVariables(named.typeParameters);
-  }
-
-  accept(ElementVisitor visitor, arg) {
-    return visitor.visitMixinApplicationElement(this, arg);
-  }
-}
-
-class NamedMixinApplicationElementX extends MixinApplicationElementX
-    implements DeclarationSite {
-  final NamedMixinApplication node;
-
-  NamedMixinApplicationElementX(
-      String name, CompilationUnitElement enclosing, int id, this.node)
-      : super(name, enclosing, id);
-
-  Modifiers get modifiers => node.modifiers;
-
-  DeclarationSite get declarationSite => this;
-
-  ClassElement get subclass => null;
-}
-
-class UnnamedMixinApplicationElementX extends MixinApplicationElementX {
-  final Node node;
-  final ClassElement subclass;
-
-  UnnamedMixinApplicationElementX(
-      String name, ClassElement subclass, int id, this.node)
-      : this.subclass = subclass,
-        super(name, subclass.compilationUnit, id);
-
-  bool get isUnnamedMixinApplication => true;
-
-  bool get isAbstract => true;
-}
-
-class LabelDefinitionX extends LabelDefinition<Node> {
-  final Label label;
-  final String labelName;
-  final JumpTargetX target;
-  bool isBreakTarget = false;
-  bool isContinueTarget = false;
-
-  LabelDefinitionX(Label label, String labelName, this.target)
-      : this.label = label,
-        this.labelName = labelName;
-
-  // In case of a synthetic label, just use [labelName] for identifying the
-  // label.
-  String get name => label == null ? labelName : label.identifier.source;
-
-  void setBreakTarget() {
-    isBreakTarget = true;
-    target.isBreakTarget = true;
-  }
-
-  void setContinueTarget() {
-    isContinueTarget = true;
-    target.isContinueTarget = true;
-  }
-
-  String toString() => 'Label:${name}';
-}
-
-class JumpTargetX extends JumpTarget<Node> {
-  final ExecutableElement executableContext;
-  final Node statement;
-  final int nestingLevel;
-  List<LabelDefinition<Node>> labels = <LabelDefinition<Node>>[];
-  bool isBreakTarget = false;
-  bool isContinueTarget = false;
-
-  final int hashCode = ElementX.newHashCode();
-
-  JumpTargetX(this.statement, this.nestingLevel, this.executableContext);
-
-  MemberElement get memberContext => executableContext.memberContext;
-
-  LabelDefinition<Node> addLabel(Label label, String labelName,
-      {bool isBreakTarget: false, bool isContinueTarget: false}) {
-    LabelDefinitionX result = new LabelDefinitionX(label, labelName, this);
-    labels.add(result);
-    if (isBreakTarget) {
-      result.setBreakTarget();
-    }
-    if (isContinueTarget) {
-      result.setContinueTarget();
-    }
-    return result;
-  }
-
-  bool get isSwitch => statement is SwitchStatement;
-
-  bool get isSwitchCase => statement is SwitchCase;
-
-  String toString() => 'Target:$statement';
-}
-
-class TypeVariableElementX extends ElementX
-    with AstElementMixin
-    implements TypeVariableElement {
-  final int index;
-  final Node node;
-  ResolutionTypeVariableType typeCache;
-  ResolutionDartType boundCache;
-
-  TypeVariableElementX(
-      String name, GenericElement enclosing, this.index, this.node)
-      : super(name, ElementKind.TYPE_VARIABLE, enclosing);
-
-  GenericElement get typeDeclaration => enclosingElement;
-
-  ResolutionTypeVariableType computeType(Resolution resolution) => type;
-
-  ResolutionTypeVariableType get type {
-    assert(
-        typeCache != null, failedAt(this, "Type has not been set on $this."));
-    return typeCache;
-  }
-
-  ResolutionDartType get bound {
-    assert(
-        boundCache != null, failedAt(this, "Bound has not been set on $this."));
-    return boundCache;
-  }
-
-  bool get hasNode => true;
-
-  Node parseNode(ParsingContext parsing) => node;
-
-  Token get position => node.getBeginToken();
-
-  accept(ElementVisitor visitor, arg) {
-    return visitor.visitTypeVariableElement(this, arg);
-  }
-
-  // A type variable cannot be patched therefore defines itself.
-  AstElement get definingElement => this;
-}
-
-/**
- * A single metadata annotation.
- *
- * For example, consider:
- *
- *     class Data {
- *       const Data();
- *     }
- *
- *     const data = const Data();
- *
- *     @data
- *     class Foo {}
- *
- *     @data @data
- *     class Bar {}
- *
- * In this example, there are three instances of [MetadataAnnotation]
- * and they correspond each to a location in the source code where
- * there is an at-sign, '@'. The [constant] of each of these instances
- * are the same compile-time constant, [: const Data() :].
- *
- * The mirror system does not have a concept matching this class.
- */
-abstract class MetadataAnnotationX implements MetadataAnnotation {
-  /**
-   * The compile-time constant which this annotation resolves to.
-   * In the mirror system, this would be an object mirror.
-   */
-  ConstantExpression constant;
-  Element annotatedElement;
-  int resolutionState;
-
-  /**
-   * The beginning token of this annotation, or [:null:] if it is synthetic.
-   */
-  Token get beginToken;
-
-  Token get endToken;
-
-  final int hashCode = ElementX.newHashCode();
-
-  MetadataAnnotationX([this.resolutionState = STATE_NOT_STARTED]);
-
-  MetadataAnnotation ensureResolved(Resolution resolution) {
-    if (annotatedElement.isClass || annotatedElement.isTypedef) {
-      TypeDeclarationElement typeDeclaration = annotatedElement;
-      typeDeclaration.ensureResolved(resolution);
-    }
-    if (resolutionState == STATE_NOT_STARTED) {
-      resolution.resolveMetadataAnnotation(this);
-    }
-    return this;
-  }
-
-  Node parseNode(ParsingContext parsing);
-
-  SourceSpan get sourcePosition {
-    Uri uri = annotatedElement.compilationUnit.script.resourceUri;
-    return new SourceSpan.fromTokens(uri, beginToken, endToken);
-  }
-
-  String toString() => 'MetadataAnnotation($constant, $resolutionState)';
-}
-
-/// Metadata annotation on a parameter.
-class ParameterMetadataAnnotation extends MetadataAnnotationX {
-  final Metadata metadata;
-
-  ParameterMetadataAnnotation(Metadata this.metadata);
-
-  Node parseNode(ParsingContext parsing) => metadata.expression;
-
-  Token get beginToken => metadata.getBeginToken();
-
-  Token get endToken => metadata.getEndToken();
-
-  bool get hasNode => true;
-
-  Metadata get node => metadata;
-}
-
-/// Mixin for the implementation of patched elements.
-///
-/// See `patch_parser.dart` for a description of the terminology.
-abstract class PatchMixin<E extends Element> implements Element {
-  E patch = null;
-  E origin = null;
-
-  bool get isPatch => origin != null;
-  bool get isPatched => patch != null;
-
-  bool get isImplementation => !isPatched;
-  bool get isDeclaration => !isPatch;
-
-  E get implementation => isPatched ? patch : this;
-  E get declaration => isPatch ? origin : this;
-
-  /// Applies a patch to this element. This method must be called at most once.
-  void applyPatch(PatchMixin<E> patch) {
-    assert(this.patch == null, failedAt(this, "Element is patched twice."));
-    assert(this.origin == null, failedAt(this, "Origin element is a patch."));
-    assert(patch.origin == null, failedAt(patch, "Element is patched twice."));
-    assert(patch.patch == null, failedAt(patch, "Patch element is patched."));
-    this.patch = patch as E;
-    patch.origin = this as E;
-  }
-}
-
-/// Abstract implementation of the [AstElement] interface.
-abstract class AstElementMixin implements AstElement {
-  /// The element whose node defines this element.
-  ///
-  /// For patched functions the defining element is the patch element found
-  /// through [implementation] since its node define the implementation of the
-  /// function. For patched classes the defining element is the origin element
-  /// found through [declaration] since its node define the inheritance relation
-  /// for the class. For unpatched elements the defining element is the element
-  /// itself.
-  AstElement get definingElement;
-
-  bool get hasResolvedAst {
-    return definingElement.hasNode && definingElement.hasTreeElements;
-  }
-
-  ResolvedAst get resolvedAst {
-    Node node = definingElement.node;
-    Node body;
-    if (definingElement.isField) {
-      FieldElement field = definingElement;
-      body = field.initializer;
-    } else if (node != null && node.asFunctionExpression() != null) {
-      body = node.asFunctionExpression().body;
-    }
-    return new ParsedResolvedAst(
-        declaration,
-        node,
-        body,
-        definingElement.treeElements,
-        definingElement.compilationUnit.script.resourceUri);
-  }
-}
diff --git a/pkg/compiler/lib/src/elements/operators.dart b/pkg/compiler/lib/src/elements/operators.dart
index adf1813..ddc9cff3 100644
--- a/pkg/compiler/lib/src/elements/operators.dart
+++ b/pkg/compiler/lib/src/elements/operators.dart
@@ -322,197 +322,3 @@
 
   String get selectorName => '??';
 }
-
-enum AssignmentOperatorKind {
-  ASSIGN,
-  IF_NULL,
-  ADD,
-  SUB,
-  MUL,
-  DIV,
-  IDIV,
-  MOD,
-  SHL,
-  SHR,
-  AND,
-  OR,
-  XOR,
-}
-
-class AssignmentOperator {
-  final AssignmentOperatorKind kind;
-  final BinaryOperator binaryOperator;
-  final String name;
-  final bool isUserDefinable;
-
-  const AssignmentOperator._(this.kind, this.name, this.binaryOperator,
-      {this.isUserDefinable: true});
-
-  String get selectorName {
-    return binaryOperator != null ? binaryOperator.selectorName : null;
-  }
-
-  String toString() => name;
-
-  /// The = operator.
-  static const AssignmentOperator ASSIGN = const AssignmentOperator._(
-      AssignmentOperatorKind.ASSIGN, '=', null,
-      isUserDefinable: false);
-
-  /// The ??= operator.
-  static const AssignmentOperator IF_NULL = const AssignmentOperator._(
-      AssignmentOperatorKind.IF_NULL, '??=', BinaryOperator.IF_NULL,
-      isUserDefinable: false);
-
-  /// The += assignment operator.
-  static const AssignmentOperator ADD = const AssignmentOperator._(
-      AssignmentOperatorKind.ADD, '+=', BinaryOperator.ADD);
-
-  /// The -= assignment operator.
-  static const AssignmentOperator SUB = const AssignmentOperator._(
-      AssignmentOperatorKind.SUB, '-=', BinaryOperator.SUB);
-
-  /// The *= assignment operator.
-  static const AssignmentOperator MUL = const AssignmentOperator._(
-      AssignmentOperatorKind.MUL, '*=', BinaryOperator.MUL);
-
-  /// The /= assignment operator.
-  static const AssignmentOperator DIV = const AssignmentOperator._(
-      AssignmentOperatorKind.DIV, '/=', BinaryOperator.DIV);
-
-  /// The ~/= assignment operator.
-  static const AssignmentOperator IDIV = const AssignmentOperator._(
-      AssignmentOperatorKind.IDIV, '~/=', BinaryOperator.IDIV);
-
-  /// The %= assignment operator.
-  static const AssignmentOperator MOD = const AssignmentOperator._(
-      AssignmentOperatorKind.MOD, '%=', BinaryOperator.MOD);
-
-  /// The <<= assignment operator.
-  static const AssignmentOperator SHL = const AssignmentOperator._(
-      AssignmentOperatorKind.SHL, '<<=', BinaryOperator.SHL);
-
-  /// The >>= assignment operator.
-  static const AssignmentOperator SHR = const AssignmentOperator._(
-      AssignmentOperatorKind.SHR, '>>=', BinaryOperator.SHR);
-
-  /// The &= assignment operator.
-  static const AssignmentOperator AND = const AssignmentOperator._(
-      AssignmentOperatorKind.AND, '&=', BinaryOperator.AND);
-
-  /// The |= assignment operator.
-  static const AssignmentOperator OR = const AssignmentOperator._(
-      AssignmentOperatorKind.OR, '|=', BinaryOperator.OR);
-
-  /// The ^= assignment operator.
-  static const AssignmentOperator XOR = const AssignmentOperator._(
-      AssignmentOperatorKind.XOR, '^=', BinaryOperator.XOR);
-
-  static AssignmentOperator parse(String value) {
-    switch (value) {
-      case '=':
-        return ASSIGN;
-      case '??=':
-        return IF_NULL;
-      case '*=':
-        return MUL;
-      case '/=':
-        return DIV;
-      case '%=':
-        return MOD;
-      case '~/=':
-        return IDIV;
-      case '+=':
-        return ADD;
-      case '-=':
-        return SUB;
-      case '<<=':
-        return SHL;
-      case '>>=':
-        return SHR;
-      case '&=':
-        return AND;
-      case '^=':
-        return XOR;
-      case '|=':
-        return OR;
-      default:
-        return null;
-    }
-  }
-
-  // ignore: MISSING_RETURN
-  static AssignmentOperator fromKind(AssignmentOperatorKind kind) {
-    switch (kind) {
-      case AssignmentOperatorKind.ASSIGN:
-        return ASSIGN;
-      case AssignmentOperatorKind.IF_NULL:
-        return IF_NULL;
-      case AssignmentOperatorKind.ADD:
-        return ADD;
-      case AssignmentOperatorKind.SUB:
-        return SUB;
-      case AssignmentOperatorKind.MUL:
-        return MUL;
-      case AssignmentOperatorKind.DIV:
-        return DIV;
-      case AssignmentOperatorKind.IDIV:
-        return IDIV;
-      case AssignmentOperatorKind.MOD:
-        return MOD;
-      case AssignmentOperatorKind.SHL:
-        return SHL;
-      case AssignmentOperatorKind.SHR:
-        return SHR;
-      case AssignmentOperatorKind.AND:
-        return AND;
-      case AssignmentOperatorKind.OR:
-        return OR;
-      case AssignmentOperatorKind.XOR:
-        return XOR;
-    }
-  }
-}
-
-enum IncDecOperatorKind { INC, DEC }
-
-class IncDecOperator {
-  final IncDecOperatorKind kind;
-  final String name;
-  final BinaryOperator binaryOperator;
-
-  const IncDecOperator._(this.kind, this.name, this.binaryOperator);
-
-  String get selectorName => binaryOperator.selectorName;
-
-  String toString() => name;
-
-  /// The prefix/postfix ++ operator.
-  static const IncDecOperator INC =
-      const IncDecOperator._(IncDecOperatorKind.INC, '++', BinaryOperator.ADD);
-
-  /// The prefix/postfix -- operator.
-  static const IncDecOperator DEC =
-      const IncDecOperator._(IncDecOperatorKind.DEC, '--', BinaryOperator.SUB);
-
-  static IncDecOperator parse(String value) {
-    switch (value) {
-      case '++':
-        return INC;
-      case '--':
-        return DEC;
-      default:
-        return null;
-    }
-  }
-
-  // ignore: MISSING_RETURN
-  static IncDecOperator fromKind(IncDecOperatorKind kind) {
-    switch (kind) {
-      case IncDecOperatorKind.INC:
-        return INC;
-      case IncDecOperatorKind.DEC:
-        return DEC;
-    }
-  }
-}
diff --git a/pkg/compiler/lib/src/elements/resolution_types.dart b/pkg/compiler/lib/src/elements/resolution_types.dart
deleted file mode 100644
index 3c0949f..0000000
--- a/pkg/compiler/lib/src/elements/resolution_types.dart
+++ /dev/null
@@ -1,1879 +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.
-
-/// Implementation of the Dart types hierarchy in 'types.dart' specifically
-/// tailored to the resolution phase of the compiler.
-
-library resolution_types;
-
-import 'dart:math' show min;
-
-import '../common.dart';
-import '../common/resolution.dart' show Resolution;
-import '../common_elements.dart';
-import '../ordered_typeset.dart' show OrderedTypeSet;
-import '../util/util.dart' show equalElements;
-import 'elements.dart';
-import 'entities.dart';
-import 'modelx.dart' show TypeDeclarationElementX;
-import 'names.dart';
-import 'types.dart';
-
-enum ResolutionTypeKind {
-  FUNCTION,
-  INTERFACE,
-  TYPEDEF,
-  TYPE_VARIABLE,
-  MALFORMED_TYPE,
-  DYNAMIC,
-  VOID,
-}
-
-abstract class ResolutionDartType implements DartType {
-  String get name;
-
-  ResolutionTypeKind get kind;
-
-  const ResolutionDartType();
-
-  /**
-   * Returns the [Element] which declared this type.
-   *
-   * This can be [ClassElement] for classes, [TypedefElement] for typedefs,
-   * [TypeVariableElement] for type variables and [FunctionElement] for
-   * function types.
-   *
-   * Invariant: [element] must be a declaration element.
-   */
-  Element get element;
-
-  /**
-   * Performs the substitution [: [arguments[i]/parameters[i]]this :].
-   *
-   * The notation is known from this lambda calculus rule:
-   *
-   *     (lambda x.e0)e1 -> [e1/x]e0.
-   *
-   * See [ResolutionTypeVariableType] for a motivation for this method.
-   *
-   * Invariant: There must be the same number of [arguments] and [parameters].
-   */
-  ResolutionDartType subst(covariant List<ResolutionDartType> arguments,
-      covariant List<ResolutionDartType> parameters);
-
-  /// Performs the substitution of the type arguments of [type] for their
-  /// corresponding type variables in this type.
-  ResolutionDartType substByContext(GenericType type) {
-    return subst(type.typeArguments, type.element.typeVariables);
-  }
-
-  /// Computes the unaliased type of this type.
-  ///
-  /// The unaliased type of a typedef'd type is the unaliased type to which its
-  /// name is bound. The unaliased version of any other type is the type itself.
-  ///
-  /// For example, the unaliased type of `typedef A Func<A,B>(B b)` is the
-  /// function type `(B) -> A` and the unaliased type of `Func<int,String>`
-  /// is the function type `(String) -> int`.
-  // TODO(johnniwinther): Maybe move this to [TypedefType].
-  void computeUnaliased(Resolution resolution) {}
-
-  /// Returns the unaliased type of this type.
-  ///
-  /// The unaliased type of a typedef'd type is the unaliased type to which its
-  /// name is bound. The unaliased version of any other type is the type itself.
-  ///
-  /// For example, the unaliased type of `typedef A Func<A,B>(B b)` is the
-  /// function type `(B) -> A` and the unaliased type of `Func<int,String>`
-  /// is the function type `(String) -> int`.
-  ResolutionDartType get unaliased => this;
-
-  /**
-   * If this type is malformed or a generic type created with the wrong number
-   * of type arguments then [userProvidedBadType] holds the bad type provided
-   * by the user.
-   */
-  ResolutionDartType get userProvidedBadType => null;
-
-  /// Is [: true :] if this type has no explicit type arguments.
-  bool get isRaw => true;
-
-  /// Returns the raw version of this type.
-  ResolutionDartType asRaw() => this;
-
-  /// Is [: true :] if this type has no non-dynamic type arguments.
-  bool get treatAsRaw => isRaw;
-
-  /// Is [: true :] if this type should be treated as the dynamic type.
-  bool get treatAsDynamic => false;
-
-  /// Is [: true :] if this type is the dynamic type.
-  bool get isDynamic => kind == ResolutionTypeKind.DYNAMIC;
-
-  /// Is [: true :] if this type is the void type.
-  bool get isVoid => kind == ResolutionTypeKind.VOID;
-
-  /// Is [: true :] if this is the type of `Object` from dart:core.
-  bool get isObject => false;
-
-  /// Is [: true :] if this type is an interface type.
-  bool get isInterfaceType => kind == ResolutionTypeKind.INTERFACE;
-
-  /// Is [: true :] if this type is a typedef.
-  bool get isTypedef => kind == ResolutionTypeKind.TYPEDEF;
-
-  /// Is [: true :] if this type is a function type.
-  bool get isFunctionType => kind == ResolutionTypeKind.FUNCTION;
-
-  /// Is [: true :] if this type is a type variable.
-  bool get isTypeVariable => kind == ResolutionTypeKind.TYPE_VARIABLE;
-
-  @override
-  bool get isFunctionTypeVariable => false;
-
-  @override
-  bool get isFutureOr => false;
-
-  /// Is [: true :] if this type is a malformed type.
-  bool get isMalformed => false;
-
-  /// Is `true` if this type is declared by an enum.
-  bool get isEnumType => false;
-
-  /// Returns an occurrence of a type variable within this type, if any.
-  ResolutionTypeVariableType get typeVariableOccurrence => null;
-
-  /// Applies [f] to each occurence of a [ResolutionTypeVariableType] within
-  /// this type.
-  void forEachTypeVariable(f(ResolutionTypeVariableType variable)) {}
-
-  ResolutionTypeVariableType _findTypeVariableOccurrence(
-      List<ResolutionDartType> types) {
-    for (ResolutionDartType type in types) {
-      ResolutionTypeVariableType typeVariable = type.typeVariableOccurrence;
-      if (typeVariable != null) {
-        return typeVariable;
-      }
-    }
-    return null;
-  }
-
-  /// Is [: true :] if this type contains any type variables.
-  bool get containsTypeVariables => typeVariableOccurrence != null;
-
-  bool get containsFreeTypeVariables {
-    assert(!containsMethodTypeVariableType,
-        'Used only after removing method type variables');
-    return containsTypeVariables;
-  }
-
-  /// Returns a textual representation of this type as if it was the type
-  /// of a member named [name].
-  String getStringAsDeclared(String name) {
-    return new TypeDeclarationFormatter().format(this, name);
-  }
-
-  R accept<R, A>(covariant ResolutionDartTypeVisitor<R, A> visitor, A argument);
-
-  void visitChildren<R, A>(
-      ResolutionDartTypeVisitor<R, A> visitor, A argument) {}
-
-  static void visitList<R, A>(List<ResolutionDartType> types,
-      ResolutionDartTypeVisitor<R, A> visitor, A argument) {
-    for (ResolutionDartType type in types) {
-      type.accept(visitor, argument);
-    }
-  }
-
-  /// Returns a [ResolutionDartType] which corresponds to [this] except that
-  /// each contained [MethodTypeVariableType] is replaced by a
-  /// [ResolutionDynamicType].
-  /// GENERIC_METHODS: Temporary, only used with '--generic-method-syntax'.
-  ResolutionDartType get dynamifyMethodTypeVariableType => this;
-
-  /// Returns true iff [this] is or contains a [MethodTypeVariableType].
-  /// GENERIC_METHODS: Temporary, only used with '--generic-method-syntax'
-  bool get containsMethodTypeVariableType => false;
-}
-
-/**
- * Represents a type variable, that is the type parameters of a class type.
- *
- * For example, in [: class Array<E> { ... } :], E is a type variable.
- *
- * Each class should have its own unique type variables, one for each type
- * parameter. A class with type parameters is said to be parameterized or
- * generic.
- *
- * Non-static members, constructors, and factories of generic
- * class/interface can refer to type variables of the current class
- * (not of supertypes).
- *
- * When using a generic type, also known as an application or
- * instantiation of the type, the actual type arguments should be
- * substituted for the type variables in the class declaration.
- *
- * For example, given a box, [: class Box<T> { T value; } :], the
- * type of the expression [: new Box<String>().value :] is
- * [: String :] because we must substitute [: String :] for the
- * the type variable [: T :].
- */
-class ResolutionTypeVariableType extends ResolutionDartType
-    implements TypeVariableType {
-  final TypeVariableElement element;
-
-  ResolutionTypeVariableType(this.element);
-
-  ResolutionTypeKind get kind => ResolutionTypeKind.TYPE_VARIABLE;
-
-  String get name => element.name;
-
-  ResolutionDartType subst(covariant List<ResolutionDartType> arguments,
-      covariant List<ResolutionDartType> parameters) {
-    assert(arguments.length == parameters.length);
-    if (parameters.isEmpty) {
-      // Return fast on empty substitutions.
-      return this;
-    }
-    for (int index = 0; index < arguments.length; index++) {
-      ResolutionTypeVariableType parameter = parameters[index];
-      ResolutionDartType argument = arguments[index];
-      if (parameter == this) {
-        return argument;
-      }
-    }
-    // The type variable was not substituted.
-    return this;
-  }
-
-  ResolutionTypeVariableType get typeVariableOccurrence => this;
-
-  void forEachTypeVariable(f(ResolutionTypeVariableType variable)) {
-    f(this);
-  }
-
-  R accept<R, A>(DartTypeVisitor<R, A> visitor, A argument) {
-    return visitor.visitTypeVariableType(this, argument);
-  }
-
-  int get hashCode => 17 * element.hashCode;
-
-  bool operator ==(other) {
-    if (other is! ResolutionTypeVariableType) return false;
-    return identical(other.element, element);
-  }
-
-  String toString() => '${element.typeDeclaration.name}.$name';
-}
-
-/// Provides a thin model of method type variables: They are treated as if
-/// their value were `dynamic` when used in a type annotation, and as a
-/// malformed type when used in an `as` or `is` expression.
-class MethodTypeVariableType extends ResolutionTypeVariableType {
-  MethodTypeVariableType(TypeVariableElement element) : super(element);
-
-  @override
-  bool get treatAsDynamic => true;
-
-  @override
-  bool get isMalformed => true;
-
-  @override
-  ResolutionDartType get dynamifyMethodTypeVariableType =>
-      const ResolutionDynamicType();
-
-  @override
-  get containsMethodTypeVariableType => true;
-}
-
-class ResolutionVoidType extends ResolutionDartType implements VoidType {
-  const ResolutionVoidType();
-
-  ResolutionTypeKind get kind => ResolutionTypeKind.VOID;
-
-  String get name => 'void';
-
-  Element get element => null;
-
-  ResolutionDartType subst(covariant List<ResolutionDartType> arguments,
-      covariant List<ResolutionDartType> parameters) {
-    // Void cannot be substituted.
-    return this;
-  }
-
-  R accept<R, A>(DartTypeVisitor<R, A> visitor, A argument) {
-    return visitor.visitVoidType(this, argument);
-  }
-
-  String toString() => name;
-
-  int get hashCode => 6007;
-}
-
-class MalformedType extends ResolutionDartType {
-  final ErroneousElement element;
-
-  /**
-   * [declaredType] holds the type which the user wrote in code.
-   *
-   * For instance, for a resolved but malformed type like [: Map<String> :] the
-   * [declaredType] is [: Map<String> :] whereas for an unresolved type
-   * [userProvidedBadType] is [: null :].
-   */
-  final ResolutionDartType userProvidedBadType;
-
-  /**
-   * Type arguments for the malformed typed, if these cannot fit in the
-   * [declaredType].
-   *
-   * This field is for instance used for [: dynamic<int> :] and [: T<int> :]
-   * where [: T :] is a type variable, in which case [declaredType] holds
-   * [: dynamic :] and [: T :], respectively, or for [: X<int> :] where [: X :]
-   * is not resolved or does not imply a type.
-   */
-  final List<ResolutionDartType> typeArguments;
-
-  final int hashCode = _nextHash = (_nextHash + 1).toUnsigned(30);
-  static int _nextHash = 43765;
-
-  MalformedType(this.element, this.userProvidedBadType,
-      [this.typeArguments = null]);
-
-  ResolutionTypeKind get kind => ResolutionTypeKind.MALFORMED_TYPE;
-
-  String get name => element.name;
-
-  ResolutionDartType subst(covariant List<ResolutionDartType> arguments,
-      covariant List<ResolutionDartType> parameters) {
-    // Malformed types are not substitutable.
-    return this;
-  }
-
-  // Malformed types are treated as dynamic.
-  bool get treatAsDynamic => true;
-
-  @override
-  bool get isMalformed => true;
-
-  R accept<R, A>(
-      covariant ResolutionDartTypeVisitor<R, A> visitor, A argument) {
-    return visitor.visitMalformedType(this, argument);
-  }
-
-  String toString() {
-    var sb = new StringBuffer();
-    if (typeArguments != null) {
-      if (userProvidedBadType != null) {
-        sb.write(userProvidedBadType.name);
-      } else {
-        sb.write(element.name);
-      }
-      if (!typeArguments.isEmpty) {
-        sb.write('<');
-        sb.write(typeArguments.join(', '));
-        sb.write('>');
-      }
-    } else {
-      sb.write(userProvidedBadType.toString());
-    }
-    return sb.toString();
-  }
-}
-
-abstract class GenericType extends ResolutionDartType {
-  final TypeDeclarationElement element;
-  final List<ResolutionDartType> typeArguments;
-
-  GenericType(
-      TypeDeclarationElement element, List<ResolutionDartType> typeArguments,
-      {bool checkTypeArgumentCount: true})
-      : this.element = element,
-        this.typeArguments = typeArguments,
-        this.containsMethodTypeVariableType =
-            typeArguments.any(_typeContainsMethodTypeVariableType) {
-    assert(
-        element != null,
-        failedAt(
-            CURRENT_ELEMENT_SPANNABLE, "Missing element for generic type."));
-    assert(() {
-      if (!checkTypeArgumentCount) return true;
-      if (element is TypeDeclarationElementX) {
-        return element.thisTypeCache == null ||
-            typeArguments.length == element.typeVariables.length;
-      }
-      return true;
-    }(),
-        failedAt(
-            element,
-            'Invalid type argument count on ${element.thisType}. '
-            'Provided type arguments: $typeArguments.'));
-  }
-
-  /// Creates a new instance of this type using the provided type arguments.
-  GenericType createInstantiation(List<ResolutionDartType> newTypeArguments);
-
-  GenericType subst(covariant List<ResolutionDartType> arguments,
-      covariant List<ResolutionDartType> parameters) {
-    if (typeArguments.isEmpty) {
-      // Return fast on non-generic types.
-      return this;
-    }
-    if (parameters.isEmpty) {
-      assert(arguments.isEmpty);
-      // Return fast on empty substitutions.
-      return this;
-    }
-    List<ResolutionDartType> newTypeArguments =
-        Types.substTypes(typeArguments, arguments, parameters);
-    if (!identical(typeArguments, newTypeArguments)) {
-      // Create a new type only if necessary.
-      return createInstantiation(newTypeArguments);
-    }
-    return this;
-  }
-
-  ResolutionTypeVariableType get typeVariableOccurrence {
-    return _findTypeVariableOccurrence(typeArguments);
-  }
-
-  void forEachTypeVariable(f(ResolutionTypeVariableType variable)) {
-    for (ResolutionDartType type in typeArguments) {
-      type.forEachTypeVariable(f);
-    }
-  }
-
-  void visitChildren<R, A>(
-      ResolutionDartTypeVisitor<R, A> visitor, var argument) {
-    ResolutionDartType.visitList(typeArguments, visitor, argument);
-  }
-
-  String toString() {
-    StringBuffer sb = new StringBuffer();
-    sb.write(name);
-    if (!isRaw) {
-      sb.write('<');
-      sb.write(typeArguments.join(', '));
-      sb.write('>');
-    }
-    return sb.toString();
-  }
-
-  @override
-  final bool containsMethodTypeVariableType;
-
-  @override
-  ResolutionDartType get dynamifyMethodTypeVariableType {
-    if (!containsMethodTypeVariableType) return this;
-    List<ResolutionDartType> newTypeArguments = typeArguments
-        .map((ResolutionDartType type) => type.dynamifyMethodTypeVariableType)
-        .toList();
-    return createInstantiation(newTypeArguments);
-  }
-
-  int get hashCode {
-    int hash = element.hashCode;
-    for (ResolutionDartType argument in typeArguments) {
-      int argumentHash = argument != null ? argument.hashCode : 0;
-      hash = 17 * hash + 3 * argumentHash;
-    }
-    return hash;
-  }
-
-  bool operator ==(other) {
-    if (other is! GenericType) return false;
-    return kind == other.kind &&
-        element == other.element &&
-        equalElements(typeArguments, other.typeArguments);
-  }
-
-  /// Returns `true` if the declaration of this type has type variables.
-  bool get isGeneric => !typeArguments.isEmpty;
-
-  bool get isRaw => typeArguments.isEmpty || identical(this, element.rawType);
-
-  GenericType asRaw() => element.rawType;
-
-  bool get treatAsRaw {
-    if (isRaw) return true;
-    for (ResolutionDartType type in typeArguments) {
-      if (!type.treatAsDynamic) return false;
-    }
-    return true;
-  }
-}
-
-class ResolutionInterfaceType extends GenericType implements InterfaceType {
-  int _hashCode;
-
-  ResolutionInterfaceType(ClassElement element,
-      [List<ResolutionDartType> typeArguments = const <ResolutionDartType>[]])
-      : super(element, typeArguments) {
-    assert(element.isDeclaration, failedAt(element));
-  }
-
-  ResolutionInterfaceType.forUserProvidedBadType(ClassElement element,
-      [List<ResolutionDartType> typeArguments = const <ResolutionDartType>[]])
-      : super(element, typeArguments, checkTypeArgumentCount: false);
-
-  ClassElement get element => super.element;
-
-  ResolutionTypeKind get kind => ResolutionTypeKind.INTERFACE;
-
-  String get name => element.name;
-
-  bool get isObject => element.isObject;
-
-  bool get isEnumType => element.isEnumClass;
-
-  ResolutionInterfaceType createInstantiation(
-      List<ResolutionDartType> newTypeArguments) {
-    return new ResolutionInterfaceType(element, newTypeArguments);
-  }
-
-  /**
-   * Returns the type as an instance of class [other], if possible, null
-   * otherwise.
-   */
-  ResolutionInterfaceType asInstanceOf(ClassElement other) {
-    other = other.declaration;
-    if (element == other) return this;
-    ResolutionInterfaceType supertype = element.asInstanceOf(other);
-    if (supertype != null) {
-      List<ResolutionDartType> arguments = Types.substTypes(
-          supertype.typeArguments, typeArguments, element.typeVariables);
-      return new ResolutionInterfaceType(supertype.element, arguments);
-    }
-    return null;
-  }
-
-  MemberSignature lookupInterfaceMember(Name name) {
-    MemberSignature member = element.lookupInterfaceMember(name);
-    if (member != null && isGeneric) {
-      return new InterfaceMember(this, member);
-    }
-    return member;
-  }
-
-  MemberSignature lookupClassMember(Name name) {
-    MemberSignature member = element.lookupClassMember(name);
-    if (member != null && isGeneric) {
-      return new InterfaceMember(this, member);
-    }
-    return member;
-  }
-
-  int get hashCode => _hashCode ??= super.hashCode;
-
-  ResolutionInterfaceType asRaw() => super.asRaw();
-
-  R accept<R, A>(DartTypeVisitor<R, A> visitor, A argument) {
-    return visitor.visitInterfaceType(this, argument);
-  }
-
-  /// Returns the type of the 'call' method in this interface type, or
-  /// `null` if the interface type has no 'call' method.
-  ResolutionFunctionType get callType {
-    ResolutionFunctionType type = element.callType;
-    return type != null && isGeneric ? type.substByContext(this) : type;
-  }
-
-  ResolutionInterfaceType subst(covariant List<ResolutionDartType> arguments,
-      covariant List<ResolutionDartType> parameters) {
-    return super.subst(arguments, parameters);
-  }
-}
-
-/// Special subclass of [ResolutionInterfaceType] used for generic interface
-/// types created with the wrong number of type arguments.
-///
-/// The type uses `dynamic` for all it s type arguments.
-class BadInterfaceType extends ResolutionInterfaceType {
-  final ResolutionInterfaceType userProvidedBadType;
-
-  BadInterfaceType(
-      ClassElement element, ResolutionInterfaceType this.userProvidedBadType)
-      : super(element, element.rawType.typeArguments);
-
-  String toString() {
-    return userProvidedBadType.toString();
-  }
-}
-
-/**
- * Special subclass of [ResolutionTypedefType] used for generic typedef types
- * created with the wrong number of type arguments.
- *
- * The type uses [:dynamic:] for all it s type arguments.
- */
-class BadTypedefType extends ResolutionTypedefType {
-  final ResolutionTypedefType userProvidedBadType;
-
-  BadTypedefType(
-      TypedefElement element, ResolutionTypedefType this.userProvidedBadType)
-      : super(element, element.rawType.typeArguments);
-
-  String toString() {
-    return userProvidedBadType.toString();
-  }
-}
-
-class ResolutionFunctionType extends ResolutionDartType
-    implements FunctionType {
-  final FunctionTypedElement element;
-  final ResolutionDartType returnType;
-  final List<ResolutionDartType> parameterTypes;
-  final List<ResolutionDartType> optionalParameterTypes;
-
-  /**
-   * The names of the named parameters ordered lexicographically.
-   */
-  final List<String> namedParameters;
-
-  /**
-   * The types of the named parameters in the order corresponding to the
-   * [namedParameters].
-   */
-  final List<ResolutionDartType> namedParameterTypes;
-
-  TypedefType get typedefType => null;
-
-  factory ResolutionFunctionType(FunctionTypedElement element,
-      [ResolutionDartType returnType = const ResolutionDynamicType(),
-      List<ResolutionDartType> parameterTypes = const <ResolutionDartType>[],
-      List<ResolutionDartType> optionalParameterTypes =
-          const <ResolutionDartType>[],
-      List<String> namedParameters = const <String>[],
-      List<ResolutionDartType> namedParameterTypes =
-          const <ResolutionDartType>[]]) {
-    assert(element != null, failedAt(CURRENT_ELEMENT_SPANNABLE));
-    assert(element.isDeclaration, failedAt(element));
-    return new ResolutionFunctionType.internal(
-        element,
-        returnType,
-        parameterTypes,
-        optionalParameterTypes,
-        namedParameters,
-        namedParameterTypes);
-  }
-
-  factory ResolutionFunctionType.synthesized(
-      [ResolutionDartType returnType = const ResolutionDynamicType(),
-      List<ResolutionDartType> parameterTypes = const <ResolutionDartType>[],
-      List<ResolutionDartType> optionalParameterTypes =
-          const <ResolutionDartType>[],
-      List<String> namedParameters = const <String>[],
-      List<ResolutionDartType> namedParameterTypes =
-          const <ResolutionDartType>[]]) {
-    return new ResolutionFunctionType.internal(null, returnType, parameterTypes,
-        optionalParameterTypes, namedParameters, namedParameterTypes);
-  }
-
-  factory ResolutionFunctionType.generalized(
-      ResolutionDartType returnType,
-      List<ResolutionDartType> parameterTypes,
-      List<ResolutionDartType> optionalParameterTypes,
-      List<String> namedParameters,
-      List<ResolutionDartType> namedParameterTypes) {
-    return new ResolutionFunctionType.internal(null, returnType, parameterTypes,
-        optionalParameterTypes, namedParameters, namedParameterTypes);
-  }
-
-  ResolutionFunctionType.internal(FunctionTypedElement this.element,
-      [ResolutionDartType returnType = const ResolutionDynamicType(),
-      List<ResolutionDartType> parameterTypes = const <ResolutionDartType>[],
-      List<ResolutionDartType> optionalParameterTypes =
-          const <ResolutionDartType>[],
-      List<String> namedParameters = const <String>[],
-      List<ResolutionDartType> namedParameterTypes =
-          const <ResolutionDartType>[]])
-      : this.returnType = returnType,
-        this.parameterTypes = parameterTypes,
-        this.optionalParameterTypes = optionalParameterTypes,
-        this.namedParameters = namedParameters,
-        this.namedParameterTypes = namedParameterTypes,
-        this.containsMethodTypeVariableType = returnType
-                .containsMethodTypeVariableType ||
-            parameterTypes.any(_typeContainsMethodTypeVariableType) ||
-            optionalParameterTypes.any(_typeContainsMethodTypeVariableType) ||
-            namedParameterTypes.any(_typeContainsMethodTypeVariableType) {
-    assert(element == null || element.isDeclaration,
-        failedAt(CURRENT_ELEMENT_SPANNABLE));
-    // Assert that optional and named parameters are not used at the same time.
-    assert(optionalParameterTypes.isEmpty || namedParameterTypes.isEmpty);
-    assert(namedParameters.length == namedParameterTypes.length);
-  }
-
-  @override
-  final List<FunctionTypeVariable> typeVariables =
-      const <FunctionTypeVariable>[];
-
-  FunctionType instantiate(List<DartType> arguments) {
-    throw new UnsupportedError("ResolutionFunctionType.instantiate");
-  }
-
-  ResolutionTypeKind get kind => ResolutionTypeKind.FUNCTION;
-
-  ResolutionDartType getNamedParameterType(String name) {
-    for (int i = 0; i < namedParameters.length; i++) {
-      if (namedParameters[i] == name) {
-        return namedParameterTypes[i];
-      }
-    }
-    return null;
-  }
-
-  ResolutionDartType subst(covariant List<ResolutionDartType> arguments,
-      covariant List<ResolutionDartType> parameters) {
-    if (parameters.isEmpty) {
-      assert(arguments.isEmpty);
-      // Return fast on empty substitutions.
-      return this;
-    }
-    ResolutionDartType newReturnType = returnType.subst(arguments, parameters);
-    bool changed = !identical(newReturnType, returnType);
-    List<ResolutionDartType> newParameterTypes =
-        Types.substTypes(parameterTypes, arguments, parameters);
-    List<ResolutionDartType> newOptionalParameterTypes =
-        Types.substTypes(optionalParameterTypes, arguments, parameters);
-    List<ResolutionDartType> newNamedParameterTypes =
-        Types.substTypes(namedParameterTypes, arguments, parameters);
-    if (!changed &&
-        (!identical(parameterTypes, newParameterTypes) ||
-            !identical(optionalParameterTypes, newOptionalParameterTypes) ||
-            !identical(namedParameterTypes, newNamedParameterTypes))) {
-      changed = true;
-    }
-    if (changed) {
-      // Create a new type only if necessary.
-      return new ResolutionFunctionType.internal(
-          element,
-          newReturnType,
-          newParameterTypes,
-          newOptionalParameterTypes,
-          namedParameters,
-          newNamedParameterTypes);
-    }
-    return this;
-  }
-
-  ResolutionTypeVariableType get typeVariableOccurrence {
-    ResolutionTypeVariableType typeVariableType =
-        returnType.typeVariableOccurrence;
-    if (typeVariableType != null) return typeVariableType;
-
-    typeVariableType = _findTypeVariableOccurrence(parameterTypes);
-    if (typeVariableType != null) return typeVariableType;
-
-    typeVariableType = _findTypeVariableOccurrence(optionalParameterTypes);
-    if (typeVariableType != null) return typeVariableType;
-
-    return _findTypeVariableOccurrence(namedParameterTypes);
-  }
-
-  void forEachTypeVariable(f(ResolutionTypeVariableType variable)) {
-    returnType.forEachTypeVariable(f);
-    parameterTypes.forEach((ResolutionDartType type) {
-      type.forEachTypeVariable(f);
-    });
-    optionalParameterTypes.forEach((ResolutionDartType type) {
-      type.forEachTypeVariable(f);
-    });
-    namedParameterTypes.forEach((ResolutionDartType type) {
-      type.forEachTypeVariable(f);
-    });
-  }
-
-  R accept<R, A>(covariant DartTypeVisitor<R, A> visitor, A argument) {
-    return visitor.visitFunctionType(this, argument);
-  }
-
-  void visitChildren<R, A>(
-      ResolutionDartTypeVisitor<R, A> visitor, var argument) {
-    returnType.accept(visitor, argument);
-    ResolutionDartType.visitList(parameterTypes, visitor, argument);
-    ResolutionDartType.visitList(optionalParameterTypes, visitor, argument);
-    ResolutionDartType.visitList(namedParameterTypes, visitor, argument);
-  }
-
-  String toString() {
-    StringBuffer sb = new StringBuffer();
-    sb.write('(');
-    sb.write(parameterTypes.join(', '));
-    bool first = parameterTypes.isEmpty;
-    if (!optionalParameterTypes.isEmpty) {
-      if (!first) {
-        sb.write(', ');
-      }
-      sb.write('[');
-      sb.write(optionalParameterTypes.join(', '));
-      sb.write(']');
-      first = false;
-    }
-    if (!namedParameterTypes.isEmpty) {
-      if (!first) {
-        sb.write(', ');
-      }
-      sb.write('{');
-      first = true;
-      for (int i = 0; i < namedParameters.length; i++) {
-        if (!first) {
-          sb.write(', ');
-        }
-        sb.write(namedParameterTypes[i]);
-        sb.write(' ');
-        sb.write(namedParameters[i]);
-        first = false;
-      }
-      sb.write('}');
-    }
-    sb.write(') -> ${returnType}');
-    return sb.toString();
-  }
-
-  String get name => 'Function';
-
-  @override
-  ResolutionDartType get dynamifyMethodTypeVariableType {
-    if (!containsMethodTypeVariableType) return this;
-    ResolutionDartType eraseIt(ResolutionDartType type) =>
-        type.dynamifyMethodTypeVariableType;
-    ResolutionDartType newReturnType =
-        returnType.dynamifyMethodTypeVariableType;
-    List<ResolutionDartType> newParameterTypes =
-        parameterTypes.map(eraseIt).toList();
-    List<ResolutionDartType> newOptionalParameterTypes =
-        optionalParameterTypes.map(eraseIt).toList();
-    List<ResolutionDartType> newNamedParameterTypes =
-        namedParameterTypes.map(eraseIt).toList();
-    return new ResolutionFunctionType.internal(
-        element,
-        newReturnType,
-        newParameterTypes,
-        newOptionalParameterTypes,
-        namedParameters,
-        newNamedParameterTypes);
-  }
-
-  @override
-  final bool containsMethodTypeVariableType;
-
-  int get hashCode {
-    int hash = 3 * returnType.hashCode;
-    for (ResolutionDartType parameter in parameterTypes) {
-      hash = 17 * hash + 5 * parameter.hashCode;
-    }
-    for (ResolutionDartType parameter in optionalParameterTypes) {
-      hash = 19 * hash + 7 * parameter.hashCode;
-    }
-    for (String name in namedParameters) {
-      hash = 23 * hash + 11 * name.hashCode;
-    }
-    for (ResolutionDartType parameter in namedParameterTypes) {
-      hash = 29 * hash + 13 * parameter.hashCode;
-    }
-    return hash;
-  }
-
-  bool operator ==(other) {
-    if (other is! ResolutionFunctionType) return false;
-    return returnType == other.returnType &&
-        equalElements(parameterTypes, other.parameterTypes) &&
-        equalElements(optionalParameterTypes, other.optionalParameterTypes) &&
-        equalElements(namedParameters, other.namedParameters) &&
-        equalElements(namedParameterTypes, other.namedParameterTypes);
-  }
-}
-
-bool _typeContainsMethodTypeVariableType(ResolutionDartType type) =>
-    type.containsMethodTypeVariableType;
-
-class ResolutionTypedefType extends GenericType implements TypedefType {
-  ResolutionDartType _unaliased;
-
-  ResolutionTypedefType(TypedefElement element,
-      [List<ResolutionDartType> typeArguments = const <ResolutionDartType>[]])
-      : super(element, typeArguments);
-
-  ResolutionTypedefType.forUserProvidedBadType(TypedefElement element,
-      [List<ResolutionDartType> typeArguments = const <ResolutionDartType>[]])
-      : super(element, typeArguments, checkTypeArgumentCount: false);
-
-  TypedefElement get element => super.element;
-
-  ResolutionTypeKind get kind => ResolutionTypeKind.TYPEDEF;
-
-  String get name => element.name;
-
-  ResolutionTypedefType createInstantiation(
-      List<ResolutionDartType> newTypeArguments) {
-    return new ResolutionTypedefType(element, newTypeArguments);
-  }
-
-  ResolutionTypedefType subst(covariant List<ResolutionDartType> arguments,
-      covariant List<ResolutionDartType> parameters) {
-    return super.subst(arguments, parameters);
-  }
-
-  void computeUnaliased(Resolution resolution) {
-    if (_unaliased == null) {
-      element.ensureResolved(resolution);
-      if (element.isMalformed) {
-        _unaliased = const ResolutionDynamicType();
-        return;
-      }
-      element.checkCyclicReference(resolution);
-      element.alias.computeUnaliased(resolution);
-      _unaliased = element.alias.unaliased.substByContext(this);
-    }
-  }
-
-  ResolutionDartType get unaliased {
-    if (_unaliased == null) {
-      ResolutionDartType definition = element.alias.unaliased;
-      _unaliased = definition.substByContext(this);
-    }
-    return _unaliased;
-  }
-
-  int get hashCode => super.hashCode;
-
-  ResolutionTypedefType asRaw() => super.asRaw();
-
-  R accept<R, A>(
-      covariant ResolutionDartTypeVisitor<R, A> visitor, A argument) {
-    return visitor.visitTypedefType(this, argument);
-  }
-}
-
-/**
- * Special type for the `dynamic` type.
- */
-class ResolutionDynamicType extends ResolutionDartType implements DynamicType {
-  const ResolutionDynamicType();
-
-  Element get element => null;
-
-  String get name => 'dynamic';
-
-  bool get treatAsDynamic => true;
-
-  ResolutionTypeKind get kind => ResolutionTypeKind.DYNAMIC;
-
-  ResolutionDartType subst(covariant List<ResolutionDartType> arguments,
-          covariant List<ResolutionDartType> parameters) =>
-      this;
-
-  R accept<R, A>(DartTypeVisitor<R, A> visitor, A argument) {
-    return visitor.visitDynamicType(this, argument);
-  }
-
-  int get hashCode => 91;
-
-  String toString() => name;
-}
-
-/**
- * [InterfaceMember] encapsulates a member (method, field, property) with
- * the types of the declarer and receiver in order to do substitution on the
- * member type.
- *
- * Consider for instance these classes and the variable `B<String> b`:
- *
- *     class A<E> {
- *       E field;
- *     }
- *     class B<F> extends A<F> {}
- *
- * In an [InterfaceMember] for `b.field` the [receiver] is the type
- * `B<String>` and the declarer is the type `A<F>`, which is the supertype of
- * `B<F>` from which `field` has been inherited. To compute the type of
- * `b.field` we must first substitute `E` by `F` using the relation between
- * `A<E>` and `A<F>`, and then `F` by `String` using the relation between
- * `B<F>` and `B<String>`.
- */
-class InterfaceMember implements MemberSignature {
-  final ResolutionInterfaceType instance;
-  final MemberSignature member;
-
-  InterfaceMember(this.instance, this.member);
-
-  Name get name => member.name;
-
-  ResolutionDartType get type => member.type.substByContext(instance);
-
-  ResolutionFunctionType get functionType =>
-      member.functionType.substByContext(instance);
-
-  bool get isGetter => member.isGetter;
-
-  bool get isSetter => member.isSetter;
-
-  bool get isMethod => member.isMethod;
-
-  Iterable<Member> get declarations => member.declarations;
-}
-
-abstract class ResolutionDartTypeVisitor<R, A> extends DartTypeVisitor<R, A> {
-  const ResolutionDartTypeVisitor();
-
-  R visitMalformedType(MalformedType type, A argument) => null;
-
-  R visitTypedefType(TypedefType type, A argument) => null;
-}
-
-abstract class BaseResolutionDartTypeVisitor<R, A>
-    extends BaseDartTypeVisitor<R, A>
-    implements ResolutionDartTypeVisitor<R, A> {
-  const BaseResolutionDartTypeVisitor();
-
-  @override
-  R visitMalformedType(MalformedType type, A argument) =>
-      visitType(type, argument);
-
-  R visitGenericType(GenericType type, A argument) => visitType(type, argument);
-
-  @override
-  R visitInterfaceType(covariant ResolutionInterfaceType type, A argument) =>
-      visitGenericType(type, argument);
-
-  @override
-  R visitTypedefType(covariant ResolutionTypedefType type, A argument) =>
-      visitGenericType(type, argument);
-}
-
-abstract class AbstractTypeRelationMixin
-    implements
-        AbstractTypeRelation<ResolutionDartType>,
-        ResolutionDartTypeVisitor<bool, ResolutionDartType> {
-  Resolution get resolution;
-
-  @override
-  CommonElements get commonElements => resolution.commonElements;
-
-  /// Ensures that the super hierarchy of [type] is computed.
-  void ensureResolved(covariant ResolutionInterfaceType type) {
-    // TODO(johnniwinther): Currently needed since literal types like int,
-    // double, bool etc. might not have been resolved yet.
-    type.element.ensureResolved(resolution);
-  }
-
-  /// Returns the unaliased version of [type].
-  ResolutionDartType getUnaliased(covariant ResolutionDartType type) {
-    type.computeUnaliased(resolution);
-    return type.unaliased;
-  }
-
-  @override
-  DartType getTypeVariableBound(covariant TypeVariableElement element) =>
-      element.bound;
-
-  @override
-  FunctionType getCallType(covariant ResolutionInterfaceType type) =>
-      type.callType;
-
-  @override
-  InterfaceType asInstanceOf(
-          covariant ResolutionInterfaceType type, ClassEntity cls) =>
-      type.asInstanceOf(cls);
-
-  /// Handle as dynamic for both subtype and more specific relation to avoid
-  /// spurious errors from malformed types.
-  bool visitMalformedType(MalformedType t, ResolutionDartType s) => true;
-
-  bool visitTypedefType(
-          covariant ResolutionTypedefType t, ResolutionDartType s) =>
-      visitType(t, s);
-}
-
-class ResolutionMoreSpecificVisitor
-    extends MoreSpecificVisitor<ResolutionDartType>
-    with AbstractTypeRelationMixin {
-  final Resolution resolution;
-  bool get strongMode => false;
-
-  ResolutionMoreSpecificVisitor(this.resolution);
-}
-
-class ResolutionSubtypeVisitor extends SubtypeVisitor<ResolutionDartType>
-    with AbstractTypeRelationMixin {
-  final Resolution resolution;
-  bool get strongMode => false;
-
-  ResolutionSubtypeVisitor(this.resolution);
-}
-
-class ResolutionPotentialSubtypeVisitor
-    extends PotentialSubtypeVisitor<ResolutionDartType>
-    with AbstractTypeRelationMixin {
-  final Resolution resolution;
-  bool get strongMode => false;
-
-  ResolutionPotentialSubtypeVisitor(this.resolution);
-}
-
-/**
- * Callback used to check whether the [typeArgument] of [type] is a valid
- * substitute for the bound of [typeVariable]. [bound] holds the bound against
- * which [typeArgument] should be checked.
- */
-typedef void CheckTypeVariableBound<T>(T context, DartType typeArgument,
-    TypeVariableType typeVariable, DartType bound);
-
-class Types extends DartTypes {
-  final Resolution resolution;
-  final ResolutionMoreSpecificVisitor moreSpecificVisitor;
-  final ResolutionSubtypeVisitor subtypeVisitor;
-  final ResolutionPotentialSubtypeVisitor potentialSubtypeVisitor;
-
-  CommonElements get commonElements => resolution.commonElements;
-
-  DiagnosticReporter get reporter => resolution.reporter;
-
-  Types(Resolution resolution)
-      : this.resolution = resolution,
-        this.moreSpecificVisitor =
-            new ResolutionMoreSpecificVisitor(resolution),
-        this.subtypeVisitor = new ResolutionSubtypeVisitor(resolution),
-        this.potentialSubtypeVisitor =
-            new ResolutionPotentialSubtypeVisitor(resolution);
-
-  Types copy(Resolution resolution) {
-    return new Types(resolution);
-  }
-
-  @override
-  InterfaceType asInstanceOf(
-      covariant ResolutionInterfaceType type, ClassEntity cls) {
-    return type.asInstanceOf(cls);
-  }
-
-  @override
-  ResolutionDartType substByContext(covariant ResolutionDartType base,
-      covariant ResolutionInterfaceType context) {
-    return base.substByContext(context);
-  }
-
-  @override
-  InterfaceType getThisType(covariant ClassElement cls) => cls.thisType;
-
-  @override
-  ResolutionInterfaceType getSupertype(covariant ClassElement cls) =>
-      cls.supertype;
-
-  @override
-  Iterable<InterfaceType> getSupertypes(covariant ClassElement cls) {
-    assert(cls.allSupertypes != null,
-        failedAt(cls, 'Supertypes have not been computed for $cls.'));
-    return cls.allSupertypes;
-  }
-
-  @override
-  Iterable<InterfaceType> getInterfaces(covariant ClassElement cls) {
-    return new List<InterfaceType>.from(cls.interfaces.toList());
-  }
-
-  @override
-  FunctionType getCallType(covariant ResolutionInterfaceType type) =>
-      type.callType;
-
-  /// Flatten [type] by recursively removing enclosing `Future` annotations.
-  ///
-  /// Defined in the language specification as:
-  ///
-  ///   If T = Future<S> then flatten(T) = flatten(S).
-  ///   Otherwise if T <: Future then let S be a type such that T << Future<S>
-  ///   and for all R, if T << Future<R> then S << R. Then flatten(T) =  S.
-  ///   In any other circumstance, flatten(T) = T.
-  ///
-  /// For instance:
-  ///     flatten(T) = T
-  ///     flatten(Future<T>) = T
-  ///     flatten(Future<Future<T>>) = T
-  ///
-  /// This method is used in the static typing of await and type checking of
-  /// return.
-  ResolutionDartType flatten(ResolutionDartType type) {
-    if (type is ResolutionInterfaceType) {
-      if (type.element == commonElements.futureClass) {
-        // T = Future<S>
-        return flatten(type.typeArguments.first);
-      }
-      ResolutionInterfaceType futureType =
-          type.asInstanceOf(commonElements.futureClass);
-      if (futureType != null) {
-        // T << Future<S>
-        return futureType.typeArguments.single;
-      }
-    }
-    return type;
-  }
-
-  /// Returns true if [t] is more specific than [s].
-  bool isMoreSpecific(ResolutionDartType t, ResolutionDartType s) {
-    return moreSpecificVisitor.isMoreSpecific(t, s);
-  }
-
-  /// Returns the most specific type of [t] and [s] or `null` if neither is more
-  /// specific than the other.
-  ResolutionDartType getMostSpecific(
-      ResolutionDartType t, ResolutionDartType s) {
-    if (isMoreSpecific(t, s)) {
-      return t;
-    } else if (isMoreSpecific(s, t)) {
-      return s;
-    } else {
-      return null;
-    }
-  }
-
-  /** Returns true if t is a subtype of s */
-  bool isSubtype(
-      covariant ResolutionDartType t, covariant ResolutionDartType s) {
-    return subtypeVisitor.isSubtype(t, s);
-  }
-
-  bool isAssignable(
-      covariant ResolutionDartType r, covariant ResolutionDartType s) {
-    return subtypeVisitor.isAssignable(r, s);
-  }
-
-  bool isPotentialSubtype(
-      covariant ResolutionDartType t, covariant ResolutionDartType s,
-      {bool assumeInstantiations: true}) {
-    // TODO(johnniwinther): Return a set of variable points in the positive
-    // cases.
-    return potentialSubtypeVisitor.isPotentialSubtype(t, s,
-        assumeInstantiations: assumeInstantiations);
-  }
-
-  @override
-  void checkTypeVariableBounds<T>(
-      T context,
-      List<DartType> typeArguments,
-      List<DartType> typeVariables,
-      void checkTypeVariableBound(T context, DartType typeArgument,
-          TypeVariableType typeVariable, DartType bound)) {
-    void f(T context, DartType typeArgument, TypeVariableType typeVariable,
-            DartType bound) =>
-        checkTypeVariableBound(context, typeArgument, typeVariable, bound);
-    genericCheckTypeVariableBounds(context, typeArguments, typeVariables, f);
-  }
-
-  /**
-   * Checks the type arguments of [type] against the type variable bounds
-   * declared on [element]. Calls [checkTypeVariableBound] on each type
-   * argument and bound.
-   */
-  void genericCheckTypeVariableBounds<T>(
-      T context,
-      List<DartType> typeArguments,
-      List<DartType> typeVariables,
-      CheckTypeVariableBound<T> checkTypeVariableBound) {
-    assert(typeVariables.length == typeArguments.length);
-    for (int index = 0; index < typeArguments.length; index++) {
-      ResolutionTypeVariableType typeVariable = typeVariables[index];
-      ResolutionDartType bound =
-          typeVariable.element.bound.subst(typeArguments, typeVariables);
-      ResolutionDartType typeArgument = typeArguments[index];
-      checkTypeVariableBound(context, typeArgument, typeVariable, bound);
-    }
-  }
-
-  /**
-   * Helper method for performing substitution of a list of types.
-   *
-   * If no types are changed by the substitution, the [types] is returned
-   * instead of a newly created list.
-   */
-  static List<ResolutionDartType> substTypes(List<ResolutionDartType> types,
-      List<ResolutionDartType> arguments, List<ResolutionDartType> parameters) {
-    bool changed = false;
-    List<ResolutionDartType> result =
-        new List<ResolutionDartType>.generate(types.length, (index) {
-      ResolutionDartType type = types[index];
-      ResolutionDartType argument = type.subst(arguments, parameters);
-      if (!changed && !identical(argument, type)) {
-        changed = true;
-      }
-      return argument;
-    });
-    // Use the new List only if necessary.
-    return changed ? result : types;
-  }
-
-  /**
-   * A `compareTo` function that globally orders types using
-   * [Elements.compareByPosition] to order types defined by a declaration.
-   *
-   * The order is:
-   * * void
-   * * dynamic
-   * * interface, typedef, type variables ordered by element order
-   *   - interface and typedef of the same element are ordered by
-   *     the order of their type arguments
-   * * function types, ordered by
-   *   - return type
-   *   - required parameter types
-   *   - optional parameter types
-   *   - named parameter names
-   *   - named parameter types
-   * * malformed types
-   * * statement types
-   */
-  static int compare(ResolutionDartType a, ResolutionDartType b) {
-    if (a == b) return 0;
-    if (a.isVoid) {
-      // [b] is not void => a < b.
-      return -1;
-    } else if (b.isVoid) {
-      // [a] is not void => a > b.
-      return 1;
-    }
-    if (a.isDynamic) {
-      // [b] is not dynamic => a < b.
-      return -1;
-    } else if (b.isDynamic) {
-      // [a] is not dynamic => a > b.
-      return 1;
-    }
-    bool isDefinedByDeclaration(ResolutionDartType type) {
-      return type.isInterfaceType || type.isTypedef || type.isTypeVariable;
-    }
-
-    if (isDefinedByDeclaration(a)) {
-      if (isDefinedByDeclaration(b)) {
-        int result = Elements.compareByPosition(a.element, b.element);
-        if (result != 0) return result;
-        if (a.isTypeVariable) {
-          return b.isTypeVariable
-              ? 0
-              : 1; // [b] is not a type variable => a > b.
-        } else {
-          if (b.isTypeVariable) {
-            // [a] is not a type variable => a < b.
-            return -1;
-          } else {
-            return compareList((a as GenericType).typeArguments,
-                (b as GenericType).typeArguments);
-          }
-        }
-      } else {
-        // [b] is neither an interface, typedef, type variable, dynamic,
-        // nor void => a < b.
-        return -1;
-      }
-    } else if (isDefinedByDeclaration(b)) {
-      // [a] is neither an interface, typedef, type variable, dynamic,
-      // nor void => a > b.
-      return 1;
-    }
-    if (a.isFunctionType) {
-      if (b.isFunctionType) {
-        ResolutionFunctionType aFunc = a;
-        ResolutionFunctionType bFunc = b;
-        int result = compare(aFunc.returnType, bFunc.returnType);
-        if (result != 0) return result;
-        result = compareList(aFunc.parameterTypes, bFunc.parameterTypes);
-        if (result != 0) return result;
-        result = compareList(
-            aFunc.optionalParameterTypes, bFunc.optionalParameterTypes);
-        if (result != 0) return result;
-        // TODO(karlklose): reuse [compareList].
-        Iterator<String> aNames = aFunc.namedParameters.iterator;
-        Iterator<String> bNames = bFunc.namedParameters.iterator;
-        while (aNames.moveNext() && bNames.moveNext()) {
-          int result = aNames.current.compareTo(bNames.current);
-          if (result != 0) return result;
-        }
-        if (aNames.moveNext()) {
-          // [aNames] is longer that [bNames] => a > b.
-          return 1;
-        } else if (bNames.moveNext()) {
-          // [bNames] is longer that [aNames] => a < b.
-          return -1;
-        }
-        return compareList(
-            aFunc.namedParameterTypes, bFunc.namedParameterTypes);
-      } else {
-        // [b] is a malformed or statement type => a < b.
-        return -1;
-      }
-    } else if (b.isFunctionType) {
-      // [b] is a malformed or statement type => a > b.
-      return 1;
-    }
-    assert(a.isMalformed);
-    assert(b.isMalformed);
-    // TODO(johnniwinther): Can we do this better?
-    return Elements.compareByPosition(a.element, b.element);
-  }
-
-  static int compareList(
-      List<ResolutionDartType> a, List<ResolutionDartType> b) {
-    for (int index = 0; index < min(a.length, b.length); index++) {
-      int result = compare(a[index], b[index]);
-      if (result != 0) return result;
-    }
-    if (a.length > b.length) {
-      return 1;
-    } else if (a.length < b.length) {
-      return -1;
-    }
-    return 0;
-  }
-
-  static List<ResolutionDartType> sorted(Iterable<ResolutionDartType> types) {
-    return types.toList()..sort(compare);
-  }
-
-  /// Computes the least upper bound of two interface types [a] and [b].
-  ResolutionInterfaceType computeLeastUpperBoundInterfaces(
-      ResolutionInterfaceType a, ResolutionInterfaceType b) {
-    /// Returns the set of supertypes of [type] at depth [depth].
-    Set<ResolutionDartType> getSupertypesAtDepth(
-        ResolutionInterfaceType type, int depth) {
-      OrderedTypeSet types = type.element.allSupertypesAndSelf;
-      Set<ResolutionDartType> set = new Set<ResolutionDartType>();
-      types.forEach(depth, (_supertype) {
-        ResolutionInterfaceType supertype = _supertype;
-        set.add(supertype.substByContext(type));
-      });
-      return set;
-    }
-
-    ClassElement aClass = a.element;
-    ClassElement bClass = b.element;
-    int maxCommonDepth = min(aClass.hierarchyDepth, bClass.hierarchyDepth);
-    for (int depth = maxCommonDepth; depth >= 0; depth--) {
-      Set<ResolutionDartType> aTypeSet = getSupertypesAtDepth(a, depth);
-      Set<ResolutionDartType> bTypeSet = getSupertypesAtDepth(b, depth);
-      Set<ResolutionDartType> intersection = aTypeSet..retainAll(bTypeSet);
-      if (intersection.length == 1) {
-        return intersection.first;
-      }
-    }
-
-    reporter.internalError(CURRENT_ELEMENT_SPANNABLE,
-        'No least upper bound computed for $a and $b.');
-    return null;
-  }
-
-  /// Computes the least upper bound of the types in the longest prefix of [a]
-  /// and [b].
-  List<ResolutionDartType> computeLeastUpperBoundsTypes(
-      List<ResolutionDartType> a, List<ResolutionDartType> b) {
-    if (a.isEmpty || b.isEmpty) return const <ResolutionDartType>[];
-    int prefixLength = min(a.length, b.length);
-    List<ResolutionDartType> types = new List<ResolutionDartType>(prefixLength);
-    for (int index = 0; index < prefixLength; index++) {
-      types[index] = computeLeastUpperBound(a[index], b[index]);
-    }
-    return types;
-  }
-
-  /// Computes the least upper bound of two function types [a] and [b].
-  ///
-  /// If the required parameter count of [a] and [b] does not match, `Function`
-  /// is returned.
-  ///
-  /// Otherwise, a function type is returned whose return type and
-  /// parameter types are the least upper bound of those of [a] and [b],
-  /// respectively. In addition, the optional parameters are the least upper
-  /// bound of the longest common prefix of the optional parameters of [a] and
-  /// [b], and the named parameters are the least upper bound of those common to
-  /// [a] and [b].
-  ResolutionDartType computeLeastUpperBoundFunctionTypes(
-      ResolutionFunctionType a, ResolutionFunctionType b) {
-    if (a.parameterTypes.length != b.parameterTypes.length) {
-      ResolutionInterfaceType functionType = commonElements.functionType;
-      return functionType;
-    }
-    ResolutionDartType returnType =
-        computeLeastUpperBound(a.returnType, b.returnType);
-    List<ResolutionDartType> parameterTypes =
-        computeLeastUpperBoundsTypes(a.parameterTypes, b.parameterTypes);
-    List<ResolutionDartType> optionalParameterTypes =
-        computeLeastUpperBoundsTypes(
-            a.optionalParameterTypes, b.optionalParameterTypes);
-    List<String> namedParameters = <String>[];
-    List<String> aNamedParameters = a.namedParameters;
-    List<String> bNamedParameters = b.namedParameters;
-    List<ResolutionDartType> namedParameterTypes = <ResolutionDartType>[];
-    List<ResolutionDartType> aNamedParameterTypes = a.namedParameterTypes;
-    List<ResolutionDartType> bNamedParameterTypes = b.namedParameterTypes;
-    int aIndex = 0;
-    int bIndex = 0;
-    while (
-        aIndex < aNamedParameters.length && bIndex < bNamedParameters.length) {
-      String aNamedParameter = aNamedParameters[aIndex];
-      String bNamedParameter = bNamedParameters[bIndex];
-      int result = aNamedParameter.compareTo(bNamedParameter);
-      if (result == 0) {
-        namedParameters.add(aNamedParameter);
-        namedParameterTypes.add(computeLeastUpperBound(
-            aNamedParameterTypes[aIndex], bNamedParameterTypes[bIndex]));
-      }
-      if (result <= 0) {
-        aIndex++;
-      }
-      if (result >= 0) {
-        bIndex++;
-      }
-    }
-    return new ResolutionFunctionType.synthesized(returnType, parameterTypes,
-        optionalParameterTypes, namedParameters, namedParameterTypes);
-  }
-
-  /// Computes the least upper bound of two types of which at least one is a
-  /// type variable. The least upper bound of a type variable is defined in
-  /// terms of its bound, but to ensure reflexivity we need to check for common
-  /// bounds transitively.
-  ResolutionDartType computeLeastUpperBoundTypeVariableTypes(
-      ResolutionDartType a, ResolutionDartType b) {
-    Set<ResolutionDartType> typeVariableBounds = new Set<ResolutionDartType>();
-    while (a.isTypeVariable) {
-      if (a == b) return a;
-      typeVariableBounds.add(a);
-      TypeVariableElement element = a.element;
-      a = element.bound;
-    }
-    while (b.isTypeVariable) {
-      if (typeVariableBounds.contains(b)) return b;
-      TypeVariableElement element = b.element;
-      b = element.bound;
-    }
-    return computeLeastUpperBound(a, b);
-  }
-
-  /// Computes the least upper bound for [a] and [b].
-  ResolutionDartType computeLeastUpperBound(
-      ResolutionDartType a, ResolutionDartType b) {
-    if (a == b) return a;
-
-    if (a.isTypeVariable || b.isTypeVariable) {
-      return computeLeastUpperBoundTypeVariableTypes(a, b);
-    }
-
-    a.computeUnaliased(resolution);
-    a = a.unaliased;
-    b.computeUnaliased(resolution);
-    b = b.unaliased;
-
-    if (a.treatAsDynamic || b.treatAsDynamic)
-      return const ResolutionDynamicType();
-    if (a.isVoid || b.isVoid) return const ResolutionVoidType();
-
-    if (a.isFunctionType && b.isFunctionType) {
-      return computeLeastUpperBoundFunctionTypes(a, b);
-    }
-
-    if (a.isFunctionType) {
-      ResolutionInterfaceType functionType = commonElements.functionType;
-      a = functionType;
-    }
-    if (b.isFunctionType) {
-      ResolutionInterfaceType functionType = commonElements.functionType;
-      b = functionType;
-    }
-
-    if (a.isInterfaceType && b.isInterfaceType) {
-      return computeLeastUpperBoundInterfaces(a, b);
-    }
-    return const ResolutionDynamicType();
-  }
-
-  /// Computes the unaliased type of the first non type variable bound of
-  /// [type].
-  ///
-  /// This is used to normalize malformed types, type variables and typedef
-  /// before use in typechecking.
-  ///
-  /// Malformed types are normalized to `dynamic`. Typedefs are normalized to
-  /// their alias, or `dynamic` if cyclic. Type variables are normalized to the
-  /// normalized type of their bound, or `Object` if cyclic.
-  ///
-  /// For instance for these types:
-  ///
-  ///     class Foo<T extends Bar, S extends T, U extends Baz> {}
-  ///     class Bar<X extends Y, Y extends X> {}
-  ///     typedef Baz();
-  ///
-  /// the unaliased bounds types are:
-  ///
-  ///     unaliasedBound(Foo) = Foo
-  ///     unaliasedBound(Bar) = Bar
-  ///     unaliasedBound(Unresolved) = `dynamic`
-  ///     unaliasedBound(Baz) = ()->dynamic
-  ///     unaliasedBound(T) = Bar
-  ///     unaliasedBound(S) = unaliasedBound(T) = Bar
-  ///     unaliasedBound(U) = unaliasedBound(Baz) = ()->dynamic
-  ///     unaliasedBound(X) = unaliasedBound(Y) = `Object`
-  ///
-  static ResolutionDartType computeUnaliasedBound(
-      Resolution resolution, ResolutionDartType type) {
-    ResolutionDartType originalType = type;
-    while (type.isTypeVariable) {
-      ResolutionTypeVariableType variable = type;
-      type = variable.element.bound;
-      if (type == originalType) {
-        ResolutionInterfaceType objectType =
-            resolution.commonElements.objectType;
-        type = objectType;
-      }
-    }
-    if (type.isMalformed) {
-      return const ResolutionDynamicType();
-    }
-    type.computeUnaliased(resolution);
-    return type.unaliased;
-  }
-
-  /// Computes the interface type of [type], which is the type that defines
-  /// the property of [type].
-  ///
-  /// For an interface type it is the type itself, for a type variable it is the
-  /// interface type of the bound, for function types and typedefs it is the
-  /// `Function` type. For other types, like `dynamic`, `void` and malformed
-  /// types, there is no interface type and `null` is returned.
-  ///
-  /// For instance for these types:
-  ///
-  ///     class Foo<T extends Bar, S extends T, U extends Baz> {}
-  ///     class Bar {}
-  ///     typedef Baz();
-  ///
-  /// the interface types are:
-  ///
-  ///     interfaceType(Foo) = Foo
-  ///     interfaceType(Bar) = Bar
-  ///     interfaceType(Baz) = interfaceType(()->dynamic) = Function
-  ///     interfaceType(T) = interfaceType(Bar) = Bar
-  ///     interfaceType(S) = interfaceType(T) = interfaceType(Bar) = Bar
-  ///     interfaceType(U) = interfaceType(Baz)
-  ///                      = intefaceType(()->dynamic) = Function
-  ///
-  /// When typechecking `o.foo` the interface type of the static type of `o` is
-  /// used to lookup the existence and type of `foo`.
-  ///
-  static ResolutionInterfaceType computeInterfaceType(
-      Resolution resolution, ResolutionDartType type) {
-    type = computeUnaliasedBound(resolution, type);
-    if (type.treatAsDynamic) {
-      return null;
-    }
-    if (type.isFunctionType) {
-      ResolutionInterfaceType functionType =
-          resolution.commonElements.functionType;
-      type = functionType;
-    }
-    assert(type.isInterfaceType,
-        failedAt(NO_LOCATION_SPANNABLE, "unexpected type kind ${type.kind}."));
-    return type;
-  }
-}
-
-/// Visitor used to compute an instantiation of a generic type that is more
-/// specific than a given type.
-///
-/// The visitor tries to compute constraints for all type variables in the
-/// visited type by structurally matching it with the argument type. If the
-/// constraints are too complex or the two types are too different, `false`
-/// is returned. Otherwise, the [constraintMap] holds the valid constraints.
-class MoreSpecificSubtypeVisitor
-    extends BaseResolutionDartTypeVisitor<bool, ResolutionDartType> {
-  final Types types;
-  Map<ResolutionTypeVariableType, ResolutionDartType> constraintMap;
-
-  MoreSpecificSubtypeVisitor(this.types);
-
-  /// Compute an instance of [element] which is more specific than [supertype].
-  /// If no instance is found, `null` is returned.
-  ///
-  /// Note that this computation is a heuristic. It does not find a suggestion
-  /// in all possible cases.
-  ResolutionInterfaceType computeMoreSpecific(
-      ClassElement element, ResolutionInterfaceType supertype) {
-    ResolutionInterfaceType supertypeInstance =
-        element.thisType.asInstanceOf(supertype.element);
-    if (supertypeInstance == null) return null;
-
-    constraintMap = new Map<ResolutionTypeVariableType, ResolutionDartType>();
-    element.typeVariables.forEach((ResolutionDartType typeVariable) {
-      constraintMap[typeVariable] = const ResolutionDynamicType();
-    });
-    if (supertypeInstance.accept(this, supertype)) {
-      List<ResolutionDartType> variables = element.typeVariables;
-      List<ResolutionDartType> typeArguments =
-          new List<ResolutionDartType>.generate(
-              variables.length, (int index) => constraintMap[variables[index]]);
-      return element.thisType.createInstantiation(typeArguments);
-    }
-    return null;
-  }
-
-  bool visitType(
-      covariant ResolutionDartType type, ResolutionDartType argument) {
-    return types.isMoreSpecific(type, argument);
-  }
-
-  bool visitTypes(List<ResolutionDartType> a, List<ResolutionDartType> b) {
-    int prefixLength = min(a.length, b.length);
-    for (int index = 0; index < prefixLength; index++) {
-      if (!a[index].accept(this, b[index])) return false;
-    }
-    return prefixLength == a.length && a.length == b.length;
-  }
-
-  bool visitTypeVariableType(
-      covariant ResolutionTypeVariableType type, ResolutionDartType argument) {
-    ResolutionDartType constraint =
-        types.getMostSpecific(constraintMap[type], argument);
-    constraintMap[type] = constraint;
-    return constraint != null;
-  }
-
-  bool visitFunctionType(
-      covariant ResolutionFunctionType type, ResolutionDartType argument) {
-    if (argument is ResolutionFunctionType) {
-      if (type.parameterTypes.length != argument.parameterTypes.length) {
-        return false;
-      }
-      if (type.optionalParameterTypes.length !=
-          argument.optionalParameterTypes.length) {
-        return false;
-      }
-      if (type.namedParameters != argument.namedParameters) {
-        return false;
-      }
-
-      if (!type.returnType.accept(this, argument.returnType)) return false;
-      if (visitTypes(type.parameterTypes, argument.parameterTypes)) {
-        return false;
-      }
-      if (visitTypes(
-          type.optionalParameterTypes, argument.optionalParameterTypes)) {
-        return false;
-      }
-      return visitTypes(type.namedParameterTypes, argument.namedParameterTypes);
-    }
-    return false;
-  }
-
-  bool visitGenericType(GenericType type, ResolutionDartType argument) {
-    if (argument is GenericType) {
-      if (type.element != argument.element) return false;
-      return visitTypes(type.typeArguments, argument.typeArguments);
-    }
-    return false;
-  }
-}
-
-/// Visitor used to print type annotation like they used in the source code.
-/// The visitor is especially for printing a function type like
-/// `(Foo,[Bar])->Baz` as `Baz m(Foo a1, [Bar a2])`.
-class TypeDeclarationFormatter
-    extends BaseResolutionDartTypeVisitor<dynamic, String> {
-  Set<String> usedNames;
-  StringBuffer sb;
-
-  /// Creates textual representation of [type] as if a member by the [name] were
-  /// declared. For instance 'String foo' for `format(String, 'foo')`.
-  String format(ResolutionDartType type, String name) {
-    sb = new StringBuffer();
-    usedNames = new Set<String>();
-    type.accept(this, name);
-    usedNames = null;
-    return sb.toString();
-  }
-
-  String createName(String name) {
-    if (name != null && !usedNames.contains(name)) {
-      usedNames.add(name);
-      return name;
-    }
-    int index = usedNames.length;
-    String proposal;
-    do {
-      proposal = '${name}${index++}';
-    } while (usedNames.contains(proposal));
-    usedNames.add(proposal);
-    return proposal;
-  }
-
-  void visit(covariant ResolutionDartType type, [_]) {
-    type.accept(this, null);
-  }
-
-  void visitTypes(List<ResolutionDartType> types, String prefix) {
-    bool needsComma = false;
-    for (ResolutionDartType type in types) {
-      if (needsComma) {
-        sb.write(', ');
-      }
-      type.accept(this, prefix);
-      needsComma = true;
-    }
-  }
-
-  void visitType(covariant ResolutionDartType type, String name) {
-    if (name == null) {
-      sb.write(type);
-    } else {
-      sb.write('$type ${createName(name)}');
-    }
-  }
-
-  void visitGenericType(GenericType type, String name) {
-    sb.write(type.name);
-    if (!type.treatAsRaw) {
-      sb.write('<');
-      visitTypes(type.typeArguments, null);
-      sb.write('>');
-    }
-    if (name != null) {
-      sb.write(' ');
-      sb.write(createName(name));
-    }
-  }
-
-  void visitFunctionType(covariant ResolutionFunctionType type, String name) {
-    visit(type.returnType);
-    sb.write(' ');
-    if (name != null) {
-      sb.write(name);
-    } else {
-      sb.write(createName('f'));
-    }
-    sb.write('(');
-    visitTypes(type.parameterTypes, 'a');
-    bool needsComma = !type.parameterTypes.isEmpty;
-    if (!type.optionalParameterTypes.isEmpty) {
-      if (needsComma) {
-        sb.write(', ');
-      }
-      sb.write('[');
-      visitTypes(type.optionalParameterTypes, 'a');
-      sb.write(']');
-      needsComma = true;
-    }
-    if (!type.namedParameterTypes.isEmpty) {
-      if (needsComma) {
-        sb.write(', ');
-      }
-      sb.write('{');
-      List<String> namedParameters = type.namedParameters;
-      List<ResolutionDartType> namedParameterTypes = type.namedParameterTypes;
-      needsComma = false;
-      for (int index = 0; index < namedParameters.length; index++) {
-        if (needsComma) {
-          sb.write(', ');
-        }
-        namedParameterTypes[index].accept(this, namedParameters[index]);
-        needsComma = true;
-      }
-      sb.write('}');
-    }
-    sb.write(')');
-  }
-}
diff --git a/pkg/compiler/lib/src/elements/visitor.dart b/pkg/compiler/lib/src/elements/visitor.dart
deleted file mode 100644
index 339dfba..0000000
--- a/pkg/compiler/lib/src/elements/visitor.dart
+++ /dev/null
@@ -1,241 +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.
-
-library visitor;
-
-import '../closure.dart'
-    show BoxFieldElement, ClosureClassElement, ClosureFieldElement;
-import 'elements.dart';
-
-abstract class ElementVisitor<R, A> {
-  const ElementVisitor();
-
-  R visit(covariant Element e, covariant A arg) => e.accept(this, arg);
-
-  R visitErroneousElement(covariant ErroneousElement e, covariant A arg) =>
-      null;
-  R visitWarnOnUseElement(covariant WarnOnUseElement e, covariant A arg) =>
-      null;
-  R visitAmbiguousElement(covariant AmbiguousElement e, covariant A arg) =>
-      null;
-  R visitCompilationUnitElement(
-          covariant CompilationUnitElement e, covariant A arg) =>
-      null;
-  R visitLibraryElement(covariant LibraryElement e, covariant A arg) => null;
-  R visitImportElement(covariant ImportElement e, covariant A arg) => null;
-  R visitExportElement(covariant ExportElement e, covariant A arg) => null;
-  R visitPrefixElement(covariant PrefixElement e, covariant A arg) => null;
-  R visitTypedefElement(covariant TypedefElement e, covariant A arg) => null;
-  R visitLocalVariableElement(
-          covariant LocalVariableElement e, covariant A arg) =>
-      null;
-  R visitParameterElement(covariant ParameterElement e, covariant A arg) =>
-      null;
-  R visitFormalElement(covariant FormalElement e, covariant A arg) => null;
-  R visitFieldElement(covariant FieldElement e, covariant A arg) => null;
-  R visitFieldParameterElement(
-          covariant InitializingFormalElement e, covariant A arg) =>
-      null;
-  R visitAbstractFieldElement(
-          covariant AbstractFieldElement e, covariant A arg) =>
-      null;
-  R visitMethodElement(covariant MethodElement e, covariant A arg) => null;
-  R visitGetterElement(covariant GetterElement e, covariant A arg) => null;
-  R visitSetterElement(covariant SetterElement e, covariant A arg) => null;
-  R visitLocalFunctionElement(
-          covariant LocalFunctionElement e, covariant A arg) =>
-      null;
-  R visitConstructorElement(covariant ConstructorElement e, covariant A arg) =>
-      null;
-  R visitConstructorBodyElement(
-          covariant ConstructorBodyElement e, covariant A arg) =>
-      null;
-  R visitClassElement(covariant ClassElement e, covariant A arg) => null;
-  R visitMixinApplicationElement(
-          covariant MixinApplicationElement e, covariant A arg) =>
-      null;
-  R visitEnumClassElement(covariant EnumClassElement e, covariant A arg) =>
-      null;
-  R visitTypeVariableElement(
-          covariant TypeVariableElement e, covariant A arg) =>
-      null;
-  R visitBoxFieldElement(covariant BoxFieldElement e, covariant A arg) => null;
-  R visitClosureClassElement(
-          covariant ClosureClassElement e, covariant A arg) =>
-      null;
-  R visitClosureFieldElement(
-          covariant ClosureFieldElement e, covariant A arg) =>
-      null;
-}
-
-abstract class BaseElementVisitor<R, A> extends ElementVisitor<R, A> {
-  const BaseElementVisitor();
-
-  R visitElement(covariant Element e, covariant A arg);
-
-  @override
-  R visitErroneousElement(covariant ErroneousElement e, covariant A arg) {
-    return visitElement(e, arg);
-  }
-
-  @override
-  R visitWarnOnUseElement(covariant WarnOnUseElement e, covariant A arg) {
-    return visitElement(e, arg);
-  }
-
-  @override
-  R visitAmbiguousElement(covariant AmbiguousElement e, covariant A arg) {
-    return visitElement(e, arg);
-  }
-
-  R visitScopeContainerElement(
-      covariant ScopeContainerElement e, covariant A arg) {
-    return visitElement(e, arg);
-  }
-
-  @override
-  R visitCompilationUnitElement(
-      covariant CompilationUnitElement e, covariant A arg) {
-    return visitElement(e, arg);
-  }
-
-  @override
-  R visitLibraryElement(covariant LibraryElement e, covariant A arg) {
-    return visitScopeContainerElement(e, arg);
-  }
-
-  @override
-  R visitImportElement(covariant ImportElement e, covariant A arg) {
-    return visitElement(e, arg);
-  }
-
-  @override
-  R visitExportElement(covariant ExportElement e, covariant A arg) {
-    return visitElement(e, arg);
-  }
-
-  @override
-  R visitPrefixElement(covariant PrefixElement e, covariant A arg) {
-    return visitElement(e, arg);
-  }
-
-  @override
-  R visitTypedefElement(covariant TypedefElement e, covariant A arg) {
-    return visitElement(e, arg);
-  }
-
-  R visitVariableElement(covariant VariableElement e, covariant A arg) {
-    return visitElement(e, arg);
-  }
-
-  @override
-  R visitLocalVariableElement(
-      covariant LocalVariableElement e, covariant A arg) {
-    return visitVariableElement(e, arg);
-  }
-
-  @override
-  R visitParameterElement(covariant ParameterElement e, covariant A arg) {
-    return visitVariableElement(e, arg);
-  }
-
-  @override
-  R visitFormalElement(covariant FormalElement e, covariant A arg) {
-    return visitElement(e, arg);
-  }
-
-  @override
-  R visitFieldElement(covariant FieldElement e, covariant A arg) {
-    return visitVariableElement(e, arg);
-  }
-
-  @override
-  R visitFieldParameterElement(
-      covariant InitializingFormalElement e, covariant A arg) {
-    return visitParameterElement(e, arg);
-  }
-
-  @override
-  R visitAbstractFieldElement(
-      covariant AbstractFieldElement e, covariant A arg) {
-    return visitElement(e, arg);
-  }
-
-  R visitFunctionElement(covariant FunctionElement e, covariant A arg) {
-    return visitElement(e, arg);
-  }
-
-  @override
-  R visitMethodElement(covariant MethodElement e, covariant A arg) {
-    return visitFunctionElement(e, arg);
-  }
-
-  @override
-  R visitGetterElement(covariant GetterElement e, covariant A arg) {
-    return visitFunctionElement(e, arg);
-  }
-
-  @override
-  R visitSetterElement(covariant SetterElement e, covariant A arg) {
-    return visitFunctionElement(e, arg);
-  }
-
-  @override
-  R visitLocalFunctionElement(
-      covariant LocalFunctionElement e, covariant A arg) {
-    return visitFunctionElement(e, arg);
-  }
-
-  @override
-  R visitConstructorElement(covariant ConstructorElement e, covariant A arg) {
-    return visitFunctionElement(e, arg);
-  }
-
-  @override
-  R visitConstructorBodyElement(
-      covariant ConstructorBodyElement e, covariant A arg) {
-    return visitElement(e, arg);
-  }
-
-  @override
-  R visitClassElement(covariant ClassElement e, covariant A arg) {
-    return visitScopeContainerElement(e, arg);
-  }
-
-  R visitTypeDeclarationElement(
-      covariant TypeDeclarationElement e, covariant A arg) {
-    return visitElement(e, arg);
-  }
-
-  @override
-  R visitMixinApplicationElement(
-      covariant MixinApplicationElement e, covariant A arg) {
-    return visitClassElement(e, arg);
-  }
-
-  @override
-  R visitEnumClassElement(covariant EnumClassElement e, covariant A arg) {
-    return visitClassElement(e, arg);
-  }
-
-  @override
-  R visitTypeVariableElement(covariant TypeVariableElement e, covariant A arg) {
-    return visitElement(e, arg);
-  }
-
-  @override
-  R visitBoxFieldElement(covariant BoxFieldElement e, covariant A arg) {
-    return visitElement(e, arg);
-  }
-
-  @override
-  R visitClosureClassElement(covariant ClosureClassElement e, covariant A arg) {
-    return visitClassElement(e, arg);
-  }
-
-  @override
-  R visitClosureFieldElement(covariant ClosureFieldElement e, covariant A arg) {
-    return visitVariableElement(e, arg);
-  }
-}
diff --git a/pkg/compiler/lib/src/frontend_strategy.dart b/pkg/compiler/lib/src/frontend_strategy.dart
index b6943cb..8f915bf 100644
--- a/pkg/compiler/lib/src/frontend_strategy.dart
+++ b/pkg/compiler/lib/src/frontend_strategy.dart
@@ -14,20 +14,14 @@
 import 'elements/entities.dart';
 import 'elements/types.dart';
 import 'enqueue.dart';
-import 'environment.dart';
-import 'js_backend/backend.dart';
 import 'js_backend/backend_usage.dart';
 import 'js_backend/interceptor_data.dart';
-import 'js_backend/mirrors_analysis.dart';
-import 'js_backend/mirrors_data.dart';
 import 'js_backend/native_data.dart';
 import 'js_backend/no_such_method_registry.dart';
 import 'js_backend/runtime_types.dart';
 import 'library_loader.dart';
 import 'native/enqueue.dart' show NativeResolutionEnqueuer;
 import 'native/resolver.dart';
-import 'patch_parser.dart';
-import 'resolved_uri_translator.dart';
 import 'universe/class_hierarchy_builder.dart';
 import 'universe/world_builder.dart';
 import 'universe/world_impact.dart';
@@ -36,16 +30,8 @@
 /// the resolved element model.
 abstract class FrontendStrategy {
   /// Creates library loader task for this strategy.
-  LibraryLoaderTask createLibraryLoader(
-      ResolvedUriTranslator uriTranslator,
-      ScriptLoader scriptLoader,
-      api.CompilerInput compilerInput,
-      ElementScanner scriptScanner,
-      PatchResolverFunction patchResolverFunc,
-      PatchParserTask patchParser,
-      Environment environment,
-      DiagnosticReporter reporter,
-      Measurer measurer);
+  LibraryLoaderTask createLibraryLoader(api.CompilerInput compilerInput,
+      DiagnosticReporter reporter, Measurer measurer);
 
   /// Returns the [ElementEnvironment] for the element model used in this
   /// strategy.
@@ -103,16 +89,6 @@
   FunctionEntity computeMain(
       LibraryEntity mainLibrary, WorldImpactBuilder impactBuilder);
 
-  // TODO(johnniwinther): Reuse the following classes between strategies:
-
-  /// Creates the [MirrorsDataBuilder] for this strategy.
-  MirrorsDataBuilder createMirrorsDataBuilder();
-
-  /// Creates the [MirrorsResolutionAnalysis] for this strategy.
-  // TODO(johnniwinther): Avoid passing [JavaScriptBackend].
-  MirrorsResolutionAnalysis createMirrorsResolutionAnalysis(
-      JavaScriptBackend backend);
-
   /// Creates the [RuntimeTypesNeedBuilder] for this strategy.
   RuntimeTypesNeedBuilder createRuntimeTypesNeedBuilder();
 
@@ -153,7 +129,7 @@
 /// Class that deletes the contents of an [WorldImpact] cache.
 // TODO(redemption): this can be deleted when we sunset the old front end.
 abstract class ImpactCacheDeleter {
-  bool retainCachesForTesting;
+  static bool retainCachesForTesting = false;
 
   /// Removes the [WorldImpact] for [element] from the resolution cache. Later
   /// calls to [getWorldImpact] or [computeWorldImpact] returns an empty impact.
diff --git a/pkg/compiler/lib/src/id_generator.dart b/pkg/compiler/lib/src/id_generator.dart
deleted file mode 100644
index 9107c7a..0000000
--- a/pkg/compiler/lib/src/id_generator.dart
+++ /dev/null
@@ -1,13 +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.
-
-/// A generator of globally unique identifiers.
-class IdGenerator {
-  int _nextFreeId = 0;
-
-  /// Returns the next free identifier.
-  ///
-  /// This identifier is guaranteed to be unique.
-  int getNextFreeId() => _nextFreeId++;
-}
diff --git a/pkg/compiler/lib/src/inferrer/ast_inferrer_engine.dart b/pkg/compiler/lib/src/inferrer/ast_inferrer_engine.dart
deleted file mode 100644
index acea941..0000000
--- a/pkg/compiler/lib/src/inferrer/ast_inferrer_engine.dart
+++ /dev/null
@@ -1,224 +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 '../common.dart';
-import '../common/names.dart';
-import '../compiler.dart';
-import '../constants/expressions.dart';
-import '../constants/values.dart';
-import '../elements/elements.dart';
-import '../elements/entities.dart';
-import '../resolution/tree_elements.dart';
-import '../tree/nodes.dart' as ast;
-import '../types/types.dart';
-import '../world.dart';
-import 'builder.dart';
-import 'inferrer_engine.dart';
-import 'type_graph_nodes.dart';
-import 'type_system.dart';
-
-class AstInferrerEngine extends InferrerEngineImpl<ast.Node> {
-  final Compiler compiler;
-
-  AstInferrerEngine(this.compiler, ClosedWorld closedWorld,
-      ClosedWorldRefiner closedWorldRefiner, FunctionEntity mainElement)
-      : super(
-            compiler.options,
-            compiler.progress,
-            compiler.reporter,
-            compiler.outputProvider,
-            closedWorld,
-            closedWorldRefiner,
-            compiler.backend.mirrorsData,
-            compiler.backend.noSuchMethodRegistry,
-            mainElement,
-            compiler.backendStrategy.sorter,
-            const TypeSystemStrategyImpl());
-
-  GlobalTypeInferenceElementData<ast.Node> createElementData() =>
-      new AstGlobalTypeInferenceElementData();
-
-  int computeMemberSize(MemberEntity member) => resolveAstApproxSize(member);
-
-  ast.Node computeMemberBody(covariant MemberElement member) {
-    ResolvedAst resolvedAst = member.resolvedAst;
-    ast.Node body;
-    if (resolvedAst.kind == ResolvedAstKind.PARSED) {
-      body = resolvedAst.body;
-      if (member.isField &&
-          member.isInstanceMember &&
-          !member.isFinal &&
-          body is ast.LiteralNull) {
-        return null;
-      }
-    }
-    return body;
-  }
-
-  FunctionEntity lookupCallMethod(covariant ClassElement cls) {
-    MethodElement callMethod = cls.lookupMember(Identifiers.call);
-    if (callMethod == null || callMethod.isAbstract) {
-      callMethod = cls.lookupMember(Identifiers.noSuchMethod_);
-    }
-    return callMethod;
-  }
-
-  TypeInformation computeMemberTypeInformation(
-      MemberEntity member, ast.Node body) {
-    ElementGraphBuilder visitor =
-        new ElementGraphBuilder(member, compiler, this);
-    return visitor.run();
-  }
-
-  bool isFieldInitializerPotentiallyNull(
-      FieldEntity field, ast.Node initializer) {
-    dynamic argument = initializer;
-    // TODO(13429): We could do better here by using the
-    // constant handler to figure out if it's a lazy field or not.
-    return argument.asSend() != null ||
-        (argument.asNewExpression() != null && !argument.isConst);
-  }
-
-  ConstantValue getFieldConstant(covariant FieldElement field) {
-    ConstantExpression constant = field.constant;
-    if (constant != null) {
-      ConstantValue value =
-          compiler.backend.constants.getConstantValue(constant);
-      if (value == null) {
-        assert(
-            field.isInstanceMember ||
-                constant.isImplicit ||
-                constant.isPotential,
-            failedAt(
-                field,
-                "Constant expression without value: "
-                "${constant.toStructuredText()}."));
-      }
-      return value;
-    }
-    return null;
-  }
-
-  @override
-  bool hasCallType(covariant ClassElement cls) {
-    return cls.callType != null;
-  }
-
-  /// Computes a 'size' of [_element] based on the number of selectors in the
-  /// associated [TreeElements]. This is used for sorting member for the type
-  /// inference work-queue.
-  // TODO(johnniwinther): This is brittle and cannot be translated in the
-  // kernel based inference. Find a more stable a reproducable size measure.
-  static int resolveAstApproxSize(_element) {
-    MemberElement element = _element;
-    ResolvedAst resolvedAst = element.resolvedAst;
-    element = element.implementation;
-    if (resolvedAst.kind == ResolvedAstKind.PARSED) {
-      TreeElementMapping mapping = resolvedAst.elements;
-      return mapping.getSelectorCount();
-    }
-    return 0;
-  }
-}
-
-class TypeSystemStrategyImpl implements TypeSystemStrategy<ast.Node> {
-  const TypeSystemStrategyImpl();
-
-  @override
-  MemberTypeInformation createMemberTypeInformation(
-      covariant MemberElement member) {
-    assert(member.isDeclaration, failedAt(member));
-    if (member.isField) {
-      FieldElement field = member;
-      return new FieldTypeInformation(field, field.type);
-    } else if (member.isGetter) {
-      GetterElement getter = member;
-      return new GetterTypeInformation(getter, getter.type);
-    } else if (member.isSetter) {
-      SetterElement setter = member;
-      return new SetterTypeInformation(setter);
-    } else if (member.isFunction) {
-      MethodElement method = member;
-      return new MethodTypeInformation(method, method.type);
-    } else {
-      ConstructorElement constructor = member;
-      if (constructor.isFactoryConstructor) {
-        return new FactoryConstructorTypeInformation(
-            constructor, constructor.type);
-      } else {
-        return new GenerativeConstructorTypeInformation(constructor);
-      }
-    }
-  }
-
-  @override
-  ParameterTypeInformation createParameterTypeInformation(
-      covariant ParameterElement parameter, TypeSystem<ast.Node> types) {
-    assert(parameter.isImplementation, failedAt(parameter));
-    FunctionTypedElement function = parameter.functionDeclaration.declaration;
-    if (function.isLocal) {
-      LocalFunctionElement localFunction = function;
-      MethodElement callMethod = localFunction.callMethod;
-      return new ParameterTypeInformation.localFunction(
-          types.getInferredTypeOfMember(callMethod),
-          parameter,
-          parameter.type,
-          callMethod);
-    } else if (function.isInstanceMember) {
-      MethodElement method = function;
-      return new ParameterTypeInformation.instanceMember(
-          types.getInferredTypeOfMember(method),
-          parameter,
-          parameter.type,
-          method,
-          new ParameterAssignments());
-    } else {
-      MethodElement method = function;
-      return new ParameterTypeInformation.static(
-          types.getInferredTypeOfMember(method),
-          parameter,
-          parameter.type,
-          method,
-          // TODO(johnniwinther): Is this still valid now that initializing
-          // formals also introduce locals?
-          isInitializingFormal: parameter.isInitializingFormal);
-    }
-  }
-
-  @override
-  void forEachParameter(
-      covariant MethodElement function, void f(Local parameter)) {
-    MethodElement impl = function.implementation;
-    FunctionSignature signature = impl.functionSignature;
-    signature.forEachParameter((FormalElement _parameter) {
-      ParameterElement parameter = _parameter;
-      f(parameter);
-    });
-  }
-
-  @override
-  bool checkMapNode(ast.Node node) {
-    return node is ast.LiteralMap;
-  }
-
-  @override
-  bool checkListNode(ast.Node node) {
-    return node is ast.LiteralList || node is ast.Send;
-  }
-
-  @override
-  bool checkLoopPhiNode(ast.Node node) {
-    return node is ast.Loop || node is ast.SwitchStatement;
-  }
-
-  @override
-  bool checkPhiNode(ast.Node node) {
-    return true;
-  }
-
-  @override
-  bool checkClassEntity(covariant ClassElement cls) {
-    return cls.isDeclaration;
-  }
-}
diff --git a/pkg/compiler/lib/src/inferrer/builder.dart b/pkg/compiler/lib/src/inferrer/builder.dart
deleted file mode 100644
index bf8b69d..0000000
--- a/pkg/compiler/lib/src/inferrer/builder.dart
+++ /dev/null
@@ -1,3021 +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.
-
-library simple_types_inferrer;
-
-import '../closure.dart' show ClosureRepresentationInfo, ScopeInfo;
-import '../common.dart';
-import '../common/names.dart' show Identifiers, Selectors;
-import '../compiler.dart' show Compiler;
-import '../constants/constant_system.dart';
-import '../constants/expressions.dart';
-import '../constants/values.dart' show ConstantValue, IntConstantValue;
-import '../elements/elements.dart';
-import '../elements/entities.dart';
-import '../elements/jumps.dart';
-import '../elements/names.dart';
-import '../elements/operators.dart' as op;
-import '../elements/resolution_types.dart'
-    show ResolutionDartType, ResolutionInterfaceType;
-import '../js_backend/backend.dart' show JavaScriptBackend;
-import '../native/native.dart' as native;
-import '../resolution/semantic_visitor.dart';
-import '../resolution/tree_elements.dart' show TreeElements;
-import '../tree/tree.dart' as ast;
-import '../types/constants.dart' show computeTypeMask;
-import '../types/types.dart' show TypeMask, GlobalTypeInferenceElementData;
-import '../universe/call_structure.dart' show CallStructure;
-import '../universe/selector.dart' show Selector;
-import '../universe/side_effects.dart' show SideEffectsBuilder;
-import '../util/util.dart' show Link, Setlet;
-import '../world.dart' show ClosedWorld;
-import 'inferrer_engine.dart';
-import 'locals_handler.dart';
-import 'type_graph_nodes.dart';
-import 'type_system.dart';
-
-/// [ElementGraphBuilder] can be thought of as a type-inference graph
-/// builder for a single element.
-///
-/// Calling [run] will start the work of visiting the body of the code to
-/// construct a set of infernece-nodes that abstractly represent what the code
-/// is doing.
-///
-/// This visitor is parameterized by an [InferenceEngine], which internally
-/// decides how to represent inference nodes.
-class ElementGraphBuilder extends ast.Visitor<TypeInformation>
-    with
-        SemanticSendResolvedMixin<TypeInformation, dynamic>,
-        CompoundBulkMixin<TypeInformation, dynamic>,
-        SetIfNullBulkMixin<TypeInformation, dynamic>,
-        PrefixBulkMixin<TypeInformation, dynamic>,
-        PostfixBulkMixin<TypeInformation, dynamic>,
-        ErrorBulkMixin<TypeInformation, dynamic>,
-        NewBulkMixin<TypeInformation, dynamic>,
-        SetBulkMixin<TypeInformation, dynamic>
-    implements SemanticSendVisitor<TypeInformation, dynamic> {
-  final Compiler compiler;
-  final MemberElement analyzedElement;
-  final ResolvedAst resolvedAst;
-  final TypeSystem<ast.Node> types;
-  final Map<JumpTarget, List<LocalsHandler>> breaksFor =
-      new Map<JumpTarget, List<LocalsHandler>>();
-  final Map<JumpTarget, List<LocalsHandler>> continuesFor =
-      new Map<JumpTarget, List<LocalsHandler>>();
-  LocalsHandler<ast.Node> locals;
-  final List<TypeInformation> cascadeReceiverStack =
-      new List<TypeInformation>();
-
-  TypeInformation returnType;
-  bool visitingInitializers = false;
-  bool isConstructorRedirect = false;
-  bool seenSuperConstructorCall = false;
-  final SideEffectsBuilder sideEffectsBuilder;
-  final MemberElement outermostElement;
-  final InferrerEngine inferrer;
-  final Setlet<Entity> capturedVariables = new Setlet<Entity>();
-  final GlobalTypeInferenceElementData memberData;
-
-  ElementGraphBuilder.internal(
-      MemberElement analyzedElement,
-      this.resolvedAst,
-      this.outermostElement,
-      InferrerEngine inferrer,
-      this.compiler,
-      this.locals)
-      : this.analyzedElement = analyzedElement,
-        this.inferrer = inferrer,
-        this.types = inferrer.types,
-        this.memberData = inferrer.dataOfMember(analyzedElement.memberContext),
-        this.sideEffectsBuilder = analyzedElement is MethodElement
-            ? inferrer.closedWorldRefiner.getSideEffectsBuilder(analyzedElement)
-            : new SideEffectsBuilder.free(analyzedElement) {
-    assert(analyzedElement.isDeclaration);
-    assert(outermostElement != null);
-    assert(outermostElement.isDeclaration);
-    if (locals != null) return;
-    ast.Node node;
-    if (resolvedAst.kind == ResolvedAstKind.PARSED) {
-      node = resolvedAst.node;
-    }
-    FieldInitializationScope<ast.Node> fieldScope =
-        analyzedElement.isGenerativeConstructor
-            ? new FieldInitializationScope<ast.Node>(types)
-            : null;
-    locals = new LocalsHandler<ast.Node>(
-        inferrer, types, compiler.options, node, fieldScope);
-  }
-
-  ElementGraphBuilder(
-      MemberElement element, Compiler compiler, InferrerEngine inferrer,
-      [LocalsHandler handler])
-      : this.internal(element, element.resolvedAst,
-            element.memberContext.declaration, inferrer, compiler, handler);
-
-  TreeElements get elements => resolvedAst.elements;
-
-  bool accumulateIsChecks = false;
-  bool conditionIsSimple = false;
-  List<ast.Send> isChecks;
-  int loopLevel = 0;
-
-  bool get inLoop => loopLevel > 0;
-  bool get isThisExposed {
-    return analyzedElement.isGenerativeConstructor
-        ? locals.fieldScope.isThisExposed
-        : true;
-  }
-
-  void set isThisExposed(value) {
-    if (analyzedElement.isGenerativeConstructor) {
-      locals.fieldScope.isThisExposed = value;
-    }
-  }
-
-  void initializationIsIndefinite() {
-    if (analyzedElement.isGenerativeConstructor) {
-      locals.fieldScope.isIndefinite = true;
-    }
-  }
-
-  DiagnosticReporter get reporter => compiler.reporter;
-
-  ClosedWorld get closedWorld => inferrer.closedWorld;
-
-  @override
-  SemanticSendVisitor<TypeInformation, dynamic> get sendVisitor => this;
-
-  @override
-  TypeInformation apply(ast.Node node, _) => visit(node);
-
-  TypeInformation visitAssert(ast.Assert node) {
-    // Avoid pollution from assert statement unless enabled.
-    if (!compiler.options.enableUserAssertions) {
-      return null;
-    }
-    List<ast.Send> tests = <ast.Send>[];
-    bool simpleCondition = handleCondition(node.condition, tests);
-    LocalsHandler saved = locals;
-    locals = new LocalsHandler.from(locals, node);
-    updateIsChecks(tests, usePositive: true);
-
-    LocalsHandler thenLocals = locals;
-    locals = new LocalsHandler.from(saved, node);
-    if (simpleCondition) updateIsChecks(tests, usePositive: false);
-    visit(node.message);
-    locals.seenReturnOrThrow = true;
-    saved.mergeDiamondFlow(thenLocals, locals);
-    locals = saved;
-    return null;
-  }
-
-  @override
-  TypeInformation bulkHandleSet(ast.SendSet node, _) {
-    return handleSendSet(node);
-  }
-
-  @override
-  TypeInformation bulkHandleCompound(ast.SendSet node, _) {
-    return handleSendSet(node);
-  }
-
-  @override
-  TypeInformation bulkHandleSetIfNull(ast.SendSet node, _) {
-    return handleSendSet(node);
-  }
-
-  @override
-  TypeInformation bulkHandlePrefix(ast.SendSet node, _) {
-    return handleSendSet(node);
-  }
-
-  @override
-  TypeInformation bulkHandlePostfix(ast.SendSet node, _) {
-    return handleSendSet(node);
-  }
-
-  @override
-  TypeInformation bulkHandleError(ast.Node node, ErroneousElement error, _) {
-    return types.dynamicType;
-  }
-
-  TypeInformation visitNode(ast.Node node) {
-    return node.visitChildren(this);
-  }
-
-  TypeInformation visit(ast.Node node) {
-    return node == null ? null : node.accept(this);
-  }
-
-  TypeInformation visitLiteralString(ast.LiteralString node) {
-    return types.stringLiteralType(node.dartString.slowToString());
-  }
-
-  TypeInformation visitStringJuxtaposition(ast.StringJuxtaposition node) {
-    node.visitChildren(this);
-    return types.stringType;
-  }
-
-  TypeInformation visitLiteralBool(ast.LiteralBool node) {
-    return types.boolLiteralType(node.value);
-  }
-
-  TypeInformation visitLiteralDouble(ast.LiteralDouble node) {
-    ConstantSystem constantSystem = closedWorld.constantSystem;
-    // The JavaScript backend may turn this literal into an integer at
-    // runtime.
-    return types.getConcreteTypeFor(
-        computeTypeMask(closedWorld, constantSystem.createDouble(node.value)));
-  }
-
-  TypeInformation visitLiteralInt(ast.LiteralInt node) {
-    ConstantSystem constantSystem = closedWorld.constantSystem;
-    // The JavaScript backend may turn this literal into a double at
-    // runtime.
-    return types.getConcreteTypeFor(
-        computeTypeMask(closedWorld, constantSystem.createInt(node.value)));
-  }
-
-  TypeInformation visitLiteralNull(ast.LiteralNull node) {
-    return types.nullType;
-  }
-
-  TypeInformation visitLiteralSymbol(ast.LiteralSymbol node) {
-    return types
-        .nonNullSubtype(closedWorld.commonElements.symbolImplementationClass);
-  }
-
-  @override
-  void previsitDeferredAccess(ast.Send node, PrefixElement prefix, _) {
-    // Deferred access does not affect inference.
-  }
-
-  TypeInformation handleTypeLiteralGet() {
-    return types.typeType;
-  }
-
-  @override
-  TypeInformation bulkHandleNode(ast.Node node, String message, _) {
-    return internalError(node, message.replaceAll('#', '$node'));
-  }
-
-  @override
-  TypeInformation visitConstantGet(
-      ast.Send node, ConstantExpression constant, _) {
-    return bulkHandleNode(node, "Constant read `#` unhandled.", _);
-  }
-
-  @override
-  TypeInformation visitConstantInvoke(
-      ast.Send node,
-      ConstantExpression constant,
-      ast.NodeList arguments,
-      CallStructure callStructure,
-      _) {
-    return bulkHandleNode(node, "Constant invoke `#` unhandled.", _);
-  }
-
-  TypeInformation visitClassTypeLiteralGet(
-      ast.Send node, ConstantExpression constant, _) {
-    return handleTypeLiteralGet();
-  }
-
-  TypeInformation visitClassTypeLiteralInvoke(
-      ast.Send node,
-      ConstantExpression constant,
-      ast.NodeList arguments,
-      CallStructure callStructure,
-      _) {
-    return handleTypeLiteralInvoke(arguments);
-  }
-
-  TypeInformation visitTypedefTypeLiteralGet(
-      ast.Send node, ConstantExpression constant, _) {
-    return handleTypeLiteralGet();
-  }
-
-  TypeInformation visitTypedefTypeLiteralInvoke(
-      ast.Send node,
-      ConstantExpression constant,
-      ast.NodeList arguments,
-      CallStructure callStructure,
-      _) {
-    return handleTypeLiteralInvoke(arguments);
-  }
-
-  TypeInformation visitTypeVariableTypeLiteralGet(
-      ast.Send node, TypeVariableElement element, _) {
-    return handleTypeLiteralGet();
-  }
-
-  TypeInformation visitTypeVariableTypeLiteralInvoke(
-      ast.Send node,
-      TypeVariableElement element,
-      ast.NodeList arguments,
-      CallStructure callStructure,
-      _) {
-    return handleTypeLiteralInvoke(arguments);
-  }
-
-  TypeInformation visitDynamicTypeLiteralGet(
-      ast.Send node, ConstantExpression constant, _) {
-    return handleTypeLiteralGet();
-  }
-
-  TypeInformation visitDynamicTypeLiteralInvoke(
-      ast.Send node,
-      ConstantExpression constant,
-      ast.NodeList arguments,
-      CallStructure callStructure,
-      _) {
-    return handleTypeLiteralInvoke(arguments);
-  }
-
-  TypeInformation _thisType;
-  TypeInformation get thisType {
-    if (_thisType != null) return _thisType;
-    ClassElement cls = outermostElement.enclosingClass;
-    if (closedWorld.isUsedAsMixin(cls)) {
-      return _thisType = types.nonNullSubtype(cls);
-    } else {
-      return _thisType = types.nonNullSubclass(cls);
-    }
-  }
-
-  @override
-  TypeInformation visitThisGet(ast.Identifier node, _) {
-    return thisType;
-  }
-
-  TypeInformation visitIdentifier(ast.Identifier node) {
-    if (node.isThis()) {
-      return thisType;
-    } else if (node.isSuper()) {
-      return internalError(node, 'Unexpected expression $node.');
-    } else {
-      Element element = elements[node];
-      if (Elements.isLocal(element)) {
-        LocalElement local = element;
-        return locals.use(local);
-      }
-      return null;
-    }
-  }
-
-  void potentiallyAddIsCheck(ast.Send node) {
-    if (!accumulateIsChecks) return;
-    if (!Elements.isLocal(elements[node.receiver])) return;
-    isChecks.add(node);
-  }
-
-  void potentiallyAddNullCheck(ast.Send node, ast.Node receiver) {
-    if (!accumulateIsChecks) return;
-    if (!Elements.isLocal(elements[receiver])) return;
-    isChecks.add(node);
-  }
-
-  void updateIsChecks(List<ast.Node> tests, {bool usePositive}) {
-    if (tests == null) return;
-    for (ast.Send node in tests) {
-      if (node.isTypeTest) {
-        if (node.isIsNotCheck) {
-          if (usePositive) continue;
-        } else {
-          if (!usePositive) continue;
-        }
-        ResolutionDartType type =
-            elements.getType(node.typeAnnotationFromIsCheckOrCast);
-        Element element = elements[node.receiver];
-        if (Elements.isLocal(element)) {
-          LocalElement local = element;
-          locals.narrow(local, type, node);
-        }
-      } else {
-        Element receiverElement = elements[node.receiver];
-        Element argumentElement = elements[node.arguments.first];
-        String operator = node.selector.asOperator().source;
-        if ((operator == '==' && usePositive) ||
-            (operator == '!=' && !usePositive)) {
-          // Type the elements as null.
-          if (Elements.isLocal(receiverElement)) {
-            LocalElement local = receiverElement;
-            locals.update(local, types.nullType, node, local.type);
-          }
-          if (Elements.isLocal(argumentElement)) {
-            LocalElement local = argumentElement;
-            locals.update(local, types.nullType, node, local.type);
-          }
-        } else {
-          // Narrow the elements to a non-null type.
-          ResolutionInterfaceType objectType =
-              closedWorld.commonElements.objectType;
-          if (Elements.isLocal(receiverElement)) {
-            LocalElement local = receiverElement;
-            locals.narrow(local, objectType, node);
-          }
-          if (Elements.isLocal(argumentElement)) {
-            LocalElement local = argumentElement;
-            locals.narrow(local, objectType, node);
-          }
-        }
-      }
-    }
-  }
-
-  @override
-  TypeInformation visitIndex(
-      ast.Send node, ast.Node receiver, ast.Node index, _) {
-    return handleDynamicInvoke(node);
-  }
-
-  @override
-  TypeInformation visitDynamicPropertyInvoke(ast.Send node, ast.Node receiver,
-      ast.NodeList arguments, Selector selector, _) {
-    return handleDynamicInvoke(node);
-  }
-
-  @override
-  TypeInformation visitIfNotNullDynamicPropertyInvoke(ast.Send node,
-      ast.Node receiver, ast.NodeList arguments, Selector selector, _) {
-    return handleDynamicInvoke(node);
-  }
-
-  @override
-  TypeInformation visitThisPropertyInvoke(
-      ast.Send node, ast.NodeList arguments, Selector selector, _) {
-    return handleDynamicInvoke(node);
-  }
-
-  @override
-  TypeInformation visitIfNull(ast.Send node, ast.Node left, ast.Node right, _) {
-    TypeInformation firstType = visit(left);
-    TypeInformation secondType = visit(right);
-    return types.allocateDiamondPhi(types.narrowNotNull(firstType), secondType);
-  }
-
-  @override
-  TypeInformation visitLogicalAnd(
-      ast.Send node, ast.Node left, ast.Node right, _) {
-    conditionIsSimple = false;
-    bool oldAccumulateIsChecks = accumulateIsChecks;
-    List<ast.Send> oldIsChecks = isChecks;
-    if (!accumulateIsChecks) {
-      accumulateIsChecks = true;
-      isChecks = <ast.Send>[];
-    }
-    visit(left);
-    LocalsHandler saved = locals;
-    locals = new LocalsHandler.from(locals, node);
-    updateIsChecks(isChecks, usePositive: true);
-    LocalsHandler narrowed;
-    if (oldAccumulateIsChecks) {
-      narrowed = new LocalsHandler.topLevelCopyOf(locals);
-    } else {
-      accumulateIsChecks = false;
-      isChecks = oldIsChecks;
-    }
-    visit(right);
-    if (oldAccumulateIsChecks) {
-      bool invalidatedInRightHandSide(ast.Send test) {
-        Element receiver = elements[test.receiver];
-        if (receiver is LocalElement) {
-          return narrowed.locals[receiver] != locals.locals[receiver];
-        }
-        return false;
-      }
-
-      isChecks.removeWhere(invalidatedInRightHandSide);
-    }
-    saved.mergeDiamondFlow(locals, null);
-    locals = saved;
-    return types.boolType;
-  }
-
-  @override
-  TypeInformation visitLogicalOr(
-      ast.Send node, ast.Node left, ast.Node right, _) {
-    conditionIsSimple = false;
-    List<ast.Send> tests = <ast.Send>[];
-    bool isSimple = handleCondition(left, tests);
-    LocalsHandler saved = locals;
-    locals = new LocalsHandler.from(locals, node);
-    if (isSimple) updateIsChecks(tests, usePositive: false);
-    bool oldAccumulateIsChecks = accumulateIsChecks;
-    accumulateIsChecks = false;
-    visit(right);
-    accumulateIsChecks = oldAccumulateIsChecks;
-    saved.mergeDiamondFlow(locals, null);
-    locals = saved;
-    return types.boolType;
-  }
-
-  @override
-  TypeInformation visitNot(ast.Send node, ast.Node expression, _) {
-    bool oldAccumulateIsChecks = accumulateIsChecks;
-    accumulateIsChecks = false;
-    visit(expression);
-    accumulateIsChecks = oldAccumulateIsChecks;
-    return types.boolType;
-  }
-
-  @override
-  TypeInformation visitIs(
-      ast.Send node, ast.Node expression, ResolutionDartType type, _) {
-    potentiallyAddIsCheck(node);
-    visit(expression);
-    return types.boolType;
-  }
-
-  @override
-  TypeInformation visitIsNot(
-      ast.Send node, ast.Node expression, ResolutionDartType type, _) {
-    potentiallyAddIsCheck(node);
-    visit(expression);
-    return types.boolType;
-  }
-
-  @override
-  TypeInformation visitAs(
-      ast.Send node, ast.Node expression, ResolutionDartType type, _) {
-    TypeInformation receiverType = visit(expression);
-    return types.narrowType(receiverType, type);
-  }
-
-  @override
-  TypeInformation visitUnary(
-      ast.Send node, op.UnaryOperator operator, ast.Node expression, _) {
-    return handleDynamicInvoke(node);
-  }
-
-  @override
-  TypeInformation visitNotEquals(
-      ast.Send node, ast.Node left, ast.Node right, _) {
-    handleDynamicInvoke(node);
-    return types.boolType;
-  }
-
-  @override
-  TypeInformation visitEquals(ast.Send node, ast.Node left, ast.Node right, _) {
-    return handleDynamicInvoke(node);
-  }
-
-  @override
-  TypeInformation visitBinary(ast.Send node, ast.Node left,
-      op.BinaryOperator operator, ast.Node right, _) {
-    return handleDynamicInvoke(node);
-  }
-
-  // Because some nodes just visit their children, we may end up
-  // visiting a type annotation, that may contain a send in case of a
-  // prefixed type. Therefore we explicitly visit the type annotation
-  // to avoid confusing the [ResolvedVisitor].
-  visitTypeAnnotation(ast.TypeAnnotation node) {}
-
-  TypeInformation visitConditional(ast.Conditional node) {
-    List<ast.Send> tests = <ast.Send>[];
-    bool simpleCondition = handleCondition(node.condition, tests);
-    LocalsHandler saved = locals;
-    locals = new LocalsHandler.from(locals, node);
-    updateIsChecks(tests, usePositive: true);
-    TypeInformation firstType = visit(node.thenExpression);
-    LocalsHandler thenLocals = locals;
-    locals = new LocalsHandler.from(saved, node);
-    if (simpleCondition) updateIsChecks(tests, usePositive: false);
-    TypeInformation secondType = visit(node.elseExpression);
-    saved.mergeDiamondFlow(thenLocals, locals);
-    locals = saved;
-    TypeInformation type = types.allocateDiamondPhi(firstType, secondType);
-    return type;
-  }
-
-  TypeInformation visitVariableDefinitions(ast.VariableDefinitions node) {
-    for (Link<ast.Node> link = node.definitions.nodes;
-        !link.isEmpty;
-        link = link.tail) {
-      ast.Node definition = link.head;
-      if (definition is ast.Identifier) {
-        LocalElement local = elements[definition];
-        locals.update(local, types.nullType, node, local.type);
-      } else {
-        assert(definition.asSendSet() != null);
-        handleSendSet(definition);
-      }
-    }
-    return null;
-  }
-
-  bool handleCondition(ast.Node node, List<ast.Send> tests) {
-    bool oldConditionIsSimple = conditionIsSimple;
-    bool oldAccumulateIsChecks = accumulateIsChecks;
-    List<ast.Send> oldIsChecks = isChecks;
-    accumulateIsChecks = true;
-    conditionIsSimple = true;
-    isChecks = tests;
-    visit(node);
-    bool simpleCondition = conditionIsSimple;
-    accumulateIsChecks = oldAccumulateIsChecks;
-    isChecks = oldIsChecks;
-    conditionIsSimple = oldConditionIsSimple;
-    return simpleCondition;
-  }
-
-  TypeInformation visitIf(ast.If node) {
-    List<ast.Send> tests = <ast.Send>[];
-    bool simpleCondition = handleCondition(node.condition, tests);
-    LocalsHandler saved = locals;
-    locals = new LocalsHandler.from(locals, node);
-    updateIsChecks(tests, usePositive: true);
-    visit(node.thenPart);
-    LocalsHandler thenLocals = locals;
-    locals = new LocalsHandler.from(saved, node);
-    if (simpleCondition) updateIsChecks(tests, usePositive: false);
-    visit(node.elsePart);
-    saved.mergeDiamondFlow(thenLocals, locals);
-    locals = saved;
-    return null;
-  }
-
-  void setupBreaksAndContinues(JumpTarget element) {
-    if (element == null) return;
-    if (element.isContinueTarget) continuesFor[element] = <LocalsHandler>[];
-    if (element.isBreakTarget) breaksFor[element] = <LocalsHandler>[];
-  }
-
-  void clearBreaksAndContinues(JumpTarget element) {
-    continuesFor.remove(element);
-    breaksFor.remove(element);
-  }
-
-  List<LocalsHandler> getBreaks(JumpTarget element) {
-    List<LocalsHandler> list = <LocalsHandler>[locals];
-    if (element == null) return list;
-    if (!element.isBreakTarget) return list;
-    return list..addAll(breaksFor[element]);
-  }
-
-  List<LocalsHandler> getLoopBackEdges(JumpTarget element) {
-    List<LocalsHandler> list = <LocalsHandler>[locals];
-    if (element == null) return list;
-    if (!element.isContinueTarget) return list;
-    return list..addAll(continuesFor[element]);
-  }
-
-  TypeInformation handleLoop(ast.Node node, void logic()) {
-    loopLevel++;
-    bool changed = false;
-    JumpTarget target = elements.getTargetDefinition(node);
-    LocalsHandler saved = locals;
-    saved.startLoop(node);
-    do {
-      // Setup (and clear in case of multiple iterations of the loop)
-      // the lists of breaks and continues seen in the loop.
-      setupBreaksAndContinues(target);
-      locals = new LocalsHandler.from(saved, node);
-      logic();
-      changed = saved.mergeAll(getLoopBackEdges(target));
-    } while (changed);
-    loopLevel--;
-    saved.endLoop(node);
-    bool keepOwnLocals = node.asDoWhile() == null;
-    saved.mergeAfterBreaks(getBreaks(target), keepOwnLocals: keepOwnLocals);
-    locals = saved;
-    clearBreaksAndContinues(target);
-    return null;
-  }
-
-  TypeInformation visitWhile(ast.While node) {
-    return handleLoop(node, () {
-      List<ast.Send> tests = <ast.Send>[];
-      handleCondition(node.condition, tests);
-      updateIsChecks(tests, usePositive: true);
-      visit(node.body);
-    });
-  }
-
-  TypeInformation visitDoWhile(ast.DoWhile node) {
-    return handleLoop(node, () {
-      visit(node.body);
-      List<ast.Send> tests = <ast.Send>[];
-      handleCondition(node.condition, tests);
-      // TODO(29309): This condition appears to strengthen both the back-edge
-      // and exit-edge. For now, avoid strengthening on the condition until the
-      // proper fix is found.
-      //
-      //     updateIsChecks(tests, usePositive: true);
-    });
-  }
-
-  TypeInformation visitFor(ast.For node) {
-    visit(node.initializer);
-    return handleLoop(node, () {
-      List<ast.Send> tests = <ast.Send>[];
-      handleCondition(node.condition, tests);
-      updateIsChecks(tests, usePositive: true);
-      visit(node.body);
-      visit(node.update);
-    });
-  }
-
-  TypeInformation visitTryStatement(ast.TryStatement node) {
-    LocalsHandler saved = locals;
-    locals = new LocalsHandler.from(locals, node, useOtherTryBlock: false);
-    initializationIsIndefinite();
-    visit(node.tryBlock);
-    saved.mergeDiamondFlow(locals, null);
-    locals = saved;
-    for (ast.Node catchBlock in node.catchBlocks) {
-      saved = locals;
-      locals = new LocalsHandler.from(locals, catchBlock);
-      visit(catchBlock);
-      saved.mergeDiamondFlow(locals, null);
-      locals = saved;
-    }
-    visit(node.finallyBlock);
-    return null;
-  }
-
-  TypeInformation visitThrow(ast.Throw node) {
-    node.visitChildren(this);
-    locals.seenReturnOrThrow = true;
-    return types.nonNullEmpty();
-  }
-
-  TypeInformation visitCatchBlock(ast.CatchBlock node) {
-    ast.Node exception = node.exception;
-    if (exception != null) {
-      ResolutionDartType type = elements.getType(node.type);
-      TypeInformation mask;
-      if (type == null || type.treatAsDynamic || type.isTypeVariable) {
-        mask = types.dynamicType;
-      } else {
-        ResolutionInterfaceType interfaceType = type;
-        mask = types.nonNullSubtype(interfaceType.element);
-      }
-      LocalElement local = elements[exception];
-      locals.update(local, mask, node, local.type);
-    }
-    ast.Node trace = node.trace;
-    if (trace != null) {
-      LocalElement local = elements[trace];
-      locals.update(local, types.dynamicType, node, local.type);
-    }
-    visit(node.block);
-    return null;
-  }
-
-  TypeInformation visitParenthesizedExpression(
-      ast.ParenthesizedExpression node) {
-    return visit(node.expression);
-  }
-
-  TypeInformation visitBlock(ast.Block node) {
-    if (node.statements != null) {
-      for (ast.Node statement in node.statements) {
-        visit(statement);
-        if (locals.aborts) break;
-      }
-    }
-    return null;
-  }
-
-  TypeInformation visitLabeledStatement(ast.LabeledStatement node) {
-    ast.Statement body = node.statement;
-    if (body is ast.Loop ||
-        body is ast.SwitchStatement ||
-        Elements.isUnusedLabel(node, elements)) {
-      // Loops and switches handle their own labels.
-      visit(body);
-    } else {
-      JumpTarget targetElement = elements.getTargetDefinition(body);
-      setupBreaksAndContinues(targetElement);
-      visit(body);
-      locals.mergeAfterBreaks(getBreaks(targetElement));
-      clearBreaksAndContinues(targetElement);
-    }
-    return null;
-  }
-
-  TypeInformation visitBreakStatement(ast.BreakStatement node) {
-    JumpTarget target = elements.getTargetOf(node);
-    locals.seenBreakOrContinue = true;
-    // Do a deep-copy of the locals, because the code following the
-    // break will change them.
-    breaksFor[target].add(new LocalsHandler.deepCopyOf(locals));
-    return null;
-  }
-
-  TypeInformation visitContinueStatement(ast.ContinueStatement node) {
-    JumpTarget target = elements.getTargetOf(node);
-    locals.seenBreakOrContinue = true;
-    // Do a deep-copy of the locals, because the code following the
-    // continue will change them.
-    continuesFor[target].add(new LocalsHandler.deepCopyOf(locals));
-    return null;
-  }
-
-  internalError(Spannable node, String reason) {
-    reporter.internalError(node, reason);
-  }
-
-  TypeInformation visitSwitchStatement(ast.SwitchStatement node) {
-    visit(node.parenthesizedExpression);
-
-    setupBreaksAndContinues(elements.getTargetDefinition(node));
-    if (Elements.switchStatementHasContinue(node, elements)) {
-      void forEachLabeledCase(void action(JumpTarget target)) {
-        for (ast.SwitchCase switchCase in node.cases) {
-          for (ast.Node labelOrCase in switchCase.labelsAndCases) {
-            if (labelOrCase.asLabel() == null) continue;
-            LabelDefinition labelElement =
-                elements.getLabelDefinition(labelOrCase);
-            if (labelElement != null) {
-              action(labelElement.target);
-            }
-          }
-        }
-      }
-
-      forEachLabeledCase((JumpTarget target) {
-        setupBreaksAndContinues(target);
-      });
-
-      // If the switch statement has a continue, we conservatively
-      // visit all cases and update [locals] until we have reached a
-      // fixed point.
-      bool changed;
-      locals.startLoop(node);
-      do {
-        changed = false;
-        for (ast.Node switchCase in node.cases) {
-          LocalsHandler saved = locals;
-          locals = new LocalsHandler.from(locals, switchCase);
-          visit(switchCase);
-          changed = saved.mergeAll([locals]) || changed;
-          locals = saved;
-        }
-      } while (changed);
-      locals.endLoop(node);
-
-      forEachLabeledCase((JumpTarget target) {
-        clearBreaksAndContinues(target);
-      });
-    } else {
-      LocalsHandler saved = locals;
-      List<LocalsHandler> localsToMerge = <LocalsHandler>[];
-      bool hasDefaultCase = false;
-
-      for (ast.SwitchCase switchCase in node.cases) {
-        if (switchCase.isDefaultCase) {
-          hasDefaultCase = true;
-        }
-        locals = new LocalsHandler.from(saved, switchCase);
-        visit(switchCase);
-        localsToMerge.add(locals);
-      }
-      saved.mergeAfterBreaks(localsToMerge, keepOwnLocals: !hasDefaultCase);
-      locals = saved;
-    }
-    clearBreaksAndContinues(elements.getTargetDefinition(node));
-    return null;
-  }
-
-  TypeInformation visitCascadeReceiver(ast.CascadeReceiver node) {
-    var type = visit(node.expression);
-    cascadeReceiverStack.add(type);
-    return type;
-  }
-
-  TypeInformation visitCascade(ast.Cascade node) {
-    // Ignore the result of the cascade send and return the type of the cascade
-    // receiver.
-    visit(node.expression);
-    return cascadeReceiverStack.removeLast();
-  }
-
-  void analyzeSuperConstructorCall(ConstructorElement target) {
-    assert(target.isDeclaration);
-    inferrer.analyze(target);
-    isThisExposed = isThisExposed || inferrer.checkIfExposesThis(target);
-  }
-
-  TypeInformation run() {
-    var node;
-    if (resolvedAst.kind == ResolvedAstKind.PARSED) {
-      node = resolvedAst.node;
-    }
-    ast.Expression initializer;
-    if (analyzedElement.isField) {
-      initializer = resolvedAst.body;
-      if (initializer == null) {
-        // Eagerly bailout, because computing the closure data only
-        // works for functions and field assignments.
-        return types.nullType;
-      }
-    }
-    // Update the locals that are boxed in [locals]. These locals will
-    // be handled specially, in that we are computing their LUB at
-    // each update, and reading them yields the type that was found in a
-    // previous analysis of [outermostElement].
-    ScopeInfo scopeInfo = compiler.backendStrategy.closureDataLookup
-        .getScopeInfo(analyzedElement);
-    scopeInfo.forEachBoxedVariable((variable, field) {
-      locals.setCapturedAndBoxed(variable, field);
-    });
-    if (analyzedElement.isField) {
-      return visit(initializer);
-    }
-
-    MethodElement function = analyzedElement.implementation;
-    FunctionSignature signature = function.functionSignature;
-    signature.forEachOptionalParameter((FormalElement _element) {
-      ParameterElement parameter = _element;
-      ast.Expression defaultValue = parameter.initializer;
-      // TODO(25566): The default value of a parameter of a redirecting factory
-      // constructor comes from the corresponding parameter of the target.
-
-      // If this is a default value from a different context (because
-      // the current function is synthetic, e.g., a constructor from
-      // a mixin application), we have to start a new inferrer visitor
-      // with the correct context.
-      // TODO(johnniwinther): Remove once function signatures are fixed.
-      ElementGraphBuilder visitor = this;
-      if (inferrer.hasAlreadyComputedTypeOfParameterDefault(parameter)) return;
-
-      FunctionElement declaration = parameter.functionDeclaration.declaration;
-      MethodElement declarationMethod = declaration is LocalFunctionElement
-          ? declaration.callMethod
-          : declaration;
-      bool needNewContext = declarationMethod != analyzedElement;
-      if (needNewContext) {
-        assert(
-            declarationMethod is ConstructorElement,
-            failedAt(
-                parameter,
-                "Unexpected function declaration "
-                "${declarationMethod}, expected ${analyzedElement}."));
-        visitor =
-            new ElementGraphBuilder(declarationMethod, compiler, inferrer);
-      }
-      TypeInformation type =
-          (defaultValue == null) ? types.nullType : visitor.visit(defaultValue);
-      inferrer.setDefaultTypeOfParameter(parameter, type,
-          isInstanceMember: function.isInstanceMember);
-    });
-
-    if (closedWorld.nativeData.isNativeMember(analyzedElement)) {
-      // Native methods do not have a body, and we currently just say
-      // they return dynamic.
-      return types.dynamicType;
-    }
-
-    if (analyzedElement.isGenerativeConstructor) {
-      ConstructorElement analyzedConstructor = analyzedElement;
-      isThisExposed = false;
-      signature.forEachParameter((FormalElement _element) {
-        ParameterElement element = _element;
-        TypeInformation parameterType = inferrer.typeOfParameter(element);
-        if (element.isInitializingFormal) {
-          InitializingFormalElement initializingFormal = element;
-          if (initializingFormal.fieldElement.isFinal) {
-            inferrer.recordTypeOfField(
-                initializingFormal.fieldElement, parameterType);
-          } else {
-            locals.updateField(initializingFormal.fieldElement, parameterType);
-            inferrer.recordTypeOfField(
-                initializingFormal.fieldElement, parameterType);
-          }
-        }
-        locals.update(element, parameterType, node, element.type);
-      });
-      ClassElement cls = analyzedConstructor.enclosingClass;
-      Spannable spannable = node;
-      if (analyzedConstructor.isSynthesized) {
-        spannable = analyzedConstructor;
-        synthesizeForwardingCall(
-            spannable, analyzedConstructor.definingConstructor);
-      } else {
-        visitingInitializers = true;
-        if (node.initializers != null) {
-          for (ast.Node initializer in node.initializers) {
-            ast.SendSet fieldInitializer = initializer.asSendSet();
-            if (fieldInitializer != null) {
-              handleSendSet(fieldInitializer);
-            } else {
-              Element element = elements[initializer];
-              handleConstructorSend(initializer, element);
-            }
-          }
-        }
-        visitingInitializers = false;
-        // For a generative constructor like: `Foo();`, we synthesize
-        // a call to the default super constructor (the one that takes
-        // no argument). Resolution ensures that such a constructor
-        // exists.
-        if (!isConstructorRedirect &&
-            !seenSuperConstructorCall &&
-            !cls.isObject) {
-          ConstructorElement target = cls.superclass.lookupDefaultConstructor();
-          ArgumentsTypes arguments = new ArgumentsTypes([], {});
-          analyzeSuperConstructorCall(target);
-          inferrer.registerCalledMember(node, null, null, outermostElement,
-              target, arguments, sideEffectsBuilder, inLoop);
-        }
-        visit(node.body);
-        inferrer.recordExposesThis(analyzedConstructor, isThisExposed);
-      }
-      if (!isConstructorRedirect) {
-        // Iterate over all instance fields, and give a null type to
-        // fields that we haven't initialized for sure.
-        cls.forEachInstanceField((_, FieldElement field) {
-          if (field.isFinal) return;
-          TypeInformation type = locals.fieldScope.readField(field);
-          ResolvedAst resolvedAst = field.resolvedAst;
-          if (type == null &&
-              (resolvedAst.body == null ||
-                  resolvedAst.body is ast.LiteralNull)) {
-            inferrer.recordTypeOfField(field, types.nullType);
-          }
-        });
-      }
-      if (analyzedElement.isGenerativeConstructor && cls.isAbstract) {
-        if (closedWorld.isInstantiated(cls)) {
-          returnType = types.nonNullSubclass(cls);
-        } else {
-          // TODO(johnniwinther): Avoid analyzing [analyzedElement] in this
-          // case; it's never called.
-          returnType = types.nonNullEmpty();
-        }
-      } else {
-        returnType = types.nonNullExact(cls);
-      }
-    } else {
-      signature.forEachParameter((FormalElement _element) {
-        ParameterElement element = _element;
-        locals.update(
-            element, inferrer.typeOfParameter(element), node, element.type);
-      });
-      visit(node.body);
-      switch (function.asyncMarker) {
-        case AsyncMarker.SYNC:
-          if (returnType == null) {
-            // No return in the body.
-            returnType = locals.seenReturnOrThrow
-                ? types.nonNullEmpty() // Body always throws.
-                : types.nullType;
-          } else if (!locals.seenReturnOrThrow) {
-            // We haven't seen returns on all branches. So the method may
-            // also return null.
-            recordReturnType(types.nullType);
-          }
-          break;
-
-        case AsyncMarker.SYNC_STAR:
-          // TODO(asgerf): Maybe make a ContainerTypeMask for these? The type
-          //               contained is the method body's return type.
-          recordReturnType(types.syncStarIterableType);
-          break;
-
-        case AsyncMarker.ASYNC:
-          recordReturnType(types.asyncFutureType);
-          break;
-
-        case AsyncMarker.ASYNC_STAR:
-          recordReturnType(types.asyncStarStreamType);
-          break;
-      }
-    }
-
-    assert(breaksFor.isEmpty);
-    assert(continuesFor.isEmpty);
-    return returnType;
-  }
-
-  TypeInformation visitFunctionExpression(ast.FunctionExpression node) {
-    // We loose track of [this] in closures (see issue 20840). To be on
-    // the safe side, we mark [this] as exposed here. We could do better by
-    // analyzing the closure.
-    // TODO(herhut): Analyze whether closure exposes this.
-    isThisExposed = true;
-    LocalFunctionElement element = elements.getFunctionDefinition(node);
-    // We don't put the closure in the work queue of the
-    // inferrer, because it will share information with its enclosing
-    // method, like for example the types of local variables.
-    LocalsHandler closureLocals =
-        new LocalsHandler.from(locals, node, useOtherTryBlock: false);
-    ElementGraphBuilder visitor = new ElementGraphBuilder(
-        element.callMethod, compiler, inferrer, closureLocals);
-    visitor.run();
-    inferrer.recordReturnType(element.callMethod, visitor.returnType);
-
-    // Record the types of captured non-boxed variables. Types of
-    // these variables may already be there, because of an analysis of
-    // a previous closure.
-    ClosureRepresentationInfo nestedClosureData =
-        compiler.backendStrategy.closureDataLookup.getClosureInfo(node);
-    nestedClosureData.forEachFreeVariable((variable, field) {
-      if (!nestedClosureData.isVariableBoxed(variable)) {
-        if (variable == nestedClosureData.thisLocal) {
-          inferrer.recordTypeOfField(field, thisType);
-        }
-        // The type is null for type parameters.
-        if (locals.locals[variable] == null) return;
-        inferrer.recordTypeOfField(field, locals.locals[variable]);
-      }
-      capturedVariables.add(variable);
-    });
-
-    return inferrer.concreteTypes.putIfAbsent(node, () {
-      return types.allocateClosure(element.callMethod);
-    });
-  }
-
-  TypeInformation visitFunctionDeclaration(ast.FunctionDeclaration node) {
-    LocalFunctionElement element =
-        elements.getFunctionDefinition(node.function);
-    TypeInformation type =
-        inferrer.concreteTypes.putIfAbsent(node.function, () {
-      return types.allocateClosure(element.callMethod);
-    });
-    locals.update(element, type, node, element.type);
-    visit(node.function);
-    return type;
-  }
-
-  TypeInformation visitStringInterpolation(ast.StringInterpolation node) {
-    // Interpolation could have any effects since it could call any toString()
-    // method.
-    // TODO(sra): This could be modelled by a call to toString() but with a
-    // guaranteed String return type.  Interpolation of known types would get
-    // specialized effects.  This would not currently be effective since the JS
-    // code in the toString methods for intercepted primitive types is assumed
-    // to have all effects.  Effect annotations on JS code would be needed to
-    // get the benefit.
-    sideEffectsBuilder.setAllSideEffects();
-    node.visitChildren(this);
-    return types.stringType;
-  }
-
-  TypeInformation visitLiteralList(ast.LiteralList node) {
-    // We only set the type once. We don't need to re-visit the children
-    // when re-analyzing the node.
-    return inferrer.concreteTypes.putIfAbsent(node, () {
-      TypeInformation elementType;
-      int length = 0;
-      for (ast.Node element in node.elements.nodes) {
-        TypeInformation type = visit(element);
-        elementType = elementType == null
-            ? types.allocatePhi(null, null, type, isTry: false)
-            : types.addPhiInput(null, elementType, type);
-        length++;
-      }
-      elementType = elementType == null
-          ? types.nonNullEmpty()
-          : types.simplifyPhi(null, null, elementType);
-      TypeInformation containerType =
-          node.isConst ? types.constListType : types.growableListType;
-      return types.allocateList(
-          containerType, node, outermostElement, elementType, length);
-    });
-  }
-
-  TypeInformation visitLiteralMap(ast.LiteralMap node) {
-    return inferrer.concreteTypes.putIfAbsent(node, () {
-      ast.NodeList entries = node.entries;
-      List keyTypes = [];
-      List valueTypes = [];
-
-      for (ast.LiteralMapEntry entry in entries) {
-        keyTypes.add(visit(entry.key));
-        valueTypes.add(visit(entry.value));
-      }
-
-      TypeInformation type = node.isConst ? types.constMapType : types.mapType;
-      return types.allocateMap(
-          type, node, outermostElement, keyTypes, valueTypes);
-    });
-  }
-
-  bool isThisOrSuper(ast.Node node) => node.isThis() || node.isSuper();
-
-  bool isInClassOrSubclass(Element element) {
-    ClassElement cls = outermostElement.enclosingClass;
-    ClassElement enclosing = element.enclosingClass;
-    return closedWorld.isSubclassOf(enclosing, cls);
-  }
-
-  void checkIfExposesThis(Selector selector, TypeMask mask) {
-    if (isThisExposed) return;
-    if (inferrer.closedWorld.includesClosureCall(selector, mask)) {
-      // TODO(ngeoffray): We could do better here if we knew what we
-      // are calling does not expose this.
-      isThisExposed = true;
-    } else {
-      inferrer.forEachElementMatching(selector, mask, (MemberEntity element) {
-        if (element.isField) {
-          FieldElement field = element;
-          ResolvedAst elementResolvedAst = field.resolvedAst;
-          if (!selector.isSetter &&
-              isInClassOrSubclass(field) &&
-              !field.isFinal &&
-              locals.fieldScope.readField(field) == null &&
-              elementResolvedAst.body == null) {
-            // If the field is being used before this constructor
-            // actually had a chance to initialize it, say it can be
-            // null.
-            inferrer.recordTypeOfField(field, types.nullType);
-          }
-          // Accessing a field does not expose [:this:].
-          return true;
-        }
-        // TODO(ngeoffray): We could do better here if we knew what we
-        // are calling does not expose this.
-        isThisExposed = true;
-        return false;
-      });
-    }
-  }
-
-  bool get inInstanceContext {
-    return (outermostElement.isInstanceMember && !outermostElement.isField) ||
-        outermostElement.isGenerativeConstructor;
-  }
-
-  bool treatAsInstanceMember(Element element) {
-    return (Elements.isUnresolved(element) && inInstanceContext) ||
-        (element != null && element.isInstanceMember);
-  }
-
-  TypeInformation handleSendSet(ast.SendSet node) {
-    Element element = elements[node];
-    if (!Elements.isUnresolved(element) && element.impliesType) {
-      node.visitChildren(this);
-      return types.dynamicType;
-    }
-
-    Selector getterSelector = elements.getGetterSelectorInComplexSendSet(node);
-    TypeMask getterMask = memberData.typeOfGetter(node);
-    TypeMask operatorMask = memberData.typeOfOperator(node);
-    Selector setterSelector = elements.getSelector(node);
-    TypeMask setterMask = memberData.typeOfSend(node);
-
-    String op = node.assignmentOperator.source;
-    bool isIncrementOrDecrement = op == '++' || op == '--';
-
-    TypeInformation receiverType;
-    bool isCallOnThis = false;
-    if (node.receiver == null) {
-      if (treatAsInstanceMember(element)) {
-        receiverType = thisType;
-        isCallOnThis = true;
-      }
-    } else {
-      if (node.receiver != null) {
-        Element receiver = elements[node.receiver];
-        if (receiver is! PrefixElement && receiver is! ClassElement) {
-          // TODO(johnniwinther): Avoid blindly recursing on the receiver.
-          receiverType = visit(node.receiver);
-        }
-      }
-      isCallOnThis = isThisOrSuper(node.receiver);
-    }
-
-    TypeInformation rhsType;
-
-    if (isIncrementOrDecrement) {
-      rhsType = types.uint31Type;
-      if (node.isIndex) visit(node.arguments.head);
-    } else if (node.isIndex) {
-      visit(node.arguments.head);
-      rhsType = visit(node.arguments.tail.head);
-    } else {
-      rhsType = visit(node.arguments.head);
-    }
-
-    if (!visitingInitializers && !isThisExposed) {
-      for (ast.Node node in node.arguments) {
-        if (isThisOrSuper(node)) {
-          isThisExposed = true;
-          break;
-        }
-      }
-      if (!isThisExposed && isCallOnThis) {
-        checkIfExposesThis(
-            setterSelector, types.newTypedSelector(receiverType, setterMask));
-        if (getterSelector != null) {
-          checkIfExposesThis(
-              getterSelector, types.newTypedSelector(receiverType, getterMask));
-        }
-      }
-    }
-
-    if (node.isIndex) {
-      return internalError(node, "Unexpected index operation");
-    } else if (op == '=') {
-      return handlePlainAssignment(node, element, setterSelector, setterMask,
-          receiverType, rhsType, node.arguments.head);
-    } else {
-      // [foo ??= bar], [: foo++ :] or [: foo += 1 :].
-      TypeInformation getterType;
-      TypeInformation newType;
-
-      if (Elements.isMalformed(element)) return types.dynamicType;
-
-      if (Elements.isStaticOrTopLevelField(element)) {
-        Element getterElement = elements[node.selector];
-        getterType = handleStaticSend(
-            node, getterSelector, getterMask, getterElement, null);
-      } else if (Elements.isUnresolved(element) ||
-          element.isSetter ||
-          element.isField) {
-        getterType = handleDynamicSend(CallType.complex, node, getterSelector,
-            getterMask, receiverType, null);
-      } else if (element.isLocal) {
-        LocalElement local = element;
-        getterType = locals.use(local);
-      } else {
-        // Bogus SendSet, for example [: myMethod += 42 :].
-        getterType = types.dynamicType;
-      }
-
-      if (op == '??=') {
-        newType = types.allocateDiamondPhi(getterType, rhsType);
-      } else {
-        Selector operatorSelector =
-            elements.getOperatorSelectorInComplexSendSet(node);
-        newType = handleDynamicSend(CallType.complex, node, operatorSelector,
-            operatorMask, getterType, new ArgumentsTypes([rhsType], null));
-      }
-
-      if (Elements.isStaticOrTopLevelField(element)) {
-        handleStaticSend(node, setterSelector, setterMask, element,
-            new ArgumentsTypes([newType], null));
-      } else if (Elements.isUnresolved(element) ||
-          element.isSetter ||
-          element.isField) {
-        handleDynamicSend(CallType.complex, node, setterSelector, setterMask,
-            receiverType, new ArgumentsTypes([newType], null));
-      } else if (element.isLocal) {
-        LocalElement local = element;
-        locals.update(local, newType, node, local.type,
-            isSetIfNull: node.isIfNullAssignment);
-      }
-
-      if (node.isPostfix) {
-        if (node.isConditional) {
-          return getterType;
-        } else {
-          // We have just successfully performed a `+ 1` operation on the getter
-          // so we know it to be not `null`.
-          return types.narrowNotNull(getterType);
-        }
-      } else {
-        return newType;
-      }
-    }
-  }
-
-  /// Handle compound index set, like `foo[0] += 42` or `foo[0]++`.
-  TypeInformation handleCompoundIndexSet(
-      ast.SendSet node,
-      TypeInformation receiverType,
-      TypeInformation indexType,
-      TypeInformation rhsType) {
-    Selector getterSelector = elements.getGetterSelectorInComplexSendSet(node);
-
-    TypeMask getterMask = memberData.typeOfGetter(node);
-    Selector operatorSelector =
-        elements.getOperatorSelectorInComplexSendSet(node);
-    TypeMask operatorMask = memberData.typeOfOperator(node);
-    Selector setterSelector = elements.getSelector(node);
-    TypeMask setterMask = memberData.typeOfSend(node);
-
-    TypeInformation getterType = handleDynamicSend(
-        CallType.complex,
-        node,
-        getterSelector,
-        getterMask,
-        receiverType,
-        new ArgumentsTypes([indexType], null));
-
-    TypeInformation returnType;
-    if (node.isIfNullAssignment) {
-      returnType = types.allocateDiamondPhi(getterType, rhsType);
-    } else {
-      returnType = handleDynamicSend(CallType.complex, node, operatorSelector,
-          operatorMask, getterType, new ArgumentsTypes([rhsType], null));
-    }
-    handleDynamicSend(CallType.complex, node, setterSelector, setterMask,
-        receiverType, new ArgumentsTypes([indexType, returnType], null));
-
-    if (node.isPostfix) {
-      return getterType;
-    } else {
-      return returnType;
-    }
-  }
-
-  /// Handle compound prefix/postfix operations, like `a[0]++`.
-  TypeInformation handleCompoundPrefixPostfix(
-      ast.Send node, TypeInformation receiverType, TypeInformation indexType) {
-    return handleCompoundIndexSet(
-        node, receiverType, indexType, types.uint31Type);
-  }
-
-  @override
-  TypeInformation visitIndexPostfix(ast.Send node, ast.Node receiver,
-      ast.Node index, op.IncDecOperator operator, _) {
-    TypeInformation receiverType = visit(receiver);
-    TypeInformation indexType = visit(index);
-    return handleCompoundPrefixPostfix(node, receiverType, indexType);
-  }
-
-  @override
-  TypeInformation visitIndexPrefix(ast.Send node, ast.Node receiver,
-      ast.Node index, op.IncDecOperator operator, _) {
-    TypeInformation receiverType = visit(receiver);
-    TypeInformation indexType = visit(index);
-    return handleCompoundPrefixPostfix(node, receiverType, indexType);
-  }
-
-  @override
-  TypeInformation visitCompoundIndexSet(ast.SendSet node, ast.Node receiver,
-      ast.Node index, op.AssignmentOperator operator, ast.Node rhs, _) {
-    TypeInformation receiverType = visit(receiver);
-    TypeInformation indexType = visit(index);
-    TypeInformation rhsType = visit(rhs);
-    return handleCompoundIndexSet(node, receiverType, indexType, rhsType);
-  }
-
-  @override
-  TypeInformation visitIndexSetIfNull(
-      ast.SendSet node, ast.Node receiver, ast.Node index, ast.Node rhs, _) {
-    TypeInformation receiverType = visit(receiver);
-    TypeInformation indexType = visit(index);
-    TypeInformation rhsType = visit(rhs);
-    return handleCompoundIndexSet(node, receiverType, indexType, rhsType);
-  }
-
-  @override
-  TypeInformation visitSuperIndexPrefix(ast.Send node, MethodElement getter,
-      MethodElement setter, ast.Node index, op.IncDecOperator operator, _) {
-    TypeInformation indexType = visit(index);
-    return handleSuperIndexPrefixPostfix(node, getter, setter, indexType);
-  }
-
-  @override
-  TypeInformation visitSuperIndexPostfix(ast.Send node, MethodElement getter,
-      MethodElement setter, ast.Node index, op.IncDecOperator operator, _) {
-    TypeInformation indexType = visit(index);
-    return handleSuperIndexPrefixPostfix(node, getter, setter, indexType);
-  }
-
-  /// Handle compound prefix/postfix operations, like `super[0]++`.
-  TypeInformation handleSuperIndexPrefixPostfix(ast.Send node, Element getter,
-      Element setter, TypeInformation indexType) {
-    return _handleSuperCompoundIndexSet(
-        node, getter, setter, indexType, types.uint31Type);
-  }
-
-  /// Handle compound super index set, like `super[42] =+ 2`.
-  TypeInformation handleSuperCompoundIndexSet(ast.SendSet node, Element getter,
-      Element setter, ast.Node index, ast.Node rhs) {
-    TypeInformation indexType = visit(index);
-    TypeInformation rhsType = visit(rhs);
-    return _handleSuperCompoundIndexSet(
-        node, getter, setter, indexType, rhsType);
-  }
-
-  TypeInformation _handleSuperCompoundIndexSet(ast.SendSet node, Element getter,
-      Element setter, TypeInformation indexType, TypeInformation rhsType) {
-    Selector getterSelector = elements.getGetterSelectorInComplexSendSet(node);
-
-    TypeMask getterMask = memberData.typeOfGetter(node);
-    Selector setterSelector = elements.getSelector(node);
-    TypeMask setterMask = memberData.typeOfSend(node);
-
-    TypeInformation getterType = handleSuperSend(node, getterSelector,
-        getterMask, getter, new ArgumentsTypes([indexType], null));
-
-    TypeInformation returnType;
-    if (node.isIfNullAssignment) {
-      returnType = types.allocateDiamondPhi(getterType, rhsType);
-    } else {
-      Selector operatorSelector =
-          elements.getOperatorSelectorInComplexSendSet(node);
-      TypeMask operatorMask = memberData.typeOfOperator(node);
-      returnType = handleDynamicSend(CallType.complex, node, operatorSelector,
-          operatorMask, getterType, new ArgumentsTypes([rhsType], null));
-    }
-    handleSuperSend(node, setterSelector, setterMask, setter,
-        new ArgumentsTypes([indexType, returnType], null));
-
-    return node.isPostfix ? getterType : returnType;
-  }
-
-  TypeInformation handleSuperSend(ast.Node node, Selector selector,
-      TypeMask mask, Element element, ArgumentsTypes arguments) {
-    if (element.isMalformed) {
-      return handleSuperNoSuchMethod(node, selector, mask, arguments);
-    } else {
-      return handleStaticSend(node, selector, mask, element, arguments);
-    }
-  }
-
-  @override
-  TypeInformation visitSuperCompoundIndexSet(
-      ast.SendSet node,
-      MethodElement getter,
-      MethodElement setter,
-      ast.Node index,
-      op.AssignmentOperator operator,
-      ast.Node rhs,
-      _) {
-    return handleSuperCompoundIndexSet(node, getter, setter, index, rhs);
-  }
-
-  @override
-  TypeInformation visitSuperIndexSetIfNull(
-      ast.SendSet node,
-      MethodElement getter,
-      MethodElement setter,
-      ast.Node index,
-      ast.Node rhs,
-      _) {
-    return handleSuperCompoundIndexSet(node, getter, setter, index, rhs);
-  }
-
-  @override
-  TypeInformation visitUnresolvedSuperCompoundIndexSet(
-      ast.SendSet node,
-      Element element,
-      ast.Node index,
-      op.AssignmentOperator operator,
-      ast.Node rhs,
-      _) {
-    return handleSuperCompoundIndexSet(node, element, element, index, rhs);
-  }
-
-  @override
-  TypeInformation visitUnresolvedSuperIndexSetIfNull(
-      ast.Send node, Element element, ast.Node index, ast.Node rhs, _) {
-    return handleSuperCompoundIndexSet(node, element, element, index, rhs);
-  }
-
-  @override
-  TypeInformation visitUnresolvedSuperGetterCompoundIndexSet(
-      ast.SendSet node,
-      Element element,
-      MethodElement setter,
-      ast.Node index,
-      op.AssignmentOperator operator,
-      ast.Node rhs,
-      _) {
-    return handleSuperCompoundIndexSet(node, element, setter, index, rhs);
-  }
-
-  @override
-  TypeInformation visitUnresolvedSuperGetterIndexSetIfNull(ast.SendSet node,
-      Element element, MethodElement setter, ast.Node index, ast.Node rhs, _) {
-    return handleSuperCompoundIndexSet(node, element, setter, index, rhs);
-  }
-
-  @override
-  TypeInformation visitUnresolvedSuperSetterCompoundIndexSet(
-      ast.SendSet node,
-      MethodElement getter,
-      Element element,
-      ast.Node index,
-      op.AssignmentOperator operator,
-      ast.Node rhs,
-      _) {
-    return handleSuperCompoundIndexSet(node, getter, element, index, rhs);
-  }
-
-  @override
-  TypeInformation visitUnresolvedSuperSetterIndexSetIfNull(ast.SendSet node,
-      MethodElement getter, Element element, ast.Node index, ast.Node rhs, _) {
-    return handleSuperCompoundIndexSet(node, getter, element, index, rhs);
-  }
-
-  @override
-  TypeInformation visitUnresolvedSuperIndexPrefix(ast.Send node,
-      Element element, ast.Node index, op.IncDecOperator operator, _) {
-    TypeInformation indexType = visit(index);
-    return handleSuperIndexPrefixPostfix(node, element, element, indexType);
-  }
-
-  @override
-  TypeInformation visitUnresolvedSuperGetterIndexPrefix(
-      ast.SendSet node,
-      Element element,
-      MethodElement setter,
-      ast.Node index,
-      op.IncDecOperator operator,
-      _) {
-    TypeInformation indexType = visit(index);
-    return handleSuperIndexPrefixPostfix(node, element, setter, indexType);
-  }
-
-  @override
-  TypeInformation visitUnresolvedSuperSetterIndexPrefix(
-      ast.SendSet node,
-      MethodElement getter,
-      Element element,
-      ast.Node index,
-      op.IncDecOperator operator,
-      _) {
-    TypeInformation indexType = visit(index);
-    return handleSuperIndexPrefixPostfix(node, getter, element, indexType);
-  }
-
-  @override
-  TypeInformation visitUnresolvedSuperIndexPostfix(ast.Send node,
-      Element element, ast.Node index, op.IncDecOperator operator, _) {
-    TypeInformation indexType = visit(index);
-    return handleSuperIndexPrefixPostfix(node, element, element, indexType);
-  }
-
-  @override
-  TypeInformation visitUnresolvedSuperGetterIndexPostfix(
-      ast.SendSet node,
-      Element element,
-      MethodElement setter,
-      ast.Node index,
-      op.IncDecOperator operator,
-      _) {
-    TypeInformation indexType = visit(index);
-    return handleSuperIndexPrefixPostfix(node, element, setter, indexType);
-  }
-
-  @override
-  TypeInformation visitUnresolvedSuperSetterIndexPostfix(
-      ast.SendSet node,
-      MethodElement getter,
-      Element element,
-      ast.Node index,
-      op.IncDecOperator operator,
-      _) {
-    TypeInformation indexType = visit(index);
-    return handleSuperIndexPrefixPostfix(node, getter, element, indexType);
-  }
-
-  @override
-  TypeInformation visitSuperFieldCompound(ast.Send node, FieldElement field,
-      op.AssignmentOperator operator, ast.Node rhs, _) {
-    return handleSuperCompound(node, field, field, rhs);
-  }
-
-  @override
-  TypeInformation visitSuperFieldSetterCompound(
-      ast.Send node,
-      FieldElement field,
-      SetterElement setter,
-      op.AssignmentOperator operator,
-      ast.Node rhs,
-      _) {
-    return handleSuperCompound(node, field, setter, rhs);
-  }
-
-  @override
-  TypeInformation visitSuperGetterFieldCompound(
-      ast.Send node,
-      GetterElement getter,
-      FieldElement field,
-      op.AssignmentOperator operator,
-      ast.Node rhs,
-      _) {
-    return handleSuperCompound(node, getter, field, rhs);
-  }
-
-  @override
-  TypeInformation visitSuperGetterSetterCompound(
-      ast.Send node,
-      GetterElement getter,
-      SetterElement setter,
-      op.AssignmentOperator operator,
-      ast.Node rhs,
-      _) {
-    return handleSuperCompound(node, getter, setter, rhs);
-  }
-
-  @override
-  TypeInformation visitSuperMethodSetterCompound(
-      ast.Send node,
-      FunctionElement method,
-      SetterElement setter,
-      op.AssignmentOperator operator,
-      ast.Node rhs,
-      _) {
-    return handleSuperCompound(node, method, setter, rhs);
-  }
-
-  @override
-  TypeInformation visitUnresolvedSuperCompound(ast.Send node, Element element,
-      op.AssignmentOperator operator, ast.Node rhs, _) {
-    return handleSuperCompound(node, element, element, rhs);
-  }
-
-  @override
-  TypeInformation visitUnresolvedSuperGetterCompound(
-      ast.SendSet node,
-      Element getter,
-      SetterElement setter,
-      op.AssignmentOperator operator,
-      ast.Node rhs,
-      _) {
-    return handleSuperCompound(node, getter, setter, rhs);
-  }
-
-  @override
-  TypeInformation visitUnresolvedSuperSetterCompound(
-      ast.Send node,
-      GetterElement getter,
-      Element setter,
-      op.AssignmentOperator operator,
-      ast.Node rhs,
-      _) {
-    return handleSuperCompound(node, getter, setter, rhs);
-  }
-
-  @override
-  TypeInformation visitSuperFieldFieldSetIfNull(ast.Send node,
-      FieldElement readField, FieldElement writtenField, ast.Node rhs, _) {
-    return handleSuperCompound(node, readField, writtenField, rhs);
-  }
-
-  @override
-  TypeInformation visitSuperFieldSetIfNull(
-      ast.Send node, FieldElement field, ast.Node rhs, _) {
-    return handleSuperCompound(node, field, field, rhs);
-  }
-
-  @override
-  TypeInformation visitSuperFieldSetterSetIfNull(ast.Send node,
-      FieldElement field, SetterElement setter, ast.Node rhs, _) {
-    return handleSuperCompound(node, field, setter, rhs);
-  }
-
-  @override
-  TypeInformation visitSuperGetterFieldSetIfNull(ast.Send node,
-      GetterElement getter, FieldElement field, ast.Node rhs, _) {
-    return handleSuperCompound(node, getter, field, rhs);
-  }
-
-  @override
-  TypeInformation visitSuperGetterSetterSetIfNull(ast.Send node,
-      GetterElement getter, SetterElement setter, ast.Node rhs, _) {
-    return handleSuperCompound(node, getter, setter, rhs);
-  }
-
-  @override
-  TypeInformation visitSuperMethodSetIfNull(
-      ast.Send node, FunctionElement method, ast.Node rhs, _) {
-    return handleSuperCompound(node, method, null, rhs);
-  }
-
-  @override
-  TypeInformation visitSuperMethodSetterSetIfNull(ast.Send node,
-      FunctionElement method, SetterElement setter, ast.Node rhs, _) {
-    return handleSuperCompound(node, method, setter, rhs);
-  }
-
-  TypeInformation handleSuperCompound(
-      ast.SendSet node, Element getter, Element setter, ast.Node rhs) {
-    TypeInformation rhsType = visit(rhs);
-    return _handleSuperCompound(node, getter, setter, rhsType);
-  }
-
-  @override
-  TypeInformation visitSuperFieldFieldPostfix(
-      ast.SendSet node,
-      FieldElement readField,
-      FieldElement writtenField,
-      op.IncDecOperator operator,
-      _) {
-    return handleSuperPrefixPostfix(node, readField, writtenField);
-  }
-
-  @override
-  TypeInformation visitSuperFieldFieldPrefix(
-      ast.SendSet node,
-      FieldElement readField,
-      FieldElement writtenField,
-      op.IncDecOperator operator,
-      _) {
-    return handleSuperPrefixPostfix(node, readField, writtenField);
-  }
-
-  @override
-  TypeInformation visitSuperFieldPostfix(
-      ast.SendSet node, FieldElement field, op.IncDecOperator operator, _) {
-    return handleSuperPrefixPostfix(node, field, field);
-  }
-
-  @override
-  TypeInformation visitSuperFieldPrefix(
-      ast.SendSet node, FieldElement field, op.IncDecOperator operator, _) {
-    return handleSuperPrefixPostfix(node, field, field);
-  }
-
-  @override
-  TypeInformation visitSuperFieldSetterPostfix(ast.SendSet node,
-      FieldElement field, SetterElement setter, op.IncDecOperator operator, _) {
-    return handleSuperPrefixPostfix(node, field, setter);
-  }
-
-  @override
-  TypeInformation visitSuperFieldSetterPrefix(ast.SendSet node,
-      FieldElement field, SetterElement setter, op.IncDecOperator operator, _) {
-    return handleSuperPrefixPostfix(node, field, setter);
-  }
-
-  @override
-  TypeInformation visitSuperGetterFieldPostfix(ast.SendSet node,
-      GetterElement getter, FieldElement field, op.IncDecOperator operator, _) {
-    return handleSuperPrefixPostfix(node, getter, field);
-  }
-
-  @override
-  TypeInformation visitSuperGetterFieldPrefix(ast.SendSet node,
-      GetterElement getter, FieldElement field, op.IncDecOperator operator, _) {
-    return handleSuperPrefixPostfix(node, getter, field);
-  }
-
-  @override
-  TypeInformation visitSuperGetterSetterPostfix(
-      ast.SendSet node,
-      GetterElement getter,
-      SetterElement setter,
-      op.IncDecOperator operator,
-      _) {
-    return handleSuperPrefixPostfix(node, getter, setter);
-  }
-
-  @override
-  TypeInformation visitSuperGetterSetterPrefix(
-      ast.SendSet node,
-      GetterElement getter,
-      SetterElement setter,
-      op.IncDecOperator operator,
-      _) {
-    return handleSuperPrefixPostfix(node, getter, setter);
-  }
-
-  @override
-  TypeInformation visitSuperMethodSetterPostfix(
-      ast.SendSet node,
-      FunctionElement method,
-      SetterElement setter,
-      op.IncDecOperator operator,
-      _) {
-    return handleSuperPrefixPostfix(node, method, setter);
-  }
-
-  @override
-  TypeInformation visitSuperMethodSetterPrefix(
-      ast.SendSet node,
-      FunctionElement method,
-      SetterElement setter,
-      op.IncDecOperator operator,
-      _) {
-    return handleSuperPrefixPostfix(node, method, setter);
-  }
-
-  @override
-  TypeInformation visitUnresolvedSuperPrefix(
-      ast.SendSet node, Element element, op.IncDecOperator operator, _) {
-    return handleSuperPrefixPostfix(node, element, element);
-  }
-
-  @override
-  TypeInformation visitUnresolvedSuperPostfix(
-      ast.SendSet node, Element element, op.IncDecOperator operator, _) {
-    return handleSuperPrefixPostfix(node, element, element);
-  }
-
-  @override
-  TypeInformation visitUnresolvedSuperGetterPrefix(ast.SendSet node,
-      Element getter, SetterElement setter, op.IncDecOperator operator, _) {
-    return handleSuperPrefixPostfix(node, getter, setter);
-  }
-
-  @override
-  TypeInformation visitUnresolvedSuperGetterPostfix(ast.SendSet node,
-      Element getter, SetterElement setter, op.IncDecOperator operator, _) {
-    return handleSuperPrefixPostfix(node, getter, setter);
-  }
-
-  @override
-  TypeInformation visitUnresolvedSuperSetterPrefix(ast.SendSet node,
-      GetterElement getter, Element setter, op.IncDecOperator operator, _) {
-    return handleSuperPrefixPostfix(node, getter, setter);
-  }
-
-  @override
-  TypeInformation visitUnresolvedSuperSetterPostfix(ast.SendSet node,
-      GetterElement getter, Element setter, op.IncDecOperator operator, _) {
-    return handleSuperPrefixPostfix(node, getter, setter);
-  }
-
-  TypeInformation handleSuperPrefixPostfix(
-      ast.SendSet node, Element getter, Element setter) {
-    return _handleSuperCompound(node, getter, setter, types.uint31Type);
-  }
-
-  TypeInformation _handleSuperCompound(ast.SendSet node, Element getter,
-      Element setter, TypeInformation rhsType) {
-    Selector getterSelector = elements.getGetterSelectorInComplexSendSet(node);
-    TypeMask getterMask = memberData.typeOfGetter(node);
-    Selector setterSelector = elements.getSelector(node);
-    TypeMask setterMask = memberData.typeOfSend(node);
-
-    TypeInformation getterType =
-        handleSuperSend(node, getterSelector, getterMask, getter, null);
-
-    TypeInformation returnType;
-    if (node.isIfNullAssignment) {
-      returnType = types.allocateDiamondPhi(getterType, rhsType);
-    } else {
-      Selector operatorSelector =
-          elements.getOperatorSelectorInComplexSendSet(node);
-      TypeMask operatorMask = memberData.typeOfOperator(node);
-      returnType = handleDynamicSend(CallType.complex, node, operatorSelector,
-          operatorMask, getterType, new ArgumentsTypes([rhsType], null));
-    }
-    handleSuperSend(node, setterSelector, setterMask, setter,
-        new ArgumentsTypes([returnType], null));
-
-    return node.isPostfix ? getterType : returnType;
-  }
-
-  /// Handle index set, like `foo[0] = 42`.
-  TypeInformation handleIndexSet(ast.SendSet node, TypeInformation receiverType,
-      TypeInformation indexType, TypeInformation rhsType) {
-    Selector setterSelector = elements.getSelector(node);
-    TypeMask setterMask = memberData.typeOfSend(node);
-    handleDynamicSend(CallType.complex, node, setterSelector, setterMask,
-        receiverType, new ArgumentsTypes([indexType, rhsType], null));
-    return rhsType;
-  }
-
-  @override
-  TypeInformation visitIndexSet(
-      ast.SendSet node, ast.Node receiver, ast.Node index, ast.Node rhs, _) {
-    TypeInformation receiverType = visit(receiver);
-    TypeInformation indexType = visit(index);
-    TypeInformation rhsType = visit(rhs);
-    return handleIndexSet(node, receiverType, indexType, rhsType);
-  }
-
-  /// Handle super index set, like `super[42] = true`.
-  TypeInformation handleSuperIndexSet(
-      ast.SendSet node, Element element, ast.Node index, ast.Node rhs) {
-    TypeInformation indexType = visit(index);
-    TypeInformation rhsType = visit(rhs);
-    Selector setterSelector = elements.getSelector(node);
-    TypeMask setterMask = memberData.typeOfSend(node);
-    handleStaticSend(node, setterSelector, setterMask, element,
-        new ArgumentsTypes([indexType, rhsType], null));
-    return rhsType;
-  }
-
-  @override
-  TypeInformation visitSuperIndexSet(ast.SendSet node, FunctionElement function,
-      ast.Node index, ast.Node rhs, _) {
-    return handleSuperIndexSet(node, function, index, rhs);
-  }
-
-  @override
-  TypeInformation visitUnresolvedSuperIndexSet(ast.SendSet node,
-      ErroneousElement element, ast.Node index, ast.Node rhs, _) {
-    return handleSuperIndexSet(node, element, index, rhs);
-  }
-
-  TypeInformation handlePlainAssignment(
-      ast.Node node,
-      Element element,
-      Selector setterSelector,
-      TypeMask setterMask,
-      TypeInformation receiverType,
-      TypeInformation rhsType,
-      ast.Node rhs) {
-    ArgumentsTypes arguments = new ArgumentsTypes([rhsType], null);
-    if (Elements.isMalformed(element)) {
-      // Code will always throw.
-    } else if (Elements.isStaticOrTopLevelField(element)) {
-      handleStaticSend(node, setterSelector, setterMask, element, arguments);
-    } else if (Elements.isUnresolved(element) || element.isSetter) {
-      if (analyzedElement.isGenerativeConstructor &&
-          (node.asSendSet() != null) &&
-          (node.asSendSet().receiver != null) &&
-          node.asSendSet().receiver.isThis()) {
-        TypeMask typedMask = types.newTypedSelector(thisType, setterMask);
-        if (!closedWorld.includesClosureCall(setterSelector, typedMask)) {
-          Iterable<MemberEntity> targets =
-              closedWorld.locateMembers(setterSelector, typedMask);
-          // We just recognized a field initialization of the form:
-          // `this.foo = 42`. If there is only one target, we can update
-          // its type.
-          if (targets.length == 1) {
-            MemberElement single = targets.first;
-            if (single.isField) {
-              FieldElement field = single;
-              locals.updateField(field, rhsType);
-            }
-          }
-        }
-      }
-      handleDynamicSend(CallType.access, node, setterSelector, setterMask,
-          receiverType, arguments);
-    } else if (element.isField) {
-      FieldElement field = element;
-      if (field.isFinal) {
-        inferrer.recordTypeOfField(field, rhsType);
-      } else {
-        if (analyzedElement.isGenerativeConstructor) {
-          locals.updateField(field, rhsType);
-        }
-        if (visitingInitializers) {
-          inferrer.recordTypeOfField(field, rhsType);
-        } else {
-          handleDynamicSend(CallType.complex, node, setterSelector, setterMask,
-              receiverType, arguments);
-        }
-      }
-    } else if (element.isLocal) {
-      LocalElement local = element;
-      ast.SendSet sendSet = node.asSendSet();
-      bool isSetIfNull = sendSet != null && sendSet.isIfNullAssignment;
-      locals.update(local, rhsType, node, local.type, isSetIfNull: isSetIfNull);
-    }
-    return rhsType;
-  }
-
-  /// Handle a super access or invocation that results in a `noSuchMethod` call.
-  TypeInformation handleErroneousSuperSend(ast.Send node) {
-    ArgumentsTypes arguments =
-        node.isPropertyAccess ? null : analyzeArguments(node.arguments);
-    Selector selector = elements.getSelector(node);
-    TypeMask mask = memberData.typeOfSend(node);
-    // TODO(herhut): We could do better here if we knew what we
-    // are calling does not expose this.
-    // TODO(johnniwinther): Do we still need this when calling directly?
-    isThisExposed = true;
-    return handleSuperNoSuchMethod(node, selector, mask, arguments);
-  }
-
-  TypeInformation handleSuperNoSuchMethod(ast.Send node, Selector selector,
-      TypeMask mask, ArgumentsTypes arguments) {
-    // Ensure we create a node, to make explicit the call to the
-    // `noSuchMethod` handler.
-    ClassElement cls = outermostElement.enclosingClass;
-    MethodElement element = cls.lookupSuperMember(Identifiers.noSuchMethod_);
-    if (!Selectors.noSuchMethod_.signatureApplies(element)) {
-      ClassElement objectClass = closedWorld.commonElements.objectClass;
-      element = objectClass.lookupMember(Identifiers.noSuchMethod_);
-    }
-    return handleStaticSend(node, selector, mask, element, arguments);
-  }
-
-  /// Handle a .call invocation on the values retrieved from the super
-  /// [element]. For instance `super.foo(bar)` where `foo` is a field or getter.
-  TypeInformation handleSuperClosureCall(
-      ast.Send node, MemberElement element, ast.NodeList arguments) {
-    ArgumentsTypes argumentTypes = analyzeArguments(arguments.nodes);
-    Selector selector = elements.getSelector(node);
-    TypeMask mask = memberData.typeOfSend(node);
-    // TODO(herhut): We could do better here if we knew what we
-    // are calling does not expose this.
-    isThisExposed = true;
-    return inferrer.registerCalledClosure(
-        node,
-        selector,
-        mask,
-        inferrer.typeOfMember(element),
-        outermostElement,
-        argumentTypes,
-        sideEffectsBuilder,
-        inLoop: inLoop);
-  }
-
-  /// Handle an invocation of super [method].
-  TypeInformation handleSuperMethodInvoke(
-      ast.Send node, MethodElement method, ArgumentsTypes arguments) {
-    // TODO(herhut): We could do better here if we knew what we
-    // are calling does not expose this.
-    isThisExposed = true;
-    Selector selector = elements.getSelector(node);
-    TypeMask mask = memberData.typeOfSend(node);
-    return handleStaticSend(node, selector, mask, method, arguments);
-  }
-
-  /// Handle access to a super field or getter [element].
-  TypeInformation handleSuperGet(ast.Send node, Element element) {
-    // TODO(herhut): We could do better here if we knew what we
-    // are calling does not expose this.
-    isThisExposed = true;
-    Selector selector = elements.getSelector(node);
-    TypeMask mask = memberData.typeOfSend(node);
-    return handleStaticSend(node, selector, mask, element, null);
-  }
-
-  /// Handle update to a super field or setter [element].
-  TypeInformation handleSuperSet(ast.Send node, Element element, ast.Node rhs) {
-    TypeInformation rhsType = visit(rhs);
-    // TODO(herhut): We could do better here if we knew what we
-    // are calling does not expose this.
-    isThisExposed = true;
-    Selector selector = elements.getSelector(node);
-    TypeMask mask = memberData.typeOfSend(node);
-    handleStaticSend(
-        node, selector, mask, element, new ArgumentsTypes([rhsType], null));
-    return rhsType;
-  }
-
-  @override
-  TypeInformation visitSuperFieldSet(
-      ast.Send node, FieldElement method, ast.Node rhs, _) {
-    return handleSuperSet(node, method, rhs);
-  }
-
-  @override
-  TypeInformation visitSuperSetterSet(
-      ast.SendSet node, SetterElement field, ast.Node rhs, _) {
-    return handleSuperSet(node, field, rhs);
-  }
-
-  @override
-  TypeInformation visitUnresolvedSuperIndex(
-      ast.Send node, Element element, ast.Node index, _) {
-    return handleErroneousSuperSend(node);
-  }
-
-  @override
-  TypeInformation visitUnresolvedSuperUnary(
-      ast.Send node, op.UnaryOperator operator, Element element, _) {
-    return handleErroneousSuperSend(node);
-  }
-
-  @override
-  TypeInformation visitUnresolvedSuperBinary(ast.Send node, Element element,
-      op.BinaryOperator operator, ast.Node argument, _) {
-    return handleErroneousSuperSend(node);
-  }
-
-  @override
-  TypeInformation visitUnresolvedSuperGet(ast.Send node, Element element, _) {
-    return handleErroneousSuperSend(node);
-  }
-
-  @override
-  TypeInformation visitSuperSetterGet(ast.Send node, MethodElement setter, _) {
-    return handleErroneousSuperSend(node);
-  }
-
-  @override
-  TypeInformation visitSuperGetterSet(
-      ast.Send node, GetterElement getter, ast.Node rhs, _) {
-    return handleErroneousSuperSend(node);
-  }
-
-  @override
-  TypeInformation visitSuperMethodSet(
-      ast.SendSet node, MethodElement method, ast.Node rhs, _) {
-    return handleErroneousSuperSend(node);
-  }
-
-  @override
-  TypeInformation visitFinalSuperFieldSet(
-      ast.Send node, FieldElement method, ast.Node rhs, _) {
-    return handleErroneousSuperSend(node);
-  }
-
-  @override
-  TypeInformation visitUnresolvedSuperSet(
-      ast.Send node, Element element, ast.Node rhs, _) {
-    return handleErroneousSuperSend(node);
-  }
-
-  @override
-  TypeInformation visitUnresolvedSuperInvoke(
-      ast.Send node, Element element, ast.Node argument, Selector selector, _) {
-    return handleErroneousSuperSend(node);
-  }
-
-  @override
-  TypeInformation visitSuperFieldGet(ast.Send node, FieldElement field, _) {
-    return handleSuperGet(node, field);
-  }
-
-  @override
-  TypeInformation visitSuperGetterGet(ast.Send node, MethodElement method, _) {
-    return handleSuperGet(node, method);
-  }
-
-  @override
-  TypeInformation visitSuperMethodGet(ast.Send node, MethodElement method, _) {
-    return handleSuperGet(node, method);
-  }
-
-  @override
-  TypeInformation visitSuperFieldInvoke(ast.Send node, FieldElement field,
-      ast.NodeList arguments, CallStructure callStructure, _) {
-    return handleSuperClosureCall(node, field, arguments);
-  }
-
-  @override
-  TypeInformation visitSuperGetterInvoke(ast.Send node, GetterElement getter,
-      ast.NodeList arguments, CallStructure callStructure, _) {
-    return handleSuperClosureCall(node, getter, arguments);
-  }
-
-  @override
-  TypeInformation visitSuperMethodInvoke(ast.Send node, MethodElement method,
-      ast.NodeList arguments, CallStructure callStructure, _) {
-    return handleSuperMethodInvoke(
-        node, method, analyzeArguments(arguments.nodes));
-  }
-
-  @override
-  TypeInformation visitSuperSetterInvoke(ast.Send node, SetterElement setter,
-      ast.NodeList arguments, CallStructure callStructure, _) {
-    return handleErroneousSuperSend(node);
-  }
-
-  @override
-  TypeInformation visitSuperIndex(
-      ast.Send node, MethodElement method, ast.Node index, _) {
-    return handleSuperMethodInvoke(
-        node, method, analyzeArguments(node.arguments));
-  }
-
-  @override
-  TypeInformation visitSuperEquals(
-      ast.Send node, MethodElement method, ast.Node argument, _) {
-    // TODO(johnniwinther): Special case ==.
-    return handleSuperMethodInvoke(
-        node, method, analyzeArguments(node.arguments));
-  }
-
-  @override
-  TypeInformation visitSuperNotEquals(
-      ast.Send node, MethodElement method, ast.Node argument, _) {
-    // TODO(johnniwinther): Special case !=.
-    return handleSuperMethodInvoke(
-        node, method, analyzeArguments(node.arguments));
-  }
-
-  @override
-  TypeInformation visitSuperBinary(ast.Send node, MethodElement method,
-      op.BinaryOperator operator, ast.Node argument, _) {
-    return handleSuperMethodInvoke(
-        node, method, analyzeArguments(node.arguments));
-  }
-
-  @override
-  TypeInformation visitSuperUnary(
-      ast.Send node, op.UnaryOperator operator, MethodElement method, _) {
-    return handleSuperMethodInvoke(
-        node, method, analyzeArguments(node.arguments));
-  }
-
-  @override
-  TypeInformation visitSuperMethodIncompatibleInvoke(
-      ast.Send node,
-      MethodElement method,
-      ast.NodeList arguments,
-      CallStructure callStructure,
-      _) {
-    return handleErroneousSuperSend(node);
-  }
-
-  // Try to find the length given to a fixed array constructor call.
-  int findLength(ast.Send node) {
-    ast.Node firstArgument = node.arguments.head;
-    Element element = elements[firstArgument];
-    ast.LiteralInt length = firstArgument.asLiteralInt();
-    if (length != null) {
-      return length.value;
-    } else if (element != null &&
-        element.isField &&
-        Elements.isStaticOrTopLevelField(element)) {
-      FieldElement fieldElement = element;
-      if (closedWorld.fieldNeverChanges(fieldElement)) {
-        ConstantValue value =
-            compiler.backend.constants.getConstantValue(fieldElement.constant);
-        if (value != null && value.isInt) {
-          IntConstantValue intValue = value;
-          return intValue.intValue;
-        }
-      }
-    }
-    return null;
-  }
-
-  TypeInformation visitAwait(ast.Await node) {
-    TypeInformation futureType = node.expression.accept(this);
-    return inferrer.registerAwait(node, futureType);
-  }
-
-  TypeInformation visitYield(ast.Yield node) {
-    TypeInformation operandType = node.expression.accept(this);
-    return inferrer.registerYield(node, operandType);
-  }
-
-  TypeInformation handleTypeLiteralInvoke(ast.NodeList arguments) {
-    // This is reached when users forget to put a `new` in front of a type
-    // literal. The emitter will generate an actual call (even though it is
-    // likely invalid), and for that it needs to have the arguments processed
-    // as well.
-    analyzeArguments(arguments.nodes);
-    return types.dynamicType;
-  }
-
-  /// Handle constructor invocation of [constructor].
-  TypeInformation handleConstructorSend(
-      ast.Send node, ConstructorElement constructor) {
-    ConstructorElement target = constructor.implementation;
-    ArgumentsTypes arguments = analyzeArguments(node.arguments);
-    if (visitingInitializers) {
-      if (ast.Initializers.isConstructorRedirect(node)) {
-        isConstructorRedirect = true;
-      } else if (ast.Initializers.isSuperConstructorCall(node)) {
-        seenSuperConstructorCall = true;
-        analyzeSuperConstructorCall(constructor);
-      }
-    }
-    // If we are looking at a new expression on a forwarding factory, we have to
-    // forward the call to the effective target of the factory.
-    // TODO(herhut): Remove the loop once effectiveTarget forwards to patches.
-    while (target.isFactoryConstructor) {
-      if (!target.isRedirectingFactory) break;
-      target = target.effectiveTarget.implementation;
-    }
-    if (closedWorld.commonElements.isForeign(target)) {
-      return handleForeignSend(node, target);
-    }
-    Selector selector = elements.getSelector(node);
-    CallStructure callStructure = selector.callStructure;
-    TypeMask mask = memberData.typeOfSend(node);
-    // In erroneous code the number of arguments in the selector might not
-    // match the function element.
-    // TODO(polux): return nonNullEmpty and check it doesn't break anything
-    if (target.isMalformed ||
-        !callStructure.signatureApplies(target.parameterStructure)) {
-      return types.dynamicType;
-    }
-
-    TypeInformation returnType =
-        handleStaticSend(node, selector, mask, target.declaration, arguments);
-    if (Elements.isGrowableListConstructorCall(
-        constructor, node, closedWorld.commonElements)) {
-      return inferrer.concreteTypes.putIfAbsent(
-          node,
-          () => types.allocateList(types.growableListType, node,
-              outermostElement, types.nonNullEmpty(), 0));
-    } else if (Elements.isFixedListConstructorCall(
-            constructor, node, closedWorld.commonElements) ||
-        Elements.isFilledListConstructorCall(
-            constructor, node, closedWorld.commonElements)) {
-      int length = findLength(node);
-      TypeInformation elementType = Elements.isFixedListConstructorCall(
-              constructor, node, closedWorld.commonElements)
-          ? types.nullType
-          : arguments.positional[1];
-
-      return inferrer.concreteTypes.putIfAbsent(
-          node,
-          () => types.allocateList(types.fixedListType, node, outermostElement,
-              elementType, length));
-    } else if (Elements.isConstructorOfTypedArraySubclass(
-        constructor, closedWorld)) {
-      int length = findLength(node);
-      MemberElement member = target.enclosingClass.lookupMember('[]');
-      TypeInformation elementType = inferrer.returnTypeOfMember(member);
-      return inferrer.concreteTypes.putIfAbsent(
-          node,
-          () => types.allocateList(types.nonNullExact(target.enclosingClass),
-              node, outermostElement, elementType, length));
-    } else {
-      return returnType;
-    }
-  }
-
-  @override
-  TypeInformation bulkHandleNew(ast.NewExpression node, _) {
-    Element element = elements[node.send];
-    return handleConstructorSend(node.send, element);
-  }
-
-  @override
-  TypeInformation errorNonConstantConstructorInvoke(
-      ast.NewExpression node,
-      Element element,
-      ResolutionDartType type,
-      ast.NodeList arguments,
-      CallStructure callStructure,
-      _) {
-    return bulkHandleNew(node, _);
-  }
-
-  /// Handle invocation of a top level or static field or getter [element].
-  TypeInformation handleStaticFieldOrGetterInvoke(
-      ast.Send node, MemberElement element) {
-    ArgumentsTypes arguments = analyzeArguments(node.arguments);
-    Selector selector = elements.getSelector(node);
-    TypeMask mask = memberData.typeOfSend(node);
-    handleStaticSend(node, selector, mask, element, arguments);
-    return inferrer.registerCalledClosure(
-        node,
-        selector,
-        mask,
-        inferrer.typeOfMember(element),
-        outermostElement,
-        arguments,
-        sideEffectsBuilder,
-        inLoop: inLoop);
-  }
-
-  /// Handle invocation of a top level or static [function].
-  TypeInformation handleStaticFunctionInvoke(
-      ast.Send node, MethodElement function) {
-    if (closedWorld.commonElements.isForeign(function)) {
-      return handleForeignSend(node, function);
-    }
-    ArgumentsTypes arguments = analyzeArguments(node.arguments);
-    Selector selector = elements.getSelector(node);
-    TypeMask mask = memberData.typeOfSend(node);
-    return handleStaticSend(node, selector, mask, function, arguments);
-  }
-
-  /// Handle an static invocation of an unresolved target or with incompatible
-  /// arguments to a resolved target.
-  TypeInformation handleInvalidStaticInvoke(ast.Send node) {
-    analyzeArguments(node.arguments);
-    return types.dynamicType;
-  }
-
-  @override
-  TypeInformation visitStaticFieldInvoke(ast.Send node, FieldElement field,
-      ast.NodeList arguments, CallStructure callStructure, _) {
-    return handleStaticFieldOrGetterInvoke(node, field);
-  }
-
-  @override
-  TypeInformation visitStaticFunctionInvoke(
-      ast.Send node,
-      MethodElement function,
-      ast.NodeList arguments,
-      CallStructure callStructure,
-      _) {
-    return handleStaticFunctionInvoke(node, function);
-  }
-
-  @override
-  TypeInformation visitStaticFunctionIncompatibleInvoke(
-      ast.Send node,
-      MethodElement function,
-      ast.NodeList arguments,
-      CallStructure callStructure,
-      _) {
-    return handleInvalidStaticInvoke(node);
-  }
-
-  @override
-  TypeInformation visitStaticGetterInvoke(ast.Send node, GetterElement getter,
-      ast.NodeList arguments, CallStructure callStructure, _) {
-    return handleStaticFieldOrGetterInvoke(node, getter);
-  }
-
-  @override
-  TypeInformation visitTopLevelFieldInvoke(ast.Send node, FieldElement field,
-      ast.NodeList arguments, CallStructure callStructure, _) {
-    return handleStaticFieldOrGetterInvoke(node, field);
-  }
-
-  @override
-  TypeInformation visitTopLevelFunctionInvoke(
-      ast.Send node,
-      MethodElement function,
-      ast.NodeList arguments,
-      CallStructure callStructure,
-      _) {
-    return handleStaticFunctionInvoke(node, function);
-  }
-
-  @override
-  TypeInformation visitTopLevelFunctionIncompatibleInvoke(
-      ast.Send node,
-      MethodElement function,
-      ast.NodeList arguments,
-      CallStructure callStructure,
-      _) {
-    return handleInvalidStaticInvoke(node);
-  }
-
-  @override
-  TypeInformation visitTopLevelGetterInvoke(ast.Send node, GetterElement getter,
-      ast.NodeList arguments, CallStructure callStructure, _) {
-    if (getter.isDeferredLoaderGetter) {
-      return types.dynamicType;
-    }
-    return handleStaticFieldOrGetterInvoke(node, getter);
-  }
-
-  @override
-  TypeInformation visitStaticSetterInvoke(ast.Send node, MethodElement setter,
-      ast.NodeList arguments, CallStructure callStructure, _) {
-    return handleInvalidStaticInvoke(node);
-  }
-
-  @override
-  TypeInformation visitTopLevelSetterInvoke(ast.Send node, MethodElement setter,
-      ast.NodeList arguments, CallStructure callStructure, _) {
-    return handleInvalidStaticInvoke(node);
-  }
-
-  @override
-  TypeInformation visitUnresolvedInvoke(ast.Send node, Element element,
-      ast.NodeList arguments, Selector selector, _) {
-    return handleInvalidStaticInvoke(node);
-  }
-
-  TypeInformation handleForeignSend(ast.Send node, Element element) {
-    ArgumentsTypes arguments = analyzeArguments(node.arguments);
-    Selector selector = elements.getSelector(node);
-    TypeMask mask = memberData.typeOfSend(node);
-    String name = element.name;
-    handleStaticSend(node, selector, mask, element, arguments);
-    if (name == JavaScriptBackend.JS ||
-        name == JavaScriptBackend.JS_EMBEDDED_GLOBAL ||
-        name == JavaScriptBackend.JS_BUILTIN) {
-      native.NativeBehavior nativeBehavior = elements.getNativeData(node);
-      sideEffectsBuilder.add(nativeBehavior.sideEffects);
-      return inferrer.typeOfNativeBehavior(nativeBehavior);
-    } else if (name == JavaScriptBackend.JS_STRING_CONCAT) {
-      return types.stringType;
-    } else {
-      sideEffectsBuilder.setAllSideEffects();
-      return types.dynamicType;
-    }
-  }
-
-  ArgumentsTypes analyzeArguments(Link<ast.Node> arguments) {
-    List positional = [];
-    Map<String, TypeInformation> named;
-    for (var argument in arguments) {
-      ast.NamedArgument namedArgument = argument.asNamedArgument();
-      if (namedArgument != null) {
-        argument = namedArgument.expression;
-        if (named == null) named = new Map<String, TypeInformation>();
-        named[namedArgument.name.source] = argument.accept(this);
-      } else {
-        positional.add(argument.accept(this));
-      }
-      // TODO(ngeoffray): We could do better here if we knew what we
-      // are calling does not expose this.
-      isThisExposed = isThisExposed || argument.isThis();
-    }
-    return new ArgumentsTypes(positional, named);
-  }
-
-  /// Read a local variable, function or parameter.
-  TypeInformation handleLocalGet(ast.Send node, LocalElement local) {
-    assert(locals.use(local) != null);
-    return locals.use(local);
-  }
-
-  /// Read a static or top level field.
-  TypeInformation handleStaticFieldGet(ast.Send node, FieldElement field) {
-    Selector selector = elements.getSelector(node);
-    TypeMask mask = memberData.typeOfSend(node);
-    return handleStaticSend(node, selector, mask, field, null);
-  }
-
-  /// Invoke a static or top level getter.
-  TypeInformation handleStaticGetterGet(ast.Send node, GetterElement getter) {
-    Selector selector = elements.getSelector(node);
-    TypeMask mask = memberData.typeOfSend(node);
-    return handleStaticSend(node, selector, mask, getter, null);
-  }
-
-  /// Closurize a static or top level function.
-  TypeInformation handleStaticFunctionGet(
-      ast.Send node, MethodElement function) {
-    Selector selector = elements.getSelector(node);
-    TypeMask mask = memberData.typeOfSend(node);
-    return handleStaticSend(node, selector, mask, function, null);
-  }
-
-  @override
-  TypeInformation visitDynamicPropertyGet(
-      ast.Send node, ast.Node receiver, Name name, _) {
-    return handleDynamicGet(node);
-  }
-
-  @override
-  TypeInformation visitIfNotNullDynamicPropertyGet(
-      ast.Send node, ast.Node receiver, Name name, _) {
-    return handleDynamicGet(node);
-  }
-
-  @override
-  TypeInformation visitLocalVariableGet(
-      ast.Send node, LocalVariableElement variable, _) {
-    return handleLocalGet(node, variable);
-  }
-
-  @override
-  TypeInformation visitParameterGet(
-      ast.Send node, ParameterElement parameter, _) {
-    return handleLocalGet(node, parameter);
-  }
-
-  @override
-  TypeInformation visitLocalFunctionGet(
-      ast.Send node, LocalFunctionElement function, _) {
-    return handleLocalGet(node, function);
-  }
-
-  @override
-  TypeInformation visitStaticFieldGet(ast.Send node, FieldElement field, _) {
-    return handleStaticFieldGet(node, field);
-  }
-
-  @override
-  TypeInformation visitStaticFunctionGet(
-      ast.Send node, MethodElement function, _) {
-    return handleStaticFunctionGet(node, function);
-  }
-
-  @override
-  TypeInformation visitStaticGetterGet(ast.Send node, GetterElement getter, _) {
-    return handleStaticGetterGet(node, getter);
-  }
-
-  @override
-  TypeInformation visitThisPropertyGet(ast.Send node, Name name, _) {
-    return handleDynamicGet(node);
-  }
-
-  @override
-  TypeInformation visitTopLevelFieldGet(ast.Send node, FieldElement field, _) {
-    return handleStaticFieldGet(node, field);
-  }
-
-  @override
-  TypeInformation visitTopLevelFunctionGet(
-      ast.Send node, MethodElement function, _) {
-    return handleStaticFunctionGet(node, function);
-  }
-
-  @override
-  TypeInformation visitTopLevelGetterGet(
-      ast.Send node, GetterElement getter, _) {
-    if (getter.isDeferredLoaderGetter) {
-      return types.functionType;
-    }
-    return handleStaticGetterGet(node, getter);
-  }
-
-  @override
-  TypeInformation visitStaticSetterGet(ast.Send node, MethodElement setter, _) {
-    return types.dynamicType;
-  }
-
-  @override
-  TypeInformation visitTopLevelSetterGet(
-      ast.Send node, MethodElement setter, _) {
-    return types.dynamicType;
-  }
-
-  @override
-  TypeInformation visitUnresolvedGet(ast.Send node, Element element, _) {
-    return types.dynamicType;
-  }
-
-  /// Handle .call invocation on [closure].
-  TypeInformation handleCallInvoke(ast.Send node, TypeInformation closure) {
-    ArgumentsTypes arguments = analyzeArguments(node.arguments);
-    Selector selector = elements.getSelector(node);
-    TypeMask mask = memberData.typeOfSend(node);
-    return handleDynamicSend(
-        CallType.access, node, selector, mask, closure, arguments);
-  }
-
-  @override
-  TypeInformation visitExpressionInvoke(ast.Send node, ast.Node expression,
-      ast.NodeList arguments, CallStructure callStructure, _) {
-    return handleCallInvoke(node, expression.accept(this));
-  }
-
-  @override
-  TypeInformation visitThisInvoke(
-      ast.Send node, ast.NodeList arguments, CallStructure callStructure, _) {
-    return handleCallInvoke(node, thisType);
-  }
-
-  @override
-  TypeInformation visitParameterInvoke(
-      ast.Send node,
-      ParameterElement parameter,
-      ast.NodeList arguments,
-      CallStructure callStructure,
-      _) {
-    return handleCallInvoke(node, locals.use(parameter));
-  }
-
-  @override
-  TypeInformation visitLocalVariableInvoke(
-      ast.Send node,
-      LocalVariableElement variable,
-      ast.NodeList arguments,
-      CallStructure callStructure,
-      _) {
-    return handleCallInvoke(node, locals.use(variable));
-  }
-
-  @override
-  TypeInformation visitLocalFunctionInvoke(
-      ast.Send node,
-      LocalFunctionElement function,
-      ast.NodeList arguments,
-      CallStructure callStructure,
-      _) {
-    ArgumentsTypes argumentTypes = analyzeArguments(node.arguments);
-    Selector selector = elements.getSelector(node);
-    TypeMask mask = memberData.typeOfSend(node);
-    // This only works for function statements. We need a
-    // more sophisticated type system with function types to support
-    // more.
-    return inferrer.registerCalledMember(node, selector, mask, outermostElement,
-        function.callMethod, argumentTypes, sideEffectsBuilder, inLoop);
-  }
-
-  @override
-  TypeInformation visitLocalFunctionIncompatibleInvoke(
-      ast.Send node,
-      LocalFunctionElement function,
-      ast.NodeList arguments,
-      CallStructure callStructure,
-      _) {
-    analyzeArguments(node.arguments);
-    return types.dynamicType;
-  }
-
-  TypeInformation handleStaticSend(ast.Node node, Selector selector,
-      TypeMask mask, MemberElement element, ArgumentsTypes arguments) {
-    assert(element.isDeclaration);
-    assert(!element.isFactoryConstructor ||
-        !(element as ConstructorElement).isRedirectingFactory);
-    // Erroneous elements may be unresolved, for example missing getters.
-    if (Elements.isUnresolved(element)) return types.dynamicType;
-    // TODO(herhut): should we follow redirecting constructors here? We would
-    // need to pay attention if the constructor is pointing to an erroneous
-    // element.
-    return inferrer.registerCalledMember(node, selector, mask, outermostElement,
-        element, arguments, sideEffectsBuilder, inLoop);
-  }
-
-  TypeInformation handleDynamicSend(
-      CallType callType,
-      ast.Node node,
-      Selector selector,
-      TypeMask mask,
-      TypeInformation receiverType,
-      ArgumentsTypes arguments) {
-    assert(receiverType != null);
-    if (types.selectorNeedsUpdate(receiverType, mask)) {
-      mask = receiverType == types.dynamicType
-          ? null
-          : types.newTypedSelector(receiverType, mask);
-      inferrer.updateSelectorInMember(
-          outermostElement, callType, node, selector, mask);
-    }
-
-    // If the receiver of the call is a local, we may know more about
-    // its type by refining it with the potential targets of the
-    // calls.
-    ast.Send send = node.asSend();
-    bool isConditional = false;
-    if (send != null) {
-      isConditional = send.isConditional;
-      ast.Send receiver = send.receiver?.asSend();
-      Element element;
-      if (receiver != null && receiver.isPropertyAccess) {
-        // We have `local.method()` || `local?.method()`.
-        element = elements[receiver];
-      } else if (send.receiver == null) {
-        // We have `local()`.
-        element = elements[send];
-      }
-      if (Elements.isLocal(element) && !capturedVariables.contains(element)) {
-        TypeInformation refinedType = types.refineReceiver(
-            selector, mask, receiverType,
-            isConditional: send.isConditional);
-        LocalElement local = element;
-        locals.update(local, refinedType, node, local.type);
-      }
-      // TODO(johnniwinther): Enable this to improve precision of conditional
-      // access. This cannot currently be done because the receiver and the
-      // call shares type mask.
-      /*if (isConditional) {
-      receiverType = types.narrowNotNull(receiverType);
-      }*/
-    }
-
-    return inferrer.registerCalledSelector(callType, node, selector, mask,
-        receiverType, outermostElement, arguments, sideEffectsBuilder,
-        inLoop: inLoop, isConditional: isConditional);
-  }
-
-  TypeInformation handleDynamicInvoke(ast.Send node) {
-    return _handleDynamicSend(node);
-  }
-
-  TypeInformation handleDynamicGet(ast.Send node) {
-    return _handleDynamicSend(node);
-  }
-
-  TypeInformation _handleDynamicSend(ast.Send node) {
-    Element element = elements[node];
-    TypeInformation receiverType;
-    bool isCallOnThis = false;
-    if (node.receiver == null) {
-      if (treatAsInstanceMember(element)) {
-        isCallOnThis = true;
-        receiverType = thisType;
-      }
-    } else {
-      ast.Node receiver = node.receiver;
-      isCallOnThis = isThisOrSuper(receiver);
-      receiverType = visit(receiver);
-    }
-
-    Selector selector = elements.getSelector(node);
-    TypeMask mask = memberData.typeOfSend(node);
-    if (!isThisExposed && isCallOnThis) {
-      checkIfExposesThis(selector, types.newTypedSelector(receiverType, mask));
-    }
-
-    ArgumentsTypes arguments =
-        node.isPropertyAccess ? null : analyzeArguments(node.arguments);
-    if (selector.name == '==' || selector.name == '!=') {
-      if (types.isNull(receiverType)) {
-        potentiallyAddNullCheck(node, node.arguments.head);
-        return types.boolType;
-      } else if (types.isNull(arguments.positional[0])) {
-        potentiallyAddNullCheck(node, node.receiver);
-        return types.boolType;
-      }
-    }
-    return handleDynamicSend(
-        CallType.access, node, selector, mask, receiverType, arguments);
-  }
-
-  void recordReturnType(TypeInformation type) {
-    MethodElement analyzedMethod = analyzedElement;
-    returnType =
-        inferrer.addReturnTypeForMethod(analyzedMethod, returnType, type);
-  }
-
-  TypeInformation synthesizeForwardingCall(
-      Spannable node, ConstructorElement element) {
-    assert(element.isDeclaration);
-    MethodElement function = analyzedElement.implementation;
-    FunctionSignature signature = function.functionSignature;
-    FunctionSignature calleeSignature = element.functionSignature;
-    if (!calleeSignature.isCompatibleWith(signature)) {
-      return types.nonNullEmpty();
-    }
-
-    List<TypeInformation> unnamed = <TypeInformation>[];
-    signature.forEachRequiredParameter((FormalElement _element) {
-      ParameterElement element = _element;
-      assert(locals.use(element) != null);
-      unnamed.add(locals.use(element));
-    });
-
-    Map<String, TypeInformation> named;
-    if (signature.optionalParametersAreNamed) {
-      named = new Map<String, TypeInformation>();
-      signature.forEachOptionalParameter((FormalElement _element) {
-        ParameterElement element = _element;
-        named[element.name] = locals.use(element);
-      });
-    } else {
-      signature.forEachOptionalParameter((FormalElement _element) {
-        ParameterElement element = _element;
-        unnamed.add(locals.use(element));
-      });
-    }
-
-    ArgumentsTypes arguments = new ArgumentsTypes(unnamed, named);
-    return inferrer.registerCalledMember(node, null, null, outermostElement,
-        element, arguments, sideEffectsBuilder, inLoop);
-  }
-
-  TypeInformation visitRedirectingFactoryBody(ast.RedirectingFactoryBody node) {
-    ConstructorElement element = elements.getRedirectingTargetConstructor(node);
-    if (Elements.isMalformed(element)) {
-      recordReturnType(types.dynamicType);
-    } else {
-      // We don't create a selector for redirecting factories, and
-      // the send is just a property access. Therefore we must
-      // manually create the [ArgumentsTypes] of the call, and
-      // manually register [analyzedElement] as a caller of [element].
-      TypeInformation mask =
-          synthesizeForwardingCall(node.constructorReference, element);
-      recordReturnType(mask);
-    }
-    locals.seenReturnOrThrow = true;
-    return null;
-  }
-
-  TypeInformation visitReturn(ast.Return node) {
-    ast.Node expression = node.expression;
-    recordReturnType(
-        expression == null ? types.nullType : expression.accept(this));
-    locals.seenReturnOrThrow = true;
-    initializationIsIndefinite();
-    return null;
-  }
-
-  TypeInformation handleForInLoop(
-      ast.ForIn node,
-      TypeInformation iteratorType,
-      Selector currentSelector,
-      TypeMask currentMask,
-      Selector moveNextSelector,
-      TypeMask moveNextMask) {
-    handleDynamicSend(CallType.forIn, node, moveNextSelector, moveNextMask,
-        iteratorType, new ArgumentsTypes.empty());
-    TypeInformation currentType = handleDynamicSend(CallType.forIn, node,
-        currentSelector, currentMask, iteratorType, new ArgumentsTypes.empty());
-
-    if (node.expression.isThis()) {
-      // Any reasonable implementation of an iterator would expose
-      // this, so we play it safe and assume it will.
-      isThisExposed = true;
-    }
-
-    ast.Node identifier = node.declaredIdentifier;
-    Element element = elements.getForInVariable(node);
-    Selector selector = elements.getSelector(identifier);
-    TypeMask mask = memberData.typeOfSend(identifier.asSend());
-
-    TypeInformation receiverType;
-    if (element != null && element.isInstanceMember) {
-      receiverType = thisType;
-    } else {
-      receiverType = types.dynamicType;
-    }
-
-    handlePlainAssignment(identifier, element, selector, mask, receiverType,
-        currentType, node.expression);
-    return handleLoop(node, () {
-      visit(node.body);
-    });
-  }
-
-  TypeInformation visitAsyncForIn(ast.AsyncForIn node) {
-    TypeInformation expressionType = visit(node.expression);
-
-    Selector currentSelector = Selectors.current;
-    TypeMask currentMask = memberData.typeOfIteratorCurrent(node);
-    Selector moveNextSelector = Selectors.moveNext;
-    TypeMask moveNextMask = memberData.typeOfIteratorMoveNext(node);
-
-    ConstructorElement ctor =
-        closedWorld.commonElements.streamIteratorConstructor;
-
-    /// Synthesize a call to the [StreamIterator] constructor.
-    TypeInformation iteratorType = handleStaticSend(
-        node, null, null, ctor, new ArgumentsTypes([expressionType], null));
-
-    return handleForInLoop(node, iteratorType, currentSelector, currentMask,
-        moveNextSelector, moveNextMask);
-  }
-
-  TypeInformation visitSyncForIn(ast.SyncForIn node) {
-    TypeInformation expressionType = visit(node.expression);
-    Selector iteratorSelector = Selectors.iterator;
-    TypeMask iteratorMask = memberData.typeOfIterator(node);
-    Selector currentSelector = Selectors.current;
-    TypeMask currentMask = memberData.typeOfIteratorCurrent(node);
-    Selector moveNextSelector = Selectors.moveNext;
-    TypeMask moveNextMask = memberData.typeOfIteratorMoveNext(node);
-
-    TypeInformation iteratorType = handleDynamicSend(
-        CallType.forIn,
-        node,
-        iteratorSelector,
-        iteratorMask,
-        expressionType,
-        new ArgumentsTypes.empty());
-
-    return handleForInLoop(node, iteratorType, currentSelector, currentMask,
-        moveNextSelector, moveNextMask);
-  }
-}
diff --git a/pkg/compiler/lib/src/inferrer/builder_kernel.dart b/pkg/compiler/lib/src/inferrer/builder_kernel.dart
index 6d6b2f5..2998bbf 100644
--- a/pkg/compiler/lib/src/inferrer/builder_kernel.dart
+++ b/pkg/compiler/lib/src/inferrer/builder_kernel.dart
@@ -18,6 +18,7 @@
 import '../native/behavior.dart';
 import '../options.dart';
 import '../types/constants.dart';
+import '../types/masks.dart';
 import '../types/types.dart';
 import '../universe/selector.dart';
 import '../universe/side_effects.dart';
@@ -1536,7 +1537,8 @@
   @override
   visitTryCatch(ir.TryCatch node) {
     LocalsHandler saved = _locals;
-    _locals = new LocalsHandler.from(_locals, node, useOtherTryBlock: false);
+    _locals = new LocalsHandler.from(_locals, node,
+        isTry: true, useOtherTryBlock: false);
     initializationIsIndefinite();
     visit(node.body);
     saved.mergeDiamondFlow(_locals, null);
@@ -1553,7 +1555,8 @@
   @override
   visitTryFinally(ir.TryFinally node) {
     LocalsHandler saved = _locals;
-    _locals = new LocalsHandler.from(_locals, node, useOtherTryBlock: false);
+    _locals = new LocalsHandler.from(_locals, node,
+        isTry: true, useOtherTryBlock: false);
     initializationIsIndefinite();
     visit(node.body);
     saved.mergeDiamondFlow(_locals, null);
diff --git a/pkg/compiler/lib/src/inferrer/closure_tracer.dart b/pkg/compiler/lib/src/inferrer/closure_tracer.dart
index 1c131cb..8f785fb 100644
--- a/pkg/compiler/lib/src/inferrer/closure_tracer.dart
+++ b/pkg/compiler/lib/src/inferrer/closure_tracer.dart
@@ -7,7 +7,7 @@
 import '../common/names.dart' show Names;
 import '../elements/entities.dart';
 import '../js_backend/backend.dart' show JavaScriptBackend;
-import '../types/types.dart' show TypeMask;
+import '../types/masks.dart' show TypeMask;
 import '../universe/selector.dart' show Selector;
 import 'debug.dart' as debug;
 import 'inferrer_engine.dart';
diff --git a/pkg/compiler/lib/src/inferrer/inferrer_engine.dart b/pkg/compiler/lib/src/inferrer/inferrer_engine.dart
index 184b42e..9a5fdc1 100644
--- a/pkg/compiler/lib/src/inferrer/inferrer_engine.dart
+++ b/pkg/compiler/lib/src/inferrer/inferrer_engine.dart
@@ -10,17 +10,16 @@
 import '../compiler.dart';
 import '../common_elements.dart';
 import '../constants/values.dart';
-import '../elements/elements.dart'
-    show ConstructorElement, Elements, MemberElement, ParameterElement;
 import '../elements/entities.dart';
 import '../elements/names.dart';
 import '../js_backend/annotations.dart' as optimizerHints;
-import '../js_backend/mirrors_data.dart';
 import '../js_backend/no_such_method_registry.dart';
 import '../js_emitter/sorter.dart';
 import '../native/behavior.dart' as native;
 import '../options.dart';
+import '../types/abstract_value_domain.dart';
 import '../types/constants.dart';
+import '../types/masks.dart';
 import '../types/types.dart';
 import '../universe/call_structure.dart';
 import '../universe/selector.dart';
@@ -32,7 +31,6 @@
 import 'locals_handler.dart';
 import 'list_tracer.dart';
 import 'map_tracer.dart';
-import 'builder.dart';
 import 'type_graph_dump.dart';
 import 'type_graph_inferrer.dart';
 import 'type_graph_nodes.dart';
@@ -60,7 +58,8 @@
   ClosedWorld get closedWorld;
   ClosedWorldRefiner get closedWorldRefiner;
   DiagnosticReporter get reporter;
-  CommonMasks get commonMasks => closedWorld.abstractValueDomain;
+  AbstractValueDomain get abstractValueDomain =>
+      closedWorld.abstractValueDomain;
   CommonElements get commonElements => closedWorld.commonElements;
 
   // TODO(johnniwinther): This should be part of [ClosedWorld] or
@@ -79,8 +78,7 @@
   void analyzeMapAndEnqueue(MapTypeInformation info);
 
   /// Notifies to the inferrer that [analyzedElement] can have return type
-  /// [newType]. [currentType] is the type the [ElementGraphBuilder] currently
-  /// found.
+  /// [newType]. [currentType] is the type the inference has currently found.
   ///
   /// Returns the new type for [analyzedElement].
   TypeInformation addReturnTypeForMethod(
@@ -288,9 +286,6 @@
   final Map<MemberEntity, GlobalTypeInferenceElementData> _memberData =
       new Map<MemberEntity, GlobalTypeInferenceElementData>();
 
-  // TODO(johnniwinther): This should be accessible throught [closedWorld].
-  final MirrorsData mirrorsData;
-
   final NoSuchMethodRegistry noSuchMethodRegistry;
 
   final Sorter sorter;
@@ -302,7 +297,6 @@
       this._compilerOutput,
       this.closedWorld,
       this.closedWorldRefiner,
-      this.mirrorsData,
       this.noSuchMethodRegistry,
       this.mainElement,
       this.sorter,
@@ -332,7 +326,6 @@
    */
   void updateSideEffects(SideEffectsBuilder sideEffectsBuilder,
       Selector selector, MemberEntity callee) {
-    assert(!(callee is MemberElement && !callee.isDeclaration));
     if (callee.isField) {
       if (callee.isInstanceMember) {
         if (selector.isSetter) {
@@ -402,16 +395,6 @@
     GlobalTypeInferenceElementData data = dataOfMember(owner);
     assert(validCallType(callType, node));
     switch (callType) {
-      case CallType.complex:
-        if (selector.isSetter || selector.isIndexSet) {
-          data.setTypeMask(node, mask);
-        } else if (selector.isGetter || selector.isIndex) {
-          data.setGetterTypeMaskInComplexSendSet(node, mask);
-        } else {
-          assert(selector.isOperator);
-          data.setOperatorTypeMaskInComplexSendSet(node, mask);
-        }
-        break;
       case CallType.access:
         data.setTypeMask(node, mask);
         break;
@@ -429,12 +412,10 @@
   }
 
   bool checkIfExposesThis(ConstructorEntity element) {
-    assert(!(element is ConstructorElement && !element.isDeclaration));
     return generativeConstructorsExposingThis.contains(element);
   }
 
   void recordExposesThis(ConstructorEntity element, bool exposesThis) {
-    assert(!(element is ConstructorElement && !element.isDeclaration));
     if (exposesThis) {
       generativeConstructorsExposingThis.add(element);
     }
@@ -460,7 +441,7 @@
 
     info.bailedOut = false;
     info.elementType.inferred = true;
-    TypeMask fixedListType = commonMasks.fixedListType;
+    TypeMask fixedListType = abstractValueDomain.fixedListType;
     if (info.originalType.forwardTo == fixedListType) {
       info.checksGrowable = tracer.callsGrowableMethod;
     }
@@ -700,7 +681,6 @@
   FunctionEntity lookupCallMethod(ClassEntity cls);
 
   void analyze(MemberEntity element) {
-    assert(!(element is MemberElement && !element.isDeclaration));
     if (analyzedElements.contains(element)) return;
     analyzedElements.add(element);
 
@@ -901,7 +881,6 @@
 
   void setDefaultTypeOfParameter(Local parameter, TypeInformation type,
       {bool isInstanceMember}) {
-    assert(!(parameter is ParameterElement && !parameter.isImplementation));
     assert(
         type != null, failedAt(parameter, "No default type for $parameter."));
     TypeInformation existing = defaultTypeOfParameter[parameter];
@@ -928,14 +907,12 @@
   }
 
   TypeInformation getDefaultTypeOfParameter(Local parameter) {
-    assert(!(parameter is ParameterElement && !parameter.isImplementation));
     return defaultTypeOfParameter.putIfAbsent(parameter, () {
       return new PlaceholderTypeInformation(types.currentMember);
     });
   }
 
   bool hasAlreadyComputedTypeOfParameterDefault(Local parameter) {
-    assert(!(parameter is ParameterElement && !parameter.isImplementation));
     TypeInformation seen = defaultTypeOfParameter[parameter];
     return (seen != null && seen is! PlaceholderTypeInformation);
   }
@@ -1154,7 +1131,7 @@
       } else if (element.isGetter) {
         return returnTypeOfMember(element);
       } else {
-        assert(element is MemberElement && Elements.isUnresolved(element));
+        assert(false, failedAt(element, "Unexpected member $element"));
         return types.dynamicType;
       }
     } else if (element.isGetter || element.isField) {
@@ -1177,7 +1154,7 @@
     if ((element.isTopLevel || element.isStatic) && !element.isAssignable) {
       return true;
     }
-    return !mirrorsData.isMemberAccessibleByReflection(element);
+    return true;
   }
 
   /// Returns true if global optimizations such as type inferencing can apply to
@@ -1187,8 +1164,7 @@
   /// backend calls, but the optimizations don't see those calls.
   bool canFunctionParametersBeUsedForGlobalOptimizations(
       FunctionEntity function) {
-    return !closedWorld.backendUsage.isFunctionUsedByBackend(function) &&
-        !mirrorsData.isMemberAccessibleByReflection(function);
+    return !closedWorld.backendUsage.isFunctionUsedByBackend(function);
   }
 
   @override
diff --git a/pkg/compiler/lib/src/inferrer/kernel_inferrer_engine.dart b/pkg/compiler/lib/src/inferrer/kernel_inferrer_engine.dart
index dc823ff..7b49435 100644
--- a/pkg/compiler/lib/src/inferrer/kernel_inferrer_engine.dart
+++ b/pkg/compiler/lib/src/inferrer/kernel_inferrer_engine.dart
@@ -13,12 +13,12 @@
 import '../constants/values.dart';
 import '../elements/entities.dart';
 import '../elements/types.dart';
-import '../js_backend/mirrors_data.dart';
 import '../js_backend/no_such_method_registry.dart';
 import '../js_emitter/sorter.dart';
 import '../js_model/locals.dart';
 import '../kernel/element_map.dart';
 import '../options.dart';
+import '../types/abstract_value_domain.dart';
 import '../types/types.dart';
 import '../world.dart';
 import 'builder_kernel.dart';
@@ -56,7 +56,6 @@
         _closureDataLookup,
         closedWorld,
         closedWorldRefiner,
-        _compiler.backend.mirrorsData,
         _compiler.backend.noSuchMethodRegistry,
         main,
         _compiler.backendStrategy.sorter);
@@ -83,14 +82,13 @@
         // for closure elements.
         inferrer.inferrer.lookupDataOfMember(member),
         inferrer,
-        isJsInterop,
-        dynamicType);
+        isJsInterop);
   }
 
   GlobalTypeInferenceParameterResult<ir.Node> createParameterResult(
       TypeGraphInferrer<ir.Node> inferrer, Local parameter) {
     return new GlobalTypeInferenceParameterResultImpl<ir.Node>(
-        parameter, inferrer, dynamicType);
+        parameter, inferrer);
   }
 }
 
@@ -109,7 +107,6 @@
       this._closureDataLookup,
       ClosedWorld closedWorld,
       ClosedWorldRefiner closedWorldRefiner,
-      MirrorsData mirrorsData,
       NoSuchMethodRegistry noSuchMethodRegistry,
       FunctionEntity mainElement,
       Sorter sorter)
@@ -120,7 +117,6 @@
             compilerOutput,
             closedWorld,
             closedWorldRefiner,
-            mirrorsData,
             noSuchMethodRegistry,
             mainElement,
             sorter,
@@ -335,80 +331,65 @@
 class KernelGlobalTypeInferenceElementData
     extends GlobalTypeInferenceElementData<ir.Node> {
   // TODO(johnniwinther): Rename this together with [typeOfSend].
-  Map<ir.Node, TypeMask> _sendMap;
+  Map<ir.Node, AbstractValue> _sendMap;
 
-  Map<ir.ForInStatement, TypeMask> _iteratorMap;
-  Map<ir.ForInStatement, TypeMask> _currentMap;
-  Map<ir.ForInStatement, TypeMask> _moveNextMap;
+  Map<ir.ForInStatement, AbstractValue> _iteratorMap;
+  Map<ir.ForInStatement, AbstractValue> _currentMap;
+  Map<ir.ForInStatement, AbstractValue> _moveNextMap;
 
   @override
-  TypeMask typeOfSend(ir.Node node) {
+  AbstractValue typeOfSend(ir.Node node) {
     if (_sendMap == null) return null;
     return _sendMap[node];
   }
 
   @override
-  void setCurrentTypeMask(covariant ir.ForInStatement node, TypeMask mask) {
-    _currentMap ??= <ir.ForInStatement, TypeMask>{};
+  void setCurrentTypeMask(
+      covariant ir.ForInStatement node, AbstractValue mask) {
+    _currentMap ??= <ir.ForInStatement, AbstractValue>{};
     _currentMap[node] = mask;
   }
 
   @override
-  void setMoveNextTypeMask(covariant ir.ForInStatement node, TypeMask mask) {
-    _moveNextMap ??= <ir.ForInStatement, TypeMask>{};
+  void setMoveNextTypeMask(
+      covariant ir.ForInStatement node, AbstractValue mask) {
+    _moveNextMap ??= <ir.ForInStatement, AbstractValue>{};
     _moveNextMap[node] = mask;
   }
 
   @override
-  void setIteratorTypeMask(covariant ir.ForInStatement node, TypeMask mask) {
-    _iteratorMap ??= <ir.ForInStatement, TypeMask>{};
+  void setIteratorTypeMask(
+      covariant ir.ForInStatement node, AbstractValue mask) {
+    _iteratorMap ??= <ir.ForInStatement, AbstractValue>{};
     _iteratorMap[node] = mask;
   }
 
   @override
-  TypeMask typeOfIteratorCurrent(covariant ir.ForInStatement node) {
+  AbstractValue typeOfIteratorCurrent(covariant ir.ForInStatement node) {
     if (_currentMap == null) return null;
     return _currentMap[node];
   }
 
   @override
-  TypeMask typeOfIteratorMoveNext(covariant ir.ForInStatement node) {
+  AbstractValue typeOfIteratorMoveNext(covariant ir.ForInStatement node) {
     if (_moveNextMap == null) return null;
     return _moveNextMap[node];
   }
 
   @override
-  TypeMask typeOfIterator(covariant ir.ForInStatement node) {
+  AbstractValue typeOfIterator(covariant ir.ForInStatement node) {
     if (_iteratorMap == null) return null;
     return _iteratorMap[node];
   }
 
   @override
-  void setOperatorTypeMaskInComplexSendSet(ir.Node node, TypeMask mask) {
-    throw new UnsupportedError(
-        'KernelGlobalTypeInferenceElementData.setOperatorTypeMaskInComplexSendSet');
-  }
-
-  @override
-  void setGetterTypeMaskInComplexSendSet(ir.Node node, TypeMask mask) {
-    throw new UnsupportedError(
-        'KernelGlobalTypeInferenceElementData.setGetterTypeMaskInComplexSendSet');
-  }
-
-  @override
-  void setTypeMask(ir.Node node, TypeMask mask) {
-    _sendMap ??= <ir.Node, TypeMask>{};
+  void setTypeMask(ir.Node node, AbstractValue mask) {
+    _sendMap ??= <ir.Node, AbstractValue>{};
     _sendMap[node] = mask;
   }
 
   @override
-  TypeMask typeOfOperator(ir.Node node) {
-    throw new UnsupportedError(
-        'KernelGlobalTypeInferenceElementData.typeOfOperator');
-  }
-
-  @override
-  TypeMask typeOfGetter(ir.Node node) {
+  AbstractValue typeOfGetter(ir.Node node) {
     if (_sendMap == null) return null;
     return _sendMap[node];
   }
diff --git a/pkg/compiler/lib/src/inferrer/locals_handler.dart b/pkg/compiler/lib/src/inferrer/locals_handler.dart
index 7b0736a..26b41c7 100644
--- a/pkg/compiler/lib/src/inferrer/locals_handler.dart
+++ b/pkg/compiler/lib/src/inferrer/locals_handler.dart
@@ -5,12 +5,10 @@
 library locals_handler;
 
 import 'dart:collection' show IterableMixin;
-
+import 'package:kernel/ast.dart' as ir;
 import '../options.dart' show CompilerOptions;
-import '../elements/elements.dart';
 import '../elements/entities.dart';
 import '../elements/types.dart';
-import '../tree/tree.dart';
 import '../util/util.dart';
 import 'inferrer_engine.dart';
 import 'type_graph_nodes.dart';
@@ -32,15 +30,22 @@
   /// The [Node] that created this scope.
   final T block;
 
-  VariableScope(this.block, [parent])
+  /// `true` if this scope is for a try block.
+  final bool isTry;
+
+  VariableScope(this.block, {VariableScope parent, this.isTry})
       : this.variables = null,
-        this.parent = parent;
+        this.parent = parent {
+    assert(isTry == (block is ir.TryCatch || block is ir.TryFinally),
+        "Unexpected block $block for isTry=$isTry");
+  }
 
   VariableScope.deepCopyOf(VariableScope<T> other)
       : variables = other.variables == null
             ? null
             : new Map<Local, TypeInformation>.from(other.variables),
         block = other.block,
+        isTry = other.isTry,
         parent = other.parent == null
             ? null
             : new VariableScope.deepCopyOf(other.parent);
@@ -50,6 +55,7 @@
             ? null
             : new Map<Local, TypeInformation>.from(other.variables),
         block = other.block,
+        isTry = other.isTry,
         parent = other.parent;
 
   TypeInformation operator [](Local variable) {
@@ -261,13 +267,14 @@
 
   LocalsHandler(this.inferrer, this.types, this.options, T block,
       [this.fieldScope])
-      : locals = new VariableScope<T>(block),
+      : locals = new VariableScope<T>(block, isTry: false),
         _capturedAndBoxed = new Map<Local, FieldEntity>(),
         tryBlock = null;
 
   LocalsHandler.from(LocalsHandler<T> other, T block,
-      {bool useOtherTryBlock: true})
-      : locals = new VariableScope<T>(block, other.locals),
+      {bool isTry: false, bool useOtherTryBlock: true})
+      : locals =
+            new VariableScope<T>(block, isTry: isTry, parent: other.locals),
         fieldScope = new FieldInitializationScope<T>.from(other.fieldScope),
         _capturedAndBoxed = other._capturedAndBoxed,
         types = other.types,
@@ -295,7 +302,6 @@
         options = other.options;
 
   TypeInformation use(Local local) {
-    assert(!(local is LocalElement && !local.isImplementation));
     if (_capturedAndBoxed.containsKey(local)) {
       FieldEntity field = _capturedAndBoxed[local];
       return inferrer.typeOfMember(field);
@@ -320,7 +326,7 @@
             local,
             types.allocatePhi(
                 locals.block, local, types.narrowNotNull(currentType),
-                isTry: locals.block is TryStatement),
+                isTry: locals.isTry),
             type);
       }
       locals[local] = type;
@@ -329,7 +335,7 @@
     if (_capturedAndBoxed.containsKey(local)) {
       inferrer.recordTypeOfField(_capturedAndBoxed[local], type);
     } else if (inTryBlock) {
-      // We don'TypeInformation know if an assignment in a try block
+      // We don't know if an assignment in a try block
       // will be executed, so all assignments in that block are
       // potential types after we have left it. We update the parent
       // of the try block so that, at exit of the try block, we get
@@ -338,7 +344,7 @@
       if (existing != null) {
         TypeInformation phiType = types.allocatePhi(
             tryBlock.locals.block, local, existing,
-            isTry: tryBlock.locals.block is TryStatement);
+            isTry: tryBlock.locals.isTry);
         TypeInformation inputType = types.addPhiInput(local, phiType, type);
         tryBlock.locals.parent[local] = inputType;
       }
@@ -459,7 +465,8 @@
     // Use a separate locals handler to perform the merge in, so that Phi
     // creation does not invalidate previous type knowledge while we might
     // still look it up.
-    LocalsHandler<T> merged = new LocalsHandler<T>.from(this, level);
+    LocalsHandler<T> merged =
+        new LocalsHandler<T>.from(this, level, isTry: locals.isTry);
     Set<Local> seenLocals = new Setlet<Local>();
     bool allBranchesAbort = true;
     // Merge all other handlers.
@@ -502,7 +509,7 @@
       TypeInformation newType;
       if (seen != null && !seen.contains(local)) {
         newType = types.allocatePhi(locals.block, local, otherType,
-            isTry: locals.block is TryStatement);
+            isTry: locals.isTry);
         seen.add(local);
       } else {
         newType = types.addPhiInput(local, myType, otherType);
@@ -530,8 +537,8 @@
 
   void startLoop(T loop) {
     locals.forEachLocal((Local variable, TypeInformation type) {
-      TypeInformation newType = types.allocateLoopPhi(loop, variable, type,
-          isTry: loop is TryStatement);
+      TypeInformation newType =
+          types.allocateLoopPhi(loop, variable, type, isTry: false);
       if (newType != type) {
         locals[variable] = newType;
       }
diff --git a/pkg/compiler/lib/src/inferrer/node_tracer.dart b/pkg/compiler/lib/src/inferrer/node_tracer.dart
index b1ed67d..032b254 100644
--- a/pkg/compiler/lib/src/inferrer/node_tracer.dart
+++ b/pkg/compiler/lib/src/inferrer/node_tracer.dart
@@ -6,7 +6,7 @@
 
 import '../common/names.dart' show Identifiers;
 import '../elements/entities.dart';
-import '../types/types.dart' show ContainerTypeMask, MapTypeMask;
+import '../types/masks.dart' show ContainerTypeMask, MapTypeMask;
 import '../util/util.dart' show Setlet;
 import 'debug.dart' as debug;
 import 'inferrer_engine.dart';
diff --git a/pkg/compiler/lib/src/inferrer/type_graph_dump.dart b/pkg/compiler/lib/src/inferrer/type_graph_dump.dart
index 116eb19..d8242e9 100644
--- a/pkg/compiler/lib/src/inferrer/type_graph_dump.dart
+++ b/pkg/compiler/lib/src/inferrer/type_graph_dump.dart
@@ -4,9 +4,9 @@
 library dart2js.inferrer.type_graph_dump;
 
 import '../../compiler_new.dart';
-import '../elements/elements.dart';
 import '../elements/entities.dart';
-import '../types/types.dart';
+import '../elements/entity_utils.dart' as utils;
+import '../types/masks.dart';
 import 'inferrer_engine.dart';
 import 'type_graph_nodes.dart';
 import 'debug.dart';
@@ -116,9 +116,8 @@
         parts.add(element.name);
       }
     } else {
-      parts.add(Elements
-          .operatorNameToIdentifier(element.name)
-          .replaceAll(r'$', '-'));
+      parts.add(
+          utils.operatorNameToIdentifier(element.name).replaceAll(r'$', '-'));
     }
     String filename = parts.where((x) => x != null && x != '').join('.');
     if (usedFilenames.add(filename)) return filename;
diff --git a/pkg/compiler/lib/src/inferrer/type_graph_inferrer.dart b/pkg/compiler/lib/src/inferrer/type_graph_inferrer.dart
index b59bf9f..d6482a3 100644
--- a/pkg/compiler/lib/src/inferrer/type_graph_inferrer.dart
+++ b/pkg/compiler/lib/src/inferrer/type_graph_inferrer.dart
@@ -6,15 +6,11 @@
 
 import 'dart:collection' show Queue;
 
-import '../compiler.dart' show Compiler;
 import '../elements/entities.dart';
-import '../tree/tree.dart' as ast show Node;
-import '../types/masks.dart'
-    show CommonMasks, ContainerTypeMask, MapTypeMask, TypeMask;
+import '../types/abstract_value_domain.dart';
 import '../types/types.dart';
 import '../universe/selector.dart' show Selector;
 import '../world.dart' show ClosedWorld, ClosedWorldRefiner;
-import 'ast_inferrer_engine.dart';
 import 'inferrer_engine.dart';
 import 'type_graph_nodes.dart';
 
@@ -61,9 +57,10 @@
 
   String get name => 'Graph inferrer';
 
-  CommonMasks get commonMasks => closedWorld.abstractValueDomain;
+  AbstractValueDomain get abstractValueDomain =>
+      closedWorld.abstractValueDomain;
 
-  TypeMask get _dynamicType => commonMasks.dynamicType;
+  AbstractValue get _dynamicType => abstractValueDomain.dynamicType;
 
   void analyzeMain(FunctionEntity main) {
     inferrer = createInferrerEngineFor(main);
@@ -73,34 +70,34 @@
 
   InferrerEngine<T> createInferrerEngineFor(FunctionEntity main);
 
-  TypeMask getReturnTypeOfMember(MemberEntity element) {
+  AbstractValue getReturnTypeOfMember(MemberEntity element) {
     if (_disableTypeInference) return _dynamicType;
     // Currently, closure calls return dynamic.
     if (element is! FunctionEntity) return _dynamicType;
     return inferrer.types.getInferredTypeOfMember(element).type;
   }
 
-  TypeMask getReturnTypeOfParameter(Local element) {
+  AbstractValue getReturnTypeOfParameter(Local element) {
     if (_disableTypeInference) return _dynamicType;
     return _dynamicType;
   }
 
-  TypeMask getTypeOfMember(MemberEntity element) {
+  AbstractValue getTypeOfMember(MemberEntity element) {
     if (_disableTypeInference) return _dynamicType;
     // The inferrer stores the return type for a function, so we have to
     // be careful to not return it here.
-    if (element is FunctionEntity) return commonMasks.functionType;
+    if (element is FunctionEntity) return abstractValueDomain.functionType;
     return inferrer.types.getInferredTypeOfMember(element).type;
   }
 
-  TypeMask getTypeOfParameter(Local element) {
+  AbstractValue getTypeOfParameter(Local element) {
     if (_disableTypeInference) return _dynamicType;
     // The inferrer stores the return type for a function, so we have to
     // be careful to not return it here.
     return inferrer.types.getInferredTypeOfParameter(element).type;
   }
 
-  TypeMask getTypeForNewList(T node) {
+  AbstractValue getTypeForNewList(T node) {
     if (_disableTypeInference) return _dynamicType;
     return inferrer.types.allocatedLists[node].type;
   }
@@ -111,7 +108,7 @@
     return info.checksGrowable;
   }
 
-  TypeMask getTypeOfSelector(Selector selector, TypeMask mask) {
+  AbstractValue getTypeOfSelector(Selector selector, AbstractValue receiver) {
     if (_disableTypeInference) return _dynamicType;
     // Bailout for closure calls. We're not tracking types of
     // closures.
@@ -119,30 +116,26 @@
     if (selector.isSetter || selector.isIndexSet) {
       return _dynamicType;
     }
-    if (inferrer.returnsListElementType(selector, mask)) {
-      ContainerTypeMask containerTypeMask = mask;
-      TypeMask elementType = containerTypeMask.elementType;
-      return elementType == null ? _dynamicType : elementType;
+    if (inferrer.returnsListElementType(selector, receiver)) {
+      return abstractValueDomain.getContainerElementType(receiver);
     }
-    if (inferrer.returnsMapValueType(selector, mask)) {
-      MapTypeMask mapTypeMask = mask;
-      TypeMask valueType = mapTypeMask.valueType;
-      return valueType == null ? _dynamicType : valueType;
+    if (inferrer.returnsMapValueType(selector, receiver)) {
+      return abstractValueDomain.getMapValueType(receiver);
     }
 
-    TypeMask result = const TypeMask.nonNullEmpty();
-    if (inferrer.closedWorld.includesClosureCall(selector, mask)) {
-      result = inferrer.commonMasks.dynamicType;
+    if (inferrer.closedWorld.includesClosureCall(selector, receiver)) {
+      return abstractValueDomain.dynamicType;
     } else {
       Iterable<MemberEntity> elements =
-          inferrer.closedWorld.locateMembers(selector, mask);
+          inferrer.closedWorld.locateMembers(selector, receiver);
+      List<AbstractValue> types = <AbstractValue>[];
       for (MemberEntity element in elements) {
-        TypeMask type =
+        AbstractValue type =
             inferrer.typeOfMemberWithSelector(element, selector).type;
-        result = result.union(type, inferrer.closedWorld);
+        types.add(type);
       }
+      return abstractValueDomain.unionOfMany(types);
     }
-    return result;
   }
 
   Iterable<MemberEntity> getCallersOfForTesting(MemberEntity element) {
@@ -164,24 +157,3 @@
     inferrer.clear();
   }
 }
-
-class AstTypeGraphInferrer extends TypeGraphInferrer<ast.Node> {
-  final Compiler _compiler;
-
-  AstTypeGraphInferrer(
-      this._compiler, ClosedWorld closedWorld, closedWorldRefiner,
-      {bool disableTypeInference: false})
-      : super(closedWorld, closedWorldRefiner,
-            disableTypeInference: disableTypeInference);
-
-  @override
-  InferrerEngine<ast.Node> createInferrerEngineFor(FunctionEntity main) {
-    return new AstInferrerEngine(
-        _compiler, closedWorld, closedWorldRefiner, main);
-  }
-
-  @override
-  GlobalTypeInferenceResults createResults() {
-    return new AstGlobalTypeInferenceResults(this, closedWorld);
-  }
-}
diff --git a/pkg/compiler/lib/src/inferrer/type_graph_nodes.dart b/pkg/compiler/lib/src/inferrer/type_graph_nodes.dart
index d17c19d..cb9971a 100644
--- a/pkg/compiler/lib/src/inferrer/type_graph_nodes.dart
+++ b/pkg/compiler/lib/src/inferrer/type_graph_nodes.dart
@@ -10,11 +10,8 @@
 
 import '../common/names.dart' show Identifiers;
 import '../constants/values.dart';
-import '../elements/elements.dart'
-    show ConstructorElement, LocalElement, MemberElement;
 import '../elements/entities.dart';
 import '../elements/types.dart';
-import '../tree/tree.dart' as ast show ForIn, Node, Send, SendSet;
 import '../types/masks.dart'
     show
         CommonMasks,
@@ -402,13 +399,7 @@
    */
   Map<MemberEntity, Setlet<Object>> _callers;
 
-  MemberTypeInformation._internal(this._member) : super._internal(null) {
-    assert(_checkMember(_member));
-  }
-
-  bool _checkMember(MemberEntity member) {
-    return !(member is MemberElement && !member.isDeclaration);
-  }
+  MemberTypeInformation._internal(this._member) : super._internal(null);
 
   MemberEntity get member => _member;
 
@@ -619,19 +610,19 @@
       : super._internal(element);
 
   TypeMask handleSpecialCases(InferrerEngine inferrer) {
-    CommonMasks commonMasks = inferrer.commonMasks;
+    CommonMasks abstractValueDomain = inferrer.abstractValueDomain;
     if (_constructor.isFromEnvironmentConstructor) {
       if (_constructor.enclosingClass == inferrer.commonElements.intClass) {
         giveUp(inferrer);
-        return commonMasks.intType.nullable();
+        return abstractValueDomain.intType.nullable();
       } else if (_constructor.enclosingClass ==
           inferrer.commonElements.boolClass) {
         giveUp(inferrer);
-        return commonMasks.boolType.nullable();
+        return abstractValueDomain.boolType.nullable();
       } else if (_constructor.enclosingClass ==
           inferrer.commonElements.stringClass) {
         giveUp(inferrer);
-        return commonMasks.stringType.nullable();
+        return abstractValueDomain.stringType.nullable();
       }
     }
     return _handleFunctionCase(_constructor, inferrer);
@@ -688,9 +679,7 @@
       : _isInstanceMemberParameter = false,
         _isClosureParameter = true,
         _isInitializingFormal = false,
-        super._internal(context) {
-    assert(_checkParameter(_parameter));
-  }
+        super._internal(context);
 
   ParameterTypeInformation.static(
       MemberTypeInformation context, this._parameter, this._type, this._method,
@@ -698,9 +687,7 @@
       : _isInstanceMemberParameter = false,
         _isClosureParameter = false,
         _isInitializingFormal = isInitializingFormal,
-        super._internal(context) {
-    assert(_checkParameter(_parameter));
-  }
+        super._internal(context);
 
   ParameterTypeInformation.instanceMember(
       MemberTypeInformation context,
@@ -711,13 +698,7 @@
       : _isInstanceMemberParameter = true,
         _isClosureParameter = false,
         _isInitializingFormal = false,
-        super._withAssignments(context, assignments) {
-    assert(_checkParameter(_parameter));
-  }
-
-  bool _checkParameter(Local parameter) {
-    return !(parameter is LocalElement && !parameter.isImplementation);
-  }
+        super._withAssignments(context, assignments);
 
   FunctionEntity get method => _method;
 
@@ -857,18 +838,15 @@
 
 enum CallType {
   access,
-  complex,
   forIn,
 }
 
 bool validCallType(CallType callType, Object call) {
   switch (callType) {
-    case CallType.complex:
-      return call is ast.SendSet;
     case CallType.access:
-      return call is ast.Send || call is ir.Node;
+      return call is ir.Node;
     case CallType.forIn:
-      return call is ast.ForIn || call is ir.ForInStatement;
+      return call is ir.ForInStatement;
   }
   throw new StateError('Unexpected call type $callType.');
 }
@@ -895,15 +873,7 @@
   CallSiteTypeInformation(MemberTypeInformation context, this._call,
       this.caller, this.selector, this.mask, this.arguments, this.inLoop)
       : super.noAssignments(context) {
-    assert(_checkCaller(caller));
-    // [_call] is either an AST node or a constructor element in case of a
-    // a forwarding constructor _call.
-    assert(
-        _call is ast.Node || _call is ConstructorElement || _call is ir.Node);
-  }
-
-  bool _checkCaller(MemberEntity caller) {
-    return !(caller is MemberElement && !caller.isDeclaration);
+    assert(_call is ir.Node);
   }
 
   String toString() => 'Call site $debugName $type';
@@ -929,13 +899,7 @@
       TypeMask mask,
       ArgumentsTypes arguments,
       bool inLoop)
-      : super(context, call, enclosing, selector, mask, arguments, inLoop) {
-    assert(_checkCalledElement(calledElement));
-  }
-
-  bool _checkCalledElement(MemberEntity calledElement) {
-    return !(calledElement is MemberElement && !calledElement.isDeclaration);
-  }
+      : super(context, call, enclosing, selector, mask, arguments, inLoop);
 
   MemberTypeInformation _getCalledTypeInfo(InferrerEngine inferrer) {
     return inferrer.types.getInferredTypeOfMember(calledElement);
@@ -1056,7 +1020,7 @@
     TypeMask receiverType = receiver.type;
 
     if (mask != receiverType) {
-      return receiverType == inferrer.commonMasks.dynamicType
+      return receiverType == inferrer.abstractValueDomain.dynamicType
           ? null
           : receiverType;
     } else {
@@ -1234,7 +1198,7 @@
     // for all these targets.
     TypeMask result;
     if (_hasClosureCallTargets) {
-      result = inferrer.commonMasks.dynamicType;
+      result = inferrer.abstractValueDomain.dynamicType;
     } else {
       result = inferrer.types
           .joinTypeMasks(_concreteTargets.map((MemberEntity element) {
diff --git a/pkg/compiler/lib/src/io/multi_information.dart b/pkg/compiler/lib/src/io/multi_information.dart
deleted file mode 100644
index 25c61fe..0000000
--- a/pkg/compiler/lib/src/io/multi_information.dart
+++ /dev/null
@@ -1,345 +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.
-
-/// Source information strategy that concurrently builds sourcemaps for each of
-/// child strategies.
-
-library dart2js.dual_source_information;
-
-import '../common.dart';
-import '../elements/entities.dart';
-import '../js/js_source_mapping.dart';
-import '../js/js.dart' as js;
-import '../universe/call_structure.dart';
-import 'code_output.dart' show BufferedCodeOutput;
-import 'source_information.dart';
-
-class MultiSourceInformationStrategy<T>
-    implements JavaScriptSourceInformationStrategy<T> {
-  final List<JavaScriptSourceInformationStrategy<T>> strategies;
-
-  const MultiSourceInformationStrategy(this.strategies);
-
-  @override
-  SourceInformationBuilder<T> createBuilderForContext(MemberEntity member) {
-    return new MultiSourceInformationBuilder<T>(
-        strategies.map((s) => s.createBuilderForContext(member)).toList());
-  }
-
-  @override
-  void onComplete() {
-    strategies.forEach((s) => s.onComplete());
-  }
-
-  @override
-  SourceInformation buildSourceMappedMarker() {
-    return new MultiSourceInformation(
-        strategies.map((s) => s.buildSourceMappedMarker()).toList());
-  }
-
-  @override
-  SourceInformationProcessor createProcessor(
-      SourceMapperProvider sourceMapperProvider,
-      SourceInformationReader reader) {
-    return new MultiSourceInformationProcessor(
-        new List<SourceInformationProcessor>.generate(strategies.length,
-            (int index) {
-      return strategies[index].createProcessor(sourceMapperProvider,
-          new MultiSourceInformationReader(reader, index));
-    }));
-  }
-}
-
-class MultiSourceInformationProcessor implements SourceInformationProcessor {
-  final List<SourceInformationProcessor> processors;
-
-  MultiSourceInformationProcessor(this.processors);
-
-  @override
-  void onStartPosition(js.Node node, int startPosition) {
-    processors.forEach((p) => p.onStartPosition(node, startPosition));
-  }
-
-  @override
-  void onPositions(
-      js.Node node, int startPosition, int endPosition, int closingPosition) {
-    processors.forEach((p) =>
-        p.onPositions(node, startPosition, endPosition, closingPosition));
-  }
-
-  @override
-  void process(js.Node node, BufferedCodeOutput code) {
-    processors.forEach((p) => p.process(node, code));
-  }
-}
-
-class MultiSourceInformationBuilder<T> implements SourceInformationBuilder<T> {
-  final List<SourceInformationBuilder<T>> builders;
-
-  MultiSourceInformationBuilder(this.builders);
-
-  @override
-  SourceInformationBuilder forContext(MemberEntity member) {
-    return new MultiSourceInformationBuilder(
-        builders.map((b) => b.forContext(member)).toList());
-  }
-
-  @override
-  SourceInformation buildSwitchCase(T node) {
-    return new MultiSourceInformation(
-        builders.map((b) => b.buildSwitchCase(node)).toList());
-  }
-
-  @override
-  SourceInformation buildSwitch(T node) {
-    return new MultiSourceInformation(
-        builders.map((b) => b.buildSwitch(node)).toList());
-  }
-
-  @override
-  SourceInformation buildAs(T node) {
-    return new MultiSourceInformation(
-        builders.map((b) => b.buildAs(node)).toList());
-  }
-
-  @override
-  SourceInformation buildIs(T node) {
-    return new MultiSourceInformation(
-        builders.map((b) => b.buildIs(node)).toList());
-  }
-
-  @override
-  SourceInformation buildTry(T node) {
-    return new MultiSourceInformation(
-        builders.map((b) => b.buildTry(node)).toList());
-  }
-
-  @override
-  SourceInformation buildCatch(T node) {
-    return new MultiSourceInformation(
-        builders.map((b) => b.buildCatch(node)).toList());
-  }
-
-  @override
-  SourceInformation buildBinary(T node) {
-    return new MultiSourceInformation(
-        builders.map((b) => b.buildBinary(node)).toList());
-  }
-
-  @override
-  SourceInformation buildUnary(T node) {
-    return new MultiSourceInformation(
-        builders.map((b) => b.buildUnary(node)).toList());
-  }
-
-  @override
-  SourceInformation buildIndexSet(T node) {
-    return new MultiSourceInformation(
-        builders.map((b) => b.buildIndexSet(node)).toList());
-  }
-
-  @override
-  SourceInformation buildIndex(T node) {
-    return new MultiSourceInformation(
-        builders.map((b) => b.buildIndex(node)).toList());
-  }
-
-  @override
-  SourceInformation buildForInSet(T node) {
-    return new MultiSourceInformation(
-        builders.map((b) => b.buildForInSet(node)).toList());
-  }
-
-  @override
-  SourceInformation buildForInCurrent(T node) {
-    return new MultiSourceInformation(
-        builders.map((b) => b.buildForInCurrent(node)).toList());
-  }
-
-  @override
-  SourceInformation buildForInMoveNext(T node) {
-    return new MultiSourceInformation(
-        builders.map((b) => b.buildForInMoveNext(node)).toList());
-  }
-
-  @override
-  SourceInformation buildForInIterator(T node) {
-    return new MultiSourceInformation(
-        builders.map((b) => b.buildForInIterator(node)).toList());
-  }
-
-  @override
-  SourceInformation buildStringInterpolation(T node) {
-    return new MultiSourceInformation(
-        builders.map((b) => b.buildStringInterpolation(node)).toList());
-  }
-
-  @override
-  SourceInformation buildForeignCode(T node) {
-    return new MultiSourceInformation(
-        builders.map((b) => b.buildForeignCode(node)).toList());
-  }
-
-  @override
-  SourceInformation buildVariableDeclaration() {
-    return new MultiSourceInformation(
-        builders.map((b) => b.buildVariableDeclaration()).toList());
-  }
-
-  @override
-  SourceInformation buildAwait(T node) {
-    return new MultiSourceInformation(
-        builders.map((b) => b.buildAwait(node)).toList());
-  }
-
-  @override
-  SourceInformation buildYield(T node) {
-    return new MultiSourceInformation(
-        builders.map((b) => b.buildYield(node)).toList());
-  }
-
-  @override
-  SourceInformation buildAsyncBody() {
-    return new MultiSourceInformation(
-        builders.map((b) => b.buildAsyncBody()).toList());
-  }
-
-  @override
-  SourceInformation buildAsyncExit() {
-    return new MultiSourceInformation(
-        builders.map((b) => b.buildAsyncExit()).toList());
-  }
-
-  @override
-  SourceInformation buildAssignment(T node) {
-    return new MultiSourceInformation(
-        builders.map((b) => b.buildAssignment(node)).toList());
-  }
-
-  @override
-  SourceInformation buildThrow(T node) {
-    return new MultiSourceInformation(
-        builders.map((b) => b.buildThrow(node)).toList());
-  }
-
-  @override
-  SourceInformation buildNew(T node) {
-    return new MultiSourceInformation(
-        builders.map((b) => b.buildNew(node)).toList());
-  }
-
-  @override
-  SourceInformation buildIf(T node) {
-    return new MultiSourceInformation(
-        builders.map((b) => b.buildIf(node)).toList());
-  }
-
-  @override
-  SourceInformation buildCall(T receiver, T call) {
-    return new MultiSourceInformation(
-        builders.map((b) => b.buildCall(receiver, call)).toList());
-  }
-
-  @override
-  SourceInformation buildGet(T node) {
-    return new MultiSourceInformation(
-        builders.map((b) => b.buildGet(node)).toList());
-  }
-
-  @override
-  SourceInformation buildLoop(T node) {
-    return new MultiSourceInformation(
-        builders.map((b) => b.buildLoop(node)).toList());
-  }
-
-  @override
-  SourceInformation buildImplicitReturn(MemberEntity element) {
-    return new MultiSourceInformation(
-        builders.map((b) => b.buildImplicitReturn(element)).toList());
-  }
-
-  @override
-  SourceInformation buildReturn(T node) {
-    return new MultiSourceInformation(
-        builders.map((b) => b.buildReturn(node)).toList());
-  }
-
-  @override
-  SourceInformation buildCreate(T node) {
-    return new MultiSourceInformation(
-        builders.map((b) => b.buildCreate(node)).toList());
-  }
-
-  @override
-  SourceInformation buildListLiteral(T node) {
-    return new MultiSourceInformation(
-        builders.map((b) => b.buildListLiteral(node)).toList());
-  }
-
-  @override
-  SourceInformation buildGeneric(T node) {
-    return new MultiSourceInformation(
-        builders.map((b) => b.buildGeneric(node)).toList());
-  }
-
-  @override
-  SourceInformation buildDeclaration(MemberEntity member) {
-    return new MultiSourceInformation(
-        builders.map((b) => b.buildDeclaration(member)).toList());
-  }
-
-  @override
-  SourceInformation buildStub(
-      FunctionEntity function, CallStructure callStructure) {
-    return new MultiSourceInformation(
-        builders.map((b) => b.buildStub(function, callStructure)).toList());
-  }
-
-  @override
-  SourceInformation buildGoto(T node) {
-    return new MultiSourceInformation(
-        builders.map((b) => b.buildGoto(node)).toList());
-  }
-}
-
-class MultiSourceInformation implements SourceInformation {
-  final List<SourceInformation> infos;
-
-  MultiSourceInformation(this.infos);
-
-  @override
-  String get shortText => infos.first?.shortText;
-
-  @override
-  List<SourceLocation> get sourceLocations => infos.first?.sourceLocations;
-
-  @override
-  SourceLocation get endPosition => infos.first?.endPosition;
-
-  @override
-  SourceLocation get innerPosition => infos.first?.innerPosition;
-
-  @override
-  SourceLocation get startPosition => infos.first?.startPosition;
-
-  @override
-  SourceSpan get sourceSpan => infos.first?.sourceSpan;
-
-  String toString() => '$infos';
-}
-
-class MultiSourceInformationReader implements SourceInformationReader {
-  final SourceInformationReader reader;
-  final int index;
-
-  MultiSourceInformationReader(this.reader, this.index);
-
-  @override
-  SourceInformation getSourceInformation(js.Node node) {
-    MultiSourceInformation sourceInformation =
-        reader.getSourceInformation(node);
-    if (sourceInformation == null) return null;
-    return sourceInformation.infos[index];
-  }
-}
diff --git a/pkg/compiler/lib/src/io/position_information.dart b/pkg/compiler/lib/src/io/position_information.dart
index 5704c6e..939c1c3 100644
--- a/pkg/compiler/lib/src/io/position_information.dart
+++ b/pkg/compiler/lib/src/io/position_information.dart
@@ -8,15 +8,10 @@
 library dart2js.source_information.position;
 
 import '../common.dart';
-import '../elements/elements.dart'
-    show MemberElement, MethodElement, ResolvedAst, ResolvedAstKind;
 import '../js/js.dart' as js;
 import '../js/js_debug.dart';
 import '../js/js_source_mapping.dart';
-import '../tree/tree.dart' show Node, Send;
-import '../universe/call_structure.dart';
 import 'code_output.dart' show BufferedCodeOutput;
-import 'source_file.dart';
 import 'source_information.dart';
 
 /// [SourceInformation] that consists of an offset position into the source
@@ -116,16 +111,6 @@
   }
 }
 
-class PositionSourceInformationStrategy
-    extends AbstractPositionSourceInformationStrategy<Node> {
-  const PositionSourceInformationStrategy();
-
-  @override
-  SourceInformationBuilder<Node> createBuilderForContext(MemberElement member) {
-    return new PositionSourceInformationBuilder(member);
-  }
-}
-
 /// Marker used to tag the root nodes of source-mapped code.
 ///
 /// This is needed to be able to distinguish JavaScript nodes that shouldn't
@@ -144,243 +129,6 @@
   SourceSpan get sourceSpan => new SourceSpan(null, null, null);
 }
 
-/// [SourceInformationBuilder] that generates [PositionSourceInformation] from
-/// AST nodes.
-class PositionSourceInformationBuilder
-    implements SourceInformationBuilder<Node> {
-  final SourceFile sourceFile;
-  final String name;
-  final ResolvedAst resolvedAst;
-
-  PositionSourceInformationBuilder(MemberElement member)
-      : this.resolvedAst = member.resolvedAst,
-        sourceFile = computeSourceFile(member.resolvedAst),
-        name = computeElementNameForSourceMaps(member.resolvedAst.element);
-
-  SourceInformation buildDeclaration(MemberElement member) {
-    ResolvedAst resolvedAst = member.resolvedAst;
-    String name = computeElementNameForSourceMaps(resolvedAst.element);
-    SourceFile sourceFile = computeSourceFile(resolvedAst);
-    if (resolvedAst.kind != ResolvedAstKind.PARSED) {
-      SourceSpan span = resolvedAst.element.sourcePosition;
-      return new PositionSourceInformation(
-          new OffsetSourceLocation(sourceFile, span.begin, name));
-    } else {
-      return new PositionSourceInformation(
-          new OffsetSourceLocation(
-              sourceFile, resolvedAst.node.getBeginToken().charOffset, name),
-          new OffsetSourceLocation(
-              sourceFile, resolvedAst.node.getEndToken().charOffset, name));
-    }
-  }
-
-  @override
-  SourceInformation buildStub(
-      MethodElement function, CallStructure callStructure) {
-    ResolvedAst resolvedAst = function.resolvedAst;
-    String name =
-        computeElementNameForSourceMaps(resolvedAst.element, callStructure);
-    SourceFile sourceFile = computeSourceFile(resolvedAst);
-    SourceSpan span = resolvedAst.element.sourcePosition;
-    assert(
-        span != null, failedAt(function, "No source position for $function."));
-    return new PositionSourceInformation(
-        new OffsetSourceLocation(sourceFile, span.begin, name));
-  }
-
-  /// Builds a source information object pointing the start position of [node].
-  SourceInformation buildBegin(Node node) {
-    return new PositionSourceInformation(new OffsetSourceLocation(
-        sourceFile, node.getBeginToken().charOffset, name));
-  }
-
-  /// Builds a source information object pointing the end position of [node].
-  SourceInformation buildEnd(Node node) {
-    return new PositionSourceInformation(new OffsetSourceLocation(
-        sourceFile, node.getEndToken().charOffset, name));
-  }
-
-  @override
-  SourceInformation buildGeneric(Node node) => buildBegin(node);
-
-  @override
-  SourceInformation buildCreate(Node node) => buildBegin(node);
-
-  @override
-  SourceInformation buildListLiteral(Node node) => buildBegin(node);
-
-  @override
-  SourceInformation buildReturn(Node node) {
-    SourceFile sourceFile = computeSourceFile(resolvedAst);
-    SourceLocation startPosition = new OffsetSourceLocation(
-        sourceFile, node.getBeginToken().charOffset, name);
-    SourceLocation endPosition;
-    if (resolvedAst.kind == ResolvedAstKind.PARSED) {
-      endPosition = new OffsetSourceLocation(
-          sourceFile, resolvedAst.node.getEndToken().charOffset, name);
-    }
-    return new PositionSourceInformation(startPosition, endPosition);
-  }
-
-  @override
-  SourceInformation buildImplicitReturn(MemberElement element) {
-    if (element.isSynthesized) {
-      return new PositionSourceInformation(new OffsetSourceLocation(
-          sourceFile, element.position.charOffset, name));
-    } else {
-      return new PositionSourceInformation(new OffsetSourceLocation(
-          sourceFile, element.resolvedAst.node.getEndToken().charOffset, name));
-    }
-  }
-
-  @override
-  SourceInformation buildLoop(Node node) => buildBegin(node);
-
-  @override
-  SourceInformation buildGet(Node node) {
-    Node left = node;
-    Node right = node;
-    Send send = node.asSend();
-    if (send != null) {
-      right = send.selector;
-    }
-    // For a read access like `a.b` the first source locations points to the
-    // left-most part of the access, `a` in the example, and the second source
-    // location points to the 'name' of accessed property, `b` in the
-    // example. The latter is needed when both `a` and `b` are compiled into
-    // JavaScript invocations.
-    return new PositionSourceInformation(
-        new OffsetSourceLocation(
-            sourceFile, left.getBeginToken().charOffset, name),
-        new OffsetSourceLocation(
-            sourceFile, right.getBeginToken().charOffset, name));
-  }
-
-  // TODO(johnniwinther): Clean up the use of this and [buildBinary],
-  // [buildIndex], etc.
-  @override
-  SourceInformation buildCall(Node receiver, Node call) {
-    return new PositionSourceInformation(
-        new OffsetSourceLocation(
-            sourceFile, receiver.getBeginToken().charOffset, name),
-        new OffsetSourceLocation(
-            sourceFile, call.getBeginToken().charOffset, name));
-  }
-
-  @override
-  SourceInformation buildNew(Node node) {
-    return buildBegin(node);
-  }
-
-  @override
-  SourceInformation buildIf(Node node) => buildBegin(node);
-
-  @override
-  SourceInformation buildThrow(Node node) => buildBegin(node);
-
-  @override
-  SourceInformation buildAssignment(Node node) => buildBegin(node);
-
-  SourceInformation _buildMemberBody() {
-    if (resolvedAst.kind == ResolvedAstKind.PARSED) {
-      Node body = resolvedAst.body;
-      if (body != null) {
-        return buildBegin(body);
-      }
-      // TODO(johnniwinther): Are there other cases?
-    }
-    return null;
-  }
-
-  SourceInformation _buildMemberExit() {
-    if (resolvedAst.kind == ResolvedAstKind.PARSED) {
-      Node body = resolvedAst.body;
-      if (body != null) {
-        return buildEnd(body);
-      }
-      // TODO(johnniwinther): Are there other cases?
-    }
-    return null;
-  }
-
-  @override
-  SourceInformation buildVariableDeclaration() {
-    return _buildMemberBody();
-  }
-
-  @override
-  SourceInformation buildAwait(Node node) => buildBegin(node);
-
-  @override
-  SourceInformation buildYield(Node node) => buildBegin(node);
-
-  @override
-  SourceInformation buildAsyncBody() {
-    return _buildMemberBody();
-  }
-
-  @override
-  SourceInformation buildAsyncExit() {
-    return _buildMemberExit();
-  }
-
-  @override
-  SourceInformationBuilder forContext(MemberElement member) {
-    return new PositionSourceInformationBuilder(member);
-  }
-
-  @override
-  SourceInformation buildForeignCode(Node node) => buildBegin(node);
-
-  @override
-  SourceInformation buildStringInterpolation(Node node) => buildBegin(node);
-
-  @override
-  SourceInformation buildForInIterator(Node node) => buildBegin(node);
-
-  @override
-  SourceInformation buildForInMoveNext(Node node) => buildBegin(node);
-
-  @override
-  SourceInformation buildForInCurrent(Node node) => buildBegin(node);
-
-  @override
-  SourceInformation buildForInSet(Node node) => buildBegin(node);
-
-  @override
-  SourceInformation buildIndex(Node node) => buildBegin(node);
-
-  @override
-  SourceInformation buildIndexSet(Node node) => buildBegin(node);
-
-  @override
-  SourceInformation buildBinary(Node node) => buildBegin(node);
-
-  @override
-  SourceInformation buildUnary(Node node) => buildBegin(node);
-
-  @override
-  SourceInformation buildTry(Node node) => buildBegin(node);
-
-  @override
-  SourceInformation buildCatch(Node node) => buildBegin(node);
-
-  @override
-  SourceInformation buildIs(Node node) => buildBegin(node);
-
-  @override
-  SourceInformation buildAs(Node node) => buildBegin(node);
-
-  @override
-  SourceInformation buildSwitch(Node node) => buildBegin(node);
-
-  @override
-  SourceInformation buildSwitchCase(Node node) => buildBegin(node);
-
-  @override
-  SourceInformation buildGoto(Node node) => buildBegin(node);
-}
-
 /// The start, end and closing offsets for a [js.Node].
 class CodePosition {
   final int startPosition;
diff --git a/pkg/compiler/lib/src/io/source_information.dart b/pkg/compiler/lib/src/io/source_information.dart
index 0297bc2..5cbb473 100644
--- a/pkg/compiler/lib/src/io/source_information.dart
+++ b/pkg/compiler/lib/src/io/source_information.dart
@@ -6,16 +6,8 @@
 
 import 'package:kernel/ast.dart' show Location;
 import '../common.dart';
-import '../elements/elements.dart'
-    show
-        AstElement,
-        CompilationUnitElement,
-        LocalElement,
-        ResolvedAst,
-        ResolvedAstKind;
 import '../elements/entities.dart';
 import '../js/js.dart' show JavaScriptNodeSourceInformation;
-import '../script.dart';
 import '../universe/call_structure.dart';
 import 'source_file.dart';
 
@@ -283,9 +275,7 @@
 // when the old frontend is removed.
 String computeElementNameForSourceMaps(Entity element,
     [CallStructure callStructure]) {
-  if (element is AstElement) {
-    return _computeAstElementNameForSourceMaps(element, callStructure);
-  } else if (element is ClassEntity) {
+  if (element is ClassEntity) {
     return element.name;
   } else if (element is MemberEntity) {
     String suffix = computeStubSuffix(callStructure);
@@ -309,41 +299,6 @@
   return element.name;
 }
 
-String _computeAstElementNameForSourceMaps(
-    AstElement element, CallStructure callStructure) {
-  if (element.isClosure) {
-    return computeElementNameForSourceMaps(
-        element.enclosingElement, callStructure);
-  } else if (element.isClass) {
-    return element.name;
-  } else if (element.isConstructor || element.isGenerativeConstructorBody) {
-    String className = element.enclosingClass.name;
-    if (element.name == '') {
-      return className;
-    }
-    return '$className.${element.name}';
-  } else if (element.isLocal) {
-    LocalElement local = element;
-    String name = local.name;
-    if (name == '') {
-      name = '<anonymous function>';
-    }
-    String enclosingName =
-        computeElementNameForSourceMaps(local.executableContext, callStructure);
-    return '$enclosingName.$name';
-  } else if (element.enclosingClass != null) {
-    String suffix = computeStubSuffix(callStructure);
-    if (element.enclosingClass.isClosure) {
-      return computeElementNameForSourceMaps(
-          element.enclosingClass, callStructure);
-    }
-    return '${element.enclosingClass.name}.${element.name}$suffix';
-  } else {
-    String suffix = computeStubSuffix(callStructure);
-    return '${element.name}$suffix';
-  }
-}
-
 /// Compute the suffix used for a parameter stub for [callStructure].
 String computeStubSuffix(CallStructure callStructure) {
   if (callStructure == null) return '';
@@ -358,35 +313,6 @@
   return sb.toString();
 }
 
-/// Computes the [SourceFile] for the source code of [resolvedAst].
-SourceFile computeSourceFile(ResolvedAst resolvedAst) {
-  SourceFile sourceFile;
-  if (resolvedAst.kind != ResolvedAstKind.PARSED) {
-    // Synthesized node. Use the enclosing element for the location.
-    sourceFile = resolvedAst.element.compilationUnit.script.file;
-  } else {
-    Uri uri = resolvedAst.sourceUri;
-    AstElement implementation = resolvedAst.element.implementation;
-    Script script = implementation.compilationUnit.script;
-    if (uri == script.resourceUri) {
-      sourceFile = script.file;
-    } else {
-      // Slow path, happens only for deserialized elements.
-      // TODO(johnniwinther): Support a way to get a [SourceFile] from a
-      // [Uri].
-      for (CompilationUnitElement compilationUnit
-          in implementation.library.compilationUnits) {
-        Script script = compilationUnit.script;
-        if (uri == script.resourceUri) {
-          sourceFile = script.file;
-          break;
-        }
-      }
-    }
-  }
-  return sourceFile;
-}
-
 class NoSourceLocationMarker extends SourceLocation {
   const NoSourceLocationMarker();
 
diff --git a/pkg/compiler/lib/src/io/start_end_information.dart b/pkg/compiler/lib/src/io/start_end_information.dart
deleted file mode 100644
index 099917d..0000000
--- a/pkg/compiler/lib/src/io/start_end_information.dart
+++ /dev/null
@@ -1,281 +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.
-
-/// Source information system that maps spans of Dart AST nodes to spans of
-/// JavaScript nodes.
-
-library dart2js.source_information.start_end;
-
-import 'package:front_end/src/fasta/scanner.dart' show Token;
-
-import '../common.dart';
-import '../diagnostics/messages.dart' show MessageTemplate;
-import '../elements/elements.dart'
-    show MemberElement, MethodElement, ResolvedAst, ResolvedAstKind;
-import '../js/js.dart' as js;
-import '../js/js_source_mapping.dart';
-import '../tree/tree.dart' show Node, Send;
-import '../universe/call_structure.dart';
-import 'source_file.dart';
-import 'source_information.dart';
-
-/// Source information that contains start source position and optionally an
-/// end source position.
-class StartEndSourceInformation extends SourceInformation {
-  @override
-  final SourceLocation startPosition;
-
-  @override
-  final SourceLocation endPosition;
-
-  StartEndSourceInformation(this.startPosition, [this.endPosition]);
-
-  @override
-  List<SourceLocation> get sourceLocations {
-    if (endPosition == null) {
-      return <SourceLocation>[startPosition];
-    } else {
-      return <SourceLocation>[startPosition, endPosition];
-    }
-  }
-
-  @override
-  SourceSpan get sourceSpan {
-    Uri uri = startPosition.sourceUri;
-    int begin = startPosition.offset;
-    int end = endPosition == null ? begin : endPosition.offset;
-    return new SourceSpan(uri, begin, end);
-  }
-
-  int get hashCode {
-    return 0x7FFFFFFF &
-        (startPosition.hashCode * 17 + endPosition.hashCode * 19);
-  }
-
-  bool operator ==(other) {
-    if (identical(this, other)) return true;
-    if (other is! StartEndSourceInformation) return false;
-    return startPosition == other.startPosition &&
-        endPosition == other.endPosition;
-  }
-
-  // TODO(johnniwinther): Inline this in
-  // [StartEndSourceInformationBuilder.buildDeclaration].
-  static StartEndSourceInformation _computeSourceInformation(
-      ResolvedAst resolvedAst,
-      [CallStructure callStructure]) {
-    String name =
-        computeElementNameForSourceMaps(resolvedAst.element, callStructure);
-    SourceFile sourceFile = computeSourceFile(resolvedAst);
-    int begin;
-    int end;
-    if (resolvedAst.kind != ResolvedAstKind.PARSED) {
-      // Synthesized node. Use the enclosing element for the location.
-      begin = end = resolvedAst.element.sourcePosition.begin;
-    } else {
-      Node node = resolvedAst.node;
-      begin = node.getBeginToken().charOffset;
-      end = node.getEndToken().charOffset;
-    }
-    // TODO(johnniwinther): find the right sourceFile here and remove offset
-    // checks below.
-    SourceLocation sourcePosition, endSourcePosition;
-    if (begin < sourceFile.length) {
-      sourcePosition = new OffsetSourceLocation(sourceFile, begin, name);
-    }
-    if (end < sourceFile.length) {
-      endSourcePosition = new OffsetSourceLocation(sourceFile, end, name);
-    }
-    return new StartEndSourceInformation(sourcePosition, endSourcePosition);
-  }
-
-  /// Create a textual representation of the source information using [uriText]
-  /// as the Uri representation.
-  String _computeText(String uriText) {
-    StringBuffer sb = new StringBuffer();
-    sb.write('$uriText:');
-    sb.write('[${startPosition.line},${startPosition.column}]');
-    if (endPosition != null) {
-      sb.write('-[${endPosition.line},${endPosition.column}]');
-    }
-    return sb.toString();
-  }
-
-  String get shortText {
-    return _computeText(startPosition.sourceUri.pathSegments.last);
-  }
-
-  String toString() {
-    return _computeText('${startPosition.sourceUri}');
-  }
-}
-
-class StartEndSourceInformationStrategy
-    extends JavaScriptSourceInformationStrategy<Node> {
-  const StartEndSourceInformationStrategy();
-
-  @override
-  SourceInformationBuilder<Node> createBuilderForContext(MemberElement member,
-      [CallStructure callStructure]) {
-    return new StartEndSourceInformationBuilder(member, callStructure);
-  }
-
-  @override
-  SourceInformationProcessor createProcessor(
-      SourceMapperProvider provider, SourceInformationReader reader) {
-    return new StartEndSourceInformationProcessor(provider, reader);
-  }
-}
-
-class StartEndSourceInformationProcessor extends SourceInformationProcessor {
-  /// The id for this source information engine.
-  ///
-  /// The id is added to the source map file in an extra "engine" property and
-  /// serves as a version number for the engine.
-  ///
-  /// The version history of this engine is:
-  ///
-  ///   v1: The initial version with an id.
-  static const String id = 'v1';
-
-  final SourceMapper sourceMapper;
-  final SourceInformationReader reader;
-
-  /// Used to track whether a terminating source location marker has been
-  /// registered for the top-most node with source information.
-  bool hasRegisteredRoot = false;
-
-  /// The root of the tree. Used to add a [NoSourceLocationMarker] to the start
-  /// of the output.
-  js.Node root;
-
-  /// The root of the current subtree with source information. Used to add
-  /// [NoSourceLocationMarker] after areas with source information.
-  js.Node subRoot;
-
-  StartEndSourceInformationProcessor(SourceMapperProvider provider, this.reader)
-      : this.sourceMapper = provider.createSourceMapper(id);
-
-  void onStartPosition(js.Node node, int startPosition) {
-    if (root == null) {
-      root = node;
-      sourceMapper.register(
-          node, startPosition, const NoSourceLocationMarker());
-    }
-    if (subRoot == null && reader.getSourceInformation(node) != null) {
-      subRoot = node;
-    }
-  }
-
-  @override
-  void onPositions(
-      js.Node node, int startPosition, int endPosition, int closingPosition) {
-    StartEndSourceInformation sourceInformation =
-        reader.getSourceInformation(node);
-    if (sourceInformation != null) {
-      sourceMapper.register(
-          node, startPosition, sourceInformation.startPosition);
-      if (sourceInformation.endPosition != null) {
-        sourceMapper.register(node, endPosition, sourceInformation.endPosition);
-      }
-      if (!hasRegisteredRoot) {
-        sourceMapper.register(node, endPosition, null);
-        hasRegisteredRoot = true;
-      }
-      if (node == subRoot) {
-        sourceMapper.register(
-            node, endPosition, const NoSourceLocationMarker());
-        subRoot = null;
-      }
-    }
-  }
-}
-
-/// [SourceInformationBuilder] that generates [PositionSourceInformation].
-class StartEndSourceInformationBuilder extends SourceInformationBuilder<Node> {
-  final SourceFile sourceFile;
-  final String name;
-
-  StartEndSourceInformationBuilder(MemberElement member,
-      [CallStructure callStructure])
-      : sourceFile = computeSourceFile(member.resolvedAst),
-        name = computeElementNameForSourceMaps(
-            member.resolvedAst.element, callStructure);
-
-  SourceInformation buildDeclaration(MemberElement member) {
-    return StartEndSourceInformation
-        ._computeSourceInformation(member.resolvedAst);
-  }
-
-  SourceInformation buildStub(
-      MethodElement member, CallStructure callStructure) {
-    return StartEndSourceInformation._computeSourceInformation(
-        member.resolvedAst, callStructure);
-  }
-
-  SourceLocation sourceFileLocationForToken(Token token) {
-    SourceLocation location =
-        new OffsetSourceLocation(sourceFile, token.charOffset, name);
-    checkValidSourceFileLocation(location, sourceFile, token.charOffset);
-    return location;
-  }
-
-  void checkValidSourceFileLocation(
-      SourceLocation location, SourceFile sourceFile, int offset) {
-    if (!location.isValid) {
-      throw MessageTemplate.TEMPLATES[MessageKind.INVALID_SOURCE_FILE_LOCATION]
-          .message({
-        'offset': offset,
-        'fileName': sourceFile.filename,
-        'length': sourceFile.length
-      });
-    }
-  }
-
-  @override
-  SourceInformation buildLoop(Node node) {
-    return new StartEndSourceInformation(
-        sourceFileLocationForToken(node.getBeginToken()),
-        sourceFileLocationForToken(node.getEndToken()));
-  }
-
-  @override
-  SourceInformation buildGeneric(Node node) {
-    return new StartEndSourceInformation(
-        sourceFileLocationForToken(node.getBeginToken()));
-  }
-
-  @override
-  SourceInformation buildCreate(Node node) => buildGeneric(node);
-
-  @override
-  SourceInformation buildReturn(Node node) => buildGeneric(node);
-
-  @override
-  SourceInformation buildGet(Node node) => buildGeneric(node);
-
-  @override
-  SourceInformation buildAssignment(Node node) => buildGeneric(node);
-
-  @override
-  SourceInformation buildCall(Node receiver, Node call) {
-    return buildGeneric(receiver);
-  }
-
-  @override
-  SourceInformation buildAs(Node node) {
-    // 'as' is a Send with Operator 'as' for the selector.
-    if (node is Send) return buildGeneric(node.selector ?? node);
-    return buildGeneric(node);
-  }
-
-  @override
-  SourceInformation buildIf(Node node) => buildGeneric(node);
-
-  @override
-  SourceInformationBuilder forContext(MemberElement member,
-      {SourceInformation sourceInformation}) {
-    return new StartEndSourceInformationBuilder(member);
-  }
-}
diff --git a/pkg/compiler/lib/src/js/rewrite_async.dart b/pkg/compiler/lib/src/js/rewrite_async.dart
index 936cddf..7a33482 100644
--- a/pkg/compiler/lib/src/js/rewrite_async.dart
+++ b/pkg/compiler/lib/src/js/rewrite_async.dart
@@ -415,6 +415,9 @@
     // Note that RegExes, js.ArrayInitializer and js.ObjectInitializer are not
     // [js.Literal]s.
     if (result is js.Literal) return result;
+    if (result is js.VariableUse) {
+      if (result.name == selfName) return result;
+    }
 
     js.Expression tempVar = useTempVar(allocateTempVar());
     addStatement(js.js.statement('# = #;', [tempVar, result]));
diff --git a/pkg/compiler/lib/src/js_backend/backend.dart b/pkg/compiler/lib/src/js_backend/backend.dart
index 28f2622..7188cf6 100644
--- a/pkg/compiler/lib/src/js_backend/backend.dart
+++ b/pkg/compiler/lib/src/js_backend/backend.dart
@@ -5,23 +5,17 @@
 library js_backend.backend;
 
 import '../common.dart';
-import '../common/backend_api.dart'
-    show ForeignResolver, NativeRegistry, ImpactTransformer;
+import '../common/backend_api.dart' show ImpactTransformer;
 import '../common/codegen.dart' show CodegenRegistry, CodegenWorkItem;
 import '../common/names.dart' show Uris;
-import '../common/resolution.dart' show Resolution, Target;
 import '../common/tasks.dart' show CompilerTask;
 import '../common_elements.dart' show CommonElements, ElementEnvironment;
 import '../compiler.dart' show Compiler;
 import '../constants/constant_system.dart';
-import '../constants/expressions.dart';
 import '../constants/values.dart';
 import '../deferred_load.dart' show DeferredLoadTask, OutputUnitData;
 import '../dump_info.dart' show DumpInfoTask;
-import '../elements/elements.dart';
 import '../elements/entities.dart';
-import '../elements/names.dart';
-import '../elements/resolution_types.dart';
 import '../elements/types.dart';
 import '../enqueue.dart'
     show
@@ -41,11 +35,9 @@
 import '../js_emitter/sorter.dart' show Sorter;
 import '../library_loader.dart' show LoadedLibraries;
 import '../native/native.dart' as native;
-import '../native/resolver.dart';
 import '../ssa/ssa.dart' show SsaFunctionCompiler;
 import '../tracer.dart';
-import '../tree/tree.dart';
-import '../types/types.dart';
+import '../types/masks.dart';
 import '../universe/call_structure.dart' show CallStructure;
 import '../universe/class_hierarchy_builder.dart'
     show ClassHierarchyBuilder, ClassQueries;
@@ -67,15 +59,11 @@
 import 'impact_transformer.dart';
 import 'interceptor_data.dart';
 import 'js_interop_analysis.dart' show JsInteropAnalysis;
-import 'mirrors_analysis.dart';
-import 'mirrors_data.dart';
 import 'namer.dart';
 import 'native_data.dart';
 import 'no_such_method_registry.dart';
-import 'patch_resolver.dart';
 import 'resolution_listener.dart';
 import 'runtime_types.dart';
-import 'type_variable_handler.dart';
 
 const VERBOSE_OPTIMIZER_HINTS = false;
 
@@ -114,11 +102,7 @@
   ///
   /// For a [MethodElement] this means it must be the declaration element.
   bool checkFunction(FunctionEntity method) {
-    if (method is MethodElement) {
-      return method.isDeclaration;
-    } else {
-      return '$method'.startsWith(jsElementPrefix);
-    }
+    return '$method'.startsWith(jsElementPrefix);
   }
 
   /// Returns the current cache decision. This should only be used for testing.
@@ -360,7 +344,6 @@
   List<CompilerTask> get tasks {
     List<CompilerTask> result = functionCompiler.tasks;
     result.add(emitter);
-    result.add(patchResolverTask);
     return result;
   }
 
@@ -373,9 +356,6 @@
   /// True if the html library has been loaded.
   bool htmlLibraryIsLoaded = false;
 
-  /// Codegen handler for reflective access to type variables.
-  TypeVariableCodegenAnalysis _typeVariableCodegenAnalysis;
-
   /// Resolution support for generating table of interceptors and
   /// constructors for custom elements.
   CustomElementsResolutionAnalysis _customElementsResolutionAnalysis;
@@ -390,12 +370,6 @@
   /// Support for classifying `noSuchMethod` implementations.
   NoSuchMethodRegistry noSuchMethodRegistry;
 
-  /// Resolution support for computing reflectable elements.
-  MirrorsResolutionAnalysis _mirrorsResolutionAnalysis;
-
-  /// Codegen support for computing reflectable elements.
-  MirrorsCodegenAnalysis _mirrorsCodegenAnalysis;
-
   /// The compiler task responsible for the compilation of constants for both
   /// the frontend and the backend.
   final JavaScriptConstantTask constantCompilerTask;
@@ -405,17 +379,13 @@
 
   CodegenImpactTransformer _codegenImpactTransformer;
 
-  PatchResolverTask patchResolverTask;
-
   /// The strategy used for collecting and emitting source information.
   SourceInformationStrategy sourceInformationStrategy;
 
   NativeDataBuilderImpl _nativeDataBuilder;
   NativeDataBuilder get nativeDataBuilder => _nativeDataBuilder;
-  final NativeDataResolver _nativeDataResolver;
   OneShotInterceptorData _oneShotInterceptorData;
   BackendUsageBuilder _backendUsageBuilder;
-  MirrorsDataImpl _mirrorsData;
   OutputUnitData _outputUnitData;
 
   CheckedModeHelpers _checkedModeHelpers;
@@ -425,8 +395,6 @@
   native.NativeResolutionEnqueuer _nativeResolutionEnqueuer;
   native.NativeCodegenEnqueuer _nativeCodegenEnqueuer;
 
-  Target _target;
-
   Tracer tracer;
 
   JavaScriptBackend(this.compiler,
@@ -436,22 +404,16 @@
       bool useNewSourceInfo: false})
       : this.sourceInformationStrategy =
             compiler.backendStrategy.sourceInformationStrategy,
-        constantCompilerTask = new JavaScriptConstantTask(compiler),
-        _nativeDataResolver = new NativeDataResolverImpl(compiler) {
+        constantCompilerTask = new JavaScriptConstantTask(compiler) {
     CommonElements commonElements = compiler.frontendStrategy.commonElements;
-    _target = new JavaScriptBackendTarget(this);
-    _mirrorsData = compiler.frontendStrategy.createMirrorsDataBuilder();
     _backendUsageBuilder = new BackendUsageBuilderImpl(commonElements);
     _checkedModeHelpers = new CheckedModeHelpers();
     emitter =
         new CodeEmitterTask(compiler, generateSourceMap, useStartupEmitter);
     jsInteropAnalysis = new JsInteropAnalysis(this);
-    _mirrorsResolutionAnalysis =
-        compiler.frontendStrategy.createMirrorsResolutionAnalysis(this);
 
     noSuchMethodRegistry = new NoSuchMethodRegistryImpl(
         commonElements, compiler.frontendStrategy.createNoSuchMethodResolver());
-    patchResolverTask = new PatchResolverTask(compiler);
     functionCompiler = new SsaFunctionCompiler(
         this, compiler.measurer, sourceInformationStrategy);
   }
@@ -462,12 +424,8 @@
 
   DiagnosticReporter get reporter => compiler.reporter;
 
-  Resolution get resolution => compiler.resolution;
-
   ImpactCacheDeleter get impactCacheDeleter => compiler.impactCacheDeleter;
 
-  Target get target => _target;
-
   /// Resolution support for generating table of interceptors and
   /// constructors for custom elements.
   CustomElementsResolutionAnalysis get customElementsResolutionAnalysis {
@@ -488,34 +446,8 @@
     return _customElementsCodegenAnalysis;
   }
 
-  /// Codegen handler for reflective access to type variables.
-  TypeVariableCodegenAnalysis get typeVariableCodegenAnalysis {
-    assert(
-        _typeVariableCodegenAnalysis != null,
-        failedAt(NO_LOCATION_SPANNABLE,
-            "TypeVariableHandler has not been created yet."));
-    return _typeVariableCodegenAnalysis;
-  }
-
-  MirrorsData get mirrorsData => _mirrorsData;
-
-  MirrorsDataBuilder get mirrorsDataBuilder => _mirrorsData;
-
   OutputUnitData get outputUnitData => _outputUnitData;
 
-  /// Resolution support for computing reflectable elements.
-  MirrorsResolutionAnalysis get mirrorsResolutionAnalysis =>
-      _mirrorsResolutionAnalysis;
-
-  /// Codegen support for computing reflectable elements.
-  MirrorsCodegenAnalysis get mirrorsCodegenAnalysis {
-    assert(
-        _mirrorsCodegenAnalysis != null,
-        failedAt(NO_LOCATION_SPANNABLE,
-            "MirrorsCodegenAnalysis has not been created yet."));
-    return _mirrorsCodegenAnalysis;
-  }
-
   OneShotInterceptorData get oneShotInterceptorData {
     assert(
         _oneShotInterceptorData != null,
@@ -562,31 +494,6 @@
     return constantCompilerTask.jsConstantCompiler;
   }
 
-  MethodElement resolveExternalFunction(MethodElement element) {
-    if (isForeign(compiler.frontendStrategy.commonElements, element)) {
-      return element;
-    }
-    if (_nativeDataResolver.isJsInteropMember(element)) {
-      if (element.memberName == const PublicName('[]') ||
-          element.memberName == const PublicName('[]=')) {
-        reporter.reportErrorMessage(
-            element, MessageKind.JS_INTEROP_INDEX_NOT_SUPPORTED);
-      }
-      return element;
-    }
-    return patchResolverTask.measure(() {
-      return patchResolverTask.resolveExternalFunction(element);
-    });
-  }
-
-  bool isForeign(CommonElements commonElements, Element element) =>
-      element.library == commonElements.foreignLibrary;
-
-  bool isBackendLibrary(CommonElements commonElements, LibraryElement library) {
-    return library == commonElements.interceptorsLibrary ||
-        library == commonElements.jsHelperLibrary;
-  }
-
   Namer determineNamer(
       ClosedWorld closedWorld, CodegenWorldBuilder codegenWorldBuilder) {
     return compiler.options.enableMinification
@@ -643,47 +550,12 @@
   void onResolutionClosedWorld(
       ClosedWorld closedWorld, ClosedWorldRefiner closedWorldRefiner) {
     processAnnotations(closedWorldRefiner);
-    mirrorsDataBuilder.computeMembersNeededForReflection(
-        compiler.enqueuer.resolution.worldBuilder, closedWorld);
-    mirrorsResolutionAnalysis.onResolutionComplete();
   }
 
   void onDeferredLoadComplete(OutputUnitData data) {
     _outputUnitData = compiler.backendStrategy.convertOutputUnitData(data);
   }
 
-  /// Called when resolving a call to a foreign function.
-  native.NativeBehavior resolveForeignCall(Send node, Element element,
-      CallStructure callStructure, ForeignResolver resolver) {
-    if (element.name == JS) {
-      return _nativeDataResolver.resolveJsCall(node, resolver);
-    } else if (element.name == JS_EMBEDDED_GLOBAL) {
-      return _nativeDataResolver.resolveJsEmbeddedGlobalCall(node, resolver);
-    } else if (element.name == JS_BUILTIN) {
-      return _nativeDataResolver.resolveJsBuiltinCall(node, resolver);
-    } else if (element.name == JS_INTERCEPTOR_CONSTANT) {
-      // The type constant that is an argument to JS_INTERCEPTOR_CONSTANT names
-      // a class that will be instantiated outside the program by attaching a
-      // native class dispatch record referencing the interceptor.
-      if (!node.argumentsNode.isEmpty) {
-        Node argument = node.argumentsNode.nodes.head;
-        ConstantExpression constant = resolver.getConstant(argument);
-        if (constant != null && constant.kind == ConstantExpressionKind.TYPE) {
-          TypeConstantExpression typeConstant = constant;
-          if (typeConstant.type is ResolutionInterfaceType) {
-            resolver.registerInstantiatedType(typeConstant.type);
-            // No native behavior for this call.
-            return null;
-          }
-        }
-      }
-      reporter.reportErrorMessage(
-          node, MessageKind.WRONG_ARGUMENT_FOR_JS_INTERCEPTOR_CONSTANT);
-    }
-    // No native behavior for this call.
-    return null;
-  }
-
   ResolutionEnqueuer createResolutionEnqueuer(
       CompilerTask task, Compiler compiler) {
     ElementEnvironment elementEnvironment =
@@ -694,17 +566,11 @@
         compiler.frontendStrategy.createRuntimeTypesNeedBuilder();
     BackendImpacts impacts =
         new BackendImpacts(compiler.options, commonElements);
-    TypeVariableResolutionAnalysis typeVariableResolutionAnalysis =
-        new TypeVariableResolutionAnalysis(
-            compiler.frontendStrategy.elementEnvironment,
-            impacts,
-            _backendUsageBuilder);
     _nativeResolutionEnqueuer = new native.NativeResolutionEnqueuer(
         compiler.options,
         elementEnvironment,
         commonElements,
         compiler.frontendStrategy.dartTypes,
-        _backendUsageBuilder,
         compiler.frontendStrategy.createNativeClassFinder(nativeBasicData));
     _nativeDataBuilder = new NativeDataBuilderImpl(nativeBasicData);
     _customElementsResolutionAnalysis = new CustomElementsResolutionAnalysis(
@@ -724,7 +590,6 @@
         nativeBasicData,
         _nativeResolutionEnqueuer,
         _backendUsageBuilder,
-        mirrorsDataBuilder,
         customElementsResolutionAnalysis,
         rtiNeedBuilder,
         classHierarchyBuilder);
@@ -746,11 +611,8 @@
             nativeBasicData,
             interceptorDataBuilder,
             _backendUsageBuilder,
-            mirrorsDataBuilder,
             noSuchMethodRegistry,
             customElementsResolutionAnalysis,
-            mirrorsResolutionAnalysis,
-            typeVariableResolutionAnalysis,
             _nativeResolutionEnqueuer,
             compiler.deferredLoadTask),
         compiler.frontendStrategy.createResolutionWorldBuilder(
@@ -780,9 +642,6 @@
     CommonElements commonElements = closedWorld.commonElements;
     BackendImpacts impacts =
         new BackendImpacts(compiler.options, commonElements);
-    _typeVariableCodegenAnalysis = new TypeVariableCodegenAnalysis(
-        closedWorld.elementEnvironment, this, commonElements, mirrorsData);
-    _mirrorsCodegenAnalysis = mirrorsResolutionAnalysis.close();
     _customElementsCodegenAnalysis = new CustomElementsCodegenAnalysis(
         constantSystem,
         commonElements,
@@ -810,8 +669,6 @@
             closedWorld.backendUsage,
             closedWorld.rtiNeed,
             customElementsCodegenAnalysis,
-            typeVariableCodegenAnalysis,
-            mirrorsCodegenAnalysis,
             nativeCodegenEnqueuer));
   }
 
@@ -868,8 +725,6 @@
    * Invariant: [element] must be a declaration element.
    */
   String getGeneratedCode(MemberEntity element) {
-    assert(!(element is MemberElement && !element.isDeclaration),
-        failedAt(element));
     return jsAst.prettyPrint(generatedCode[element],
         enableMinification: compiler.options.enableMinification);
   }
@@ -878,39 +733,6 @@
   int assembleProgram(ClosedWorld closedWorld) {
     int programSize = emitter.assembleProgram(namer, closedWorld);
     closedWorld.noSuchMethodData.emitDiagnostic(reporter);
-    int totalMethodCount = generatedCode.length;
-    // TODO(redemption): Support `preMirrorsMethodCount` for entities.
-    if (mirrorsCodegenAnalysis.preMirrorsMethodCount != null &&
-        totalMethodCount != mirrorsCodegenAnalysis.preMirrorsMethodCount) {
-      int mirrorCount =
-          totalMethodCount - mirrorsCodegenAnalysis.preMirrorsMethodCount;
-      double percentage = (mirrorCount / totalMethodCount) * 100;
-      DiagnosticMessage hint = reporter.createMessage(
-          closedWorld.elementEnvironment.mainLibrary,
-          MessageKind.MIRROR_BLOAT, {
-        'count': mirrorCount,
-        'total': totalMethodCount,
-        'percentage': percentage.round()
-      });
-
-      List<DiagnosticMessage> infos = <DiagnosticMessage>[];
-      for (LibraryElement library in compiler.libraryLoader.libraries) {
-        if (library.isInternalLibrary) continue;
-        for (ImportElement import in library.imports) {
-          LibraryElement importedLibrary = import.importedLibrary;
-          if (importedLibrary != closedWorld.commonElements.mirrorsLibrary)
-            continue;
-          MessageKind kind =
-              compiler.mirrorUsageAnalyzerTask.hasMirrorUsage(library)
-                  ? MessageKind.MIRROR_IMPORT
-                  : MessageKind.MIRROR_IMPORT_NO_USAGE;
-          reporter.withCurrentElement(library, () {
-            infos.add(reporter.createMessage(import, kind));
-          });
-        }
-      }
-      reporter.reportHint(hint, infos);
-    }
     return programSize;
   }
 
@@ -1013,22 +835,10 @@
     tracer.close();
   }
 
-  // Does this element belong in the output
-  bool shouldOutput(Element element) => true;
-
   /// Returns `true` if the `native` pseudo keyword is supported for [library].
   bool canLibraryUseNative(LibraryEntity library) =>
       native.maybeEnableNative(library.canonicalUri);
 
-  bool isTargetSpecificLibrary(LibraryElement library) {
-    Uri canonicalUri = library.canonicalUri;
-    if (canonicalUri == Uris.dart__js_helper ||
-        canonicalUri == Uris.dart__interceptors) {
-      return true;
-    }
-    return false;
-  }
-
   /// Process backend specific annotations.
   // TODO(johnniwinther): Merge this with [AnnotationProcessor] and use
   // [ElementEnvironment.getMemberMetadata] in [AnnotationProcessor].
@@ -1049,12 +859,6 @@
       CommonElements commonElements,
       MemberEntity element,
       ClosedWorldRefiner closedWorldRefiner) {
-    if (element is MemberElement && element.isMalformed) {
-      // Elements that are marked as malformed during parsing or resolution
-      // might be registered here. These should just be ignored.
-      return;
-    }
-
     bool hasNoInline = false;
     bool hasForceInline = false;
 
@@ -1309,9 +1113,6 @@
         impact.apply(visitor);
       } else {
         impact.apply(visitor);
-        if (impactSource is Element) {
-          impactCacheDeleter.uncacheWorldImpact(impactSource);
-        }
       }
     } else if (impactUse == DeferredLoadTask.IMPACT_USE) {
       impact.apply(visitor);
@@ -1332,55 +1133,6 @@
   }
 }
 
-class JavaScriptBackendTarget extends Target {
-  final JavaScriptBackend _backend;
-
-  JavaScriptBackendTarget(this._backend);
-
-  CommonElements get _commonElements =>
-      _backend.compiler.frontendStrategy.commonElements;
-
-  @override
-  bool isTargetSpecificLibrary(LibraryElement element) {
-    return _backend.isTargetSpecificLibrary(element);
-  }
-
-  @override
-  void resolveNativeMember(MemberElement element, NativeRegistry registry) {
-    return _backend._nativeDataResolver.resolveNativeMember(element, registry);
-  }
-
-  @override
-  MethodElement resolveExternalFunction(MethodElement element) {
-    return _backend.resolveExternalFunction(element);
-  }
-
-  @override
-  dynamic resolveForeignCall(Send node, Element element,
-      CallStructure callStructure, ForeignResolver resolver) {
-    return _backend.resolveForeignCall(node, element, callStructure, resolver);
-  }
-
-  @override
-  bool isDefaultNoSuchMethod(MethodElement element) {
-    return _commonElements.isDefaultNoSuchMethodImplementation(element);
-  }
-
-  @override
-  ClassElement defaultSuperclass(ClassElement element) {
-    return _commonElements.getDefaultSuperclass(
-        element, _backend.frontendStrategy.nativeBasicData);
-  }
-
-  @override
-  bool isNativeClass(ClassEntity element) =>
-      _backend.compiler.frontendStrategy.nativeBasicData.isNativeClass(element);
-
-  @override
-  bool isForeign(Element element) =>
-      _backend.isForeign(_commonElements, element);
-}
-
 class SuperMemberData {
   /// A set of member that are called from subclasses via `super`.
   final Set<MemberEntity> _aliasedSuperMembers = new Setlet<MemberEntity>();
diff --git a/pkg/compiler/lib/src/js_backend/backend_usage.dart b/pkg/compiler/lib/src/js_backend/backend_usage.dart
index ed8dced..8af1da3 100644
--- a/pkg/compiler/lib/src/js_backend/backend_usage.dart
+++ b/pkg/compiler/lib/src/js_backend/backend_usage.dart
@@ -4,7 +4,6 @@
 
 import '../common.dart';
 import '../common_elements.dart';
-import '../elements/elements.dart' show Element;
 import '../elements/entities.dart';
 import '../elements/types.dart';
 import '../util/util.dart' show Setlet;
@@ -144,7 +143,8 @@
 
   bool _isValidBackendUse(Entity element) {
     if (_isValidEntity(element)) return true;
-    if (element is Element) {
+    // TODO(redemption): Support these checks on kernel based elements:
+    /*if (element is Element) {
       assert(element.isDeclaration,
           failedAt(element, "Backend use $element must be the declaration."));
       if (element.implementationLibrary.isPatch ||
@@ -154,15 +154,13 @@
               element.sourcePosition.uri.path
                   .contains('_internal/js_runtime/lib/')) ||
           element.library == _commonElements.jsHelperLibrary ||
-          element.library == _commonElements.interceptorsLibrary ||
-          element.library == _commonElements.isolateHelperLibrary) {
+          element.library == _commonElements.interceptorsLibrary) {
         // TODO(johnniwinther): We should be more precise about these.
         return true;
       } else {
         return false;
       }
-    }
-    // TODO(redemption): Support remaining checks on [Entity]s.
+    }*/
     return true;
   }
 
diff --git a/pkg/compiler/lib/src/js_backend/checked_mode_helpers.dart b/pkg/compiler/lib/src/js_backend/checked_mode_helpers.dart
index 4aec501..ed231cc 100644
--- a/pkg/compiler/lib/src/js_backend/checked_mode_helpers.dart
+++ b/pkg/compiler/lib/src/js_backend/checked_mode_helpers.dart
@@ -4,9 +4,7 @@
 
 import '../common.dart';
 import '../common_elements.dart';
-import '../elements/elements.dart' show ErroneousElement;
 import '../elements/entities.dart';
-import '../elements/resolution_types.dart' show MalformedType;
 import '../elements/types.dart';
 import '../js/js.dart' as jsAst;
 import '../js/js.dart' show js;
@@ -36,20 +34,6 @@
   }
 }
 
-class MalformedCheckedModeHelper extends CheckedModeHelper {
-  const MalformedCheckedModeHelper(String name) : super(name);
-
-  CallStructure get callStructure => CallStructure.TWO_ARGS;
-
-  void generateAdditionalArguments(SsaCodeGenerator codegen, Namer namer,
-      HTypeConversion node, List<jsAst.Expression> arguments) {
-    // TODO(redemption): Support malformed types in [types.dart].
-    MalformedType type = node.typeExpression;
-    ErroneousElement element = type.element;
-    arguments.add(js.escapedString(element.message));
-  }
-}
-
 class PropertyCheckedModeHelper extends CheckedModeHelper {
   const PropertyCheckedModeHelper(String name) : super(name);
 
@@ -127,7 +111,6 @@
 
   /// All the checked mode helpers.
   static const List<CheckedModeHelper> helpers = const <CheckedModeHelper>[
-    const MalformedCheckedModeHelper('checkMalformedType'),
     const CheckedModeHelper('stringTypeCast'),
     const CheckedModeHelper('stringTypeCheck'),
     const CheckedModeHelper('doubleTypeCast'),
@@ -215,11 +198,6 @@
       DartType type, CommonElements commonElements,
       {bool typeCast, bool nativeCheckOnly}) {
     assert(!type.isTypedef);
-    if (type.isMalformed) {
-      // The same error is thrown for type test and type cast of a malformed
-      // type so we only need one check method.
-      return 'checkMalformedType';
-    }
 
     if (type.isTypeVariable) {
       return typeCast
diff --git a/pkg/compiler/lib/src/js_backend/codegen_listener.dart b/pkg/compiler/lib/src/js_backend/codegen_listener.dart
index 39c2fb4..461bd279 100644
--- a/pkg/compiler/lib/src/js_backend/codegen_listener.dart
+++ b/pkg/compiler/lib/src/js_backend/codegen_listener.dart
@@ -18,9 +18,7 @@
 import 'backend_impact.dart';
 import 'backend_usage.dart';
 import 'custom_elements_analysis.dart';
-import 'mirrors_analysis.dart';
 import 'runtime_types.dart';
-import 'type_variable_handler.dart';
 
 class CodegenEnqueuerListener extends EnqueuerListener {
   final ElementEnvironment _elementEnvironment;
@@ -31,8 +29,6 @@
   final RuntimeTypesNeed _rtiNeed;
 
   final CustomElementsCodegenAnalysis _customElementsAnalysis;
-  final TypeVariableCodegenAnalysis _typeVariableCodegenAnalysis;
-  final MirrorsCodegenAnalysis _mirrorsAnalysis;
 
   final NativeCodegenEnqueuer _nativeEnqueuer;
 
@@ -45,8 +41,6 @@
       this._backendUsage,
       this._rtiNeed,
       this._customElementsAnalysis,
-      this._typeVariableCodegenAnalysis,
-      this._mirrorsAnalysis,
       this._nativeEnqueuer);
 
   @override
@@ -110,7 +104,6 @@
     // Return early if any elements are added to avoid counting the elements as
     // due to mirrors.
     enqueuer.applyImpact(_customElementsAnalysis.flush());
-    enqueuer.applyImpact(_typeVariableCodegenAnalysis.flush());
 
     if (_backendUsage.isNoSuchMethodUsed && !_isNoSuchMethodUsed) {
       enqueuer.applyImpact(
@@ -120,7 +113,6 @@
 
     if (!enqueuer.queueIsEmpty) return false;
 
-    _mirrorsAnalysis.onQueueEmpty(enqueuer, recentClasses);
     return true;
   }
 
@@ -226,9 +218,6 @@
 
   WorldImpact _processClass(ClassEntity cls) {
     WorldImpactBuilderImpl impactBuilder = new WorldImpactBuilderImpl();
-    if (_elementEnvironment.isGenericClass(cls)) {
-      _typeVariableCodegenAnalysis.registerClassWithTypeVariables(cls);
-    }
     if (cls == _commonElements.closureClass) {
       _impacts.closureClass.registerImpact(impactBuilder, _elementEnvironment);
     }
diff --git a/pkg/compiler/lib/src/js_backend/constant_handler_javascript.dart b/pkg/compiler/lib/src/js_backend/constant_handler_javascript.dart
index b0ccafa..26f845e 100644
--- a/pkg/compiler/lib/src/js_backend/constant_handler_javascript.dart
+++ b/pkg/compiler/lib/src/js_backend/constant_handler_javascript.dart
@@ -5,13 +5,8 @@
 import '../compile_time_constants.dart';
 import '../compiler.dart' show Compiler;
 import '../constants/constant_system.dart';
-import '../constants/expressions.dart';
-import '../constants/values.dart';
-import '../elements/elements.dart';
+import '../constant_system_dart.dart';
 import '../elements/entities.dart';
-import '../elements/visitor.dart' show BaseElementVisitor;
-import '../resolution/tree_elements.dart' show TreeElements;
-import '../tree/tree.dart';
 import 'constant_system_javascript.dart';
 
 /// [ConstantCompilerTask] for compilation of constants for the JavaScript
@@ -22,89 +17,18 @@
 /// [DartConstantCompiler] for the frontend interpretation of the constants and
 /// to a [JavaScriptConstantCompiler] for the backend interpretation.
 class JavaScriptConstantTask extends ConstantCompilerTask {
-  DartConstantCompiler dartConstantCompiler;
+  ConstantSystem dartConstantSystem;
   JavaScriptConstantCompiler jsConstantCompiler;
 
   JavaScriptConstantTask(Compiler compiler)
-      : this.dartConstantCompiler = new DartConstantCompiler(compiler),
-        this.jsConstantCompiler = new JavaScriptConstantCompiler(compiler),
+      : this.dartConstantSystem = const DartConstantSystem(),
+        this.jsConstantCompiler = new JavaScriptConstantCompiler(),
         super(compiler.measurer);
 
   String get name => 'ConstantHandler';
 
   @override
-  ConstantSystem get constantSystem => dartConstantCompiler.constantSystem;
-
-  @override
-  bool hasConstantValue(ConstantExpression expression) {
-    return dartConstantCompiler.hasConstantValue(expression);
-  }
-
-  @override
-  ConstantValue getConstantValue(ConstantExpression expression) {
-    return dartConstantCompiler.getConstantValue(expression);
-  }
-
-  @override
-  ConstantValue getConstantValueForVariable(VariableElement element) {
-    return dartConstantCompiler.getConstantValueForVariable(element);
-  }
-
-  @override
-  ConstantExpression compileConstant(VariableElement element) {
-    return measure(() {
-      // TODO(het): Only report errors from one of the constant compilers
-      ConstantExpression result = dartConstantCompiler.compileConstant(element);
-      jsConstantCompiler.compileConstant(element);
-      return result;
-    });
-  }
-
-  @override
-  void evaluate(ConstantExpression constant) {
-    return measure(() {
-      dartConstantCompiler.evaluate(constant);
-      jsConstantCompiler.evaluate(constant);
-    });
-  }
-
-  @override
-  ConstantExpression compileVariable(VariableElement element) {
-    return measure(() {
-      return jsConstantCompiler.compileVariable(element);
-    });
-  }
-
-  ConstantExpression compileNode(Node node, TreeElements elements,
-      {bool enforceConst: true}) {
-    return measure(() {
-      ConstantExpression result = dartConstantCompiler
-          .compileNode(node, elements, enforceConst: enforceConst);
-      jsConstantCompiler.compileNode(node, elements,
-          enforceConst: enforceConst);
-      return result;
-    });
-  }
-
-  ConstantExpression compileMetadata(
-      MetadataAnnotation metadata, Node node, TreeElements elements) {
-    return measure(() {
-      ConstantExpression constant =
-          dartConstantCompiler.compileMetadata(metadata, node, elements);
-      jsConstantCompiler.compileMetadata(metadata, node, elements);
-      return constant;
-    });
-  }
-
-  // TODO(johnniwinther): Remove this when values are computed from the
-  // expressions.
-  @override
-  void copyConstantValues(covariant JavaScriptConstantTask task) {
-    jsConstantCompiler.constantValueMap
-        .addAll(task.jsConstantCompiler.constantValueMap);
-    dartConstantCompiler.constantValueMap
-        .addAll(task.dartConstantCompiler.constantValueMap);
-  }
+  ConstantSystem get constantSystem => dartConstantSystem;
 }
 
 /**
@@ -112,40 +36,14 @@
  * constants, initializations of global and static fields, and default values of
  * optional parameters for the JavaScript interpretation of constants.
  */
-class JavaScriptConstantCompiler extends ConstantCompilerBase
-    implements BackendConstantEnvironment {
+class JavaScriptConstantCompiler implements BackendConstantEnvironment {
   // TODO(johnniwinther): Move this to the backend constant handler.
   /** Caches the statics where the initial value cannot be eagerly compiled. */
   final Set<FieldEntity> lazyStatics = new Set<FieldEntity>();
 
-  // Constants computed for constant expressions.
-  final Map<Node, ConstantExpression> nodeConstantMap =
-      new Map<Node, ConstantExpression>();
+  JavaScriptConstantCompiler();
 
-  // Constants computed for metadata.
-  // TODO(johnniwinther): Remove this when no longer used by
-  // poi/forget_element_test.
-  final Map<MetadataAnnotation, ConstantExpression> metadataConstantMap =
-      new Map<MetadataAnnotation, ConstantExpression>();
-
-  JavaScriptConstantCompiler(Compiler compiler)
-      : super(compiler, JAVA_SCRIPT_CONSTANT_SYSTEM);
-
-  ConstantExpression compileVariableWithDefinitions(
-      VariableElement element, TreeElements definitions,
-      {bool isConst: false, bool checkType: true}) {
-    if (!isConst && lazyStatics.contains(element)) {
-      return null;
-    }
-    ConstantExpression value = super.compileVariableWithDefinitions(
-        element, definitions,
-        isConst: isConst, checkType: checkType);
-    if (!isConst && value == null) {
-      FieldElement field = element;
-      registerLazyStatic(field);
-    }
-    return value;
-  }
+  ConstantSystem get constantSystem => JAVA_SCRIPT_CONSTANT_SYSTEM;
 
   @override
   void registerLazyStatic(FieldEntity element) {
@@ -155,82 +53,4 @@
   List<FieldEntity> getLazilyInitializedFieldsForEmission() {
     return new List<FieldEntity>.from(lazyStatics);
   }
-
-  ConstantExpression compileNode(Node node, TreeElements elements,
-      {bool enforceConst: true}) {
-    return compileNodeWithDefinitions(node, elements, isConst: enforceConst);
-  }
-
-  ConstantExpression compileNodeWithDefinitions(
-      Node node, TreeElements definitions,
-      {bool isConst: true}) {
-    ConstantExpression constant = nodeConstantMap[node];
-    if (constant != null && getConstantValue(constant) != null) {
-      return constant;
-    }
-    constant =
-        super.compileNodeWithDefinitions(node, definitions, isConst: isConst);
-    if (constant != null) {
-      nodeConstantMap[node] = constant;
-    }
-    return constant;
-  }
-
-  ConstantValue getConstantValueForNode(Node node, TreeElements definitions) {
-    return getConstantValue(getConstantForNode(node, definitions));
-  }
-
-  ConstantExpression getConstantForNode(Node node, TreeElements definitions) {
-    ConstantExpression constant = nodeConstantMap[node];
-    if (constant != null) {
-      return constant;
-    }
-    return definitions.getConstant(node);
-  }
-
-  ConstantValue getConstantValueForMetadata(MetadataAnnotation metadata) {
-    return getConstantValue(metadata.constant);
-  }
-
-  @override
-  ConstantExpression compileMetadata(
-      MetadataAnnotation metadata, Node node, TreeElements elements) {
-    ConstantExpression constant =
-        super.compileMetadata(metadata, node, elements);
-    metadataConstantMap[metadata] = constant;
-    return constant;
-  }
-}
-
-class ForgetConstantElementVisitor
-    extends BaseElementVisitor<dynamic, JavaScriptConstantCompiler> {
-  const ForgetConstantElementVisitor();
-
-  void visitElement(Element e, JavaScriptConstantCompiler constants) {
-    for (MetadataAnnotation data in e.implementation.metadata) {
-      constants.metadataConstantMap.remove(data);
-      if (data.hasNode) {
-        data.node.accept(new ForgetConstantNodeVisitor(constants));
-      }
-    }
-  }
-
-  void visitFunctionElement(
-      FunctionElement e, JavaScriptConstantCompiler constants) {
-    super.visitFunctionElement(e, constants);
-    if (e.hasFunctionSignature) {
-      e.functionSignature.forEachParameter((p) => visit(p, constants));
-    }
-  }
-}
-
-class ForgetConstantNodeVisitor extends Visitor {
-  final JavaScriptConstantCompiler constants;
-
-  ForgetConstantNodeVisitor(this.constants);
-
-  void visitNode(Node node) {
-    node.visitChildren(this);
-    constants.nodeConstantMap.remove(node);
-  }
 }
diff --git a/pkg/compiler/lib/src/js_backend/element_strategy.dart b/pkg/compiler/lib/src/js_backend/element_strategy.dart
deleted file mode 100644
index c233ee8..0000000
--- a/pkg/compiler/lib/src/js_backend/element_strategy.dart
+++ /dev/null
@@ -1,180 +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 dart2js.js_backend.element_strategy;
-
-import '../backend_strategy.dart';
-import '../closure.dart' show ClosureConversionTask, ClosureTask;
-import '../common.dart';
-import '../common/codegen.dart';
-import '../common/tasks.dart';
-import '../common/work.dart';
-import '../compiler.dart';
-import '../deferred_load.dart' show OutputUnitData;
-import '../elements/elements.dart';
-import '../enqueue.dart';
-import '../inferrer/type_graph_inferrer.dart' show AstTypeGraphInferrer;
-import '../io/multi_information.dart' show MultiSourceInformationStrategy;
-import '../io/position_information.dart' show PositionSourceInformationStrategy;
-import '../io/source_information.dart';
-import '../io/start_end_information.dart'
-    show StartEndSourceInformationStrategy;
-import '../js/js_source_mapping.dart' show JavaScriptSourceInformationStrategy;
-import '../js_backend/backend.dart';
-import '../js_backend/native_data.dart';
-import '../js_emitter/sorter.dart';
-import '../resolution/resolution_strategy.dart';
-import '../ssa/builder.dart';
-import '../ssa/ssa.dart';
-import '../types/types.dart';
-import '../options.dart';
-import '../universe/world_builder.dart';
-import '../universe/world_impact.dart';
-import '../world.dart';
-
-/// Strategy for using the [Element] model from the resolver as the backend
-/// model.
-class ElementBackendStrategy extends ComputeSpannableMixin
-    implements BackendStrategy {
-  final Compiler _compiler;
-  final ClosureConversionTask closureDataLookup;
-  SourceInformationStrategy _sourceInformationStrategy;
-
-  ElementBackendStrategy(this._compiler)
-      : closureDataLookup = new ClosureTask(_compiler);
-
-  ClosedWorldRefiner createClosedWorldRefiner(
-          covariant ClosedWorldImpl closedWorld) =>
-      closedWorld;
-
-  Sorter get sorter => const ElementSorter();
-
-  @override
-  CodegenWorldBuilder createCodegenWorldBuilder(
-      NativeBasicData nativeBasicData,
-      ClosedWorld closedWorld,
-      SelectorConstraintsStrategy selectorConstraintsStrategy) {
-    return new ElementCodegenWorldBuilderImpl(
-        _compiler.backend.constants,
-        closedWorld.elementEnvironment,
-        nativeBasicData,
-        closedWorld,
-        selectorConstraintsStrategy);
-  }
-
-  @override
-  OutputUnitData convertOutputUnitData(OutputUnitData data) => data;
-
-  @override
-  WorkItemBuilder createCodegenWorkItemBuilder(ClosedWorld closedWorld) {
-    return new ElementCodegenWorkItemBuilder(
-        _compiler.backend, closedWorld, _compiler.options);
-  }
-
-  @override
-  SsaBuilder createSsaBuilder(CompilerTask task, JavaScriptBackend backend,
-      SourceInformationStrategy sourceInformationStrategy) {
-    return new SsaAstBuilder(task, backend, sourceInformationStrategy);
-  }
-
-  SourceInformationStrategy get sourceInformationStrategy {
-    return _sourceInformationStrategy ??= createSourceInformationStrategy(
-        generateSourceMap: _compiler.options.generateSourceMap,
-        useMultiSourceInfo: _compiler.options.useMultiSourceInfo,
-        useNewSourceInfo: _compiler.options.useNewSourceInfo);
-  }
-
-  static SourceInformationStrategy createSourceInformationStrategy(
-      {bool generateSourceMap: false,
-      bool useMultiSourceInfo: false,
-      bool useNewSourceInfo: false}) {
-    if (!generateSourceMap) return const JavaScriptSourceInformationStrategy();
-    if (useMultiSourceInfo) {
-      if (useNewSourceInfo) {
-        return const MultiSourceInformationStrategy(const [
-          const PositionSourceInformationStrategy(),
-          const StartEndSourceInformationStrategy()
-        ]);
-      } else {
-        return const MultiSourceInformationStrategy(const [
-          const StartEndSourceInformationStrategy(),
-          const PositionSourceInformationStrategy()
-        ]);
-      }
-    } else if (useNewSourceInfo) {
-      return const PositionSourceInformationStrategy();
-    } else {
-      return const StartEndSourceInformationStrategy();
-    }
-  }
-
-  @override
-  TypesInferrer createTypesInferrer(ClosedWorldRefiner closedWorldRefiner,
-      {bool disableTypeInference: false}) {
-    return new AstTypeGraphInferrer(
-        _compiler, closedWorldRefiner.closedWorld, closedWorldRefiner,
-        disableTypeInference: disableTypeInference);
-  }
-}
-
-/// Builder that creates the work item necessary for the code generation of a
-/// [MemberElement].
-class ElementCodegenWorkItemBuilder extends WorkItemBuilder {
-  final JavaScriptBackend _backend;
-  final ClosedWorld _closedWorld;
-  final CompilerOptions _options;
-
-  ElementCodegenWorkItemBuilder(
-      this._backend, this._closedWorld, this._options);
-
-  @override
-  WorkItem createWorkItem(MemberElement element) {
-    assert(element.isDeclaration, failedAt(element));
-    // Don't generate code for foreign elements.
-    if (_backend.isForeign(_closedWorld.commonElements, element)) return null;
-    if (element.isAbstract) return null;
-
-    // Codegen inlines field initializers. It only needs to generate
-    // code for checked setters.
-    if (element.isField && element.isInstanceMember) {
-      if (!_options.enableTypeAssertions ||
-          element.enclosingElement.isClosure) {
-        return null;
-      }
-    }
-    return new ElementCodegenWorkItem(_backend, _closedWorld, element);
-  }
-}
-
-class ElementCodegenWorkItem extends CodegenWorkItem {
-  CodegenRegistry registry;
-  final ResolvedAst resolvedAst;
-  final JavaScriptBackend _backend;
-  final ClosedWorld _closedWorld;
-
-  factory ElementCodegenWorkItem(JavaScriptBackend backend,
-      ClosedWorld closedWorld, MemberElement element) {
-    // If this assertion fails, the resolution callbacks of the backend may be
-    // missing call of form registry.registerXXX. Alternatively, the code
-    // generation could spuriously be adding dependencies on things we know we
-    // don't need.
-    assert(element.hasResolvedAst,
-        failedAt(element, "$element has no resolved ast."));
-    ResolvedAst resolvedAst = element.resolvedAst;
-    return new ElementCodegenWorkItem.internal(
-        resolvedAst, backend, closedWorld);
-  }
-
-  ElementCodegenWorkItem.internal(
-      this.resolvedAst, this._backend, this._closedWorld);
-
-  MemberElement get element => resolvedAst.element;
-
-  WorldImpact run() {
-    registry = new CodegenRegistry(_closedWorld.elementEnvironment, element);
-    return _backend.codegen(this, _closedWorld);
-  }
-
-  String toString() => 'CodegenWorkItem(${resolvedAst.element})';
-}
diff --git a/pkg/compiler/lib/src/js_backend/field_naming_mixin.dart b/pkg/compiler/lib/src/js_backend/field_naming_mixin.dart
index e2d67ea..cbb30a5 100644
--- a/pkg/compiler/lib/src/js_backend/field_naming_mixin.dart
+++ b/pkg/compiler/lib/src/js_backend/field_naming_mixin.dart
@@ -19,9 +19,7 @@
     }
 
     _FieldNamingScope names;
-    if (element is BoxFieldElement) {
-      names = new _FieldNamingScope.forBox(element.box, fieldRegistry);
-    } else if (element is JRecordField) {
+    if (element is JRecordField) {
       names = new _FieldNamingScope.forBox(element.box, fieldRegistry);
     } else {
       ClassEntity cls = element.enclosingClass;
diff --git a/pkg/compiler/lib/src/js_backend/impact_transformer.dart b/pkg/compiler/lib/src/js_backend/impact_transformer.dart
index 4fb3ac1..70e8d1a 100644
--- a/pkg/compiler/lib/src/js_backend/impact_transformer.dart
+++ b/pkg/compiler/lib/src/js_backend/impact_transformer.dart
@@ -6,7 +6,6 @@
 
 import '../universe/class_hierarchy_builder.dart' show ClassHierarchyBuilder;
 
-import '../closure.dart';
 import '../common.dart';
 import '../common_elements.dart';
 import '../common/backend_api.dart' show ImpactTransformer;
@@ -29,7 +28,6 @@
 import 'checked_mode_helpers.dart';
 import 'custom_elements_analysis.dart';
 import 'interceptor_data.dart';
-import 'mirrors_data.dart';
 import 'namer.dart';
 import 'native_data.dart';
 import 'runtime_types.dart';
@@ -42,7 +40,6 @@
   final NativeBasicData _nativeBasicData;
   final NativeResolutionEnqueuer _nativeResolutionEnqueuer;
   final BackendUsageBuilder _backendUsageBuilder;
-  final MirrorsDataBuilder _mirrorsDataBuilder;
   final CustomElementsResolutionAnalysis _customElementsResolutionAnalysis;
   final RuntimeTypesNeedBuilder _rtiNeedBuilder;
   final ClassHierarchyBuilder _classHierarchyBuilder;
@@ -55,7 +52,6 @@
       this._nativeBasicData,
       this._nativeResolutionEnqueuer,
       this._backendUsageBuilder,
-      this._mirrorsDataBuilder,
       this._customElementsResolutionAnalysis,
       this._rtiNeedBuilder,
       this._classHierarchyBuilder);
@@ -243,9 +239,6 @@
 
     if (worldImpact.constSymbolNames.isNotEmpty) {
       registerImpact(_impacts.constSymbol);
-      for (String constSymbolName in worldImpact.constSymbolNames) {
-        _mirrorsDataBuilder.registerConstSymbol(constSymbolName);
-      }
     }
 
     for (StaticUse staticUse in worldImpact.staticUses) {
@@ -432,11 +425,6 @@
         if (_rtiNeed.methodNeedsSignature(callMethod)) {
           _impacts.computeSignature
               .registerImpact(transformed, _elementEnvironment);
-        } else if (callMethod is SynthesizedCallMethodElementX) {
-          if (_rtiNeed.localFunctionNeedsSignature(callMethod.expression)) {
-            _impacts.computeSignature
-                .registerImpact(transformed, _elementEnvironment);
-          }
         }
       }
     }
diff --git a/pkg/compiler/lib/src/js_backend/interceptor_data.dart b/pkg/compiler/lib/src/js_backend/interceptor_data.dart
index 87fc04e..079aa91 100644
--- a/pkg/compiler/lib/src/js_backend/interceptor_data.dart
+++ b/pkg/compiler/lib/src/js_backend/interceptor_data.dart
@@ -9,7 +9,7 @@
 import '../elements/entities.dart';
 import '../elements/types.dart';
 import '../js/js.dart' as jsAst;
-import '../types/types.dart' show TypeMask;
+import '../types/masks.dart' show TypeMask;
 import '../universe/selector.dart';
 import '../world.dart' show ClosedWorld;
 import 'namer.dart';
diff --git a/pkg/compiler/lib/src/js_backend/js_backend.dart b/pkg/compiler/lib/src/js_backend/js_backend.dart
index aa31961..ab26bfb 100644
--- a/pkg/compiler/lib/src/js_backend/js_backend.dart
+++ b/pkg/compiler/lib/src/js_backend/js_backend.dart
@@ -11,4 +11,3 @@
 export 'custom_elements_analysis.dart';
 export 'namer.dart';
 export 'no_such_method_registry.dart';
-export 'type_variable_handler.dart';
diff --git a/pkg/compiler/lib/src/js_backend/js_interop_analysis.dart b/pkg/compiler/lib/src/js_backend/js_interop_analysis.dart
index 6fdc0ba..1869f4d 100644
--- a/pkg/compiler/lib/src/js_backend/js_interop_analysis.dart
+++ b/pkg/compiler/lib/src/js_backend/js_interop_analysis.dart
@@ -5,8 +5,7 @@
 /// Analysis to determine how to generate code for typed JavaScript interop.
 library compiler.src.js_backend.js_interop_analysis;
 
-import '../elements/resolution_types.dart'
-    show ResolutionDartType, ResolutionDynamicType, ResolutionFunctionType;
+import '../elements/types.dart';
 import '../js/js.dart' as jsAst;
 import '../js/js.dart' show js;
 import '../universe/selector.dart' show Selector;
@@ -44,13 +43,17 @@
     return new jsAst.Block(statements);
   }
 
-  ResolutionFunctionType buildJsFunctionType() {
+  FunctionType buildJsFunctionType() {
     // TODO(jacobr): consider using codegenWorldBuilder.isChecks to determine the
     // range of positional arguments that need to be supported by JavaScript
     // function types.
-    return new ResolutionFunctionType.synthesized(
-        const ResolutionDynamicType(),
-        [],
-        new List<ResolutionDartType>.filled(16, const ResolutionDynamicType()));
+    return new FunctionType(
+        const DynamicType(),
+        const <DartType>[],
+        new List<DartType>.filled(16, const DynamicType()),
+        const <String>[],
+        const <DartType>[],
+        const <FunctionTypeVariable>[],
+        null);
   }
 }
diff --git a/pkg/compiler/lib/src/js_backend/mirrors_analysis.dart b/pkg/compiler/lib/src/js_backend/mirrors_analysis.dart
deleted file mode 100644
index 8682242..0000000
--- a/pkg/compiler/lib/src/js_backend/mirrors_analysis.dart
+++ /dev/null
@@ -1,508 +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 dart2js.mirrors_handler;
-
-import '../common.dart';
-import '../common/resolution.dart';
-import '../compiler.dart';
-import '../constants/values.dart';
-import '../diagnostics/diagnostic_listener.dart';
-import '../elements/elements.dart';
-import '../elements/entities.dart';
-import '../enqueue.dart';
-import '../universe/selector.dart';
-import '../universe/use.dart';
-import '../universe/world_impact.dart';
-import 'backend.dart';
-import 'constant_handler_javascript.dart';
-import 'mirrors_data.dart';
-
-abstract class MirrorsResolutionAnalysis {
-  void onQueueEmpty(Enqueuer enqueuer, Iterable<ClassEntity> recentClasses);
-
-  void onResolutionComplete();
-
-  /// Close this analysis and create the [MirrorsCodegenAnalysis] for the
-  /// collected data.
-  MirrorsCodegenAnalysis close();
-}
-
-abstract class MirrorsCodegenAnalysis {
-  void onQueueEmpty(Enqueuer enqueuer, Iterable<ClassEntity> recentClasses);
-
-  /// Number of methods compiled before considering reflection.
-  int get preMirrorsMethodCount;
-}
-
-class MirrorsResolutionAnalysisImpl implements MirrorsResolutionAnalysis {
-  final JavaScriptBackend _backend;
-  final MirrorsHandler handler;
-
-  /// Set of elements for which metadata has been registered as dependencies.
-  final Set<Element> _registeredMetadata = new Set<Element>();
-
-  /// List of constants from metadata.  If metadata must be preserved,
-  /// these constants must be registered.
-  final List<Dependency> _metadataConstants = <Dependency>[];
-
-  StagedWorldImpactBuilder _impactBuilder = new StagedWorldImpactBuilder();
-
-  MirrorsResolutionAnalysisImpl(this._backend, Resolution resolution)
-      : handler = new MirrorsHandler(_backend, resolution);
-
-  DiagnosticReporter get _reporter => _backend.reporter;
-  Compiler get _compiler => _backend.compiler;
-  JavaScriptConstantCompiler get _constants => _backend.constants;
-  MirrorsData get _mirrorsData => _backend.mirrorsData;
-
-  /// Returns all static fields that are referenced through
-  /// `mirrorsData.targetsUsed`. If the target is a library or class all nested
-  /// static fields are included too.
-  Iterable<Element> _findStaticFieldTargets() {
-    List<Element> staticFields = <Element>[];
-
-    void addFieldsInContainer(ScopeContainerElement container) {
-      container.forEachLocalMember((Element member) {
-        if (!member.isInstanceMember && member.isField) {
-          staticFields.add(member);
-        } else if (member.isClass) {
-          addFieldsInContainer(member);
-        }
-      });
-    }
-
-    for (MemberElement target in _mirrorsData.membersInMirrorsUsedTargets) {
-      if (target.isField) {
-        staticFields.add(target);
-      }
-    }
-    for (ClassElement target in _mirrorsData.classesInMirrorsUsedTargets) {
-      addFieldsInContainer(target);
-    }
-    for (LibraryElement target in _mirrorsData.librariesInMirrorsUsedTargets) {
-      addFieldsInContainer(target);
-    }
-    return staticFields;
-  }
-
-  /// Compute the impact for elements that are matched by the mirrors used
-  /// annotation or, in lack thereof, all elements.
-  WorldImpact _computeImpactForReflectiveElements(
-      Iterable<ClassEntity> recents,
-      Iterable<ClassEntity> processedClasses,
-      Iterable<LibraryElement> loadedLibraries) {
-    handler.enqueueReflectiveElements(
-        recents, processedClasses, loadedLibraries);
-    return handler.flush();
-  }
-
-  /// Compute the impact for the static fields that have been marked as used by
-  /// reflective usage through `MirrorsUsed`.
-  WorldImpact _computeImpactForReflectiveStaticFields(
-      Iterable<Element> elements) {
-    handler.enqueueReflectiveStaticFields(elements);
-    return handler.flush();
-  }
-
-  void onQueueEmpty(Enqueuer enqueuer, Iterable<ClassEntity> recentClasses) {
-    if (_mirrorsData.isTreeShakingDisabled) {
-      enqueuer.applyImpact(_computeImpactForReflectiveElements(recentClasses,
-          enqueuer.processedClasses, _compiler.libraryLoader.libraries));
-    } else if (_mirrorsData.membersInMirrorsUsedTargets.isNotEmpty ||
-        _mirrorsData.classesInMirrorsUsedTargets.isNotEmpty ||
-        _mirrorsData.librariesInMirrorsUsedTargets.isNotEmpty) {
-      // Add all static elements (not classes) that have been requested for
-      // reflection. If there is no mirror-usage these are probably not
-      // necessary, but the backend relies on them being resolved.
-      enqueuer.applyImpact(
-          _computeImpactForReflectiveStaticFields(_findStaticFieldTargets()));
-    }
-
-    if (_mirrorsData.mustPreserveNames) _reporter.log('Preserving names.');
-
-    if (_mirrorsData.mustRetainMetadata) {
-      _reporter.log('Retaining metadata.');
-
-      for (LibraryEntity library in _compiler.libraryLoader.libraries) {
-        _mirrorsData.retainMetadataOfLibrary(library,
-            addForEmission: !enqueuer.isResolutionQueue);
-      }
-
-      if (!enqueuer.queueIsClosed) {
-        /// Register the constant value of [metadata] as live in resolution.
-        void registerMetadataConstant(MetadataAnnotation metadata) {
-          ConstantValue constant =
-              _constants.getConstantValueForMetadata(metadata);
-          Dependency dependency =
-              new Dependency(constant, metadata.annotatedElement);
-          _metadataConstants.add(dependency);
-          _impactBuilder.registerConstantUse(new ConstantUse.mirrors(constant));
-        }
-
-        // TODO(johnniwinther): We should have access to all recently processed
-        // elements and process these instead.
-        processMetadata(enqueuer.processedEntities, registerMetadataConstant);
-      } else {
-        for (Dependency dependency in _metadataConstants) {
-          _impactBuilder.registerConstantUse(
-              new ConstantUse.mirrors(dependency.constant));
-        }
-        _metadataConstants.clear();
-      }
-      enqueuer.applyImpact(_impactBuilder.flush());
-    }
-  }
-
-  /// Call [registerMetadataConstant] on all metadata from [entities].
-  void processMetadata(
-      Iterable<Entity> entities, void onMetadata(MetadataAnnotation metadata)) {
-    void processLibraryMetadata(LibraryElement library) {
-      if (_registeredMetadata.add(library)) {
-        library.metadata.forEach(onMetadata);
-        library.entryCompilationUnit.metadata.forEach(onMetadata);
-        for (ImportElement import in library.imports) {
-          import.metadata.forEach(onMetadata);
-        }
-      }
-    }
-
-    void processElementMetadata(Element element) {
-      if (_registeredMetadata.add(element)) {
-        element.metadata.forEach(onMetadata);
-        if (element.isFunction) {
-          FunctionElement function = element;
-          for (ParameterElement parameter in function.parameters) {
-            parameter.metadata.forEach(onMetadata);
-          }
-        }
-        if (element.enclosingClass != null) {
-          // Only process library of top level fields/methods
-          // (and not for classes).
-          // TODO(johnniwinther): Fix this: We are missing some metadata on
-          // libraries (example: in co19/Language/Metadata/before_export_t01).
-          if (element.enclosingElement is ClassElement) {
-            // Use [enclosingElement] instead of [enclosingClass] to ensure that
-            // we process patch class metadata for patch and injected members.
-            processElementMetadata(element.enclosingElement);
-          }
-        } else {
-          processLibraryMetadata(element.library);
-        }
-      }
-    }
-
-    entities.forEach((member) => processElementMetadata(member));
-  }
-
-  void onResolutionComplete() {
-    _registeredMetadata.clear();
-  }
-
-  MirrorsCodegenAnalysis close() => new MirrorsCodegenAnalysisImpl(
-      _backend, handler._resolution, _metadataConstants);
-}
-
-class MirrorsCodegenAnalysisImpl implements MirrorsCodegenAnalysis {
-  final JavaScriptBackend _backend;
-  final MirrorsHandler handler;
-
-  StagedWorldImpactBuilder _impactBuilder = new StagedWorldImpactBuilder();
-
-  /// List of constants from metadata.  If metadata must be preserved,
-  /// these constants must be registered.
-  final List<Dependency> _metadataConstants;
-
-  /// Number of methods compiled before considering reflection.
-  int preMirrorsMethodCount = 0;
-
-  MirrorsCodegenAnalysisImpl(
-      this._backend, Resolution resolution, this._metadataConstants)
-      : handler = new MirrorsHandler(_backend, resolution);
-
-  DiagnosticReporter get _reporter => _backend.reporter;
-  Compiler get _compiler => _backend.compiler;
-  JavaScriptConstantCompiler get _constants => _backend.constants;
-  MirrorsData get _mirrorsData => _backend.mirrorsData;
-
-  /// Compute the impact for elements that are matched by the mirrors used
-  /// annotation or, in lack thereof, all elements.
-  WorldImpact _computeImpactForReflectiveElements(
-      Iterable<ClassEntity> recents,
-      Iterable<ClassEntity> processedClasses,
-      Iterable<LibraryElement> loadedLibraries) {
-    handler.enqueueReflectiveElements(
-        recents, processedClasses, loadedLibraries);
-    return handler.flush();
-  }
-
-  void onQueueEmpty(Enqueuer enqueuer, Iterable<ClassEntity> recentClasses) {
-    if (preMirrorsMethodCount == 0) {
-      preMirrorsMethodCount = _backend.generatedCode.length;
-    }
-    if (_mirrorsData.isTreeShakingDisabled) {
-      enqueuer.applyImpact(_computeImpactForReflectiveElements(recentClasses,
-          enqueuer.processedClasses, _compiler.libraryLoader.libraries));
-    }
-
-    if (_mirrorsData.mustPreserveNames) _reporter.log('Preserving names.');
-
-    if (_mirrorsData.mustRetainMetadata) {
-      _reporter.log('Retaining metadata.');
-
-      (_compiler.libraryLoader.libraries as Iterable<LibraryElement>)
-          .forEach(_mirrorsData.retainMetadataOfLibrary);
-
-      for (Dependency dependency in _metadataConstants) {
-        _impactBuilder
-            .registerConstantUse(new ConstantUse.mirrors(dependency.constant));
-      }
-      _metadataConstants.clear();
-      enqueuer.applyImpact(_impactBuilder.flush());
-    }
-  }
-}
-
-class MirrorsHandler {
-  static final TRACE_MIRROR_ENQUEUING =
-      const bool.fromEnvironment("TRACE_MIRROR_ENQUEUING");
-
-  final JavaScriptBackend _backend;
-  final Resolution _resolution;
-
-  bool hasEnqueuedReflectiveElements = false;
-  bool hasEnqueuedReflectiveStaticFields = false;
-
-  StagedWorldImpactBuilder impactBuilder = new StagedWorldImpactBuilder();
-
-  MirrorsHandler(this._backend, this._resolution);
-
-  DiagnosticReporter get _reporter => _resolution.reporter;
-
-  WorldImpact flush() => impactBuilder.flush();
-
-  void _logEnqueueReflectiveAction(action, [msg = ""]) {
-    if (TRACE_MIRROR_ENQUEUING) {
-      print("MIRROR_ENQUEUE (R): $action $msg");
-    }
-  }
-
-  /**
-   * Decides whether an element should be included to satisfy requirements
-   * of the mirror system.
-   *
-   * During resolution, we have to resort to matching elements against the
-   * [MirrorsUsed] pattern, as we do not have a complete picture of the world,
-   * yet.
-   */
-  bool _shouldIncludeLibraryDueToMirrors(LibraryElement element,
-      {bool includedEnclosing}) {
-    return includedEnclosing ||
-        _backend.mirrorsData.isLibraryRequiredByMirrorSystem(element);
-  }
-
-  bool _shouldIncludeClassDueToMirrors(ClassElement element,
-      {bool includedEnclosing}) {
-    return includedEnclosing ||
-        _backend.mirrorsData.isClassRequiredByMirrorSystem(element);
-  }
-
-  bool _shouldIncludeMemberDueToMirrors(MemberElement element,
-      {bool includedEnclosing}) {
-    return includedEnclosing ||
-        _backend.mirrorsData.isMemberRequiredByMirrorSystem(element);
-  }
-
-  /// Enqueue the constructor [ctor] if it is required for reflection.
-  ///
-  /// [enclosingWasIncluded] provides a hint whether the enclosing element was
-  /// needed for reflection.
-  void _enqueueReflectiveConstructor(ConstructorElement constructor,
-      {bool enclosingWasIncluded}) {
-    assert(constructor.isDeclaration);
-    if (_shouldIncludeMemberDueToMirrors(constructor,
-        includedEnclosing: enclosingWasIncluded)) {
-      if (constructor.isFromEnvironmentConstructor) return;
-      _logEnqueueReflectiveAction(constructor);
-      ClassElement cls = constructor.enclosingClass;
-      impactBuilder
-          .registerTypeUse(new TypeUse.mirrorInstantiation(cls.rawType));
-      impactBuilder.registerStaticUse(new StaticUse.mirrorUse(constructor));
-    }
-  }
-
-  /// Enqueue the member [element] if it is required for reflection.
-  ///
-  /// [enclosingWasIncluded] provides a hint whether the enclosing element was
-  /// needed for reflection.
-  void _enqueueReflectiveMember(
-      MemberElement element, bool enclosingWasIncluded) {
-    assert(element.isDeclaration);
-    if (_shouldIncludeMemberDueToMirrors(element,
-        includedEnclosing: enclosingWasIncluded)) {
-      _logEnqueueReflectiveAction(element);
-      if (Elements.isStaticOrTopLevel(element)) {
-        impactBuilder.registerStaticUse(new StaticUse.mirrorUse(element));
-      } else if (element.isInstanceMember) {
-        // We need to enqueue all members matching this one in subclasses, as
-        // well.
-        // TODO(herhut): Use TypedSelector.subtype for enqueueing
-        DynamicUse dynamicUse =
-            new DynamicUse(new Selector.fromElement(element));
-        impactBuilder.registerDynamicUse(dynamicUse);
-        if (element.isField) {
-          DynamicUse dynamicUse =
-              new DynamicUse(new Selector.setter(element.memberName.setter));
-          impactBuilder.registerDynamicUse(dynamicUse);
-        }
-      }
-    }
-  }
-
-  /// Enqueue the member [element] if it is required for reflection.
-  ///
-  /// [enclosingWasIncluded] provides a hint whether the enclosing element was
-  /// needed for reflection.
-  void _enqueueReflectiveElementsInClass(
-      ClassElement cls, Iterable<ClassEntity> recents,
-      {bool enclosingWasIncluded}) {
-    assert(cls.isDeclaration);
-    if (cls.library.isInternalLibrary || cls.isInjected) return;
-    bool includeClass = _shouldIncludeClassDueToMirrors(cls,
-        includedEnclosing: enclosingWasIncluded);
-    if (includeClass) {
-      _logEnqueueReflectiveAction(cls, "register");
-      ClassElement declaration = cls.declaration;
-      declaration.ensureResolved(_resolution);
-      impactBuilder.registerTypeUse(
-          new TypeUse.mirrorInstantiation(declaration.rawType));
-    }
-    // If the class is never instantiated, we know nothing of it can possibly
-    // be reflected upon.
-    // TODO(herhut): Add a warning if a mirrors annotation cannot hit.
-    if (recents.contains(cls.declaration)) {
-      _logEnqueueReflectiveAction(cls, "members");
-      cls.constructors.forEach((Element element) {
-        _enqueueReflectiveConstructor(element.declaration,
-            enclosingWasIncluded: includeClass);
-      });
-      cls.forEachClassMember((Member member) {
-        _enqueueReflectiveMember(member.element, includeClass);
-      });
-    }
-  }
-
-  /// Set of classes that need to be considered for reflection although not
-  /// otherwise visible during resolution.
-  Iterable<ClassEntity> get _classesRequiredForReflection {
-    // TODO(herhut): Clean this up when classes needed for rti are tracked.
-    return [
-      _resolution.commonElements.closureClass,
-      _resolution.commonElements.jsIndexableClass
-    ];
-  }
-
-  /// Enqueue special classes that might not be visible by normal means or that
-  /// would not normally be enqueued:
-  ///
-  /// [Closure] is treated specially as it is the superclass of all closures.
-  /// Although it is in an internal library, we mark it as reflectable. Note
-  /// that none of its methods are reflectable, unless reflectable by
-  /// inheritance.
-  void _enqueueReflectiveSpecialClasses() {
-    Iterable<ClassElement> classes = _classesRequiredForReflection;
-    for (ClassElement cls in classes) {
-      if (_backend.mirrorsData.isClassReferencedFromMirrorSystem(cls)) {
-        _logEnqueueReflectiveAction(cls);
-        cls.ensureResolved(_resolution);
-        impactBuilder
-            .registerTypeUse(new TypeUse.mirrorInstantiation(cls.rawType));
-      }
-    }
-  }
-
-  /// Enqueue all local members of the library [lib] if they are required for
-  /// reflection.
-  void _enqueueReflectiveElementsInLibrary(
-      LibraryElement lib, Iterable<ClassEntity> recents) {
-    assert(lib.isDeclaration);
-    bool includeLibrary =
-        _shouldIncludeLibraryDueToMirrors(lib, includedEnclosing: false);
-    lib.forEachLocalMember((Element member) {
-      if (member.isInjected) return;
-      if (member.isClass) {
-        ClassElement cls = member;
-        cls.ensureResolved(_resolution);
-        do {
-          _enqueueReflectiveElementsInClass(cls, recents,
-              enclosingWasIncluded: includeLibrary);
-          cls = cls.superclass;
-        } while (cls != null && cls.isUnnamedMixinApplication);
-      } else if (member.isTypedef) {
-        TypedefElement typedef = member;
-        typedef.ensureResolved(_resolution);
-      } else {
-        _enqueueReflectiveMember(member, includeLibrary);
-      }
-    });
-  }
-
-  /// Enqueue all elements that are matched by the mirrors used
-  /// annotation or, in lack thereof, all elements.
-  // TODO(johnniwinther): Compute [WorldImpact] instead of enqueuing directly.
-  void enqueueReflectiveElements(
-      Iterable<ClassEntity> recents,
-      Iterable<ClassEntity> processedClasses,
-      Iterable<LibraryElement> loadedLibraries) {
-    if (!hasEnqueuedReflectiveElements) {
-      _logEnqueueReflectiveAction("!START enqueueAll");
-      // First round of enqueuing, visit everything that is visible to
-      // also pick up static top levels, etc.
-      // Also, during the first round, consider all classes that have been seen
-      // as recently seen, as we do not know how many rounds of resolution might
-      // have run before tree shaking is disabled and thus everything is
-      // enqueued.
-      recents = processedClasses.toSet();
-      _reporter.log('Enqueuing everything');
-      for (LibraryElement lib in loadedLibraries) {
-        _enqueueReflectiveElementsInLibrary(lib, recents);
-      }
-      _enqueueReflectiveSpecialClasses();
-      hasEnqueuedReflectiveElements = true;
-      hasEnqueuedReflectiveStaticFields = true;
-      _logEnqueueReflectiveAction("!DONE enqueueAll");
-    } else if (recents.isNotEmpty) {
-      // Keep looking at new classes until fixpoint is reached.
-      _logEnqueueReflectiveAction("!START enqueueRecents");
-      recents.forEach((ClassEntity _cls) {
-        ClassElement cls = _cls;
-        _enqueueReflectiveElementsInClass(cls, recents,
-            enclosingWasIncluded: _shouldIncludeLibraryDueToMirrors(cls.library,
-                includedEnclosing: false));
-      });
-      _logEnqueueReflectiveAction("!DONE enqueueRecents");
-    }
-  }
-
-  /// Enqueue the static fields that have been marked as used by reflective
-  /// usage through `MirrorsUsed`.
-  // TODO(johnniwinther): Compute [WorldImpact] instead of enqueuing directly.
-  void enqueueReflectiveStaticFields(Iterable<Element> elements) {
-    if (hasEnqueuedReflectiveStaticFields) return;
-    hasEnqueuedReflectiveStaticFields = true;
-    for (Element element in elements) {
-      _enqueueReflectiveMember(element, true);
-    }
-  }
-}
-
-/// Records that [constant] is used by the element behind [registry].
-class Dependency {
-  final ConstantValue constant;
-  final Element annotatedElement;
-
-  const Dependency(this.constant, this.annotatedElement);
-
-  String toString() => '$annotatedElement:${constant.toStructuredText()}';
-}
diff --git a/pkg/compiler/lib/src/js_backend/mirrors_data.dart b/pkg/compiler/lib/src/js_backend/mirrors_data.dart
deleted file mode 100644
index fe94bca..0000000
--- a/pkg/compiler/lib/src/js_backend/mirrors_data.dart
+++ /dev/null
@@ -1,708 +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 '../common.dart';
-import '../common_elements.dart';
-import '../compiler.dart';
-import '../constants/values.dart';
-import '../elements/elements.dart' show AbstractFieldElement, Element;
-import '../elements/entities.dart';
-import '../elements/names.dart';
-import '../elements/types.dart';
-import '../world.dart';
-import '../universe/world_builder.dart';
-import '../util/emptyset.dart';
-
-abstract class MirrorsData {
-  /// True if a call to preserveMetadataMarker has been seen.  This means that
-  /// metadata must be retained for dart:mirrors to work correctly.
-  // resolution-empty-queue
-  bool get mustRetainMetadata;
-
-  /// True if any metadata has been retained.  This is slightly different from
-  /// [mustRetainMetadata] and tells us if any metadata was retained.  For
-  /// example, if [mustRetainMetadata] is true but there is no metadata in the
-  /// program, this variable will stil be false.
-  // emitter
-  bool get hasRetainedMetadata;
-
-  /// True if a call to preserveLibraryNames has been seen.
-  // emitter
-  bool get mustRetainLibraryNames;
-
-  /// True if a call to preserveNames has been seen.
-  // resolution-empty-queue
-  bool get mustPreserveNames;
-
-  /// True if a call to disableTreeShaking has been seen.
-  bool get isTreeShakingDisabled;
-
-  /// Set of symbols that the user has requested for reflection.
-  Iterable<String> get symbolsUsed;
-
-  /// The members that the user has requested for reflection through the
-  /// 'targets' property of a `MirrorsUsed` annotation.
-  Iterable<MemberEntity> get membersInMirrorsUsedTargets;
-
-  /// The classes that the user has requested for reflection through the
-  /// 'targets' property of a `MirrorsUsed` annotation.
-  Iterable<ClassEntity> get classesInMirrorsUsedTargets;
-
-  /// The libraries that the user has requested for reflection through the
-  /// 'targets' property of a `MirrorsUsed` annotation.
-  Iterable<LibraryEntity> get librariesInMirrorsUsedTargets;
-
-  /// Should the getter for [element] that would normally not be generated due
-  /// to tree-shaking be retained for reflection?
-  bool shouldRetainGetter(FieldEntity element);
-
-  /// Should the setter for [element] that would normally not be generated due
-  /// to tree-shaking be retained for reflection?
-  bool shouldRetainSetter(FieldEntity element);
-
-  /// Should [name] be retained for reflection?
-  bool shouldRetainName(String name);
-
-  /// Returns `true` if the class [element] is covered by a `MirrorsUsed`
-  /// annotation.
-  ///
-  /// Note that it might still be ok to tree shake the element away if no
-  /// reflection is used in the program (and thus [isTreeShakingDisabled] is
-  /// still false). Therefore _do not_ use this predicate to decide inclusion
-  /// in the tree, use [requiredByMirrorSystem] instead.
-  bool isClassReferencedFromMirrorSystem(ClassEntity element);
-
-  /// Returns `true` if the member [element] is covered by a `MirrorsUsed`
-  /// annotation.
-  ///
-  /// Note that it might still be ok to tree shake the element away if no
-  /// reflection is used in the program (and thus [isTreeShakingDisabled] is
-  /// still false). Therefore _do not_ use this predicate to decide inclusion
-  /// in the tree, use [requiredByMirrorSystem] instead.
-  bool isMemberReferencedFromMirrorSystem(MemberEntity element);
-
-  /// Returns `true` if the library [element] is covered by a `MirrorsUsed`
-  /// annotation.
-  bool isLibraryReferencedFromMirrorSystem(LibraryEntity element);
-
-  /// Returns `true` if the typedef [element] needs reflection information at
-  /// runtime.
-  ///
-  /// This property is used to tag emitted elements with a marker which is
-  /// checked by the runtime system to throw an exception if an element is
-  /// accessed (invoked, get, set) that is not accessible for the reflective
-  /// system.
-  bool isTypedefAccessibleByReflection(TypedefEntity element);
-
-  /// Returns `true` if the class [element] needs reflection information at
-  /// runtime.
-  ///
-  /// This property is used to tag emitted elements with a marker which is
-  /// checked by the runtime system to throw an exception if an element is
-  /// accessed (invoked, get, set) that is not accessible for the reflective
-  /// system.
-  bool isClassAccessibleByReflection(ClassEntity element);
-
-  /// Returns `true` if the member [element] needs reflection information at
-  /// runtime.
-  ///
-  /// This property is used to tag emitted elements with a marker which is
-  /// checked by the runtime system to throw an exception if an element is
-  /// accessed (invoked, get, set) that is not accessible for the reflective
-  /// system.
-  bool isMemberAccessibleByReflection(MemberEntity element);
-
-  bool retainMetadataOfLibrary(LibraryEntity element,
-      {bool addForEmission: true});
-  bool retainMetadataOfTypedef(TypedefEntity element);
-  bool retainMetadataOfClass(ClassEntity element);
-  bool retainMetadataOfMember(MemberEntity element);
-
-  /// Returns true if this element has to be enqueued due to
-  /// mirror usage. Might be a subset of [referencedFromMirrorSystem] if
-  /// normal tree shaking is still active ([isTreeShakingDisabled] is false).
-  bool isLibraryRequiredByMirrorSystem(LibraryEntity element);
-  bool isClassRequiredByMirrorSystem(ClassEntity element);
-  bool isMemberRequiredByMirrorSystem(MemberEntity element);
-  bool isClassResolved(ClassEntity element);
-}
-
-abstract class MirrorsDataBuilder {
-  void registerUsedMember(MemberEntity member);
-
-  /// Called by [MirrorUsageAnalyzerTask] after it has merged all @MirrorsUsed
-  /// annotations. The arguments corresponds to the unions of the corresponding
-  /// fields of the annotations.
-  void registerMirrorUsage(
-      Set<String> symbols, Set<Element> targets, Set<Element> metaTargets);
-
-  /// Called when `const Symbol(name)` is seen.
-  void registerConstSymbol(String name);
-
-  void maybeMarkClosureAsNeededForReflection(
-      ClassEntity closureClass, FunctionEntity callMethod, Local localFunction);
-
-  void computeMembersNeededForReflection(
-      ResolutionWorldBuilder worldBuilder, ClosedWorld closedWorld);
-}
-
-abstract class MirrorsDataImpl implements MirrorsData, MirrorsDataBuilder {
-  /// True if a call to preserveMetadataMarker has been seen.  This means that
-  /// metadata must be retained for dart:mirrors to work correctly.
-  bool mustRetainMetadata = false;
-
-  /// True if any metadata has been retained.  This is slightly different from
-  /// [mustRetainMetadata] and tells us if any metadata was retained.  For
-  /// example, if [mustRetainMetadata] is true but there is no metadata in the
-  /// program, this variable will stil be false.
-  bool hasRetainedMetadata = false;
-
-  /// True if a call to preserveLibraryNames has been seen.
-  bool mustRetainLibraryNames = false;
-
-  /// True if a call to preserveNames has been seen.
-  bool mustPreserveNames = false;
-
-  /// True if a call to disableTreeShaking has been seen.
-  bool isTreeShakingDisabled = false;
-
-  /// True if there isn't sufficient @MirrorsUsed data.
-  bool hasInsufficientMirrorsUsed = false;
-
-  /// Set of symbols that the user has requested for reflection.
-  final Set<String> symbolsUsed = new Set<String>();
-
-  /// Set of elements that the user has requested for reflection.
-  final Set<MemberEntity> membersInMirrorsUsedTargets = new Set<MemberEntity>();
-  final Set<ClassEntity> classesInMirrorsUsedTargets = new Set<ClassEntity>();
-  final Set<LibraryEntity> librariesInMirrorsUsedTargets =
-      new Set<LibraryEntity>();
-  final Set<TypedefEntity> _typedefsInMirrorsUsedTargets =
-      new Set<TypedefEntity>();
-
-  /// List of annotations provided by user that indicate that the annotated
-  /// element must be retained.
-  final Set<ClassEntity> metaTargetsUsed = new Set<ClassEntity>();
-
-  // TODO(johnniwinther): Avoid the need for this.
-  final Compiler _compiler;
-
-  final ElementEnvironment _elementEnvironment;
-  final CommonElements _commonElements;
-
-  MirrorsDataImpl(
-      this._compiler, this._elementEnvironment, this._commonElements);
-
-  void registerUsedMember(MemberEntity member) {
-    if (member == _commonElements.disableTreeShakingMarker) {
-      isTreeShakingDisabled = true;
-    } else if (member == _commonElements.preserveNamesMarker) {
-      mustPreserveNames = true;
-    } else if (member == _commonElements.preserveMetadataMarker) {
-      mustRetainMetadata = true;
-    } else if (member == _commonElements.preserveLibraryNamesMarker) {
-      mustRetainLibraryNames = true;
-    }
-  }
-
-  bool shouldRetainGetter(FieldEntity element) {
-    return isTreeShakingDisabled && isMemberAccessibleByReflection(element);
-  }
-
-  bool shouldRetainSetter(FieldEntity element) {
-    return isTreeShakingDisabled && isMemberAccessibleByReflection(element);
-  }
-
-  /// Should [name] be retained for reflection?
-  bool shouldRetainName(String name) {
-    if (hasInsufficientMirrorsUsed) return mustPreserveNames;
-    if (name == '') return false;
-    return symbolsUsed.contains(name);
-  }
-
-  @override
-  bool retainMetadataOfMember(MemberEntity element) {
-    if (mustRetainMetadata) {
-      hasRetainedMetadata = true;
-      if (isMemberReferencedFromMirrorSystem(element)) {
-        _addConstantsForEmission(
-            getMemberMetadata(element, includeParameterMetadata: true));
-        return true;
-      }
-    }
-    return false;
-  }
-
-  @override
-  bool retainMetadataOfClass(ClassEntity element) {
-    if (mustRetainMetadata) {
-      hasRetainedMetadata = true;
-      if (isClassReferencedFromMirrorSystem(element)) {
-        _addConstantsForEmission(getClassMetadata(element));
-        return true;
-      }
-    }
-    return false;
-  }
-
-  @override
-  bool retainMetadataOfTypedef(TypedefEntity element) {
-    if (mustRetainMetadata) {
-      hasRetainedMetadata = true;
-      if (_isTypedefReferencedFromMirrorSystem(element)) {
-        _addConstantsForEmission(getTypedefMetadata(element));
-        return true;
-      }
-    }
-    return false;
-  }
-
-  @override
-  bool retainMetadataOfLibrary(LibraryEntity element,
-      {bool addForEmission: true}) {
-    if (mustRetainMetadata) {
-      hasRetainedMetadata = true;
-      if (isLibraryReferencedFromMirrorSystem(element)) {
-        Iterable<ConstantValue> constants = getLibraryMetadata(element);
-        if (addForEmission) {
-          _addConstantsForEmission(constants);
-        }
-        return true;
-      }
-    }
-    return false;
-  }
-
-  Iterable<ConstantValue> getLibraryMetadata(LibraryEntity element) {
-    return _elementEnvironment.getLibraryMetadata(element);
-  }
-
-  Iterable<ConstantValue> getClassMetadata(ClassEntity element) {
-    return _elementEnvironment.getClassMetadata(element);
-  }
-
-  Iterable<ConstantValue> getMemberMetadata(MemberEntity element,
-      {bool includeParameterMetadata}) {
-    return _elementEnvironment.getMemberMetadata(element,
-        includeParameterMetadata: includeParameterMetadata);
-  }
-
-  Iterable<ConstantValue> getTypedefMetadata(TypedefEntity element) {
-    return _elementEnvironment.getTypedefMetadata(element);
-  }
-
-  void _addConstantsForEmission(Iterable<ConstantValue> constants) {
-    for (ConstantValue constant in constants) {
-      CodegenWorldBuilder worldBuilder = _compiler.codegenWorldBuilder;
-      worldBuilder.addCompileTimeConstantForEmission(constant);
-    }
-  }
-
-  /// Sets of elements that are needed by reflection. Computed using
-  /// [computeMembersNeededForReflection] on first use.
-  Set<ClassEntity> _classesNeededForReflection;
-  Set<TypedefEntity> _typedefsNeededForReflection;
-  Set<MemberEntity> _membersNeededForReflection;
-  Set<Local> _closuresNeededForReflection;
-
-  /// Called by [MirrorUsageAnalyzerTask] after it has merged all @MirrorsUsed
-  /// annotations. The arguments corresponds to the unions of the corresponding
-  /// fields of the annotations.
-  // TODO(redemption): Change type of [metaTargets] to `Set<ClassEntity>`.
-  void registerMirrorUsage(
-      Set<String> symbols, Set<Element> targets, Set<Element> metaTargets) {
-    if (symbols == null && targets == null && metaTargets == null) {
-      // The user didn't specify anything, or there are imports of
-      // 'dart:mirrors' without @MirrorsUsed.
-      hasInsufficientMirrorsUsed = true;
-      return;
-    }
-    if (symbols != null) symbolsUsed.addAll(symbols);
-    if (targets != null) {
-      for (Element target in targets) {
-        if (target.isAbstractField) {
-          AbstractFieldElement field = target;
-          if (field.getter != null) {
-            membersInMirrorsUsedTargets.add(field.getter);
-          }
-          if (field.setter != null) {
-            membersInMirrorsUsedTargets.add(field.setter);
-          }
-        } else if (target.isClass) {
-          classesInMirrorsUsedTargets.add(target as ClassEntity);
-        } else if (target.isTypedef) {
-          _typedefsInMirrorsUsedTargets.add(target as TypedefEntity);
-        } else if (target.isLibrary) {
-          librariesInMirrorsUsedTargets.add(target as LibraryEntity);
-        } else if (target != null) {
-          membersInMirrorsUsedTargets.add(target as MemberEntity);
-        }
-      }
-    }
-    if (metaTargets != null) {
-      for (dynamic element in metaTargets) {
-        if (element is ClassEntity) {
-          metaTargetsUsed.add(element);
-        }
-      }
-    }
-  }
-
-  @override
-  bool isClassAccessibleByReflection(ClassEntity element) {
-    return _classesNeededForReflection.contains(_getDartClass(element));
-  }
-
-  @override
-  bool isTypedefAccessibleByReflection(TypedefEntity element) {
-    return _typedefsNeededForReflection.contains(element);
-  }
-
-  ClassEntity _getDartClass(ClassEntity cls) {
-    if (cls == _commonElements.jsIntClass) {
-      return _commonElements.intClass;
-    } else if (cls == _commonElements.jsBoolClass) {
-      return _commonElements.boolClass;
-    } else if (cls == _commonElements.jsNumberClass) {
-      return _commonElements.numClass;
-    } else if (cls == _commonElements.jsDoubleClass) {
-      return _commonElements.doubleClass;
-    } else if (cls == _commonElements.jsStringClass) {
-      return _commonElements.stringClass;
-    } else if (cls == _commonElements.jsArrayClass) {
-      return _commonElements.listClass;
-    } else if (cls == _commonElements.jsNullClass) {
-      return _commonElements.nullClass;
-    } else {
-      return cls;
-    }
-  }
-
-  bool isMemberAccessibleByReflection(MemberEntity element) {
-    return _membersNeededForReflection.contains(element);
-  }
-
-  /// Returns true if this element has to be enqueued due to
-  /// mirror usage. Might be a subset of [referencedFromMirrorSystem] if
-  /// normal tree shaking is still active ([isTreeShakingDisabled] is false).
-  bool isLibraryRequiredByMirrorSystem(LibraryEntity element) {
-    return hasInsufficientMirrorsUsed && isTreeShakingDisabled ||
-        _libraryMatchesMirrorsMetaTarget(element) ||
-        librariesInMirrorsUsedTargets.contains(element);
-  }
-
-  bool isClassRequiredByMirrorSystem(ClassEntity element) {
-    return hasInsufficientMirrorsUsed && isTreeShakingDisabled ||
-        _classMatchesMirrorsMetaTarget(element) ||
-        classesInMirrorsUsedTargets.contains(element);
-  }
-
-  bool isMemberRequiredByMirrorSystem(MemberEntity element) {
-    return hasInsufficientMirrorsUsed && isTreeShakingDisabled ||
-        _memberMatchesMirrorsMetaTarget(element) ||
-        membersInMirrorsUsedTargets.contains(element);
-  }
-
-  @override
-  bool isLibraryReferencedFromMirrorSystem(LibraryEntity element) {
-    return _libraryReferencedFromMirrorSystem(element);
-  }
-
-  @override
-  bool isMemberReferencedFromMirrorSystem(MemberEntity element) {
-    if (_memberReferencedFromMirrorSystem(element)) return true;
-    if (element.enclosingClass != null) {
-      return isClassReferencedFromMirrorSystem(element.enclosingClass);
-    } else {
-      return isLibraryReferencedFromMirrorSystem(element.library);
-    }
-  }
-
-  @override
-  bool isClassReferencedFromMirrorSystem(ClassEntity element) {
-    return _classReferencedFromMirrorSystem(element) ||
-        isLibraryReferencedFromMirrorSystem(element.library);
-  }
-
-  bool _isTypedefReferencedFromMirrorSystem(TypedefEntity element) {
-    return _typedefReferencedFromMirrorSystem(element) ||
-        isLibraryReferencedFromMirrorSystem(element.library);
-  }
-
-  bool _memberReferencedFromMirrorSystem(MemberEntity element) {
-    return hasInsufficientMirrorsUsed ||
-        _memberMatchesMirrorsMetaTarget(element) ||
-        membersInMirrorsUsedTargets.contains(element);
-  }
-
-  bool _classReferencedFromMirrorSystem(ClassEntity element) {
-    return hasInsufficientMirrorsUsed ||
-        _classMatchesMirrorsMetaTarget(element) ||
-        classesInMirrorsUsedTargets.contains(element);
-  }
-
-  bool _typedefReferencedFromMirrorSystem(TypedefEntity element) {
-    return hasInsufficientMirrorsUsed ||
-        _typedefMatchesMirrorsMetaTarget(element) ||
-        _typedefsInMirrorsUsedTargets.contains(element);
-  }
-
-  bool _libraryReferencedFromMirrorSystem(LibraryEntity element) {
-    return hasInsufficientMirrorsUsed ||
-        _libraryMatchesMirrorsMetaTarget(element) ||
-        librariesInMirrorsUsedTargets.contains(element);
-  }
-
-  bool _libraryMatchesMirrorsMetaTarget(LibraryEntity element) {
-    if (metaTargetsUsed.isEmpty) return false;
-    return _matchesMirrorsMetaTarget(getLibraryMetadata(element));
-  }
-
-  bool _classMatchesMirrorsMetaTarget(ClassEntity element) {
-    if (metaTargetsUsed.isEmpty) return false;
-    return _matchesMirrorsMetaTarget(getClassMetadata(element));
-  }
-
-  bool _memberMatchesMirrorsMetaTarget(MemberEntity element) {
-    if (metaTargetsUsed.isEmpty) return false;
-    return _matchesMirrorsMetaTarget(
-        getMemberMetadata(element, includeParameterMetadata: false));
-  }
-
-  bool _typedefMatchesMirrorsMetaTarget(TypedefEntity element) {
-    if (metaTargetsUsed.isEmpty) return false;
-    return _matchesMirrorsMetaTarget(getTypedefMetadata(element));
-  }
-
-  /**
-   * Returns `true` if the element is needed because it has an annotation
-   * of a type that is used as a meta target for reflection.
-   */
-  bool _matchesMirrorsMetaTarget(Iterable<ConstantValue> constants) {
-    if (metaTargetsUsed.isEmpty) return false;
-    for (ConstantValue constant in constants) {
-      DartType type = constant.getType(_commonElements);
-      if (type is InterfaceType && metaTargetsUsed.contains(type.element))
-        return true;
-    }
-    return false;
-  }
-
-  void createImmutableSets() {
-    _classesNeededForReflection = const ImmutableEmptySet<ClassEntity>();
-    _typedefsNeededForReflection = const ImmutableEmptySet<TypedefEntity>();
-    _membersNeededForReflection = const ImmutableEmptySet<MemberEntity>();
-    _closuresNeededForReflection = const ImmutableEmptySet<Local>();
-  }
-
-  bool isLibraryInternal(LibraryEntity library) {
-    return library.canonicalUri.scheme == 'dart' &&
-        library.canonicalUri.path.startsWith('_');
-  }
-
-  /// Whether [cls] is 'injected'.
-  ///
-  /// An injected class is declared in a patch library with no corresponding
-  /// class in the origin library.
-  // TODO(redemption): Detect injected classes from .dill.
-  bool isClassInjected(ClassEntity cls) => false;
-
-  bool isClassResolved(ClassEntity cls) => true;
-
-  void forEachConstructor(
-      ClassEntity cls, void f(ConstructorEntity constructor)) {
-    _elementEnvironment.forEachConstructor(cls, f);
-  }
-
-  void forEachClassMember(
-      ClassEntity cls, void f(MemberEntity member, Name memberName)) {
-    _elementEnvironment.forEachClassMember(cls,
-        (ClassEntity declarer, MemberEntity member) {
-      if (member.isSetter) {
-        f(member, member.memberName.setter);
-      } else {
-        f(member, member.memberName.getter);
-      }
-    });
-  }
-
-  /**
-   * Visits all classes and computes whether its members are needed for
-   * reflection.
-   *
-   * We have to precompute this set as we cannot easily answer the need for
-   * reflection locally when looking at the member: We lack the information by
-   * which classes a member is inherited. Called after resolution is complete.
-   *
-   * We filter out private libraries here, as their elements should not
-   * be visible by reflection unless some other interfaces makes them
-   * accessible.
-   */
-  void computeMembersNeededForReflection(
-      ResolutionWorldBuilder worldBuilder, ClosedWorld closedWorld) {
-    if (_membersNeededForReflection != null) return;
-    if (!closedWorld.backendUsage.isMirrorsUsed || true) {
-      createImmutableSets();
-      return;
-    }
-    // TODO(johnniwinther): Remove this:
-    _classesNeededForReflection = new Set<ClassEntity>();
-    _typedefsNeededForReflection = new Set<TypedefEntity>();
-    _membersNeededForReflection = new Set<MemberEntity>();
-    _closuresNeededForReflection = new Set<Local>();
-
-    // Compute a mapping from class to the closures it contains, so we
-    // can include the correct ones when including the class.
-    Map<ClassEntity, List<Local>> classToClosuresMap =
-        new Map<ClassEntity, List<Local>>();
-    Map<Local, MemberEntity> closureToMemberMap =
-        new Map<Local, MemberEntity>();
-    worldBuilder.forEachLocalFunction((MemberEntity member, Local closure) {
-      closureToMemberMap[closure] = member;
-      classToClosuresMap
-          .putIfAbsent(member.enclosingClass, () => [])
-          .add(closure);
-    });
-    bool foundClosure = false;
-    for (ClassEntity cls in worldBuilder.directlyInstantiatedClasses) {
-      // Do not process internal classes.
-      if (isLibraryInternal(cls.library) || isClassInjected(cls)) continue;
-      if (isClassReferencedFromMirrorSystem(cls)) {
-        Set<Name> memberNames = new Set<Name>();
-        // 1) the class (should be resolved)
-        assert(isClassResolved(cls), failedAt(cls));
-        _classesNeededForReflection.add(cls);
-        // 2) its constructors (if resolved)
-        forEachConstructor(cls, (ConstructorEntity constructor) {
-          if (worldBuilder.isMemberUsed(constructor)) {
-            _membersNeededForReflection.add(constructor);
-          }
-        });
-        // 3) all members, including fields via getter/setters (if resolved)
-        forEachClassMember(cls, (MemberEntity member, Name memberName) {
-          if (worldBuilder.isMemberUsed(member)) {
-            memberNames.add(memberName);
-            _membersNeededForReflection.add(member);
-          }
-        });
-        // 4) all overriding members of subclasses/subtypes (should be resolved)
-        if (closedWorld.hasAnyStrictSubtype(cls)) {
-          closedWorld.forEachStrictSubtypeOf(cls, (ClassEntity subcls) {
-            forEachClassMember(subcls, (MemberEntity member, Name memberName) {
-              if (memberNames.contains(memberName)) {
-                // TODO(20993): find out why this assertion fails.
-                // assert(worldBuilder.isMemberUsed(member.element),
-                //     failedAt(member.element));
-                if (worldBuilder.isMemberUsed(member)) {
-                  _membersNeededForReflection.add(member);
-                }
-              }
-            });
-          });
-        }
-        // 5) all its closures
-        List<Local> closures = classToClosuresMap[cls];
-        if (closures != null) {
-          _closuresNeededForReflection.addAll(closures);
-          foundClosure = true;
-        }
-      } else {
-        // check members themselves
-        forEachConstructor(cls, (ConstructorEntity element) {
-          if (!worldBuilder.isMemberUsed(element)) return;
-          if (_memberReferencedFromMirrorSystem(element)) {
-            _membersNeededForReflection.add(element);
-          }
-        });
-        forEachClassMember(cls, (MemberEntity member, _) {
-          if (!worldBuilder.isMemberUsed(member)) return;
-          if (_memberReferencedFromMirrorSystem(member)) {
-            _membersNeededForReflection.add(member);
-          }
-        });
-        // Also add in closures. Those might be reflectable is their enclosing
-        // member is.
-        List<Local> closures = classToClosuresMap[cls];
-        if (closures != null) {
-          for (Local closure in closures) {
-            MemberEntity member = closureToMemberMap[closure];
-            if (_memberReferencedFromMirrorSystem(member)) {
-              _closuresNeededForReflection.add(closure);
-              foundClosure = true;
-            }
-          }
-        }
-      }
-    }
-    // We also need top-level non-class elements like static functions and
-    // global fields. We use the resolution queue to decide which elements are
-    // part of the live world.
-    for (LibraryEntity lib in _elementEnvironment.libraries) {
-      if (isLibraryInternal(lib)) continue;
-      _elementEnvironment.forEachLibraryMember(lib, (MemberEntity member) {
-        if (worldBuilder.isMemberUsed(member) &&
-            isMemberReferencedFromMirrorSystem(member)) {
-          _membersNeededForReflection.add(member);
-        }
-      });
-    }
-    // And closures inside top-level elements that do not have a surrounding
-    // class. These will be in the [:null:] bucket of the [classToClosureMap].
-    if (classToClosuresMap.containsKey(null)) {
-      for (Local closure in classToClosuresMap[null]) {
-        if (isMemberReferencedFromMirrorSystem(closureToMemberMap[closure])) {
-          _closuresNeededForReflection.add(closure);
-          foundClosure = true;
-        }
-      }
-    }
-    // As we do not think about closures as classes, yet, we have to make sure
-    // their superclasses are available for reflection manually.
-    if (foundClosure) {
-      ClassEntity cls = _commonElements.closureClass;
-      _classesNeededForReflection.add(cls);
-    }
-    Set<FunctionEntity> closurizedMembers = worldBuilder.closurizedMembers;
-    if (closurizedMembers.any(_membersNeededForReflection.contains)) {
-      ClassEntity cls = _commonElements.boundClosureClass;
-      _classesNeededForReflection.add(cls);
-    }
-    // Add typedefs.
-    for (TypedefEntity element in closedWorld.allTypedefs) {
-      if (_isTypedefReferencedFromMirrorSystem(element)) {
-        _typedefsNeededForReflection.add(element);
-      }
-    }
-    // Register all symbols of reflectable elements
-    for (ClassEntity element in _classesNeededForReflection) {
-      symbolsUsed.add(element.name);
-    }
-    for (TypedefEntity element in _typedefsNeededForReflection) {
-      symbolsUsed.add(element.name);
-    }
-    for (MemberEntity element in _membersNeededForReflection) {
-      symbolsUsed.add(element.name);
-    }
-    for (Local element in _closuresNeededForReflection) {
-      symbolsUsed.add(element.name);
-    }
-  }
-
-  // TODO(20791): compute closure classes after resolution and move this code to
-  // [computeMembersNeededForReflection].
-  void maybeMarkClosureAsNeededForReflection(ClassEntity closureClass,
-      FunctionEntity callMethod, Local localFunction) {
-    if (!_closuresNeededForReflection.contains(localFunction)) return;
-    _membersNeededForReflection.add(callMethod);
-    _classesNeededForReflection.add(closureClass);
-  }
-
-  /// Called when `const Symbol(name)` is seen.
-  void registerConstSymbol(String name) {
-    symbolsUsed.add(name);
-    if (name.endsWith('=')) {
-      symbolsUsed.add(name.substring(0, name.length - 1));
-    }
-  }
-}
diff --git a/pkg/compiler/lib/src/js_backend/namer.dart b/pkg/compiler/lib/src/js_backend/namer.dart
index f671f25..b732c81 100644
--- a/pkg/compiler/lib/src/js_backend/namer.dart
+++ b/pkg/compiler/lib/src/js_backend/namer.dart
@@ -15,12 +15,10 @@
 import '../constants/values.dart';
 import '../common_elements.dart' show CommonElements, ElementEnvironment;
 import '../diagnostics/invariant.dart' show DEBUG_MODE;
-import '../elements/elements.dart' show Element, Elements, MemberElement;
 import '../elements/entities.dart';
 import '../elements/entity_utils.dart' as utils;
 import '../elements/jumps.dart';
 import '../elements/names.dart';
-import '../elements/resolution_types.dart';
 import '../elements/types.dart';
 import '../js/js.dart' as jsAst;
 import '../js_model/closure.dart';
@@ -769,7 +767,7 @@
   }
 
   String _proposeNameForConstructorBody(ConstructorBodyEntity method) {
-    String name = Elements.reconstructConstructorNameSourceString(method);
+    String name = utils.reconstructConstructorNameSourceString(method);
     // We include the method suffix on constructor bodies. It has no purpose,
     // but this way it produces the same names as previous versions of the
     // Namer class did.
@@ -1118,12 +1116,6 @@
       Entity element, String proposeName(Entity element)) {
     // TODO(asgerf): We can reuse more short names if we disambiguate with
     // a separate namespace for each of the global holder objects.
-    if (element is Element) {
-      // Ensures we only work on declarations. Non-[Element] entities do not
-      // have the declaration/implementation separation.
-      Element e = element;
-      element = e.declaration;
-    }
     jsAst.Name newName = userGlobals[element];
     if (newName == null) {
       String proposedName = proposeName(element);
@@ -1562,21 +1554,6 @@
   bool _isPropertyOfStaticStateHolder(MemberEntity element) {
     // TODO(ahe): Make sure this method's documentation is always true and
     // remove the word "intend".
-    if (element is MemberElement) {
-      // TODO(johnniwinther): Clean up this method to have a single semantics on
-      // entities.
-      return
-          // TODO(ahe): Re-write these tests to be positive (so it only returns
-          // true for static/top-level mutable fields). Right now, a number of
-          // other elements, such as bound closures also live in
-          // [staticStateHolder].
-          !element.isAccessor &&
-              !element.isClass &&
-              !element.isTypedef &&
-              !element.isConstructor &&
-              !element.isFunction &&
-              !element.isLibrary;
-    }
     return element.isField;
   }
 
@@ -1669,12 +1646,12 @@
 
   String get futureOrTypeTag => r'type';
 
-  Map<ResolutionFunctionType, jsAst.Name> functionTypeNameMap =
-      new HashMap<ResolutionFunctionType, jsAst.Name>();
+  Map<FunctionType, jsAst.Name> functionTypeNameMap =
+      new HashMap<FunctionType, jsAst.Name>();
 
   FunctionTypeNamer _functionTypeNamer;
 
-  jsAst.Name getFunctionTypeName(ResolutionFunctionType functionType) {
+  jsAst.Name getFunctionTypeName(FunctionType functionType) {
     return functionTypeNameMap.putIfAbsent(functionType, () {
       _functionTypeNamer ??= new FunctionTypeNamer(rtiEncoder);
       String proposedName = _functionTypeNamer.computeName(functionType);
@@ -2260,39 +2237,49 @@
   }
 }
 
-class FunctionTypeNamer extends BaseResolutionDartTypeVisitor {
+class FunctionTypeNamer extends BaseDartTypeVisitor {
   final RuntimeTypesEncoder rtiEncoder;
   StringBuffer sb;
 
   FunctionTypeNamer(this.rtiEncoder);
 
-  String computeName(ResolutionDartType type) {
+  String computeName(DartType type) {
     sb = new StringBuffer();
     visit(type);
     return sb.toString();
   }
 
-  visit(covariant ResolutionDartType type, [_]) {
+  visit(DartType type, [_]) {
     type.accept(this, null);
   }
 
-  visitType(covariant ResolutionDartType type, _) {
-    sb.write(type.name);
+  visitType(DartType type, _) {}
+
+  visitInterfaceType(InterfaceType type, _) {
+    sb.write(type.element.name);
   }
 
-  visitFunctionType(covariant ResolutionFunctionType type, _) {
+  visitTypedefType(TypedefType type, _) {
+    sb.write(type.element.name);
+  }
+
+  visitTypeVariableType(TypeVariableType type, _) {
+    sb.write(type.element.name);
+  }
+
+  visitFunctionType(FunctionType type, _) {
     if (rtiEncoder.isSimpleFunctionType(type)) {
       sb.write('args${type.parameterTypes.length}');
       return;
     }
     visit(type.returnType);
     sb.write('_');
-    for (ResolutionDartType parameter in type.parameterTypes) {
+    for (DartType parameter in type.parameterTypes) {
       sb.write('_');
       visit(parameter);
     }
     bool first = false;
-    for (ResolutionDartType parameter in type.optionalParameterTypes) {
+    for (DartType parameter in type.optionalParameterTypes) {
       if (!first) {
         sb.write('_');
       }
@@ -2302,7 +2289,7 @@
     }
     if (!type.namedParameterTypes.isEmpty) {
       first = false;
-      for (ResolutionDartType parameter in type.namedParameterTypes) {
+      for (DartType parameter in type.namedParameterTypes) {
         if (!first) {
           sb.write('_');
         }
diff --git a/pkg/compiler/lib/src/js_backend/patch_resolver.dart b/pkg/compiler/lib/src/js_backend/patch_resolver.dart
deleted file mode 100644
index 6c55ad3..0000000
--- a/pkg/compiler/lib/src/js_backend/patch_resolver.dart
+++ /dev/null
@@ -1,193 +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.
-
-library dart2js.js_backend.patch_resolver;
-
-import '../common.dart';
-import '../common/resolution.dart' show Resolution;
-import '../common/tasks.dart' show CompilerTask;
-import '../compiler.dart' show Compiler;
-import '../elements/resolution_types.dart';
-import '../elements/elements.dart';
-import '../elements/modelx.dart';
-import '../tree/tree.dart';
-
-class PatchResolverTask extends CompilerTask {
-  final Compiler compiler;
-  PatchResolverTask(Compiler compiler)
-      : compiler = compiler,
-        super(compiler.measurer);
-
-  DiagnosticReporter get reporter => compiler.reporter;
-
-  Resolution get resolution => compiler.resolution;
-
-  String get name => 'JavaScript patch resolver';
-
-  FunctionElement resolveExternalFunction(FunctionElementX element) {
-    if (element.isPatched) {
-      FunctionElementX patch = element.patch;
-      reporter.withCurrentElement(patch, () {
-        patch.computeType(resolution);
-      });
-      checkMatchingPatchSignatures(element, patch);
-      element = patch;
-    } else {
-      if (element.isConstructor) {
-        // Note: currently we allow a couple external methods without a patch,
-        // namely the *.fromEnvironment const constructors in int, bool, and
-        // String.  In the future we might also represent native DOM methods in
-        // dart:html this way.
-        ConstructorElementX constructor = element;
-        if (constructor.isFromEnvironmentConstructor) return element;
-      }
-      reporter.reportErrorMessage(
-          element, MessageKind.PATCH_EXTERNAL_WITHOUT_IMPLEMENTATION);
-    }
-    return element;
-  }
-
-  void checkMatchingPatchParameters(FunctionElement origin,
-      List<Element> originParameters, List<Element> patchParameters) {
-    bool isUnnamedListConstructor = origin is ConstructorElement &&
-        resolution.commonElements.isUnnamedListConstructor(origin);
-
-    assert(originParameters.length == patchParameters.length);
-    for (int index = 0; index < originParameters.length; index++) {
-      ParameterElementX originParameter = originParameters[index];
-      ParameterElementX patchParameter = patchParameters[index];
-      // TODO(johnniwinther): Remove the conditional patching when we never
-      // resolve the same method twice.
-      if (!originParameter.isPatched) {
-        originParameter.applyPatch(patchParameter);
-      } else {
-        assert(originParameter.patch == patchParameter,
-            failedAt(origin, "Inconsistent repatch of $originParameter."));
-      }
-      ResolutionDartType originParameterType =
-          originParameter.computeType(resolution);
-      ResolutionDartType patchParameterType =
-          patchParameter.computeType(resolution);
-      if (originParameterType != patchParameterType) {
-        reporter.reportError(
-            reporter.createMessage(
-                originParameter, MessageKind.PATCH_PARAMETER_TYPE_MISMATCH, {
-              'methodName': origin.name,
-              'parameterName': originParameter.name,
-              'originParameterType': originParameterType,
-              'patchParameterType': patchParameterType
-            }),
-            <DiagnosticMessage>[
-              reporter.createMessage(
-                  patchParameter,
-                  MessageKind.PATCH_POINT_TO_PARAMETER,
-                  {'parameterName': patchParameter.name}),
-            ]);
-      } else {
-        // Hack: Use unparser to test parameter equality. This only works
-        // because we are restricting patch uses and the approach cannot be used
-        // elsewhere.
-
-        // The node contains the type, so there is a potential overlap.
-        // Therefore we only check the text if the types are identical.
-        String originParameterText = originParameter.node.toString();
-        String patchParameterText = patchParameter.node.toString();
-        if (originParameterText != patchParameterText
-            // We special case the list constructor because of the
-            // optional parameter.
-            &&
-            !isUnnamedListConstructor) {
-          reporter.reportError(
-              reporter.createMessage(
-                  originParameter, MessageKind.PATCH_PARAMETER_MISMATCH, {
-                'methodName': origin.name,
-                'originParameter': originParameterText,
-                'patchParameter': patchParameterText
-              }),
-              <DiagnosticMessage>[
-                reporter.createMessage(
-                    patchParameter,
-                    MessageKind.PATCH_POINT_TO_PARAMETER,
-                    {'parameterName': patchParameter.name}),
-              ]);
-        }
-      }
-    }
-  }
-
-  void checkMatchingPatchSignatures(
-      FunctionElement origin, FunctionElement patch) {
-    // TODO(johnniwinther): Show both origin and patch locations on errors.
-    FunctionExpression originTree = origin.node;
-    FunctionSignature originSignature = origin.functionSignature;
-    FunctionExpression patchTree = patch.node;
-    FunctionSignature patchSignature = patch.functionSignature;
-
-    if ('${originTree.typeVariables}' != '${patchTree.typeVariables}') {
-      reporter.withCurrentElement(patch, () {
-        Node errorNode = patchTree.typeVariables != null
-            ? patchTree.typeVariables
-            : patchTree;
-        reporter.reportError(
-            reporter.createMessage(
-                errorNode,
-                MessageKind.PATCH_TYPE_VARIABLES_MISMATCH,
-                {'methodName': origin.name}),
-            [reporter.createMessage(origin, MessageKind.THIS_IS_THE_METHOD)]);
-      });
-    }
-    if (originSignature.type.returnType != patchSignature.type.returnType) {
-      reporter.withCurrentElement(patch, () {
-        Node errorNode =
-            patchTree.returnType != null ? patchTree.returnType : patchTree;
-        reporter.reportErrorMessage(
-            errorNode, MessageKind.PATCH_RETURN_TYPE_MISMATCH, {
-          'methodName': origin.name,
-          'originReturnType': originSignature.type.returnType,
-          'patchReturnType': patchSignature.type.returnType
-        });
-      });
-    }
-    if (originSignature.requiredParameterCount !=
-        patchSignature.requiredParameterCount) {
-      reporter.withCurrentElement(patch, () {
-        reporter.reportErrorMessage(
-            patchTree, MessageKind.PATCH_REQUIRED_PARAMETER_COUNT_MISMATCH, {
-          'methodName': origin.name,
-          'originParameterCount': originSignature.requiredParameterCount,
-          'patchParameterCount': patchSignature.requiredParameterCount
-        });
-      });
-    } else {
-      checkMatchingPatchParameters(origin, originSignature.requiredParameters,
-          patchSignature.requiredParameters);
-    }
-    if (originSignature.optionalParameterCount != 0 &&
-        patchSignature.optionalParameterCount != 0) {
-      if (originSignature.optionalParametersAreNamed !=
-          patchSignature.optionalParametersAreNamed) {
-        reporter.withCurrentElement(patch, () {
-          reporter.reportErrorMessage(
-              patchTree,
-              MessageKind.PATCH_OPTIONAL_PARAMETER_NAMED_MISMATCH,
-              {'methodName': origin.name});
-        });
-      }
-    }
-    if (originSignature.optionalParameterCount !=
-        patchSignature.optionalParameterCount) {
-      reporter.withCurrentElement(patch, () {
-        reporter.reportErrorMessage(
-            patchTree, MessageKind.PATCH_OPTIONAL_PARAMETER_COUNT_MISMATCH, {
-          'methodName': origin.name,
-          'originParameterCount': originSignature.optionalParameterCount,
-          'patchParameterCount': patchSignature.optionalParameterCount
-        });
-      });
-    } else {
-      checkMatchingPatchParameters(origin, originSignature.optionalParameters,
-          patchSignature.optionalParameters);
-    }
-  }
-}
diff --git a/pkg/compiler/lib/src/js_backend/resolution_listener.dart b/pkg/compiler/lib/src/js_backend/resolution_listener.dart
index d0ecf6e..3f97095 100644
--- a/pkg/compiler/lib/src/js_backend/resolution_listener.dart
+++ b/pkg/compiler/lib/src/js_backend/resolution_listener.dart
@@ -23,11 +23,8 @@
 import 'checked_mode_helpers.dart';
 import 'custom_elements_analysis.dart';
 import 'interceptor_data.dart';
-import 'mirrors_analysis.dart';
-import 'mirrors_data.dart';
 import 'native_data.dart' show NativeBasicData;
 import 'no_such_method_registry.dart';
-import 'type_variable_handler.dart';
 
 class ResolutionEnqueuerListener extends EnqueuerListener {
   // TODO(johnniwinther): Avoid the need for this.
@@ -41,12 +38,9 @@
   final NativeBasicData _nativeData;
   final InterceptorDataBuilder _interceptorData;
   final BackendUsageBuilder _backendUsage;
-  final MirrorsDataBuilder _mirrorsDataBuilder;
 
   final NoSuchMethodRegistry _noSuchMethodRegistry;
   final CustomElementsResolutionAnalysis _customElementsAnalysis;
-  final MirrorsResolutionAnalysis _mirrorsAnalysis;
-  final TypeVariableResolutionAnalysis _typeVariableResolutionAnalysis;
 
   final NativeResolutionEnqueuer _nativeEnqueuer;
 
@@ -61,11 +55,8 @@
       this._nativeData,
       this._interceptorData,
       this._backendUsage,
-      this._mirrorsDataBuilder,
       this._noSuchMethodRegistry,
       this._customElementsAnalysis,
-      this._mirrorsAnalysis,
-      this._typeVariableResolutionAnalysis,
       this._nativeEnqueuer,
       this._deferredLoadTask);
 
@@ -166,8 +157,6 @@
     // due to mirrors.
     enqueuer.applyImpact(_customElementsAnalysis.flush(),
         impactSource: _customElementsAnalysis);
-    enqueuer.applyImpact(_typeVariableResolutionAnalysis.flush(),
-        impactSource: _typeVariableResolutionAnalysis);
 
     for (ClassEntity cls in recentClasses) {
       MemberEntity element = _elementEnvironment.lookupLocalClassMember(
@@ -191,7 +180,6 @@
 
     if (!enqueuer.queueIsEmpty) return false;
 
-    _mirrorsAnalysis.onQueueEmpty(enqueuer, recentClasses);
     return true;
   }
 
@@ -260,16 +248,36 @@
   @override
   WorldImpact registerUsedElement(MemberEntity member) {
     WorldImpactBuilderImpl worldImpact = new WorldImpactBuilderImpl();
-    _mirrorsDataBuilder.registerUsedMember(member);
     _customElementsAnalysis.registerStaticUse(member);
 
-    if (member.isFunction && member.isInstanceMember) {
-      FunctionEntity method = member;
-      ClassEntity cls = method.enclosingClass;
+    if (member.isFunction) {
+      FunctionEntity function = member;
+      if (function.isExternal) {
+        FunctionType functionType =
+            _elementEnvironment.getFunctionType(function);
 
-      if (method.name == Identifiers.call &&
-          _elementEnvironment.isGenericClass(cls)) {
-        worldImpact.addImpact(_registerComputeSignature());
+        var allParameterTypes = <DartType>[]
+          ..addAll(functionType.parameterTypes)
+          ..addAll(functionType.optionalParameterTypes)
+          ..addAll(functionType.namedParameterTypes);
+        for (var type in allParameterTypes) {
+          if (type.isFunctionType || type.isTypedef) {
+            var closureConverter = _commonElements.closureConverter;
+            worldImpact.registerStaticUse(
+                new StaticUse.implicitInvoke(closureConverter));
+            _backendUsage.registerBackendFunctionUse(closureConverter);
+            _backendUsage.registerGlobalFunctionDependency(closureConverter);
+            break;
+          }
+        }
+      }
+      if (function.isInstanceMember) {
+        ClassEntity cls = function.enclosingClass;
+
+        if (function.name == Identifiers.call &&
+            _elementEnvironment.isGenericClass(cls)) {
+          worldImpact.addImpact(_registerComputeSignature());
+        }
       }
     }
     _backendUsage.registerUsedMember(member);
@@ -304,9 +312,6 @@
 
   WorldImpact _processClass(ClassEntity cls) {
     WorldImpactBuilderImpl impactBuilder = new WorldImpactBuilderImpl();
-    if (_elementEnvironment.isGenericClass(cls)) {
-      _typeVariableResolutionAnalysis.registerClassWithTypeVariables(cls);
-    }
     // TODO(johnniwinther): Extract an `implementationClassesOf(...)` function
     // for these into [CommonElements] or [BackendImpacts].
     // Register any helper that will be needed by the backend.
diff --git a/pkg/compiler/lib/src/js_backend/runtime_types.dart b/pkg/compiler/lib/src/js_backend/runtime_types.dart
index ab2f509..2364c42 100644
--- a/pkg/compiler/lib/src/js_backend/runtime_types.dart
+++ b/pkg/compiler/lib/src/js_backend/runtime_types.dart
@@ -6,15 +6,8 @@
 
 import '../common/names.dart' show Identifiers;
 import '../common_elements.dart' show CommonElements, ElementEnvironment;
-import '../elements/elements.dart' show ClassElement;
 import '../elements/entities.dart';
 import '../elements/names.dart';
-import '../elements/resolution_types.dart'
-    show
-        MalformedType,
-        MethodTypeVariableType,
-        ResolutionDartTypeVisitor,
-        ResolutionTypedefType;
 import '../elements/types.dart';
 import '../js/js.dart' as jsAst;
 import '../js/js.dart' show js;
@@ -39,7 +32,7 @@
 }
 
 typedef jsAst.Expression OnVariableCallback(TypeVariableType variable);
-typedef bool ShouldEncodeTypedefCallback(ResolutionTypedefType variable);
+typedef bool ShouldEncodeTypedefCallback(TypedefType variable);
 
 /// Interface for the classes and methods that need runtime types.
 abstract class RuntimeTypesNeed {
@@ -758,29 +751,6 @@
   }
 }
 
-class _ResolutionRuntimeTypesNeed extends RuntimeTypesNeedImpl {
-  _ResolutionRuntimeTypesNeed(
-      ElementEnvironment elementEnvironment,
-      BackendUsage backendUsage,
-      Set<ClassEntity> classesNeedingTypeArguments,
-      Set<FunctionEntity> methodsNeedingSignature,
-      Set<FunctionEntity> methodsNeedingTypeArguments,
-      Set<Local> localFunctionsNeedingSignature,
-      Set<Local> localFunctionsNeedingTypeArguments,
-      Set<Selector> selectorsNeedingTypeArguments)
-      : super(
-            elementEnvironment,
-            backendUsage,
-            classesNeedingTypeArguments,
-            methodsNeedingSignature,
-            methodsNeedingTypeArguments,
-            localFunctionsNeedingSignature,
-            localFunctionsNeedingTypeArguments,
-            selectorsNeedingTypeArguments);
-
-  bool checkClass(ClassElement cls) => cls.isDeclaration;
-}
-
 class TypeVariableTests {
   List<RtiNode> _nodes = <RtiNode>[];
   Map<ClassEntity, ClassNode> _classes = <ClassEntity, ClassNode>{};
@@ -1369,8 +1339,6 @@
   RuntimeTypesNeedBuilderImpl(this._elementEnvironment, DartTypes types)
       : super(types);
 
-  bool checkClass(covariant ClassEntity cls) => true;
-
   @override
   void registerClassUsingTypeVariableLiteral(ClassEntity cls) {
     classesUsingTypeVariableLiterals.add(cls);
@@ -1417,7 +1385,6 @@
       processedEntities.add(entity);
       if (entity is ClassEntity) {
         ClassEntity cls = entity;
-        assert(checkClass(cls));
         if (!_elementEnvironment.isGenericClass(cls)) return;
         if (classesNeedingTypeArguments.contains(cls)) return;
         classesNeedingTypeArguments.add(cls);
@@ -1636,35 +1603,6 @@
   }
 }
 
-class ResolutionRuntimeTypesNeedBuilderImpl
-    extends RuntimeTypesNeedBuilderImpl {
-  ResolutionRuntimeTypesNeedBuilderImpl(
-      ElementEnvironment elementEnvironment, DartTypes types)
-      : super(elementEnvironment, types);
-
-  bool checkClass(ClassElement cls) => cls.isDeclaration;
-
-  RuntimeTypesNeed _createRuntimeTypesNeed(
-      ElementEnvironment elementEnvironment,
-      BackendUsage backendUsage,
-      Set<ClassEntity> classesNeedingTypeArguments,
-      Set<FunctionEntity> methodsNeedingSignature,
-      Set<FunctionEntity> methodsNeedingTypeArguments,
-      Set<Local> localFunctionsNeedingSignature,
-      Set<Local> localFunctionsNeedingTypeArguments,
-      Set<Selector> selectorsNeedingTypeArguments) {
-    return new _ResolutionRuntimeTypesNeed(
-        _elementEnvironment,
-        backendUsage,
-        classesNeedingTypeArguments,
-        methodsNeedingSignature,
-        methodsNeedingTypeArguments,
-        localFunctionsNeedingSignature,
-        localFunctionsNeedingTypeArguments,
-        selectorsNeedingTypeArguments);
-  }
-}
-
 class _RuntimeTypesChecks implements RuntimeTypesChecks {
   final RuntimeTypesSubstitutions _substitutions;
   final TypeChecks requiredChecks;
@@ -2105,7 +2043,7 @@
 }
 
 class TypeRepresentationGenerator
-    implements ResolutionDartTypeVisitor<jsAst.Expression, Emitter> {
+    implements DartTypeVisitor<jsAst.Expression, Emitter> {
   final Namer namer;
   final NativeBasicData _nativeData;
   // If true, compile using strong mode.
@@ -2129,9 +2067,8 @@
       ShouldEncodeTypedefCallback encodeTypedef) {
     assert(typedefBindings == null);
     this.onVariable = onVariable;
-    this.shouldEncodeTypedef = (encodeTypedef != null)
-        ? encodeTypedef
-        : (ResolutionTypedefType type) => false;
+    this.shouldEncodeTypedef =
+        (encodeTypedef != null) ? encodeTypedef : (TypedefType type) => false;
     jsAst.Expression representation = visit(type, emitter);
     this.onVariable = null;
     this.shouldEncodeTypedef = null;
@@ -2302,17 +2239,11 @@
     return new jsAst.ObjectInitializer(properties);
   }
 
-  jsAst.Expression visitMalformedType(MalformedType type, Emitter emitter) {
-    // Treat malformed types as dynamic at runtime.
-    return getDynamicValue();
-  }
-
   jsAst.Expression visitVoidType(VoidType type, Emitter emitter) {
     return _strongMode ? getVoidValue() : getDynamicValue();
   }
 
-  jsAst.Expression visitTypedefType(
-      ResolutionTypedefType type, Emitter emitter) {
+  jsAst.Expression visitTypedefType(TypedefType type, Emitter emitter) {
     bool shouldEncode = shouldEncodeTypedef(type);
     DartType unaliasedType = type.unaliased;
 
@@ -2340,9 +2271,7 @@
       // inputs to correspond to type variables AND typedefs.
       typedefBindings = <TypeVariableType, jsAst.Expression>{};
       type.forEachTypeVariable((TypeVariableType variable) {
-        if (variable is! MethodTypeVariableType) {
-          typedefBindings[variable] = onVariable(variable);
-        }
+        typedefBindings[variable] = onVariable(variable);
       });
     }
 
@@ -2412,7 +2341,7 @@
   }
 }
 
-class ArgumentCollector extends ResolutionDartTypeVisitor<dynamic, bool> {
+class ArgumentCollector extends DartTypeVisitor<dynamic, bool> {
   final Set<ClassEntity> classes = new Set<ClassEntity>();
 
   void addClass(ClassEntity cls) {
@@ -2431,7 +2360,7 @@
     }
   }
 
-  visitTypedefType(ResolutionTypedefType type, bool isTypeArgument) {
+  visitTypedefType(TypedefType type, bool isTypeArgument) {
     collect(type.unaliased, isTypeArgument: isTypeArgument);
   }
 
@@ -2448,8 +2377,7 @@
   }
 }
 
-class FunctionArgumentCollector
-    extends ResolutionDartTypeVisitor<dynamic, bool> {
+class FunctionArgumentCollector extends DartTypeVisitor<dynamic, bool> {
   final Set<ClassEntity> classes = new Set<ClassEntity>();
 
   FunctionArgumentCollector();
@@ -2464,7 +2392,7 @@
     }
   }
 
-  visitTypedefType(ResolutionTypedefType type, bool inFunctionType) {
+  visitTypedefType(TypedefType type, bool inFunctionType) {
     collect(type.unaliased, inFunctionType: inFunctionType);
   }
 
@@ -2547,7 +2475,7 @@
       'TypeCheck(cls=$cls,needsIs=$needsIs,substitution=$substitution)';
 }
 
-class TypeVisitor extends ResolutionDartTypeVisitor<void, bool> {
+class TypeVisitor extends DartTypeVisitor<void, bool> {
   Set<FunctionTypeVariable> _visitedFunctionTypeVariables =
       new Set<FunctionTypeVariable>();
 
diff --git a/pkg/compiler/lib/src/js_backend/type_variable_handler.dart b/pkg/compiler/lib/src/js_backend/type_variable_handler.dart
deleted file mode 100644
index 81a3f76..0000000
--- a/pkg/compiler/lib/src/js_backend/type_variable_handler.dart
+++ /dev/null
@@ -1,187 +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.
-
-import '../common_elements.dart';
-import '../constants/expressions.dart';
-import '../constants/values.dart';
-import '../deferred_load.dart' show OutputUnit;
-import '../elements/entities.dart';
-import '../elements/types.dart';
-import '../js/js.dart' as jsAst;
-import '../js_emitter/js_emitter.dart'
-    show CodeEmitterTask, MetadataCollector, Placeholder;
-import '../universe/call_structure.dart' show CallStructure;
-import '../universe/use.dart' show ConstantUse;
-import '../universe/world_impact.dart';
-import 'backend.dart';
-import 'backend_usage.dart' show BackendUsageBuilder;
-import 'backend_impact.dart';
-import 'mirrors_data.dart';
-
-/// Resolution analysis that prepares for the construction of TypeVariable
-/// constants needed at runtime.
-class TypeVariableResolutionAnalysis {
-  final ElementEnvironment _elementEnvironment;
-  final BackendImpacts _impacts;
-  final BackendUsageBuilder _backendUsageBuilder;
-
-  /**
-   * Set to 'true' on first encounter of a class with type variables.
-   */
-  bool _seenClassesWithTypeVariables = false;
-
-  /// Impact builder used for the resolution world computation.
-  final StagedWorldImpactBuilder impactBuilder = new StagedWorldImpactBuilder();
-
-  TypeVariableResolutionAnalysis(
-      this._elementEnvironment, this._impacts, this._backendUsageBuilder);
-
-  /// Compute the [WorldImpact] for the type variables registered since last
-  /// flush.
-  WorldImpact flush() {
-    return impactBuilder.flush();
-  }
-
-  void registerClassWithTypeVariables(ClassEntity cls) {
-    // On first encounter, we have to ensure that the support classes get
-    // resolved.
-    if (!_seenClassesWithTypeVariables) {
-      _impacts.typeVariableMirror
-          .registerImpact(impactBuilder, _elementEnvironment);
-      _backendUsageBuilder.processBackendImpact(_impacts.typeVariableMirror);
-      _seenClassesWithTypeVariables = true;
-    }
-  }
-}
-
-/// Codegen handler that creates TypeVariable constants needed at runtime.
-class TypeVariableCodegenAnalysis {
-  final ElementEnvironment _elementEnvironment;
-  final JavaScriptBackend _backend;
-  final CommonElements _commonElements;
-  final MirrorsData _mirrorsData;
-
-  /**
-   *  Maps a class element to a list with indices that point to type variables
-   *  constants for each of the class' type variables.
-   */
-  Map<ClassEntity, List<jsAst.Expression>> _typeVariables =
-      new Map<ClassEntity, List<jsAst.Expression>>();
-
-  /**
-   *  Maps a TypeVariableType to the index pointing to the constant representing
-   *  the corresponding type variable at runtime.
-   */
-  Map<TypeVariableEntity, jsAst.Expression> _typeVariableConstants =
-      new Map<TypeVariableEntity, jsAst.Expression>();
-
-  /// Impact builder used for the codegen world computation.
-  final StagedWorldImpactBuilder _impactBuilder =
-      new StagedWorldImpactBuilder();
-
-  TypeVariableCodegenAnalysis(this._elementEnvironment, this._backend,
-      this._commonElements, this._mirrorsData);
-
-  CodeEmitterTask get _task => _backend.emitter;
-  MetadataCollector get _metadataCollector => _task.metadataCollector;
-
-  /// Compute the [WorldImpact] for the type variables registered since last
-  /// flush.
-  WorldImpact flush() {
-    return _impactBuilder.flush();
-  }
-
-  void registerClassWithTypeVariables(ClassEntity cls) {
-    if (_mirrorsData.isClassAccessibleByReflection(cls)) {
-      processTypeVariablesOf(cls);
-    }
-  }
-
-  void processTypeVariablesOf(ClassEntity cls) {
-    // Do not process classes twice.
-    if (_typeVariables.containsKey(cls)) return;
-
-    List<jsAst.Expression> constants = <jsAst.Expression>[];
-
-    InterfaceType thisType = _elementEnvironment.getThisType(cls);
-    for (TypeVariableType currentTypeVariable in thisType.typeArguments) {
-      TypeVariableEntity typeVariableElement = currentTypeVariable.element;
-
-      // TODO(sigmund): use output unit for `cls` (Issue #31032)
-      OutputUnit outputUnit = _backend.outputUnitData.mainOutputUnit;
-      jsAst.Expression boundIndex = _metadataCollector.reifyType(
-          _elementEnvironment.getTypeVariableBound(typeVariableElement),
-          outputUnit);
-      ConstantValue boundValue = new SyntheticConstantValue(
-          SyntheticConstantKind.TYPEVARIABLE_REFERENCE, boundIndex);
-      ClassEntity typeVariableClass = _commonElements.typeVariableClass;
-      ConstantExpression constant = new ConstructedConstantExpression(
-          _elementEnvironment.getThisType(typeVariableClass),
-          _commonElements.typeVariableConstructor,
-          const CallStructure.unnamed(3), [
-        new TypeConstantExpression(
-            _elementEnvironment.getRawType(cls), cls.name),
-        new StringConstantExpression(typeVariableElement.name),
-        new SyntheticConstantExpression(boundValue)
-      ]);
-
-      _backend.constants.evaluate(constant);
-      ConstantValue value = _backend.constants.getConstantValue(constant);
-      _impactBuilder
-          .registerConstantUse(new ConstantUse.typeVariableMirror(value));
-      constants.add(_reifyTypeVariableConstant(
-          value, currentTypeVariable.element, outputUnit));
-    }
-    _typeVariables[cls] = constants;
-  }
-
-  /**
-   * Adds [c] to [emitter.metadataCollector] and returns the index pointing to
-   * the entry.
-   *
-   * If the corresponding type variable has already been encountered an
-   * entry in the list has already been reserved and the constant is added
-   * there, otherwise a new entry for [c] is created.
-   */
-  jsAst.Expression _reifyTypeVariableConstant(
-      ConstantValue c, TypeVariableEntity variable, OutputUnit outputUnit) {
-    jsAst.Expression name = _task.constantReference(c);
-    jsAst.Expression result =
-        _metadataCollector.reifyExpression(name, outputUnit);
-    if (_typeVariableConstants.containsKey(variable)) {
-      Placeholder placeholder = _typeVariableConstants[variable];
-      placeholder.bind(result);
-    }
-    _typeVariableConstants[variable] = result;
-    return result;
-  }
-
-  /**
-   * Returns the index pointing to the constant in [emitter.metadataCollector]
-   * representing this type variable.
-   *
-   * If the constant has not yet been constructed, an entry is  allocated in
-   * the global metadata list and the index pointing to this entry is returned.
-   * When the corresponding constant is constructed later,
-   * [reifyTypeVariableConstant] will be called and the constant will be added
-   * on the allocated entry.
-   */
-  jsAst.Expression reifyTypeVariable(TypeVariableEntity variable) {
-    if (_typeVariableConstants.containsKey(variable)) {
-      return _typeVariableConstants[variable];
-    }
-
-    Placeholder placeholder =
-        _metadataCollector.getMetadataPlaceholder(variable);
-    return _typeVariableConstants[variable] = placeholder;
-  }
-
-  List<jsAst.Expression> typeVariablesOf(ClassEntity classElement) {
-    List<jsAst.Expression> result = _typeVariables[classElement];
-    if (result == null) {
-      result = const <jsAst.Expression>[];
-    }
-    return result;
-  }
-}
diff --git a/pkg/compiler/lib/src/js_emitter/code_emitter_task.dart b/pkg/compiler/lib/src/js_emitter/code_emitter_task.dart
index 003771e..00bfaf7 100644
--- a/pkg/compiler/lib/src/js_emitter/code_emitter_task.dart
+++ b/pkg/compiler/lib/src/js_emitter/code_emitter_task.dart
@@ -150,8 +150,8 @@
     // 'is$' method.
     typeTestRegistry.computeRequiredTypeChecks(backend.rtiChecksBuilder);
     // Compute the classes needed by RTI.
-    typeTestRegistry.computeRtiNeededClasses(backend.rtiSubstitutions,
-        backend.mirrorsData, backend.generatedCode.keys);
+    typeTestRegistry.computeRtiNeededClasses(
+        backend.rtiSubstitutions, backend.generatedCode.keys);
   }
 
   /// Creates the [Emitter] for this task.
@@ -162,17 +162,10 @@
           backend.nativeCodegenEnqueuer);
       _emitter =
           _emitterFactory.createEmitter(this, namer, closedWorld, sorter);
-      metadataCollector = new MetadataCollector(
-          compiler.options,
-          compiler.reporter,
-          _emitter,
-          backend.constants,
-          backend.typeVariableCodegenAnalysis,
-          backend.mirrorsData,
-          backend.rtiEncoder,
-          codegenWorldBuilder);
+      metadataCollector = new MetadataCollector(compiler.options,
+          compiler.reporter, _emitter, backend.rtiEncoder, codegenWorldBuilder);
       typeTestRegistry = new TypeTestRegistry(compiler.options,
-          codegenWorldBuilder, closedWorld, closedWorld.elementEnvironment);
+          codegenWorldBuilder, closedWorld.elementEnvironment);
     });
   }
 
@@ -194,7 +187,6 @@
           backend.constants,
           closedWorld.nativeData,
           closedWorld.rtiNeed,
-          backend.mirrorsData,
           closedWorld.interceptorData,
           backend.superMemberData,
           typeTestRegistry.rtiChecks,
@@ -209,8 +201,7 @@
           backend.sourceInformationStrategy,
           compiler.backendStrategy.sorter,
           typeTestRegistry.rtiNeededClasses,
-          closedWorld.elementEnvironment.mainFunction,
-          isMockCompilation: compiler.isMockCompilation);
+          closedWorld.elementEnvironment.mainFunction);
       int size = emitter.emitProgram(programBuilder);
       // TODO(floitsch): we shouldn't need the `neededClasses` anymore.
       neededClasses = programBuilder.collector.neededClasses;
diff --git a/pkg/compiler/lib/src/js_emitter/constant_ordering.dart b/pkg/compiler/lib/src/js_emitter/constant_ordering.dart
index fcd705d..da2cc06 100644
--- a/pkg/compiler/lib/src/js_emitter/constant_ordering.dart
+++ b/pkg/compiler/lib/src/js_emitter/constant_ordering.dart
@@ -5,15 +5,8 @@
 library dart2js.js_emitter.constant_ordering;
 
 import '../constants/values.dart';
-import '../elements/elements.dart' show Elements;
 import '../elements/entities.dart'
-    show Entity, ClassEntity, FieldEntity, MemberEntity, TypedefEntity;
-import '../elements/resolution_types.dart'
-    show
-        GenericType,
-        ResolutionDartType,
-        ResolutionFunctionType,
-        ResolutionTypeKind;
+    show ClassEntity, FieldEntity, LibraryEntity, MemberEntity, TypedefEntity;
 import '../elements/types.dart';
 import '../js_backend/js_backend.dart' show SyntheticConstantKind;
 import 'sorter.dart' show Sorter;
@@ -60,10 +53,8 @@
     return 0;
   }
 
-  static int compareElements(Entity a, Entity b) {
-    int r = a.name.compareTo(b.name);
-    if (r != 0) return r;
-    return Elements.compareByPosition(a, b);
+  int compareLibraries(LibraryEntity a, LibraryEntity b) {
+    return _sorter.compareLibrariesByLocation(a, b);
   }
 
   int compareClasses(ClassEntity a, ClassEntity b) {
@@ -84,45 +75,7 @@
     return _sorter.compareTypedefsByLocation(a, b);
   }
 
-  static int _compareResolutionDartTypes(
-      ResolutionDartType a, ResolutionDartType b) {
-    if (a == b) return 0;
-    int r = a.kind.index.compareTo(b.kind.index);
-    if (r != 0) return r;
-    r = compareNullable(compareElements, a.element, b.element);
-    if (r != 0) return r;
-
-    if (a is GenericType) {
-      GenericType aGeneric = a;
-      GenericType bGeneric = b;
-      r = compareLists(_compareResolutionDartTypes, aGeneric.typeArguments,
-          bGeneric.typeArguments);
-      if (r != 0) return r;
-    }
-    if (a is ResolutionFunctionType && b is ResolutionFunctionType) {
-      int r = compareLists(
-          _compareResolutionDartTypes, a.parameterTypes, b.parameterTypes);
-      if (r != 0) return r;
-      r = compareLists(_compareResolutionDartTypes, a.optionalParameterTypes,
-          b.optionalParameterTypes);
-      if (r != 0) return r;
-      r = _ConstantOrdering.compareLists((String a, String b) => a.compareTo(b),
-          a.namedParameters, b.namedParameters);
-      if (r != 0) return r;
-      r = compareLists(_compareResolutionDartTypes, a.namedParameterTypes,
-          b.namedParameterTypes);
-      if (r != 0) return r;
-      return _compareResolutionDartTypes(a.returnType, b.returnType);
-    }
-
-    throw 'unexpected compareDartTypes  $a  $b';
-  }
-
   int compareDartTypes(DartType a, DartType b) {
-    if (a is ResolutionDartType && b is ResolutionDartType) {
-      // TODO(redemption): Remove this path.
-      return _compareResolutionDartTypes(a, b);
-    }
     return _dartTypeOrdering.compare(a, b);
   }
 
@@ -230,8 +183,10 @@
   int visitDeferred(DeferredConstantValue a, DeferredConstantValue b) {
     int r = compareValues(a.referenced, b.referenced);
     if (r != 0) return r;
-    // TODO(sra): What kind of Entity is `prefix`?
-    return compareElements(a.import, b.import);
+    r = a.import.name.compareTo(b.import.name);
+    if (r != 0) return r;
+    return compareLibraries(
+        a.import.enclosingLibrary, b.import.enclosingLibrary);
   }
 
   int visitDeferredGlobal(
@@ -295,7 +250,6 @@
   const _DartTypeKindVisitor();
 
   static int kind(DartType type) {
-    assert(_usesLegacyOrder);
     return type.accept(const _DartTypeKindVisitor(), null);
   }
 
@@ -305,24 +259,6 @@
   int visitInterfaceType(covariant InterfaceType type, _) => 1;
   int visitTypedefType(covariant TypedefType type, _) => 2;
   int visitDynamicType(covariant DynamicType type, _) => 5;
-
-  // Check that the ordering of different kinds of type is consistent with
-  // ResolutionDartTypes.
-  // TODO(redemption): Remove this check.
-  static bool _usesLegacyOrder = () {
-    var v = const _DartTypeKindVisitor();
-    assert(
-        v.visitFunctionType(null, null) == ResolutionTypeKind.FUNCTION.index);
-    assert(
-        v.visitInterfaceType(null, null) == ResolutionTypeKind.INTERFACE.index);
-    assert(v.visitTypedefType(null, null) == ResolutionTypeKind.TYPEDEF.index);
-    assert(v.visitTypeVariableType(null, null) ==
-        ResolutionTypeKind.TYPE_VARIABLE.index);
-    // There is no analogue of ResolutionTypeKind.MALFORMED_TYPE.
-    assert(v.visitDynamicType(null, null) == ResolutionTypeKind.DYNAMIC.index);
-    assert(v.visitVoidType(null, null) == ResolutionTypeKind.VOID.index);
-    return true;
-  }();
 }
 
 class _DartTypeOrdering extends DartTypeVisitor<int, DartType> {
diff --git a/pkg/compiler/lib/src/js_emitter/full_emitter/class_emitter.dart b/pkg/compiler/lib/src/js_emitter/full_emitter/class_emitter.dart
index f9a75b1..ee51d11 100644
--- a/pkg/compiler/lib/src/js_emitter/full_emitter/class_emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/full_emitter/class_emitter.dart
@@ -7,15 +7,11 @@
 import '../../common.dart';
 import '../../common/names.dart' show Names;
 import '../../common_elements.dart';
-import '../../elements/resolution_types.dart' show ResolutionDartType;
 import '../../deferred_load.dart' show OutputUnit;
-import '../../elements/elements.dart' show ClassElement, FieldElement;
 import '../../elements/entities.dart';
 import '../../js/js.dart' as jsAst;
 import '../../js/js.dart' show js;
 import '../../js_backend/js_backend.dart' show CompoundName, Namer;
-import '../../universe/selector.dart' show Selector;
-import '../../util/util.dart' show equalElements;
 import '../../world.dart' show ClosedWorld;
 import '../js_emitter.dart' hide Emitter, EmitterFactory;
 import '../model.dart';
@@ -38,9 +34,6 @@
   void emitClass(Class cls, ClassBuilder enclosingBuilder, Fragment fragment) {
     ClassEntity classElement = cls.element;
 
-    assert(!(classElement is ClassElement && !classElement.isDeclaration),
-        failedAt(classElement));
-
     emitter.needsClassSupport = true;
 
     ClassEntity superclass = _elementEnvironment.getSuperClass(classElement);
@@ -123,8 +116,6 @@
       fields = container.staticFieldsForReflection;
     }
 
-    var fieldMetadata = <jsAst.Expression>[];
-    bool hasMetadata = false;
     bool fieldsAdded = false;
 
     for (Field field in fields) {
@@ -142,16 +133,6 @@
       // accessors at runtime.
       bool needsFieldsForConstructor = !emitStatics && !classIsNative;
       if (needsFieldsForConstructor || needsAccessor) {
-        dynamic metadata =
-            task.metadataCollector.buildFieldMetadataFunction(fieldElement);
-        if (metadata != null) {
-          hasMetadata = true;
-        } else {
-          metadata = new jsAst.LiteralNull();
-        }
-        fieldMetadata.add(metadata);
-        recordMangledField(fieldElement, accessorName,
-            namer.privateName(fieldElement.memberName));
         List<jsAst.Literal> fieldNameParts = <jsAst.Literal>[];
         if (!needsAccessor) {
           // Emit field for constructor generation.
@@ -185,26 +166,6 @@
           fieldNameParts.add(
               js.stringPart(FIELD_CODE_CHARACTERS[code - FIRST_FIELD_CODE]));
         }
-        // Fields can only be reflected if their declaring class is reflectable
-        // (as they are only accessible via [ClassMirror.declarations]).
-        // However, set/get operations can be performed on them, so they are
-        // reflectable in some sense, which leads to [isAccessibleByReflection]
-        // reporting `true`.
-        if (backend.mirrorsData.isMemberAccessibleByReflection(fieldElement)) {
-          fieldNameParts.add(new jsAst.LiteralString('-'));
-          if (fieldElement.isTopLevel ||
-              backend.mirrorsData
-                  .isClassAccessibleByReflection(fieldElement.enclosingClass)) {
-            // TODO(redemption): Support field entities.
-            FieldElement element = fieldElement;
-            ResolutionDartType type = element.type;
-            // TODO(sigmund): use output unit for `element` (Issue #31032)
-            OutputUnit outputUnit =
-                compiler.backend.outputUnitData.mainOutputUnit;
-            fieldNameParts
-                .add(task.metadataCollector.reifyType(type, outputUnit));
-          }
-        }
         jsAst.Literal fieldNameAst = js.concatenateStrings(fieldNameParts);
         builder.addField(fieldNameAst);
         // Add 1 because adding a field to the class also requires a comma
@@ -213,9 +174,6 @@
       }
     }
 
-    if (hasMetadata) {
-      builder.fieldMetadata = fieldMetadata;
-    }
     return fieldsAdded;
   }
 
@@ -230,8 +188,6 @@
       jsAst.Name setterName = method.name;
       compiler.dumpInfoTask
           .registerEntityAst(member, builder.addProperty(setterName, code));
-      generateReflectionDataForFieldGetterOrSetter(member, setterName, builder,
-          isGetter: false);
     }
   }
 
@@ -266,8 +222,6 @@
    */
   void emitInstanceMembers(Class cls, ClassBuilder builder) {
     ClassEntity classElement = cls.element;
-    assert(!(classElement is ClassElement && !classElement.isDeclaration),
-        failedAt(classElement));
 
     if (cls.onlyForRti || cls.isMixinApplication) return;
 
@@ -315,28 +269,6 @@
     ClassEntity classEntity = cls.element;
     jsAst.Name className = cls.name;
 
-    var metadata =
-        task.metadataCollector.buildClassMetadataFunction(classEntity);
-    if (metadata != null) {
-      classBuilder.addPropertyByName("@", metadata);
-    }
-
-    if (backend.mirrorsData.isClassAccessibleByReflection(classEntity)) {
-      // TODO(redemption): Handle class entities.
-      ClassElement classElement = classEntity;
-      List<ResolutionDartType> typeVars = classElement.typeVariables;
-      Iterable typeVariableProperties =
-          emitter.typeVariableCodegenAnalysis.typeVariablesOf(classElement);
-
-      ClassElement superclass = classElement.superclass;
-      bool hasSuper = superclass != null;
-      if ((!typeVariableProperties.isEmpty && !hasSuper) ||
-          (hasSuper && !equalElements(superclass.typeVariables, typeVars))) {
-        classBuilder.addPropertyByName(
-            '<>', new jsAst.ArrayInitializer(typeVariableProperties.toList()));
-      }
-    }
-
     List<jsAst.Property> statics = new List<jsAst.Property>();
     ClassBuilder staticsBuilder =
         new ClassBuilder.forStatics(classEntity, namer);
@@ -371,45 +303,11 @@
     String reflectionName =
         emitter.getReflectionClassName(classEntity, className);
     if (reflectionName != null) {
-      if (!backend.mirrorsData.isClassAccessibleByReflection(classEntity) ||
-          cls.onlyForRti) {
-        // TODO(herhut): Fix use of reflection name here.
-        enclosingBuilder.addPropertyByName("+$reflectionName", js.number(0));
-      } else {
-        // TODO(sigmund): use output unit for `classEntity` (Issue #31032)
-        OutputUnit outputUnit = compiler.backend.outputUnitData.mainOutputUnit;
-        // TODO(redemption): Handle class entities.
-        ClassElement classElement = classEntity;
-        List<jsAst.Expression> types = <jsAst.Expression>[];
-        if (classElement.supertype != null) {
-          types.add(task.metadataCollector
-              .reifyType(classElement.supertype, outputUnit));
-        }
-        for (ResolutionDartType interface in classElement.interfaces) {
-          types.add(task.metadataCollector.reifyType(interface, outputUnit));
-        }
-        // TODO(herhut): Fix use of reflection name here.
-        enclosingBuilder.addPropertyByName(
-            "+$reflectionName", new jsAst.ArrayInitializer(types));
-      }
+      // TODO(herhut): Fix use of reflection name here.
+      enclosingBuilder.addPropertyByName("+$reflectionName", js.number(0));
     }
   }
 
-  void recordMangledField(
-      FieldEntity member, jsAst.Name accessorName, String memberName) {
-    if (!backend.mirrorsData.shouldRetainGetter(member)) return;
-    String previousName;
-    if (member.isInstanceMember) {
-      previousName = emitter.mangledFieldNames
-          .putIfAbsent(namer.deriveGetterName(accessorName), () => memberName);
-    } else {
-      previousName = emitter.mangledGlobalFieldNames
-          .putIfAbsent(accessorName, () => memberName);
-    }
-    assert(previousName == memberName,
-        failedAt(member, '$previousName != ${memberName}'));
-  }
-
   void emitGetterForCSP(FieldEntity member, jsAst.Name fieldName,
       jsAst.Name accessorName, ClassBuilder builder) {
     jsAst.Expression function =
@@ -423,11 +321,6 @@
     emitter
         .cspPrecompiledFunctionFor(outputUnit)
         .add(js('#.prototype.# = #', [className, getterName, function]));
-    if (backend.mirrorsData.isMemberAccessibleByReflection(member)) {
-      emitter.cspPrecompiledFunctionFor(outputUnit).add(js(
-          '#.prototype.#.${namer.reflectableField} = 1',
-          [className, getterName]));
-    }
   }
 
   void emitSetterForCSP(FieldEntity member, jsAst.Name fieldName,
@@ -443,26 +336,5 @@
     emitter
         .cspPrecompiledFunctionFor(outputUnit)
         .add(js('#.prototype.# = #', [className, setterName, function]));
-    if (backend.mirrorsData.isMemberAccessibleByReflection(member)) {
-      emitter.cspPrecompiledFunctionFor(outputUnit).add(js(
-          '#.prototype.#.${namer.reflectableField} = 1',
-          [className, setterName]));
-    }
-  }
-
-  void generateReflectionDataForFieldGetterOrSetter(
-      MemberEntity member, jsAst.Name name, ClassBuilder builder,
-      {bool isGetter}) {
-    Selector selector = isGetter
-        ? new Selector.getter(member.memberName.getter)
-        : new Selector.setter(member.memberName.setter);
-    String reflectionName = emitter.getReflectionSelectorName(selector, name);
-    if (reflectionName != null) {
-      var reflectable = js(
-          backend.mirrorsData.isMemberAccessibleByReflection(member)
-              ? '1'
-              : '0');
-      builder.addPropertyByName('+$reflectionName', reflectable);
-    }
   }
 }
diff --git a/pkg/compiler/lib/src/js_emitter/full_emitter/container_builder.dart b/pkg/compiler/lib/src/js_emitter/full_emitter/container_builder.dart
index 2ded0af..144f886 100644
--- a/pkg/compiler/lib/src/js_emitter/full_emitter/container_builder.dart
+++ b/pkg/compiler/lib/src/js_emitter/full_emitter/container_builder.dart
@@ -4,12 +4,8 @@
 
 library dart2js.js_emitter.full_emitter.container_builder;
 
-import '../../constants/values.dart';
 import '../../deferred_load.dart' show OutputUnit;
-import '../../elements/elements.dart'
-    show Element, MetadataAnnotation, MethodElement;
 import '../../elements/entities.dart';
-import '../../elements/entity_utils.dart' as utils;
 import '../../elements/names.dart';
 import '../../js/js.dart' as jsAst;
 import '../../js/js.dart' show js;
@@ -32,15 +28,13 @@
     jsAst.Expression code = method.code;
     bool needsStubs = method.parameterStubs.isNotEmpty;
     bool canBeApplied = method.canBeApplied;
-    bool canBeReflected = method.canBeReflected;
     bool canTearOff = method.needsTearOff;
     jsAst.Name tearOffName = method.tearOffName;
     bool isClosure = method is InstanceMethod && method.isClosureCallMethod;
     jsAst.Name superAlias = method is InstanceMethod ? method.aliasName : null;
     bool hasSuperAlias = superAlias != null;
     jsAst.Expression memberTypeExpression = method.functionType;
-    bool needStructuredInfo =
-        canTearOff || canBeReflected || canBeApplied || hasSuperAlias;
+    bool needStructuredInfo = canTearOff || canBeApplied || hasSuperAlias;
 
     bool isIntercepted = false;
     if (method is InstanceMethod) {
@@ -102,8 +96,7 @@
 
     expressions.add(code);
 
-    bool onlyNeedsSuperAlias =
-        !(canTearOff || canBeReflected || canBeApplied || needsStubs);
+    bool onlyNeedsSuperAlias = !(canTearOff || canBeApplied || needsStubs);
 
     if (onlyNeedsSuperAlias) {
       jsAst.ArrayInitializer arrayInit =
@@ -155,50 +148,16 @@
       ..add(js.number(optionalParameterCount))
       ..add(memberTypeExpression == null ? js("null") : memberTypeExpression);
 
-    if (canBeReflected || canBeApplied) {
+    if (canBeApplied) {
       expressions.addAll(
           task.metadataCollector.reifyDefaultArguments(member, outputUnit));
 
-      if (member is MethodElement) {
-        member.functionSignature.forEachParameter((Element parameter) {
-          expressions.add(
-              task.metadataCollector.reifyName(parameter.name, outputUnit));
-          if (backend.mirrorsData.mustRetainMetadata) {
-            Iterable<jsAst.Expression> metadataIndices =
-                parameter.metadata.map((MetadataAnnotation annotation) {
-              ConstantValue constant =
-                  backend.constants.getConstantValueForMetadata(annotation);
-              codegenWorldBuilder.addCompileTimeConstantForEmission(constant);
-              return task.metadataCollector
-                  .reifyMetadata(annotation, outputUnit);
-            });
-            expressions
-                .add(new jsAst.ArrayInitializer(metadataIndices.toList()));
-          }
-        });
-      } else {
-        codegenWorldBuilder.forEachParameter(member, (_, String name, _2) {
-          expressions.add(task.metadataCollector.reifyName(name, outputUnit));
-        });
-        // TODO(redemption): Support retaining mirrors metadata.
-      }
+      codegenWorldBuilder.forEachParameter(member, (_, String name, _2) {
+        expressions.add(task.metadataCollector.reifyName(name, outputUnit));
+      });
     }
     Name memberName = member.memberName;
-    if (canBeReflected) {
-      jsAst.LiteralString reflectionName;
-      if (member.isConstructor) {
-        // TODO(herhut): This registers name as a mangled name. Do we need this
-        //               given that we use a different name below?
-        emitter.getReflectionMemberName(member, name);
-        reflectionName = new jsAst.LiteralString(
-            '"new ${utils.reconstructConstructorName(member)}"');
-      } else {
-        reflectionName = js.string(namer.privateName(memberName));
-      }
-      expressions
-        ..add(reflectionName)
-        ..addAll(task.metadataCollector.computeMetadata(member, outputUnit));
-    } else if (isClosure && canBeApplied) {
+    if (isClosure && canBeApplied) {
       expressions.add(js.string(namer.privateName(memberName)));
     }
 
diff --git a/pkg/compiler/lib/src/js_emitter/full_emitter/emitter.dart b/pkg/compiler/lib/src/js_emitter/full_emitter/emitter.dart
index e333f45..bdc35cd 100644
--- a/pkg/compiler/lib/src/js_emitter/full_emitter/emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/full_emitter/emitter.dart
@@ -4,7 +4,6 @@
 
 library dart2js.js_emitter.full_emitter;
 
-import 'dart:collection' show HashMap;
 import 'dart:convert';
 
 import 'package:js_runtime/shared/embedded_names.dart' as embeddedNames;
@@ -18,9 +17,6 @@
 import '../../common_elements.dart' show CommonElements, ElementEnvironment;
 import '../../deferred_load.dart' show OutputUnit, OutputUnitData;
 import '../../elements/entities.dart';
-import '../../elements/entity_utils.dart' as utils;
-import '../../elements/types.dart';
-import '../../elements/names.dart';
 import '../../hash/sha1.dart' show Hasher;
 import '../../io/code_output.dart';
 import '../../io/location_provider.dart' show LocationCollector;
@@ -28,15 +24,9 @@
 import '../../js/js.dart' as jsAst;
 import '../../js/js.dart' show js;
 import '../../js_backend/js_backend.dart'
-    show
-        ConstantEmitter,
-        JavaScriptBackend,
-        Namer,
-        SetterName,
-        TypeVariableCodegenAnalysis;
+    show ConstantEmitter, JavaScriptBackend, Namer;
 import '../../js_backend/native_data.dart';
 import '../../universe/call_structure.dart' show CallStructure;
-import '../../universe/selector.dart' show Selector;
 import '../../universe/world_builder.dart' show CodegenWorldBuilder;
 import '../../util/uri_extras.dart' show relativize;
 import '../../world.dart' show ClosedWorld;
@@ -90,7 +80,6 @@
   // collector.
   Map<OutputUnit, List<FieldEntity>> outputStaticNonFinalFieldLists;
   Map<OutputUnit, Set<LibraryEntity>> outputLibraryLists;
-  List<TypedefEntity> typedefsNeededForReflection;
 
   final ContainerBuilder containerBuilder;
   final ClassEmitter classEmitter;
@@ -124,15 +113,8 @@
   Map<OutputUnit, CodeOutput> outputBuffers = new Map<OutputUnit, CodeOutput>();
 
   String classesCollector;
-  final Map<jsAst.Name, String> mangledFieldNames =
-      new HashMap<jsAst.Name, String>();
-  final Map<jsAst.Name, String> mangledGlobalFieldNames =
-      new HashMap<jsAst.Name, String>();
-  final Set<jsAst.Name> recordedMangledNames = new Set<jsAst.Name>();
 
   JavaScriptBackend get backend => compiler.backend;
-  TypeVariableCodegenAnalysis get typeVariableCodegenAnalysis =>
-      backend.typeVariableCodegenAnalysis;
 
   String get _ => space;
   String get space => compiler.options.enableMinification ? "" : " ";
@@ -416,156 +398,17 @@
   /// An anonymous mixin application has no reflection name.
   ///
   /// This is used by js_mirrors.dart.
+  // TODO(johnniwinther): Do we still need this when js_mirrors is deleted?
   String getReflectionClassName(ClassEntity cls, jsAst.Name mangledName) {
-    String name = cls.name;
-    if (backend.mirrorsData.shouldRetainName(name) ||
-        // Make sure to retain names of common native types.
-        _isNativeTypeNeedingReflectionName(cls)) {
-      // TODO(ahe): Enable the next line when I can tell the difference between
-      // an instance method and a global.  They may have the same mangled name.
-      // if (recordedMangledNames.contains(mangledName)) return null;
-      recordedMangledNames.add(mangledName);
-      if (cls.isClosure) {
-        // Closures are synthesized and their name might conflict with existing
-        // globals. Assign an illegal name, and make sure they don't clash
-        // with each other.
-        return " $name";
-      }
-      if (_elementEnvironment.isUnnamedMixinApplication(cls)) return null;
+    // Make sure to retain names of common native types.
+    if (_isNativeTypeNeedingReflectionName(cls)) {
+      assert(!cls.isClosure);
+      assert(!_elementEnvironment.isUnnamedMixinApplication(cls));
       return cls.name;
     }
     return null;
   }
 
-  /// Returns the "reflection name" of a [MemberEntity], if needed.
-  ///
-  /// The reflection name of a getter 'foo' is 'foo'.
-  /// The reflection name of a setter 'foo' is 'foo='.
-  /// The reflection name of a method 'foo' is 'foo:N:M:O', where N is the
-  /// number of required arguments, M is the number of optional arguments, and
-  /// O is the named arguments.
-  /// The reflection name of a constructor is similar to a regular method but
-  /// starts with 'new '.
-  ///
-  /// This is used by js_mirrors.dart.
-  String getReflectionMemberName(MemberEntity member, jsAst.Name mangledName) {
-    String name = member.name;
-    if (backend.mirrorsData.shouldRetainName(name) ||
-        // Make sure to retain names of unnamed constructors.
-        (name == '' &&
-            backend.mirrorsData.isMemberAccessibleByReflection(member))) {
-      // TODO(ahe): Enable the next line when I can tell the difference between
-      // an instance method and a global.  They may have the same mangled name.
-      // if (recordedMangledNames.contains(mangledName)) return null;
-      recordedMangledNames.add(mangledName);
-      return getReflectionMemberNameInternal(member, mangledName);
-    }
-    return null;
-  }
-
-  String getReflectionMemberNameInternal(
-      MemberEntity member, jsAst.Name mangledName) {
-    if (member is ConstructorBodyEntity) {
-      return null;
-    }
-    if (member.isGetter) {
-      return _getReflectionGetterName(member.memberName);
-    } else if (member.isSetter) {
-      return _getReflectionSetterName(member.memberName, mangledName);
-    } else if (member.isConstructor) {
-      ConstructorEntity constructor = member;
-      String name = utils.reconstructConstructorName(constructor);
-      return _getReflectionCallStructureName(
-          name, constructor.parameterStructure.callStructure);
-    } else if (member.isFunction) {
-      FunctionEntity function = member;
-      return _getReflectionFunctionName(
-          member.memberName, function.parameterStructure.callStructure);
-    }
-    throw reporter.internalError(
-        member, 'Do not know how to reflect on this $member.');
-  }
-
-  /// Returns the "reflection name" of a [Selector], if needed.
-  ///
-  /// The reflection name of a getter 'foo' is 'foo'.
-  /// The reflection name of a setter 'foo' is 'foo='.
-  /// The reflection name of a method 'foo' is 'foo:N:M:O', where N is the
-  /// number of required arguments, M is the number of optional arguments, and
-  /// O is the named arguments.
-  ///
-  /// This is used by js_mirrors.dart.
-  String getReflectionSelectorName(Selector selector, jsAst.Name mangledName) {
-    String name = selector.name;
-    if (backend.mirrorsData.shouldRetainName(name)) {
-      // TODO(ahe): Enable the next line when I can tell the difference between
-      // an instance method and a global.  They may have the same mangled name.
-      // if (recordedMangledNames.contains(mangledName)) return null;
-      recordedMangledNames.add(mangledName);
-      if (selector.isGetter) {
-        return _getReflectionGetterName(selector.memberName);
-      } else if (selector.isSetter) {
-        return _getReflectionSetterName(selector.memberName, mangledName);
-      } else {
-        return _getReflectionFunctionName(
-            selector.memberName, selector.callStructure);
-      }
-    }
-    return null;
-  }
-
-  /// Returns the "reflection name" of a [TypedefEntity], if needed.
-  ///
-  /// The reflection name of typedef 'F' is 'F'.
-  ///
-  /// This is used by js_mirrors.dart.
-  String getReflectionTypedefName(
-      TypedefEntity typedef, jsAst.Name mangledName) {
-    String name = typedef.name;
-    if (backend.mirrorsData.shouldRetainName(name)) {
-      // TODO(ahe): Enable the next line when I can tell the difference between
-      // an instance method and a global.  They may have the same mangled name.
-      // if (recordedMangledNames.contains(mangledName)) return null;
-      recordedMangledNames.add(mangledName);
-      return typedef.name;
-    }
-    return null;
-  }
-
-  String _getReflectionGetterName(Name memberName) {
-    return namer.privateName(memberName);
-  }
-
-  String _getReflectionSetterName(Name memberName, jsAst.Name mangledName) {
-    String name = namer.privateName(memberName);
-    if (mangledName is! SetterName) return '$name=';
-    SetterName setterName = mangledName;
-    jsAst.Name base = setterName.base;
-    jsAst.Name getter = namer.deriveGetterName(base);
-    mangledFieldNames.putIfAbsent(getter, () => name);
-    assert(mangledFieldNames[getter] == name);
-    recordedMangledNames.add(getter);
-    // TODO(karlklose,ahe): we do not actually need to store information
-    // about the name of this setter in the output, but it is needed for
-    // marking the function as invokable by reflection.
-    return '$name=';
-  }
-
-  String _getReflectionFunctionName(
-      Name memberName, CallStructure callStructure) {
-    String name = namer.privateName(memberName);
-    return _getReflectionCallStructureName(name, callStructure);
-  }
-
-  String _getReflectionCallStructureName(
-      String name, CallStructure callStructure,
-      {bool isConstructor: false}) {
-    int positionalParameterCount = callStructure.positionalArgumentCount;
-    String namedArguments = namedParametersAsReflectionNames(callStructure);
-    String suffix = '$name:$positionalParameterCount$namedArguments';
-    return isConstructor ? 'new $suffix' : suffix;
-  }
-
   String namedParametersAsReflectionNames(CallStructure structure) {
     if (structure.isUnnamed) return '';
     String names = structure.getOrderedNamedArguments().join(':');
@@ -810,8 +653,6 @@
   }
 
   buildMain(jsAst.Statement invokeMain) {
-    if (compiler.isMockCompilation) return js.comment("Mock compilation");
-
     List<jsAst.Statement> parts = <jsAst.Statement>[];
 
     if (NativeGenerator
@@ -1057,13 +898,11 @@
       }
     }
 
-    String libraryName = (!compiler.options.enableMinification ||
-            backend.mirrorsData.mustRetainLibraryNames)
+    String libraryName = !compiler.options.enableMinification
         ? _elementEnvironment.getLibraryName(library)
         : "";
 
-    jsAst.Fun metadata =
-        task.metadataCollector.buildLibraryMetadataFunction(library);
+    jsAst.Fun metadata = null;
 
     ClassBuilder descriptor = libraryDescriptors[fragment][library];
 
@@ -1120,47 +959,6 @@
     cspPrecompiledConstructorNamesFor(outputUnit).add(js('#', constructorName));
   }
 
-  void assembleTypedefs(Program program) {
-    Fragment mainFragment = program.mainFragment;
-    OutputUnit mainOutputUnit = mainFragment.outputUnit;
-
-    // Emit all required typedef declarations into the main output unit.
-    // TODO(karlklose): unify required classes and typedefs to declarations
-    // and have builders for each kind.
-    for (TypedefEntity typedef in typedefsNeededForReflection) {
-      LibraryEntity library = typedef.library;
-      // TODO(karlklose): add a TypedefBuilder and move this code there.
-      FunctionType type = _elementEnvironment.getFunctionTypeOfTypedef(typedef);
-      // TODO(zarah): reify type variables once reflection on type arguments of
-      // typedefs is supported.
-      jsAst.Expression typeIndex = task.metadataCollector
-          .reifyType(type, mainOutputUnit, ignoreTypeVariables: true);
-      ClassBuilder builder = new ClassBuilder.forStatics(typedef, namer);
-      builder.addPropertyByName(
-          embeddedNames.TYPEDEF_TYPE_PROPERTY_NAME, typeIndex);
-      builder.addPropertyByName(
-          embeddedNames.TYPEDEF_PREDICATE_PROPERTY_NAME, js.boolean(true));
-
-      // We can be pretty sure that the objectClass is initialized, since
-      // typedefs are only emitted with reflection, which requires lots of
-      // classes.
-      assert(commonElements.objectClass != null);
-      builder.superName = namer.className(commonElements.objectClass);
-      jsAst.Node declaration = builder.toObjectInitializer();
-      jsAst.Name mangledName = namer.globalPropertyNameForType(typedef);
-      String reflectionName = getReflectionTypedefName(typedef, mangledName);
-      getLibraryDescriptor(library, mainFragment)
-        ..addProperty(mangledName, declaration)
-        ..addPropertyByName("+$reflectionName", js.string(''));
-      // Also emit a trivial constructor for CSP mode.
-      jsAst.Name constructorName = mangledName;
-      jsAst.Expression constructorAst = js('function() {}');
-      List<jsAst.Name> fieldNames = [];
-      assemblePrecompiledConstructor(
-          mainOutputUnit, constructorName, constructorAst, fieldNames);
-    }
-  }
-
   jsAst.Statement buildGlobalObjectSetup(bool isProgramSplit) {
     List<jsAst.Statement> parts = <jsAst.Statement>[];
 
@@ -1246,39 +1044,6 @@
     return new jsAst.Block(parts);
   }
 
-  jsAst.Statement buildMangledNames() {
-    List<jsAst.Statement> parts = <jsAst.Statement>[];
-
-    if (!mangledFieldNames.isEmpty) {
-      List<jsAst.Name> keys = mangledFieldNames.keys.toList()..sort();
-      var properties = [];
-      for (jsAst.Name key in keys) {
-        var value = js.string(mangledFieldNames[key]);
-        properties.add(new jsAst.Property(key, value));
-      }
-
-      jsAst.Expression mangledNamesAccess =
-          generateEmbeddedGlobalAccess(embeddedNames.MANGLED_NAMES);
-      var map = new jsAst.ObjectInitializer(properties);
-      parts.add(js.statement('# = #', [mangledNamesAccess, map]));
-    }
-
-    if (!mangledGlobalFieldNames.isEmpty) {
-      List<jsAst.Name> keys = mangledGlobalFieldNames.keys.toList()..sort();
-      List<jsAst.Property> properties = <jsAst.Property>[];
-      for (jsAst.Name key in keys) {
-        jsAst.Literal value = js.string(mangledGlobalFieldNames[key]);
-        properties.add(new jsAst.Property(js.quoteName(key), value));
-      }
-      jsAst.Expression mangledGlobalNamesAccess =
-          generateEmbeddedGlobalAccess(embeddedNames.MANGLED_GLOBAL_NAMES);
-      jsAst.ObjectInitializer map = new jsAst.ObjectInitializer(properties);
-      parts.add(js.statement('# = #', [mangledGlobalNamesAccess, map]));
-    }
-
-    return new jsAst.Block(parts);
-  }
-
   void checkEverythingEmitted(
       Map<ClassEntity, ClassBuilder> pendingClassBuilders) {
     if (pendingClassBuilders == null) return;
@@ -1314,7 +1079,6 @@
         assembleLibrary(library, fragment);
       }
     }
-    assembleTypedefs(program);
   }
 
   jsAst.Statement buildDeferredHeader() {
@@ -1410,8 +1174,6 @@
 
        init();
 
-       #mangledNames;
-
        #cspPrecompiledFunctions;
 
        #setupProgram;
@@ -1479,7 +1241,6 @@
       "isolatePropertiesName": js(isolatePropertiesName),
       "initName": initName,
       "functionThatReturnsNull": buildFunctionThatReturnsNull(),
-      "mangledNames": buildMangledNames(),
       "setupProgram": buildSetupProgram(
           program, compiler, backend, namer, this, _closedWorld),
       "setupProgramName": setupProgramName,
@@ -1598,8 +1359,6 @@
     outputStaticNonFinalFieldLists =
         programBuilder.collector.outputStaticNonFinalFieldLists;
     outputLibraryLists = programBuilder.collector.outputLibraryLists;
-    typedefsNeededForReflection =
-        programBuilder.collector.typedefsNeededForReflection;
 
     assembleProgram(program);
 
diff --git a/pkg/compiler/lib/src/js_emitter/full_emitter/nsm_emitter.dart b/pkg/compiler/lib/src/js_emitter/full_emitter/nsm_emitter.dart
index 9e194b88..48af9c9 100644
--- a/pkg/compiler/lib/src/js_emitter/full_emitter/nsm_emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/full_emitter/nsm_emitter.dart
@@ -51,33 +51,18 @@
     List<jsAst.Name> names = addedJsNames.keys.toList()..sort();
     for (jsAst.Name jsName in names) {
       Selector selector = addedJsNames[jsName];
-      String reflectionName =
-          emitter.getReflectionSelectorName(selector, jsName);
-
-      if (reflectionName != null) {
-        emitter.mangledFieldNames[jsName] = reflectionName;
-      }
-
       List<jsAst.Expression> argNames = selector.callStructure
           .getOrderedNamedArguments()
           .map((String name) => js.string(name))
           .toList();
       int type = selector.invocationMirrorKind;
       if (!haveVeryFewNoSuchMemberHandlers &&
-          isTrivialNsmHandler(type, argNames, selector, jsName) &&
-          reflectionName == null) {
+          isTrivialNsmHandler(type, argNames, selector, jsName)) {
         trivialNsmHandlers.add(selector);
       } else {
         StubMethod method =
             generator.generateStubForNoSuchMethod(jsName, selector);
         addProperty(method.name, method.code);
-        if (reflectionName != null) {
-          bool accessible = closedWorld
-              .locateMembers(selector, null)
-              .any(backend.mirrorsData.isMemberAccessibleByReflection);
-          addProperty(
-              namer.asName('+$reflectionName'), js(accessible ? '2' : '0'));
-        }
       }
     }
   }
diff --git a/pkg/compiler/lib/src/js_emitter/full_emitter/setup_program_builder.dart b/pkg/compiler/lib/src/js_emitter/full_emitter/setup_program_builder.dart
index b8df5d2..f5a6d47 100644
--- a/pkg/compiler/lib/src/js_emitter/full_emitter/setup_program_builder.dart
+++ b/pkg/compiler/lib/src/js_emitter/full_emitter/setup_program_builder.dart
@@ -65,10 +65,8 @@
   String defaultValuesField = namer.defaultValuesField;
   String methodsWithOptionalArgumentsField =
       namer.methodsWithOptionalArgumentsField;
-  bool retainMetadata = backend.mirrorsData.mustRetainMetadata;
-  String unmangledNameIndex = retainMetadata
-      ? ' 3 * optionalParameterCount + 2 * requiredParameterCount + 3'
-      : ' 2 * optionalParameterCount + requiredParameterCount + 3';
+  String unmangledNameIndex =
+      ' 2 * optionalParameterCount + requiredParameterCount + 3';
   String receiverParamName =
       compiler.options.enableMinification ? "r" : "receiver";
   String valueParamName = compiler.options.enableMinification ? "v" : "value";
@@ -104,7 +102,6 @@
     'deferredAction': namer.deferredAction,
     'allClasses': allClassesAccess,
     'debugFastObjects': DEBUG_FAST_OBJECTS,
-    'isTreeShakingDisabled': backend.mirrorsData.isTreeShakingDisabled,
     'precompiled': precompiledAccess,
     'finishedClassesAccess': finishedClassesAccess,
     'needsMixinSupport': emitter.needsMixinSupport,
@@ -116,7 +113,6 @@
     'isObject': namer.operatorIs(closedWorld.commonElements.objectClass),
     'specProperty': js.string(namer.nativeSpecProperty),
     'trivialNsmHandlers': emitter.buildTrivialNsmHandlers(),
-    'hasRetainedMetadata': backend.mirrorsData.hasRetainedMetadata,
     'types': typesAccess,
     'objectClassName': js.quoteName(
         namer.runtimeTypeName(closedWorld.commonElements.objectClass)),
@@ -309,8 +305,6 @@
         var desc = processedClasses.collected[cls];
         var globalObject = desc[0];
         desc = desc[1];
-        if (#isTreeShakingDisabled)
-          constructor["${namer.metadataField}"] = desc;
         allClasses[cls] = constructor;
         globalObject[cls] = constructor;
       }
@@ -520,11 +514,6 @@
       var classData = descriptor["${namer.classDescriptorProperty}"],
           split, supr, fields = classData;
 
-      if (#hasRetainedMetadata)
-        if (typeof classData == "object" &&
-            classData instanceof Array) {
-          classData = fields = classData[0];
-        }
       // ${ClassBuilder.fieldEncodingDescription}.
       var s = fields.split(";");
       fields = s[1] ? s[1].split(",") : [];
@@ -664,14 +653,6 @@
           ${readInt("array", "position")} =
               ${readInt("array", "position")} + metadataOffset;
           position++;
-          if ($retainMetadata) {
-            var metaArray = ${readInt("array", "position")};
-            for (var j = 0; j < metaArray.length; j++) {
-              ${readInt("metaArray", "j")} =
-                ${readInt("metaArray", "j")} + metadataOffset;
-            }
-            position++;
-          }
         }
       }
       var unmangledNameIndex = $unmangledNameIndex;
diff --git a/pkg/compiler/lib/src/js_emitter/metadata_collector.dart b/pkg/compiler/lib/src/js_emitter/metadata_collector.dart
index ef1ffd3..b0e6d88 100644
--- a/pkg/compiler/lib/src/js_emitter/metadata_collector.dart
+++ b/pkg/compiler/lib/src/js_emitter/metadata_collector.dart
@@ -9,30 +9,13 @@
 import '../common.dart';
 import '../constants/values.dart';
 import '../deferred_load.dart' show OutputUnit;
-import '../elements/elements.dart'
-    show
-        ClassElement,
-        ConstructorElement,
-        Element,
-        FieldElement,
-        FunctionSignature,
-        LibraryElement,
-        MemberElement,
-        MethodElement,
-        MetadataAnnotation,
-        ParameterElement;
 import '../elements/entities.dart' show FunctionEntity;
 
 import '../elements/entities.dart';
-import '../elements/resolution_types.dart' show ResolutionTypedefType;
 import '../elements/types.dart';
 import '../js/js.dart' as jsAst;
 import '../js/js.dart' show js;
-import '../js_backend/constant_handler_javascript.dart';
-import '../js_backend/mirrors_data.dart';
 import '../js_backend/runtime_types.dart' show RuntimeTypesEncoder;
-import '../js_backend/type_variable_handler.dart'
-    show TypeVariableCodegenAnalysis;
 import '../options.dart';
 import '../universe/world_builder.dart' show CodegenWorldBuilder;
 
@@ -84,43 +67,6 @@
   int compareTo(covariant _MetadataEntry other) => other._rc - this._rc;
 }
 
-abstract class Placeholder implements jsAst.DeferredNumber {
-  bind(_MetadataEntry entry);
-}
-
-class _ForwardingMetadataEntry extends _MetadataEntry implements Placeholder {
-  _MetadataEntry _forwardTo;
-  var debug;
-
-  bool get isBound => _forwardTo != null;
-
-  _ForwardingMetadataEntry([this.debug]);
-
-  _MetadataEntry get forwardTo {
-    assert(isBound, 'unbound $this $debug');
-    return _forwardTo;
-  }
-
-  jsAst.Expression get entry {
-    return forwardTo.entry;
-  }
-
-  int get value {
-    return forwardTo.value;
-  }
-
-  int get _rc => forwardTo._rc;
-
-  markSeen(jsAst.BaseVisitor visitor) => forwardTo.markSeen(visitor);
-
-  int compareTo(other) => forwardTo.compareTo(other);
-
-  bind(_MetadataEntry entry) {
-    assert(!isBound);
-    _forwardTo = entry;
-  }
-}
-
 class _MetadataList extends jsAst.DeferredExpression {
   jsAst.Expression _value;
 
@@ -142,9 +88,6 @@
   final CompilerOptions _options;
   final DiagnosticReporter reporter;
   final Emitter _emitter;
-  final JavaScriptConstantCompiler _constants;
-  final TypeVariableCodegenAnalysis _typeVariableCodegenAnalysis;
-  final MirrorsData _mirrorsData;
   final RuntimeTypesEncoder _rtiEncoder;
   final CodegenWorldBuilder _codegenWorldBuilder;
 
@@ -175,80 +118,12 @@
   Map<OutputUnit, Map<DartType, _BoundMetadataEntry>> _typesMap =
       <OutputUnit, Map<DartType, _BoundMetadataEntry>>{};
 
-  MetadataCollector(
-      this._options,
-      this.reporter,
-      this._emitter,
-      this._constants,
-      this._typeVariableCodegenAnalysis,
-      this._mirrorsData,
-      this._rtiEncoder,
-      this._codegenWorldBuilder);
-
-  jsAst.Fun buildLibraryMetadataFunction(LibraryEntity element) {
-    if (!_mirrorsData.mustRetainMetadata ||
-        !_mirrorsData.isLibraryReferencedFromMirrorSystem(element)) {
-      return null;
-    }
-    return _buildMetadataFunction(element as LibraryElement);
-  }
-
-  jsAst.Fun buildClassMetadataFunction(ClassEntity cls) {
-    if (!_mirrorsData.mustRetainMetadata ||
-        !_mirrorsData.isClassReferencedFromMirrorSystem(cls)) {
-      return null;
-    }
-    // TODO(redemption): Handle class entities.
-    ClassElement element = cls;
-    return _buildMetadataFunction(element);
-  }
-
-  bool _mustEmitMetadataForMember(MemberEntity member) {
-    if (!_mirrorsData.mustRetainMetadata) {
-      return false;
-    }
-    // TODO(redemption): Handle member entities.
-    MemberElement element = member;
-    return _mirrorsData.isMemberReferencedFromMirrorSystem(element);
-  }
-
-  jsAst.Fun buildFieldMetadataFunction(FieldEntity field) {
-    if (!_mustEmitMetadataForMember(field)) return null;
-    // TODO(redemption): Handle field entities.
-    FieldElement element = field;
-    return _buildMetadataFunction(element);
-  }
-
-  /// The metadata function returns the metadata associated with
-  /// [element] in generated code.  The metadata needs to be wrapped
-  /// in a function as it refers to constants that may not have been
-  /// constructed yet.  For example, a class is allowed to be
-  /// annotated with itself.  The metadata function is used by
-  /// mirrors_patch to implement DeclarationMirror.metadata.
-  jsAst.Fun _buildMetadataFunction(Element element) {
-    return reporter.withCurrentElement(element, () {
-      List<jsAst.Expression> metadata = <jsAst.Expression>[];
-      for (MetadataAnnotation annotation in element.metadata) {
-        ConstantValue constant =
-            _constants.getConstantValueForMetadata(annotation);
-        if (constant == null) {
-          reporter.internalError(annotation, 'Annotation value is null.');
-        } else {
-          metadata.add(_emitter.constantReference(constant));
-        }
-      }
-      if (metadata.isEmpty) return null;
-      return js(
-          'function() { return # }', new jsAst.ArrayInitializer(metadata));
-    });
-  }
+  MetadataCollector(this._options, this.reporter, this._emitter,
+      this._rtiEncoder, this._codegenWorldBuilder);
 
   List<jsAst.DeferredNumber> reifyDefaultArguments(
       FunctionEntity function, OutputUnit outputUnit) {
     // TODO(sra): These are stored on the InstanceMethod or StaticDartMethod.
-    if (function is MethodElement)
-      return reifyDefaultArgumentsAst(function, outputUnit);
-
     List<jsAst.DeferredNumber> defaultValues = <jsAst.DeferredNumber>[];
     _codegenWorldBuilder.forEachParameter(function,
         (_, String name, ConstantValue constant) {
@@ -259,100 +134,8 @@
     return defaultValues;
   }
 
-  List<jsAst.DeferredNumber> reifyDefaultArgumentsAst(
-      MethodElement function, OutputUnit outputUnit) {
-    function = function.implementation;
-    FunctionSignature signature = function.functionSignature;
-    if (signature.optionalParameterCount == 0) return const [];
-
-    // Optional parameters of redirecting factory constructors take their
-    // defaults from the corresponding parameters of the redirection target.
-    Map<ParameterElement, ParameterElement> targetParameterMap;
-    if (function is ConstructorElement) {
-      // TODO(sra): dart2js generates a redirecting factory constructor body
-      // that has the signature of the redirecting constructor that calls the
-      // redirection target. This is wrong - it should have the signature of the
-      // target. This would make the reified default arguments trivial.
-
-      ConstructorElement constructor = function;
-      while (constructor.isRedirectingFactory &&
-          !constructor.isCyclicRedirection) {
-        // TODO(sra): Remove the loop once effectiveTarget forwards to patches.
-        constructor = constructor.effectiveTarget.implementation;
-      }
-
-      if (constructor != function) {
-        if (signature.hasOptionalParameters) {
-          targetParameterMap =
-              mapRedirectingFactoryConstructorOptionalParameters(
-                  signature, constructor.functionSignature);
-        }
-      }
-    }
-
-    List<jsAst.DeferredNumber> defaultValues = <jsAst.DeferredNumber>[];
-    for (ParameterElement element in signature.optionalParameters) {
-      ParameterElement parameter =
-          (targetParameterMap == null) ? element : targetParameterMap[element];
-      ConstantValue constant = (parameter == null)
-          ? null
-          : _constants.getConstantValue(parameter.constant);
-      jsAst.Expression expression = (constant == null)
-          ? new jsAst.LiteralNull()
-          : _emitter.constantReference(constant);
-      defaultValues.add(_addGlobalMetadata(expression, outputUnit));
-    }
-    return defaultValues;
-  }
-
-  Map<ParameterElement, ParameterElement>
-      mapRedirectingFactoryConstructorOptionalParameters(
-          FunctionSignature source, FunctionSignature target) {
-    var map = <ParameterElement, ParameterElement>{};
-
-    if (source.optionalParametersAreNamed !=
-        target.optionalParametersAreNamed) {
-      // No legal optional arguments due to mismatch between named vs positional
-      // optional arguments.
-      return map;
-    }
-
-    if (source.optionalParametersAreNamed) {
-      for (ParameterElement element in source.optionalParameters) {
-        for (ParameterElement redirectedElement in target.optionalParameters) {
-          if (element.name == redirectedElement.name) {
-            map[element] = redirectedElement;
-            break;
-          }
-        }
-      }
-    } else {
-      int i = source.requiredParameterCount;
-      for (ParameterElement element in source.orderedOptionalParameters) {
-        if (i >= target.requiredParameterCount && i < target.parameterCount) {
-          map[element] = target
-              .orderedOptionalParameters[i - target.requiredParameterCount];
-        }
-        ++i;
-      }
-    }
-    return map;
-  }
-
-  jsAst.Expression reifyMetadata(
-      MetadataAnnotation annotation, OutputUnit outputUnit) {
-    ConstantValue constant = _constants.getConstantValueForMetadata(annotation);
-    if (constant == null) {
-      reporter.internalError(annotation, 'Annotation value is null.');
-      return null;
-    }
-    return _addGlobalMetadata(_emitter.constantReference(constant), outputUnit);
-  }
-
-  jsAst.Expression reifyType(DartType type, OutputUnit outputUnit,
-      {ignoreTypeVariables: false}) {
-    return addTypeInOutputUnit(type, outputUnit,
-        ignoreTypeVariables: ignoreTypeVariables);
+  jsAst.Expression reifyType(DartType type, OutputUnit outputUnit) {
+    return addTypeInOutputUnit(type, outputUnit);
   }
 
   jsAst.Expression reifyName(String name, OutputUnit outputUnit) {
@@ -364,10 +147,6 @@
     return _addGlobalMetadata(expression, outputUnit);
   }
 
-  Placeholder getMetadataPlaceholder([debug]) {
-    return new _ForwardingMetadataEntry(debug);
-  }
-
   _MetadataEntry _addGlobalMetadata(jsAst.Node node, OutputUnit outputUnit) {
     String nameToKey(jsAst.Name name) => "${name.key}";
     String printed = jsAst.prettyPrint(node,
@@ -379,14 +158,16 @@
     });
   }
 
-  jsAst.Expression _computeTypeRepresentation(DartType type,
-      {ignoreTypeVariables: false}) {
+  jsAst.Expression _computeTypeRepresentation(DartType type) {
     jsAst.Expression representation =
         _rtiEncoder.getTypeRepresentation(_emitter, type, (variable) {
-      if (ignoreTypeVariables) return new jsAst.LiteralNull();
-      return _typeVariableCodegenAnalysis.reifyTypeVariable(variable.element);
-    }, (ResolutionTypedefType typedef) {
-      return _mirrorsData.isTypedefAccessibleByReflection(typedef.element);
+      failedAt(
+          NO_LOCATION_SPANNABLE,
+          "Type representation for type variable $variable in "
+          "$type is not supported.");
+      return jsAst.LiteralNull();
+    }, (TypedefType typedef) {
+      return false;
     });
 
     if (representation is jsAst.LiteralString) {
@@ -399,41 +180,15 @@
     return representation;
   }
 
-  jsAst.Expression addTypeInOutputUnit(DartType type, OutputUnit outputUnit,
-      {ignoreTypeVariables: false}) {
+  jsAst.Expression addTypeInOutputUnit(DartType type, OutputUnit outputUnit) {
     _typesMap[outputUnit] ??= new Map<DartType, _BoundMetadataEntry>();
     return _typesMap[outputUnit].putIfAbsent(type, () {
-      return new _BoundMetadataEntry(_computeTypeRepresentation(type,
-          ignoreTypeVariables: ignoreTypeVariables));
-    });
-  }
-
-  List<jsAst.DeferredNumber> computeMetadata(
-      MethodElement element, OutputUnit outputUnit) {
-    return reporter.withCurrentElement(element, () {
-      if (!_mustEmitMetadataForMember(element))
-        return const <jsAst.DeferredNumber>[];
-      List<jsAst.DeferredNumber> metadata = <jsAst.DeferredNumber>[];
-      for (MetadataAnnotation annotation in element.metadata) {
-        metadata.add(reifyMetadata(annotation, outputUnit));
-      }
-      return metadata;
+      return new _BoundMetadataEntry(_computeTypeRepresentation(type));
     });
   }
 
   @override
   void finalizeTokens() {
-    bool checkTokensInTypes(OutputUnit outputUnit, entries) {
-      UnBoundDebugger debugger = new UnBoundDebugger(outputUnit);
-      for (_BoundMetadataEntry entry in entries) {
-        if (!entry.isUsed) continue;
-        if (debugger.findUnboundPlaceholders(entry.entry)) {
-          return false;
-        }
-      }
-      return true;
-    }
-
     void countTokensInTypes(Iterable<_BoundMetadataEntry> entries) {
       jsAst.TokenCounter counter = new jsAst.TokenCounter();
       entries
@@ -472,7 +227,6 @@
     _typesTokens.forEach((OutputUnit outputUnit, _MetadataList token) {
       Map typesMap = _typesMap[outputUnit];
       if (typesMap != null) {
-        assert(checkTokensInTypes(outputUnit, typesMap.values));
         countTokensInTypes(typesMap.values);
         token.setExpression(finalizeMap(typesMap));
       } else {
@@ -481,22 +235,3 @@
     });
   }
 }
-
-class UnBoundDebugger extends jsAst.BaseVisitor {
-  OutputUnit outputUnit;
-  bool _foundUnboundToken = false;
-
-  UnBoundDebugger(this.outputUnit);
-
-  @override
-  visitDeferredNumber(jsAst.DeferredNumber token) {
-    if (token is _ForwardingMetadataEntry && !token.isBound) {
-      _foundUnboundToken = true;
-    }
-  }
-
-  bool findUnboundPlaceholders(jsAst.Node node) {
-    node.accept(this);
-    return _foundUnboundToken;
-  }
-}
diff --git a/pkg/compiler/lib/src/js_emitter/model.dart b/pkg/compiler/lib/src/js_emitter/model.dart
index a66b830..3938cfb 100644
--- a/pkg/compiler/lib/src/js_emitter/model.dart
+++ b/pkg/compiler/lib/src/js_emitter/model.dart
@@ -21,11 +21,6 @@
   /// A map from load id to the list of fragments that need to be loaded.
   final Map<String, List<Fragment>> loadMap;
 
-  /// A map from names to strings.
-  ///
-  /// This map is needed to support `const Symbol` expressions;
-  final Map<js.Name, String> symbolsMap;
-
   // If this field is not `null` then its value must be emitted in the embedded
   // global `TYPE_TO_INTERCEPTOR_MAP`. The map references constants and classes.
   final js.Expression typeToInterceptorMap;
@@ -35,8 +30,8 @@
   final MetadataCollector _metadataCollector;
   final Iterable<js.TokenFinalizer> finalizers;
 
-  Program(this.fragments, this.holders, this.loadMap, this.symbolsMap,
-      this.typeToInterceptorMap, this._metadataCollector, this.finalizers,
+  Program(this.fragments, this.holders, this.loadMap, this.typeToInterceptorMap,
+      this._metadataCollector, this.finalizers,
       {this.needsNativeSupport,
       this.outputContainsConstantList,
       this.hasSoftDeferredClasses}) {
@@ -430,9 +425,8 @@
   final js.Name tearOffName;
   final List<ParameterStubMethod> parameterStubs;
   final bool canBeApplied;
-  final bool canBeReflected;
 
-  // Is non-null if [needsTearOff] or [canBeReflected].
+  // Is non-null if [needsTearOff].
   //
   // If the type is encoded in the metadata table this field contains an index
   // into the table. Otherwise the type contains type variables in which case
@@ -440,7 +434,7 @@
   final js.Expression functionType;
 
   // Signature information for this method. This is only required and stored
-  // here if the method [canBeApplied] or [canBeReflected]
+  // here if the method [canBeApplied].
   final int requiredParameterCount;
   final /* Map | List */ optionalParameterDefaultValues;
 
@@ -454,7 +448,6 @@
       {this.needsTearOff,
       this.tearOffName,
       this.canBeApplied,
-      this.canBeReflected,
       this.requiredParameterCount,
       this.optionalParameterDefaultValues,
       this.functionType})
@@ -462,8 +455,7 @@
     assert(needsTearOff != null);
     assert(!needsTearOff || tearOffName != null);
     assert(canBeApplied != null);
-    assert(canBeReflected != null);
-    assert((!canBeReflected && !canBeApplied) ||
+    assert(!canBeApplied ||
         (requiredParameterCount != null &&
             optionalParameterDefaultValues != null));
   }
@@ -492,7 +484,6 @@
       js.Name tearOffName,
       this.aliasName,
       bool canBeApplied,
-      bool canBeReflected,
       int requiredParameterCount,
       /* List | Map */ optionalParameterDefaultValues,
       this.isClosureCallMethod,
@@ -502,7 +493,6 @@
             needsTearOff: needsTearOff,
             tearOffName: tearOffName,
             canBeApplied: canBeApplied,
-            canBeReflected: canBeReflected,
             requiredParameterCount: requiredParameterCount,
             optionalParameterDefaultValues: optionalParameterDefaultValues,
             functionType: functionType) {
@@ -573,7 +563,6 @@
       {bool needsTearOff,
       js.Name tearOffName,
       bool canBeApplied,
-      bool canBeReflected,
       int requiredParameterCount,
       /* List | Map */ optionalParameterDefaultValues,
       js.Expression functionType})
@@ -581,7 +570,6 @@
             needsTearOff: needsTearOff,
             tearOffName: tearOffName,
             canBeApplied: canBeApplied,
-            canBeReflected: canBeReflected,
             requiredParameterCount: requiredParameterCount,
             optionalParameterDefaultValues: optionalParameterDefaultValues,
             functionType: functionType);
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 84f2502..187729f 100644
--- a/pkg/compiler/lib/src/js_emitter/parameter_stub_generator.dart
+++ b/pkg/compiler/lib/src/js_emitter/parameter_stub_generator.dart
@@ -318,6 +318,33 @@
           stubs.add(stub);
         }
       }
+
+      // A generic method might need to support `call<T>(x)` for a generic
+      // instantiation stub without `call<T>(x)` being in [callSelectors].
+      // [selector] will be `call(x)` (that already passes the appliesUnnamed
+      // check by defaulting type arguments), and the method will be generic.
+      //
+      // This is basically the same logic as above, but with type arguments.
+      if (selector.callStructure.typeArgumentCount == 0) {
+        ParameterStructure parameterStructure = member.parameterStructure;
+        if (parameterStructure.typeParameters > 0) {
+          Selector renamedSelectorWithTypeArguments = new Selector.call(
+              member.memberName,
+              selector.callStructure
+                  .withTypeArgumentCount(parameterStructure.typeParameters));
+          renamedCallSelectors.add(renamedSelectorWithTypeArguments);
+
+          if (stubSelectors.add(renamedSelectorWithTypeArguments)) {
+            Selector closureSelector =
+                new Selector.callClosureFrom(renamedSelectorWithTypeArguments);
+            ParameterStubMethod stub = generateParameterStub(
+                member, renamedSelectorWithTypeArguments, closureSelector);
+            if (stub != null) {
+              stubs.add(stub);
+            }
+          }
+        }
+      }
     }
 
     // Now run through the actual member selectors (eg. `foo$2(x, y)` and not
diff --git a/pkg/compiler/lib/src/js_emitter/program_builder/collector.dart b/pkg/compiler/lib/src/js_emitter/program_builder/collector.dart
index 7877cdb..615835e 100644
--- a/pkg/compiler/lib/src/js_emitter/program_builder/collector.dart
+++ b/pkg/compiler/lib/src/js_emitter/program_builder/collector.dart
@@ -23,7 +23,6 @@
   final NativeData _nativeData;
   final InterceptorData _interceptorData;
   final OneShotInterceptorData _oneShotInterceptorData;
-  final MirrorsData _mirrorsData;
   final ClosedWorld _closedWorld;
   final Set<ClassEntity> _rtiNeededClasses;
   final Map<MemberEntity, js.Expression> _generatedCode;
@@ -50,8 +49,6 @@
 
   final List<ClassEntity> nativeClassesAndSubclasses = <ClassEntity>[];
 
-  List<TypedefEntity> typedefsNeededForReflection;
-
   Collector(
       this._options,
       this._commonElements,
@@ -64,7 +61,6 @@
       this._nativeData,
       this._interceptorData,
       this._oneShotInterceptorData,
-      this._mirrorsData,
       this._closedWorld,
       this._rtiNeededClasses,
       this._generatedCode,
@@ -87,10 +83,6 @@
    * that needs to be emitted.
    */
   Function computeClassFilter(Iterable<ClassEntity> backendTypeHelpers) {
-    if (_mirrorsData.isTreeShakingDisabled) {
-      return (ClassEntity cls) => true;
-    }
-
     Set<ClassEntity> unneededClasses = new Set<ClassEntity>();
     // The [Bool] class is not marked as abstract, but has a factory
     // constructor that always throws. We never need to emit it.
@@ -141,46 +133,6 @@
    * Compute all the constants that must be emitted.
    */
   void computeNeededConstants() {
-    // Make sure we retain all metadata of all elements. This could add new
-    // constants to the handler.
-    if (_mirrorsData.mustRetainMetadata) {
-      // TODO(floitsch): verify that we don't run through the same elements
-      // multiple times.
-      for (MemberEntity element in _generatedCode.keys) {
-        if (_mirrorsData.isMemberAccessibleByReflection(element)) {
-          _mirrorsData.retainMetadataOfMember(element);
-        }
-      }
-      for (ClassEntity cls in neededClasses) {
-        final onlyForRti = classesOnlyNeededForRti.contains(cls);
-        if (!onlyForRti) {
-          _mirrorsData.retainMetadataOfClass(cls);
-          new FieldVisitor(
-                  _options,
-                  _elementEnvironment,
-                  _commonElements,
-                  _worldBuilder,
-                  _nativeData,
-                  _mirrorsData,
-                  _namer,
-                  _closedWorld)
-              .visitFields((FieldEntity member,
-                  js.Name name,
-                  js.Name accessorName,
-                  bool needsGetter,
-                  bool needsSetter,
-                  bool needsCheckedSetter) {
-            bool needsAccessor = needsGetter || needsSetter;
-            if (needsAccessor &&
-                _mirrorsData.isMemberAccessibleByReflection(member)) {
-              _mirrorsData.retainMetadataOfMember(member);
-            }
-          }, cls: cls);
-        }
-      }
-      typedefsNeededForReflection.forEach(_mirrorsData.retainMetadataOfTypedef);
-    }
-
     List<ConstantValue> constants =
         _worldBuilder.getConstantsForEmission(_emitter.compareConstants);
     for (ConstantValue constant in constants) {
@@ -206,11 +158,6 @@
     Set<ClassEntity> backendTypeHelpers =
         getBackendTypeHelpers(_commonElements).toSet();
 
-    // Compute needed typedefs.
-    typedefsNeededForReflection = _sorter.sortTypedefs(_closedWorld.allTypedefs
-        .where(_mirrorsData.isTypedefAccessibleByReflection)
-        .toList());
-
     // Compute needed classes.
     Set<ClassEntity> instantiatedClasses =
         // TODO(johnniwinther): This should be accessed from a codegen closed
@@ -332,14 +279,8 @@
         // TODO(johnniwinther): This should be accessed from a codegen closed
         // world.
         _worldBuilder.allReferencedStaticFields.where((FieldEntity field) {
-      if (!field.isConst) {
-        return field.isAssignable &&
-            _worldBuilder.hasConstantFieldInitializer(field);
-      } else {
-        // We also need to emit static const fields if they are available for
-        // reflection.
-        return _mirrorsData.isMemberAccessibleByReflection(field);
-      }
+      return field.isAssignable &&
+          _worldBuilder.hasConstantFieldInitializer(field);
     });
 
     _sorter.sortMembers(fields).forEach((MemberEntity e) => addToOutputUnit(e));
diff --git a/pkg/compiler/lib/src/js_emitter/program_builder/field_visitor.dart b/pkg/compiler/lib/src/js_emitter/program_builder/field_visitor.dart
index 76576af..7415a08 100644
--- a/pkg/compiler/lib/src/js_emitter/program_builder/field_visitor.dart
+++ b/pkg/compiler/lib/src/js_emitter/program_builder/field_visitor.dart
@@ -31,7 +31,6 @@
   final CommonElements _commonElements;
   final CodegenWorldBuilder _codegenWorldBuilder;
   final NativeData _nativeData;
-  final MirrorsData _mirrorsData;
   final Namer _namer;
   final ClosedWorld _closedWorld;
 
@@ -41,7 +40,6 @@
       this._commonElements,
       this._codegenWorldBuilder,
       this._nativeData,
-      this._mirrorsData,
       this._namer,
       this._closedWorld);
 
@@ -63,10 +61,6 @@
    */
   void visitFields(AcceptField f,
       {bool visitStatics: false, LibraryEntity library, ClassEntity cls}) {
-    assert(!(library is LibraryElement && !library.isDeclaration),
-        failedAt(library));
-    assert(!(cls is ClassElement && !cls.isDeclaration), failedAt(cls));
-
     bool isNativeClass = false;
     bool isLibrary = false;
     bool isInstantiated = false;
@@ -86,8 +80,6 @@
     }
 
     void visitField(FieldEntity field, {ClassEntity holder}) {
-      assert(!(field is FieldElement && !field.isDeclaration), failedAt(field));
-
       bool isMixinNativeField =
           isNativeClass && _elementEnvironment.isMixinApplication(holder);
 
@@ -153,7 +145,6 @@
   bool fieldNeedsGetter(FieldEntity field) {
     assert(field.isField);
     if (fieldAccessNeverThrows(field)) return false;
-    if (_mirrorsData.shouldRetainGetter(field)) return true;
     return field.enclosingClass != null &&
         _codegenWorldBuilder.hasInvokedGetter(field, _closedWorld);
   }
@@ -162,7 +153,6 @@
     assert(field.isField);
     if (fieldAccessNeverThrows(field)) return false;
     if (!field.isAssignable) return false;
-    if (_mirrorsData.shouldRetainSetter(field)) return true;
     return field.enclosingClass != null &&
         _codegenWorldBuilder.hasInvokedSetter(field, _closedWorld);
   }
@@ -173,7 +163,8 @@
         // knowing that it is there.  Therefore we don't need to use a getter
         // (that will throw if the getter method is missing), but can always
         // access the field directly.
-        field is ClosureFieldElement;
+        // TODO(johnniwinther): Return `true` JClosureField.
+        false;
   }
 
   bool canAvoidGeneratedCheckedSetter(FieldEntity member) {
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 3a78a8f..88f2c2d 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
@@ -7,7 +7,7 @@
 import 'dart:io';
 import 'dart:convert' show jsonDecode;
 
-import '../../closure.dart' show ClosureConversionTask, ClosureFieldElement;
+import '../../closure.dart' show ClosureConversionTask;
 import '../../common.dart';
 import '../../common/names.dart' show Names, Selectors;
 import '../../constants/values.dart'
@@ -15,8 +15,6 @@
 import '../../common_elements.dart' show CommonElements, ElementEnvironment;
 import '../../deferred_load.dart'
     show DeferredLoadTask, OutputUnit, OutputUnitData;
-import '../../elements/elements.dart'
-    show ClassElement, FieldElement, LibraryElement, MethodElement;
 import '../../elements/entities.dart';
 import '../../elements/types.dart';
 import '../../io/source_information.dart';
@@ -29,11 +27,10 @@
 import '../../js_backend/namer.dart' show Namer, StringBackedName;
 import '../../js_backend/native_data.dart';
 import '../../js_backend/interceptor_data.dart';
-import '../../js_backend/mirrors_data.dart';
 import '../../js_backend/js_interop_analysis.dart';
 import '../../js_backend/runtime_types.dart'
     show RuntimeTypesChecks, RuntimeTypesNeed, RuntimeTypesEncoder;
-import '../../js_model/elements.dart' show JSignatureMethod;
+import '../../js_model/elements.dart' show JGeneratorBody, JSignatureMethod;
 import '../../native/enqueue.dart' show NativeCodegenEnqueuer;
 import '../../options.dart';
 import '../../universe/selector.dart' show Selector;
@@ -75,7 +72,6 @@
   final JavaScriptConstantCompiler _constantHandler;
   final NativeData _nativeData;
   final RuntimeTypesNeed _rtiNeed;
-  final MirrorsData _mirrorsData;
   final InterceptorData _interceptorData;
   final SuperMemberData _superMemberData;
   final RuntimeTypesChecks _rtiChecks;
@@ -102,7 +98,6 @@
   final Registry _registry;
 
   final FunctionEntity _mainFunction;
-  final bool _isMockCompilation;
 
   /// True if the program should store function types in the metadata.
   bool _storeFunctionTypesInMetadata = false;
@@ -122,7 +117,6 @@
       this._constantHandler,
       this._nativeData,
       this._rtiNeed,
-      this._mirrorsData,
       this._interceptorData,
       this._superMemberData,
       this._rtiChecks,
@@ -137,10 +131,8 @@
       this._sourceInformationStrategy,
       this._sorter,
       Set<ClassEntity> rtiNeededClasses,
-      this._mainFunction,
-      {bool isMockCompilation})
-      : this._isMockCompilation = isMockCompilation,
-        this.collector = new Collector(
+      this._mainFunction)
+      : this.collector = new Collector(
             _options,
             _commonElements,
             _elementEnvironment,
@@ -152,7 +144,6 @@
             _nativeData,
             _interceptorData,
             _oneShotInterceptorData,
-            _mirrorsData,
             _closedWorld,
             rtiNeededClasses,
             _generatedCode,
@@ -171,13 +162,6 @@
   /// update field-initializers to point to the ConstantModel.
   final Map<ConstantValue, Constant> _constants = <ConstantValue, Constant>{};
 
-  /// Mapping from names to strings.
-  ///
-  /// This mapping is used to support `const Symbol` expressions.
-  ///
-  /// This map is filled when building classes.
-  final Map<js.Name, String> _symbolsMap = <js.Name, String>{};
-
   Set<Class> _unneededNativeClasses;
 
   /// Classes that have been allocated during a profile run.
@@ -273,7 +257,7 @@
       finalizers.add(namingFinalizer as js.TokenFinalizer);
     }
 
-    return new Program(fragments, holders, _buildLoadMap(), _symbolsMap,
+    return new Program(fragments, holders, _buildLoadMap(),
         _buildTypeToInterceptorMap(), _task.metadataCollector, finalizers,
         needsNativeSupport: needsNativeSupport,
         outputContainsConstantList: collector.outputContainsConstantList,
@@ -389,7 +373,6 @@
   }
 
   js.Statement _buildInvokeMain() {
-    if (_isMockCompilation) return js.js.comment("Mock compilation");
     return MainCallStubGenerator.generateInvokeMain(
         _task.emitter, _mainFunction);
   }
@@ -714,9 +697,6 @@
         // If the program contains `const Symbol` names we have to retain them.
         String selectorName = selector.name;
         if (selector.isSetter) selectorName = "$selectorName=";
-        if (_mirrorsData.symbolsUsed.contains(selectorName)) {
-          _symbolsMap[name] = selectorName;
-        }
         noSuchMethodStubs.add(
             classStubGenerator.generateStubForNoSuchMethod(name, selector));
       });
@@ -843,14 +823,12 @@
   }
 
   bool _methodNeedsStubs(FunctionEntity method) {
+    if (method is JGeneratorBody) return false;
+    if (method is ConstructorBodyEntity) return false;
     return method.parameterStructure.optionalParameters != 0 ||
         method.parameterStructure.typeParameters != 0;
   }
 
-  bool _methodCanBeReflected(FunctionEntity method) {
-    return _mirrorsData.isMemberAccessibleByReflection(method);
-  }
-
   bool _methodCanBeApplied(FunctionEntity method) {
     return _backendUsage.isFunctionApplyUsed &&
         _closedWorld.getMightBePassedToApply(method);
@@ -883,7 +861,6 @@
   }
 
   DartMethod _buildMethod(FunctionEntity element) {
-    assert(!(element is MethodElement && !element.isDeclaration));
     js.Name name = _namer.methodPropertyName(element);
     js.Expression code = _generatedCode[element];
 
@@ -896,7 +873,6 @@
     bool isNotApplyTarget =
         !element.isFunction || element.isGetter || element.isSetter;
 
-    bool canBeReflected = _methodCanBeReflected(element);
     bool canBeApplied = _methodCanBeApplied(element);
 
     js.Name aliasName = _superMemberData.isAliasedSuperMember(element)
@@ -911,8 +887,7 @@
         isClosureCallMethod = true;
       } else {
         // Careful with operators.
-        canTearOff = _worldBuilder.hasInvokedGetter(element, _closedWorld) ||
-            (canBeReflected && !Selector.isOperatorName(element.name));
+        canTearOff = _worldBuilder.hasInvokedGetter(element, _closedWorld);
         assert(canTearOff ||
             !_worldBuilder.methodsNeedingSuperGetter.contains(element));
         tearOffName = _namer.getterForElement(element);
@@ -936,14 +911,14 @@
 
     DartType memberType = _elementEnvironment.getFunctionType(element);
     js.Expression functionType;
-    if (canTearOff || canBeReflected) {
+    if (canTearOff) {
       OutputUnit outputUnit = _outputUnitData.outputUnitForMember(element);
       functionType = _generateFunctionType(memberType, outputUnit);
     }
 
     int requiredParameterCount;
     var /* List | Map */ optionalParameterDefaultValues;
-    if (canBeApplied || canBeReflected) {
+    if (canBeApplied) {
       // TODO(redemption): Handle function entities.
       FunctionEntity method = element;
       ParameterStructure parameterStructure = method.parameterStructure;
@@ -959,7 +934,6 @@
         isIntercepted: isIntercepted,
         aliasName: aliasName,
         canBeApplied: canBeApplied,
-        canBeReflected: canBeReflected,
         requiredParameterCount: requiredParameterCount,
         optionalParameterDefaultValues: optionalParameterDefaultValues,
         functionType: functionType);
@@ -1063,8 +1037,6 @@
 
     void visitField(FieldEntity field, js.Name name, js.Name accessorName,
         bool needsGetter, bool needsSetter, bool needsCheckedSetter) {
-      assert(!(field is FieldElement && !field.isDeclaration), failedAt(field));
-
       int getterFlags = 0;
       if (needsGetter) {
         if (visitStatics ||
@@ -1097,15 +1069,8 @@
           needsCheckedSetter));
     }
 
-    FieldVisitor visitor = new FieldVisitor(
-        _options,
-        _elementEnvironment,
-        _commonElements,
-        _worldBuilder,
-        _nativeData,
-        _mirrorsData,
-        _namer,
-        _closedWorld);
+    FieldVisitor visitor = new FieldVisitor(_options, _elementEnvironment,
+        _commonElements, _worldBuilder, _nativeData, _namer, _closedWorld);
     visitor.visitFields(visitField,
         visitStatics: visitStatics, library: library, cls: cls);
 
@@ -1145,11 +1110,9 @@
     bool isApplyTarget =
         !element.isConstructor && !element.isGetter && !element.isSetter;
     bool canBeApplied = _methodCanBeApplied(element);
-    bool canBeReflected = _methodCanBeReflected(element);
 
     bool needsTearOff = isApplyTarget &&
-        (canBeReflected ||
-            _worldBuilder.staticFunctionsNeedingGetter.contains(element));
+        _worldBuilder.staticFunctionsNeedingGetter.contains(element);
 
     js.Name tearOffName =
         needsTearOff ? _namer.staticClosureName(element) : null;
@@ -1162,14 +1125,14 @@
     }
     js.Expression functionType;
     DartType type = _elementEnvironment.getFunctionType(element);
-    if (needsTearOff || canBeReflected) {
+    if (needsTearOff) {
       OutputUnit outputUnit = _outputUnitData.outputUnitForMember(element);
       functionType = _generateFunctionType(type, outputUnit);
     }
 
     int requiredParameterCount;
     var /* List | Map */ optionalParameterDefaultValues;
-    if (canBeApplied || canBeReflected) {
+    if (canBeApplied) {
       // TODO(redemption): Support entities;
       FunctionEntity method = element;
       ParameterStructure parameterStructure = method.parameterStructure;
@@ -1184,7 +1147,6 @@
         needsTearOff: needsTearOff,
         tearOffName: tearOffName,
         canBeApplied: canBeApplied,
-        canBeReflected: canBeReflected,
         requiredParameterCount: requiredParameterCount,
         optionalParameterDefaultValues: optionalParameterDefaultValues,
         functionType: functionType);
diff --git a/pkg/compiler/lib/src/js_emitter/runtime_type_generator.dart b/pkg/compiler/lib/src/js_emitter/runtime_type_generator.dart
index b483325..3615c8c 100644
--- a/pkg/compiler/lib/src/js_emitter/runtime_type_generator.dart
+++ b/pkg/compiler/lib/src/js_emitter/runtime_type_generator.dart
@@ -5,15 +5,9 @@
 library dart2js.js_emitter.runtime_type_generator;
 
 import '../closure.dart'
-    show
-        ClosureRepresentationInfo,
-        ClosureFieldElement,
-        ClosureConversionTask,
-        ScopeInfo;
-import '../common.dart';
+    show ClosureRepresentationInfo, ClosureConversionTask, ScopeInfo;
 import '../common_elements.dart' show CommonElements;
 import '../deferred_load.dart' show OutputUnit, OutputUnitData;
-import '../elements/elements.dart' show ClassElement, MethodElement;
 import '../elements/entities.dart';
 import '../elements/types.dart';
 import '../js/js.dart' as jsAst;
@@ -142,14 +136,10 @@
       {bool storeFunctionTypeInMetadata: true}) {
     TypeTestProperties result = new TypeTestProperties();
 
-    assert(!(classElement is ClassElement && !classElement.isDeclaration),
-        failedAt(classElement));
-
     // TODO(johnniwinther): Include function signatures in [ClassChecks].
     void generateFunctionTypeSignature(ClassFunctionType classFunctionType) {
       FunctionEntity method = classFunctionType.callFunction;
       FunctionType type = classFunctionType.callType;
-      assert(!(method is MethodElement && !method.isImplementation));
 
       // TODO(johnniwinther): Avoid unneeded function type indices or
       // signatures. We either need them for mirrors or because [type] is
@@ -177,8 +167,7 @@
             if (scopeInfo is ClosureRepresentationInfo) {
               FieldEntity thisLocal = scopeInfo.thisFieldEntity;
               if (thisLocal != null) {
-                assert(thisLocal is ClosureFieldElement ||
-                    thisLocal is JClosureField);
+                assert(thisLocal is JClosureField);
                 jsAst.Name thisName =
                     _namer.instanceFieldPropertyName(thisLocal);
                 thisAccess = js('this.#', thisName);
diff --git a/pkg/compiler/lib/src/js_emitter/sorter.dart b/pkg/compiler/lib/src/js_emitter/sorter.dart
index 70fbd51..5048bb4 100644
--- a/pkg/compiler/lib/src/js_emitter/sorter.dart
+++ b/pkg/compiler/lib/src/js_emitter/sorter.dart
@@ -4,7 +4,6 @@
 
 library dart2js.js_emitter.sorter;
 
-import '../elements/elements.dart';
 import '../elements/entities.dart';
 
 /// Sorting strategy for libraries, classes and members.
@@ -26,64 +25,3 @@
   int compareTypedefsByLocation(TypedefEntity a, TypedefEntity b);
   int compareMembersByLocation(MemberEntity a, MemberEntity b);
 }
-
-class ElementSorter implements Sorter {
-  const ElementSorter();
-
-  @override
-  List<LibraryEntity> sortLibraries(Iterable<LibraryEntity> libraries) {
-    return Elements.sortedByPosition(new List.from(libraries, growable: false));
-  }
-
-  @override
-  List<ClassEntity> sortClasses(Iterable<ClassEntity> classes) {
-    List<ClassElement> regularClasses = <ClassElement>[];
-    List<MixinApplicationElement> unnamedMixins = <MixinApplicationElement>[];
-    for (ClassElement cls in classes) {
-      if (cls.isUnnamedMixinApplication) {
-        unnamedMixins.add(cls);
-      } else {
-        regularClasses.add(cls);
-      }
-    }
-    List<ClassEntity> sorted = <ClassEntity>[];
-    sorted.addAll(Elements.sortedByPosition<ClassElement>(regularClasses));
-    unnamedMixins.sort((a, b) {
-      int result = a.name.compareTo(b.name);
-      if (result != 0) return result;
-      return Elements.compareByPosition(a.mixin, b.mixin);
-    });
-    sorted.addAll(unnamedMixins);
-    return sorted;
-  }
-
-  @override
-  Iterable<TypedefEntity> sortTypedefs(Iterable<TypedefEntity> typedefs) {
-    return Elements.sortedByPosition(new List.from(typedefs, growable: false));
-  }
-
-  @override
-  Iterable<T> sortMembers<T extends MemberEntity>(Iterable<T> members) {
-    return Elements.sortedByPosition(new List.from(members, growable: false));
-  }
-
-  @override
-  int compareLibrariesByLocation(
-          covariant LibraryElement a, covariant LibraryElement b) =>
-      Elements.compareByPosition(a, b);
-
-  @override
-  int compareClassesByLocation(
-          covariant ClassElement a, covariant ClassElement b) =>
-      Elements.compareByPosition(a, b);
-
-  @override
-  int compareTypedefsByLocation(
-          covariant TypedefElement a, covariant TypedefElement b) =>
-      Elements.compareByPosition(a, b);
-
-  @override
-  int compareMembersByLocation(
-          covariant MemberElement a, covariant MemberElement b) =>
-      Elements.compareByPosition(a, b);
-}
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 9bb77ff..6996a89 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
@@ -1336,7 +1336,7 @@
     CommonElements commonElements = _closedWorld.commonElements;
     // We want to keep the original names for the most common core classes when
     // calling toString on them.
-    List<ClassElement> nativeClassesNeedingUnmangledName = [
+    List<ClassEntity> nativeClassesNeedingUnmangledName = [
       commonElements.intClass,
       commonElements.doubleClass,
       commonElements.numClass,
@@ -1404,13 +1404,10 @@
     // The [MANGLED_NAMES] table must contain the mapping for const symbols.
     // Without const symbols, the table is only relevant for reflection and
     // therefore unused in this emitter.
-    List<js.Property> mangledNamesProperties = <js.Property>[];
-    program.symbolsMap.forEach((js.Name mangledName, String unmangledName) {
-      mangledNamesProperties
-          .add(new js.Property(mangledName, js.string(unmangledName)));
-    });
-    globals.add(new js.Property(js.string(MANGLED_NAMES),
-        new js.ObjectInitializer(mangledNamesProperties)));
+    // TODO(johnniwinther): Remove the need for adding an empty list of
+    // mangled names.
+    globals.add(new js.Property(
+        js.string(MANGLED_NAMES), new js.ObjectInitializer(<js.Property>[])));
 
     globals.add(emitGetTypeFromName());
 
diff --git a/pkg/compiler/lib/src/js_emitter/startup_emitter/model_emitter.dart b/pkg/compiler/lib/src/js_emitter/startup_emitter/model_emitter.dart
index f2ba354..9c3beac 100644
--- a/pkg/compiler/lib/src/js_emitter/startup_emitter/model_emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/startup_emitter/model_emitter.dart
@@ -31,7 +31,6 @@
 import '../../compiler.dart' show Compiler;
 import '../../constants/values.dart' show ConstantValue, FunctionConstantValue;
 import '../../common_elements.dart' show CommonElements;
-import '../../elements/elements.dart' show ClassElement;
 import '../../elements/entities.dart';
 import '../../hash/sha1.dart' show Hasher;
 import '../../io/code_output.dart';
diff --git a/pkg/compiler/lib/src/js_emitter/type_test_registry.dart b/pkg/compiler/lib/src/js_emitter/type_test_registry.dart
index 1f1895b..f353ebb 100644
--- a/pkg/compiler/lib/src/js_emitter/type_test_registry.dart
+++ b/pkg/compiler/lib/src/js_emitter/type_test_registry.dart
@@ -7,16 +7,13 @@
 import '../common.dart';
 import '../common_elements.dart';
 import '../elements/entities.dart';
-import '../elements/types.dart';
 import '../js_backend/runtime_types.dart'
     show
         RuntimeTypesChecks,
         RuntimeTypesChecksBuilder,
         RuntimeTypesSubstitutions;
-import '../js_backend/mirrors_data.dart';
 import '../options.dart';
 import '../universe/world_builder.dart';
-import '../world.dart' show ClosedWorld;
 
 class TypeTestRegistry {
   final ElementEnvironment _elementEnvironment;
@@ -27,12 +24,11 @@
 
   final CompilerOptions _options;
   final CodegenWorldBuilder _codegenWorldBuilder;
-  final ClosedWorld _closedWorld;
 
   RuntimeTypesChecks _rtiChecks;
 
-  TypeTestRegistry(this._options, this._codegenWorldBuilder, this._closedWorld,
-      this._elementEnvironment);
+  TypeTestRegistry(
+      this._options, this._codegenWorldBuilder, this._elementEnvironment);
 
   RuntimeTypesChecks get rtiChecks {
     assert(
@@ -51,7 +47,7 @@
   }
 
   void computeRtiNeededClasses(RuntimeTypesSubstitutions rtiSubstitutions,
-      MirrorsData mirrorsData, Iterable<MemberEntity> liveMembers) {
+      Iterable<MemberEntity> liveMembers) {
     _rtiNeededClasses = new Set<ClassEntity>();
 
     void addClassWithSuperclasses(ClassEntity cls) {
@@ -69,47 +65,9 @@
       }
     }
 
-    // 1.  Add classes that are referenced by type arguments or substitutions in
-    //     argument checks.
+    // Add classes that are referenced by type arguments or substitutions in
+    // argument checks.
     addClassesWithSuperclasses(rtiChecks.requiredClasses);
-
-    bool canTearOff(MemberEntity function) {
-      if (!function.isFunction ||
-          function.isConstructor ||
-          function.isGetter ||
-          function.isSetter) {
-        return false;
-      } else if (function.isInstanceMember) {
-        if (!function.enclosingClass.isClosure) {
-          return _codegenWorldBuilder.hasInvokedGetter(function, _closedWorld);
-        }
-      }
-      return false;
-    }
-
-    bool canBeReflectedAsFunction(MemberEntity element) {
-      return !element.isField;
-    }
-
-    bool canBeReified(MemberEntity element) {
-      return (canTearOff(element) ||
-          mirrorsData.isMemberAccessibleByReflection(element));
-    }
-
-    // 2. Find all types referenced from the types of elements that can be
-    // reflected on 'as functions'.
-    liveMembers.where((MemberEntity element) {
-      return canBeReflectedAsFunction(element) && canBeReified(element);
-    }).forEach((_function) {
-      FunctionEntity function = _function;
-      FunctionType type = _elementEnvironment.getFunctionType(function);
-      for (ClassEntity cls in _rtiChecks.getReferencedClasses(type)) {
-        while (cls != null) {
-          _rtiNeededClasses.add(cls);
-          cls = _elementEnvironment.getSuperClass(cls);
-        }
-      }
-    });
   }
 
   void computeRequiredTypeChecks(RuntimeTypesChecksBuilder rtiChecksBuilder) {
diff --git a/pkg/compiler/lib/src/kernel/dart2js_target.dart b/pkg/compiler/lib/src/kernel/dart2js_target.dart
index f7ab997a..462ba79 100644
--- a/pkg/compiler/lib/src/kernel/dart2js_target.dart
+++ b/pkg/compiler/lib/src/kernel/dart2js_target.dart
@@ -80,10 +80,8 @@
     'dart:_foreign_helper',
     'dart:_interceptors',
     'dart:_internal',
-    'dart:_isolate_helper',
     'dart:_js_embedded_names',
     'dart:_js_helper',
-    'dart:_js_mirrors',
     'dart:_js_names',
     'dart:_native_typed_data',
     'dart:async',
@@ -104,10 +102,8 @@
     'dart:_foreign_helper',
     'dart:_interceptors',
     'dart:_internal',
-    'dart:_isolate_helper',
     'dart:_js_embedded_names',
     'dart:_js_helper',
-    'dart:_js_mirrors',
     'dart:_js_names',
     'dart:_native_typed_data',
     'dart:async',
diff --git a/pkg/compiler/lib/src/kernel/element_map.dart b/pkg/compiler/lib/src/kernel/element_map.dart
index fe468dd..13adcc4 100644
--- a/pkg/compiler/lib/src/kernel/element_map.dart
+++ b/pkg/compiler/lib/src/kernel/element_map.dart
@@ -20,7 +20,7 @@
 import '../js_model/elements.dart' show JGeneratorBody;
 import '../native/native.dart' as native;
 import '../ssa/type_builder.dart';
-import '../types/types.dart';
+import '../types/masks.dart';
 import '../universe/call_structure.dart';
 import '../universe/selector.dart';
 import '../world.dart';
diff --git a/pkg/compiler/lib/src/kernel/element_map_impl.dart b/pkg/compiler/lib/src/kernel/element_map_impl.dart
index 8a70896..a6e104d 100644
--- a/pkg/compiler/lib/src/kernel/element_map_impl.dart
+++ b/pkg/compiler/lib/src/kernel/element_map_impl.dart
@@ -20,7 +20,6 @@
 import '../constants/evaluation.dart';
 import '../constants/expressions.dart';
 import '../constants/values.dart';
-import '../elements/elements.dart';
 import '../elements/entities.dart';
 import '../elements/entity_utils.dart' as utils;
 import '../elements/names.dart';
@@ -1884,18 +1883,6 @@
   @override
   ConstantSystem get constantSystem => const JavaScriptConstantSystem();
 
-  @override
-  ConstantValue getConstantValueForVariable(VariableElement element) {
-    throw new UnimplementedError(
-        "KernelConstantEnvironment.getConstantValueForVariable");
-  }
-
-  @override
-  ConstantValue getConstantValue(ConstantExpression expression) {
-    return _getConstantValue(CURRENT_ELEMENT_SPANNABLE, expression,
-        constantRequired: true);
-  }
-
   ConstantValue _getConstantValue(
       Spannable spannable, ConstantExpression expression,
       {bool constantRequired}) {
@@ -1906,11 +1893,6 @@
           constantSystem);
     });
   }
-
-  @override
-  bool hasConstantValue(ConstantExpression expression) {
-    throw new UnimplementedError("KernelConstantEnvironment.hasConstantValue");
-  }
 }
 
 /// Evaluation environment used for computing [ConstantValue]s for
@@ -2898,7 +2880,7 @@
       } else if (node is ir.FunctionDeclaration) {
         String name = node.variable.name;
         if (name != null && name != "") {
-          parts.add(Elements.operatorNameToIdentifier(name));
+          parts.add(utils.operatorNameToIdentifier(name));
         } else {
           parts.add(anonymous);
           anonymous = '';
@@ -2911,7 +2893,7 @@
         if (node.kind == ir.ProcedureKind.Factory) {
           parts.add(utils.reconstructConstructorName(getMember(node)));
         } else {
-          parts.add(Elements.operatorNameToIdentifier(node.name.name));
+          parts.add(utils.operatorNameToIdentifier(node.name.name));
         }
       } else if (node is ir.Constructor) {
         parts.add(utils.reconstructConstructorName(getMember(node)));
diff --git a/pkg/compiler/lib/src/kernel/element_map_mixins.dart b/pkg/compiler/lib/src/kernel/element_map_mixins.dart
index 3588b19..a7f7901 100644
--- a/pkg/compiler/lib/src/kernel/element_map_mixins.dart
+++ b/pkg/compiler/lib/src/kernel/element_map_mixins.dart
@@ -158,7 +158,6 @@
       type ??= findIn(Uris.dart_core);
       type ??= findIn(Uris.dart__js_helper);
       type ??= findIn(Uris.dart__interceptors);
-      type ??= findIn(Uris.dart__isolate_helper);
       type ??= findIn(Uris.dart__native_typed_data);
       type ??= findIn(Uris.dart_collection);
       type ??= findIn(Uris.dart_math);
diff --git a/pkg/compiler/lib/src/kernel/kernel_backend_strategy.dart b/pkg/compiler/lib/src/kernel/kernel_backend_strategy.dart
index 3c3f6bf..ae1b004 100644
--- a/pkg/compiler/lib/src/kernel/kernel_backend_strategy.dart
+++ b/pkg/compiler/lib/src/kernel/kernel_backend_strategy.dart
@@ -25,6 +25,7 @@
 import '../ssa/nodes.dart';
 import '../ssa/ssa.dart';
 import '../ssa/types.dart';
+import '../types/masks.dart';
 import '../types/types.dart';
 import '../universe/selector.dart';
 import '../universe/world_impact.dart';
@@ -173,7 +174,7 @@
         !mask.satisfies(closedWorld.commonElements.jsStringClass, closedWorld);
   }
 
-  bool isFixedLength(TypeMask mask, ClosedWorld closedWorld) {
+  bool isFixedLength(covariant TypeMask mask, ClosedWorld closedWorld) {
     if (mask.isContainer && (mask as ContainerTypeMask).length != null) {
       // A container on which we have inferred the length.
       return true;
@@ -204,7 +205,7 @@
         parameter, _globalInferenceResults);
   }
 
-  TypeMask selectorTypeOf(Selector selector, TypeMask mask) {
+  TypeMask selectorTypeOf(Selector selector, covariant TypeMask mask) {
     return TypeMaskFactory.inferredTypeForSelector(
         selector, mask, _globalInferenceResults);
   }
diff --git a/pkg/compiler/lib/src/kernel/kernel_strategy.dart b/pkg/compiler/lib/src/kernel/kernel_strategy.dart
index 1872ee8..d6d273e 100644
--- a/pkg/compiler/lib/src/kernel/kernel_strategy.dart
+++ b/pkg/compiler/lib/src/kernel/kernel_strategy.dart
@@ -15,17 +15,13 @@
 import '../common_elements.dart';
 import '../compiler.dart';
 import '../deferred_load.dart' show DeferredLoadTask;
-import '../elements/elements.dart';
 import '../elements/entities.dart';
 import '../elements/types.dart';
 import '../enqueue.dart';
 import '../environment.dart' as env;
 import '../frontend_strategy.dart';
-import '../js_backend/backend.dart';
 import '../js_backend/backend_usage.dart';
 import '../js_backend/interceptor_data.dart';
-import '../js_backend/mirrors_analysis.dart';
-import '../js_backend/mirrors_data.dart';
 import '../js_backend/native_data.dart';
 import '../js_backend/no_such_method_registry.dart';
 import '../js_backend/runtime_types.dart';
@@ -34,12 +30,9 @@
 import '../native/enqueue.dart' show NativeResolutionEnqueuer;
 import '../native/resolver.dart';
 import '../options.dart';
-import '../patch_parser.dart';
-import '../resolved_uri_translator.dart';
 import '../universe/class_hierarchy_builder.dart';
 import '../universe/world_builder.dart';
 import '../universe/world_impact.dart';
-import '../world.dart';
 import 'deferred_load.dart';
 import 'element_map.dart';
 import 'element_map_impl.dart';
@@ -71,16 +64,8 @@
   }
 
   @override
-  LibraryLoaderTask createLibraryLoader(
-      ResolvedUriTranslator uriTranslator,
-      ScriptLoader scriptLoader,
-      api.CompilerInput compilerInput,
-      ElementScanner scriptScanner,
-      PatchResolverFunction patchResolverFunc,
-      PatchParserTask patchParser,
-      env.Environment environment,
-      DiagnosticReporter reporter,
-      Measurer measurer) {
+  LibraryLoaderTask createLibraryLoader(api.CompilerInput compilerInput,
+      DiagnosticReporter reporter, Measurer measurer) {
     return new KernelLibraryLoaderTask(
         _options.librariesSpecificationUri,
         _options.platformBinaries,
@@ -113,8 +98,8 @@
 
   @override
   NativeClassFinder createNativeClassFinder(NativeBasicData nativeBasicData) {
-    return new BaseNativeClassFinder(_elementMap.elementEnvironment,
-        elementMap.commonElements, nativeBasicData);
+    return new BaseNativeClassFinder(
+        _elementMap.elementEnvironment, nativeBasicData);
   }
 
   NoSuchMethodResolver createNoSuchMethodResolver() {
@@ -128,15 +113,6 @@
     return elementEnvironment.mainFunction;
   }
 
-  MirrorsDataBuilder createMirrorsDataBuilder() {
-    return new MirrorsDataBuilderImpl(elementEnvironment, commonElements);
-  }
-
-  MirrorsResolutionAnalysis createMirrorsResolutionAnalysis(
-      JavaScriptBackend backend) {
-    return new MirrorsResolutionAnalysisImpl();
-  }
-
   RuntimeTypesNeedBuilder createRuntimeTypesNeedBuilder() {
     return _runtimeTypesNeedBuilder ??= _options.disableRtiOptimization
         ? const TrivialRuntimeTypesNeedBuilder()
@@ -219,7 +195,7 @@
   }
 }
 
-class KernelWorkItem implements ResolutionWorkItem {
+class KernelWorkItem implements WorkItem {
   final CompilerTask _compilerTask;
   final KernelToElementMapForImpactImpl _elementMap;
   final ImpactTransformer _impactTransformer;
@@ -259,59 +235,3 @@
     });
   }
 }
-
-/// Mock implementation of [MirrorsDataImpl].
-class MirrorsDataBuilderImpl extends MirrorsDataImpl {
-  MirrorsDataBuilderImpl(
-      ElementEnvironment elementEnvironment, CommonElements commonElements)
-      : super(null, elementEnvironment, commonElements);
-
-  @override
-  void registerUsedMember(MemberEntity member) {}
-
-  @override
-  void computeMembersNeededForReflection(
-      ResolutionWorldBuilder worldBuilder, ClosedWorld closedWorld) {
-    // TODO(redemption): Support dart:mirrors.
-    createImmutableSets();
-  }
-
-  @override
-  void maybeMarkClosureAsNeededForReflection(ClassEntity closureClass,
-      FunctionEntity callMethod, Local localFunction) {}
-
-  @override
-  void registerConstSymbol(String name) {}
-
-  @override
-  void registerMirrorUsage(
-      Set<String> symbols, Set<Element> targets, Set<Element> metaTargets) {}
-}
-
-/// Mock implementation of [MirrorsResolutionAnalysis].
-class MirrorsResolutionAnalysisImpl implements MirrorsResolutionAnalysis {
-  @override
-  void onQueueEmpty(Enqueuer enqueuer, Iterable<ClassEntity> recentClasses) {}
-
-  @override
-  MirrorsCodegenAnalysis close() {
-    // TODO(redemption): Implement this.
-    return new MirrorsCodegenAnalysisImpl();
-  }
-
-  @override
-  void onResolutionComplete() {}
-}
-
-class MirrorsCodegenAnalysisImpl implements MirrorsCodegenAnalysis {
-  @override
-  int get preMirrorsMethodCount {
-    // TODO(redemption): Implement this.
-    return null;
-  }
-
-  @override
-  void onQueueEmpty(Enqueuer enqueuer, Iterable<ClassEntity> recentClasses) {
-    // TODO(redemption): Implement this.
-  }
-}
diff --git a/pkg/compiler/lib/src/library_loader.dart b/pkg/compiler/lib/src/library_loader.dart
index b96adbd..2124d1f 100644
--- a/pkg/compiler/lib/src/library_loader.dart
+++ b/pkg/compiler/lib/src/library_loader.dart
@@ -16,42 +16,13 @@
 import 'kernel/front_end_adapter.dart';
 import 'kernel/dart2js_target.dart' show Dart2jsTarget;
 
-import 'common/names.dart' show Uris;
 import 'common/tasks.dart' show CompilerTask, Measurer;
 import 'common.dart';
-import 'elements/elements.dart'
-    show
-        CompilationUnitElement,
-        Element,
-        ImportElement,
-        ExportElement,
-        LibraryElement;
 import 'elements/entities.dart' show LibraryEntity;
-import 'elements/modelx.dart'
-    show
-        CompilationUnitElementX,
-        DeferredLoaderGetterElementX,
-        ErroneousElementX,
-        ExportElementX,
-        ImportElementX,
-        LibraryElementX,
-        LibraryDependencyElementX,
-        PrefixElementX,
-        SyntheticImportElement;
 import 'enqueue.dart' show DeferredAction;
-import 'environment.dart';
-import 'io/source_file.dart' show Binary;
 import 'kernel/element_map_impl.dart' show KernelToElementMapForImpactImpl;
-import 'patch_parser.dart' show PatchParserTask;
 import 'resolved_uri_translator.dart';
-import 'script.dart';
-import 'tree/tree.dart';
-import 'util/util.dart' show Link, LinkBuilder;
-
-typedef Future<Iterable<LibraryElement>> ReuseLibrariesFunction(
-    Iterable<LibraryElement> libraries);
-
-typedef Uri PatchResolverFunction(String dartLibraryPath);
+import 'util/util.dart' show Link;
 
 /**
  * [CompilerTask] for loading libraries and setting up the import/export scopes.
@@ -167,19 +138,6 @@
   Future<LoadedLibraries> loadLibrary(Uri resolvedUri,
       {bool skipFileWithPartOfTag: false});
 
-  /// Reset the library loader task to prepare for compilation. If provided,
-  /// libraries matching [reuseLibrary] are reused.
-  ///
-  /// This method is used for incremental compilation.
-  void reset({bool reuseLibrary(LibraryElement library)});
-
-  /// Asynchronous version of [reset].
-  Future resetAsync(Future<bool> reuseLibrary(LibraryElement library));
-
-  /// Similar to [resetAsync] but [reuseLibrary] maps all libraries to a list
-  /// of libraries that can be reused.
-  Future<Null> resetLibraries(ReuseLibrariesFunction reuseLibraries);
-
   // TODO(johnniwinther): Move these to a separate interface.
   /// Register a deferred action to be performed during resolution.
   void registerDeferredAction(DeferredAction action);
@@ -222,563 +180,6 @@
   LibraryEntity lookupLibrary(Uri canonicalUri);
 }
 
-/// Handle for creating synthesized/patch libraries during library loading.
-abstract class LibraryLoader {
-  /// This method must be called when a new synthesized/patch library has been
-  /// created to ensure that [library] will part of library dependency graph
-  /// used for computing import/export scopes.
-  void registerNewLibrary(LibraryElement library);
-
-  /// This method must be called when a new synthesized/patch library has been
-  /// scanned in order to process the library tags in [library] and thus handle
-  /// imports/exports/parts in the synthesized/patch library.
-  Future processLibraryTags(LibraryElement library);
-}
-
-/**
- * [CombinatorFilter] is a succinct representation of a list of combinators from
- * a library dependency tag.
- */
-class CombinatorFilter {
-  const CombinatorFilter();
-
-  /**
-   * Returns [:true:] if [element] is excluded by this filter.
-   */
-  bool exclude(Element element) => false;
-
-  /**
-   * Creates a filter based on the combinators of [tag].
-   */
-  factory CombinatorFilter.fromTag(LibraryDependency tag) {
-    if (tag == null || tag.combinators == null) {
-      return const CombinatorFilter();
-    }
-
-    // If the list of combinators contain at least one [:show:] we can create
-    // a positive list of elements to include, otherwise we create a negative
-    // list of elements to exclude.
-    bool show = false;
-    Set<String> nameSet;
-    for (Combinator combinator in tag.combinators) {
-      if (combinator.isShow) {
-        show = true;
-        var set = new Set<String>();
-        for (Identifier identifier in combinator.identifiers) {
-          set.add(identifier.source);
-        }
-        if (nameSet == null) {
-          nameSet = set;
-        } else {
-          nameSet = nameSet.intersection(set);
-        }
-      }
-    }
-    if (nameSet == null) {
-      nameSet = new Set<String>();
-    }
-    for (Combinator combinator in tag.combinators) {
-      if (combinator.isHide) {
-        for (Identifier identifier in combinator.identifiers) {
-          if (show) {
-            // We have a positive list => Remove hidden elements.
-            nameSet.remove(identifier.source);
-          } else {
-            // We have no positive list => Accumulate hidden elements.
-            nameSet.add(identifier.source);
-          }
-        }
-      }
-    }
-    return show ? new ShowFilter(nameSet) : new HideFilter(nameSet);
-  }
-}
-
-/**
- * A list of combinators represented as a list of element names to include.
- */
-class ShowFilter extends CombinatorFilter {
-  final Set<String> includedNames;
-
-  ShowFilter(this.includedNames);
-
-  bool exclude(Element element) => !includedNames.contains(element.name);
-}
-
-/**
- * A list of combinators represented as a list of element names to exclude.
- */
-class HideFilter extends CombinatorFilter {
-  final Set<String> excludedNames;
-
-  HideFilter(this.excludedNames);
-
-  bool exclude(Element element) => excludedNames.contains(element.name);
-}
-
-/// Implementation class for [LibraryLoaderTask]. This library loader loads
-/// '.dart' files into the [Element] model with AST nodes which are resolved
-/// by the resolver.
-class ResolutionLibraryLoaderTask extends CompilerTask
-    implements LibraryLoaderTask {
-  /// Translates internal uris (like dart:core) to a disk location.
-  final ResolvedUriTranslator uriTranslator;
-
-  /// Loads the contents of a script file (a .dart file). Used when loading
-  /// libraries from source.
-  final ScriptLoader scriptLoader;
-
-  /// Provides a diet element model from a script file containing information
-  /// about imports and exports. Used when loading libraries from source.
-  final ElementScanner scanner;
-
-  /// Definitions provided via the `-D` command line flags. Used to resolve
-  /// conditional imports.
-  final Environment environment;
-
-  // TODO(efortuna): Don't pass PatchParserTask here.
-  final PatchParserTask _patchParserTask;
-
-  /// Function that accepts the string name of a library and returns the
-  /// path to the corresponding patch file. This is a function that is passed in
-  /// because our test mock_compiler subclasses compiler.
-  // TODO(efortuna): Refactor mock_compiler to not do this.
-  final PatchResolverFunction _patchResolverFunc;
-
-  List<DeferredAction> _deferredActions = <DeferredAction>[];
-
-  final DiagnosticReporter reporter;
-
-  ResolutionLibraryLoaderTask(
-      this.uriTranslator,
-      this.scriptLoader,
-      this.scanner,
-      this._patchResolverFunc,
-      this._patchParserTask,
-      this.environment,
-      this.reporter,
-      Measurer measurer)
-      : super(measurer);
-
-  String get name => 'LibraryLoader';
-
-  final Map<Uri, LibraryElement> libraryCanonicalUriMap =
-      new Map<Uri, LibraryElement>();
-  final Map<Uri, LibraryElement> libraryResourceUriMap =
-      new Map<Uri, LibraryElement>();
-  final Map<String, LibraryElement> libraryNames =
-      new Map<String, LibraryElement>();
-
-  Iterable<LibraryEntity> get libraries => libraryCanonicalUriMap.values;
-
-  LibraryEntity lookupLibrary(Uri canonicalUri) {
-    return libraryCanonicalUriMap[canonicalUri];
-  }
-
-  void reset({bool reuseLibrary(LibraryElement library)}) {
-    measure(() {
-      Iterable<LibraryElement> reusedLibraries = null;
-      if (reuseLibrary != null) {
-        reusedLibraries = measureSubtask(_reuseLibrarySubtaskName, () {
-          // Call [toList] to force eager calls to [reuseLibrary].
-          return libraryCanonicalUriMap.values.where(reuseLibrary).toList();
-        });
-      }
-
-      resetImplementation(reusedLibraries);
-    });
-  }
-
-  void resetImplementation(Iterable<LibraryElement> reusedLibraries) {
-    measure(() {
-      libraryCanonicalUriMap.clear();
-      libraryResourceUriMap.clear();
-      libraryNames.clear();
-
-      if (reusedLibraries != null) {
-        reusedLibraries.forEach(mapLibrary);
-      }
-    });
-  }
-
-  Future resetAsync(Future<bool> reuseLibrary(LibraryElement library)) {
-    return measure(() {
-      Future<LibraryElement> wrapper(LibraryElement library) {
-        try {
-          return reuseLibrary(library)
-              .then((bool reuse) => reuse ? library : null);
-        } catch (exception, trace) {
-          reporter.onCrashInUserCode(
-              'Uncaught exception in reuseLibrary', exception, trace);
-          rethrow;
-        }
-      }
-
-      List<Future<LibraryElement>> reusedLibrariesFuture = measureSubtask(
-          _reuseLibrarySubtaskName,
-          () => libraryCanonicalUriMap.values.map(wrapper).toList());
-
-      return Future
-          .wait(reusedLibrariesFuture)
-          .then((Iterable<LibraryElement> reusedLibraries) {
-        resetImplementation(reusedLibraries.where((e) => e != null));
-      });
-    });
-  }
-
-  Future<Null> resetLibraries(
-      Future<Iterable<LibraryElement>> reuseLibraries(
-          Iterable<LibraryElement> libraries)) {
-    return measureSubtask(_reuseLibrarySubtaskName, () {
-      return new Future<Iterable<LibraryElement>>(() {
-        // Wrap in Future to shield against errors in user code.
-        return reuseLibraries(libraryCanonicalUriMap.values);
-      }).catchError((exception, StackTrace trace) {
-        reporter.onCrashInUserCode(
-            'Uncaught exception in reuseLibraries', exception, trace);
-        throw exception; // Async rethrow.
-      }).then((Iterable<LibraryElement> reusedLibraries) {
-        measure(() {
-          resetImplementation(reusedLibraries);
-        });
-      });
-    });
-  }
-
-  /// Insert [library] in the internal maps. Used for compiler reuse.
-  void mapLibrary(LibraryElement library) {
-    libraryCanonicalUriMap[library.canonicalUri] = library;
-
-    Uri resourceUri = library.entryCompilationUnit.script.resourceUri;
-    libraryResourceUriMap[resourceUri] = library;
-
-    if (library.hasLibraryName) {
-      String name = library.libraryName;
-      libraryNames[name] = library;
-    }
-  }
-
-  Future<LoadedLibraries> loadLibrary(Uri resolvedUri,
-      {bool skipFileWithPartOfTag: false}) {
-    return measure(() async {
-      LibraryDependencyHandler handler = new LibraryDependencyHandler(this);
-      LibraryElement library = await createLibrary(
-          handler, null, resolvedUri, NO_LOCATION_SPANNABLE,
-          skipFileWithPartOfTag: skipFileWithPartOfTag);
-      if (library == null) return null;
-      return reporter.withCurrentElement(library, () {
-        return measure(() {
-          handler.computeExports();
-          return new _LoadedLibraries(library, handler.newLibraries);
-        });
-      });
-    });
-  }
-
-  /**
-   * Processes the library tags in [library].
-   *
-   * The imported/exported libraries are loaded and processed recursively but
-   * the import/export scopes are not set up.
-   */
-  Future processLibraryTags(
-      LibraryDependencyHandler handler, LibraryElementX library) {
-    TagState tagState = new TagState();
-
-    bool importsDartCore = false;
-    LinkBuilder<LibraryDependencyElementX> libraryDependencies =
-        new LinkBuilder<LibraryDependencyElementX>();
-    Uri base = library.entryCompilationUnit.script.readableUri;
-
-    return Future.forEach(library.tags, (LibraryTag tag) {
-      return reporter.withCurrentElement(library, () {
-        Uri computeUri(LibraryDependency node) {
-          StringNode uriNode = node.uri;
-          if (node.conditionalUris != null) {
-            for (ConditionalUri conditionalUri in node.conditionalUris) {
-              String key = conditionalUri.key.slowNameString;
-              String value = conditionalUri.value == null
-                  ? "true"
-                  : conditionalUri.value.dartString.slowToString();
-              String actual = environment.valueOf(key);
-              if (value == actual) {
-                uriNode = conditionalUri.uri;
-                break;
-              }
-            }
-          }
-          String tagUriString = uriNode.dartString.slowToString();
-          try {
-            return Uri.parse(tagUriString);
-          } on FormatException {
-            reporter.reportErrorMessage(
-                node.uri, MessageKind.INVALID_URI, {'uri': tagUriString});
-            return null;
-          }
-        }
-
-        if (tag.isImport) {
-          Uri uri = computeUri(tag);
-          if (uri == null) {
-            // Skip this erroneous import.
-            return new Future.value();
-          }
-          // TODO(johnniwinther): Create imports during parsing.
-          ImportElementX import =
-              new ImportElementX(library.entryCompilationUnit, tag, uri);
-          tagState.checkTag(TagState.IMPORT_OR_EXPORT, import.node, reporter);
-          if (import.uri == Uris.dart_core) {
-            importsDartCore = true;
-          }
-          library.addImportDeclaration(import);
-          libraryDependencies.addLast(import);
-        } else if (tag.isExport) {
-          Uri uri = computeUri(tag);
-          if (uri == null) {
-            // Skip this erroneous export.
-            return new Future.value();
-          }
-          // TODO(johnniwinther): Create exports during parsing.
-          ExportElementX export =
-              new ExportElementX(library.entryCompilationUnit, tag, uri);
-          tagState.checkTag(TagState.IMPORT_OR_EXPORT, export.node, reporter);
-          library.addExportDeclaration(export);
-          libraryDependencies.addLast(export);
-        } else if (tag.isLibraryName) {
-          tagState.checkTag(TagState.LIBRARY, tag, reporter);
-          if (library.libraryTag == null) {
-            // Use the first if there are multiple (which is reported as an
-            // error in [TagState.checkTag]).
-            library.libraryTag = tag;
-          }
-        } else if (tag.isPart) {
-          Part part = tag;
-          StringNode uri = part.uri;
-          Uri resolvedUri = base.resolve(uri.dartString.slowToString());
-          tagState.checkTag(TagState.PART, part, reporter);
-          return scanPart(part, resolvedUri, library);
-        } else {
-          reporter.internalError(tag, "Unhandled library tag.");
-        }
-      });
-    }).then((_) {
-      return reporter.withCurrentElement(library, () {
-        checkDuplicatedLibraryName(library);
-
-        // Import dart:core if not already imported.
-        if (!importsDartCore && library.canonicalUri != Uris.dart_core) {
-          return createLibrary(handler, null, Uris.dart_core, library)
-              .then((LibraryElement coreLibrary) {
-            handler.registerDependency(
-                library,
-                new SyntheticImportElement(
-                    library.entryCompilationUnit, Uris.dart_core, coreLibrary),
-                coreLibrary);
-          });
-        }
-      });
-    }).then((_) {
-      return Future.forEach(libraryDependencies.toList(),
-          (LibraryDependencyElementX libraryDependency) {
-        return reporter.withCurrentElement(library, () {
-          return registerLibraryFromImportExport(
-              handler, library, libraryDependency);
-        });
-      });
-    });
-  }
-
-  void checkDuplicatedLibraryName(LibraryElement library) {
-    if (library.isInternalLibrary) return;
-    Uri resourceUri = library.entryCompilationUnit.script.resourceUri;
-    LibraryElement existing =
-        libraryResourceUriMap.putIfAbsent(resourceUri, () => library);
-    if (!identical(existing, library)) {
-      if (library.hasLibraryName) {
-        reporter.withCurrentElement(library, () {
-          reporter.reportWarningMessage(
-              library, MessageKind.DUPLICATED_LIBRARY_RESOURCE, {
-            'libraryName': library.libraryName,
-            'resourceUri': resourceUri,
-            'canonicalUri1': library.canonicalUri,
-            'canonicalUri2': existing.canonicalUri
-          });
-        });
-      } else {
-        reporter.reportHintMessage(library, MessageKind.DUPLICATED_RESOURCE, {
-          'resourceUri': resourceUri,
-          'canonicalUri1': library.canonicalUri,
-          'canonicalUri2': existing.canonicalUri
-        });
-      }
-    } else if (library.hasLibraryName) {
-      String name = library.libraryName;
-      existing = libraryNames.putIfAbsent(name, () => library);
-      if (!identical(existing, library)) {
-        reporter.withCurrentElement(library, () {
-          reporter.reportWarningMessage(library,
-              MessageKind.DUPLICATED_LIBRARY_NAME, {'libraryName': name});
-        });
-        reporter.withCurrentElement(existing, () {
-          reporter.reportWarningMessage(existing,
-              MessageKind.DUPLICATED_LIBRARY_NAME, {'libraryName': name});
-        });
-      }
-    }
-  }
-
-  /**
-   * Handle a part tag in the scope of [library]. The [resolvedUri] given is
-   * used as is, any URI resolution should be done beforehand.
-   */
-  Future scanPart(Part part, Uri resolvedUri, LibraryElement library) {
-    if (!resolvedUri.isAbsolute) throw new ArgumentError(resolvedUri);
-    Uri readableUri = uriTranslator.translate(library, resolvedUri, part);
-    if (readableUri == null) return new Future.value();
-    return reporter.withCurrentElement(library, () {
-      return scriptLoader.readScript(readableUri, part).then((Script script) {
-        if (script == null) return;
-        createUnitSync(script, library);
-      });
-    });
-  }
-
-  /**
-   * Handle an import/export tag by loading the referenced library and
-   * registering its dependency in [handler] for the computation of the import/
-   * export scope. If the tag does not contain a valid URI, then its dependency
-   * is not registered in [handler].
-   */
-  Future<Null> registerLibraryFromImportExport(LibraryDependencyHandler handler,
-      LibraryElement library, LibraryDependencyElementX libraryDependency) {
-    Uri base = library.canonicalUri;
-    Uri resolvedUri = base.resolveUri(libraryDependency.uri);
-    return createLibrary(handler, library, resolvedUri, libraryDependency)
-        .then((LibraryElement loadedLibrary) {
-      if (loadedLibrary == null) return;
-      reporter.withCurrentElement(library, () {
-        libraryDependency.libraryDependency = loadedLibrary;
-        handler.registerDependency(library, libraryDependency, loadedLibrary);
-      });
-    });
-  }
-
-  Future<Script> _readScript(
-      Spannable spannable, Uri readableUri, Uri resolvedUri) {
-    if (readableUri == null) {
-      return new Future.value(new Script.synthetic(resolvedUri));
-    } else {
-      return scriptLoader.readScript(readableUri, spannable);
-    }
-  }
-
-  /**
-   * Create (or reuse) a library element for the library specified by the
-   * [resolvedUri].
-   *
-   * If a new library is created, the [handler] is notified.
-   */
-  Future<LibraryElement> createLibrary(LibraryDependencyHandler handler,
-      LibraryElement importingLibrary, Uri resolvedUri, Spannable spannable,
-      {bool skipFileWithPartOfTag: false}) async {
-    Uri readableUri =
-        uriTranslator.translate(importingLibrary, resolvedUri, spannable);
-    LibraryElement library = libraryCanonicalUriMap[resolvedUri];
-    if (library != null) {
-      return new Future.value(library);
-    }
-    return reporter.withCurrentElement(importingLibrary, () {
-      return _readScript(spannable, readableUri, resolvedUri)
-          .then((Script script) async {
-        if (script == null) return null;
-        LibraryElement element =
-            createLibrarySync(handler, script, resolvedUri);
-        CompilationUnitElementX compilationUnit = element.entryCompilationUnit;
-        if (compilationUnit.partTag != null) {
-          if (skipFileWithPartOfTag) {
-            // TODO(johnniwinther): Avoid calling
-            // [compiler.processLoadedLibraries] with this library.
-            libraryCanonicalUriMap.remove(resolvedUri);
-            return null;
-          }
-          if (importingLibrary == null) {
-            DiagnosticMessage error = reporter.withCurrentElement(
-                compilationUnit,
-                () => reporter.createMessage(
-                    compilationUnit.partTag, MessageKind.MAIN_HAS_PART_OF));
-            reporter.reportError(error);
-          } else {
-            DiagnosticMessage error = reporter.withCurrentElement(
-                compilationUnit,
-                () => reporter.createMessage(
-                    compilationUnit.partTag, MessageKind.IMPORT_PART_OF));
-            DiagnosticMessage info = reporter.withCurrentElement(
-                importingLibrary,
-                () => reporter.createMessage(
-                    spannable, MessageKind.IMPORT_PART_OF_HERE));
-            reporter.reportError(error, [info]);
-          }
-        }
-        await processLibraryTags(handler, element);
-        reporter.withCurrentElement(element, () {
-          handler.registerLibraryExports(element);
-        });
-
-        await patchLibraryIfNecessary(element, handler);
-        return element;
-      });
-    });
-  }
-
-  Future patchLibraryIfNecessary(
-      LibraryElement element, LibraryDependencyHandler handler) async {
-    if (element.isPlatformLibrary &&
-        // Don't patch library currently disallowed.
-        !element.isSynthesized &&
-        !element.isPatched) {
-      // Apply patch, if any.
-      Uri patchUri = _patchResolverFunc(element.canonicalUri.path);
-      if (patchUri != null) {
-        await _patchParserTask.patchLibrary(handler, patchUri, element);
-      }
-    }
-  }
-
-  LibraryElement createLibrarySync(
-      LibraryDependencyHandler handler, Script script, Uri resolvedUri) {
-    LibraryElement element = new LibraryElementX(script, resolvedUri);
-    return reporter.withCurrentElement(element, () {
-      if (handler != null) {
-        handler.registerNewLibrary(element);
-        libraryCanonicalUriMap[resolvedUri] = element;
-      }
-      scanner.scanLibrary(element);
-      return element;
-    });
-  }
-
-  CompilationUnitElement createUnitSync(Script script, LibraryElement library) {
-    CompilationUnitElementX unit = new CompilationUnitElementX(script, library);
-    reporter.withCurrentElement(unit, () {
-      scanner.scanUnit(unit);
-      if (unit.partTag == null && !script.isSynthesized) {
-        reporter.reportErrorMessage(unit, MessageKind.MISSING_PART_OF_TAG);
-      }
-    });
-    return unit;
-  }
-
-  void registerDeferredAction(DeferredAction action) {
-    _deferredActions.add(action);
-  }
-
-  Iterable<DeferredAction> pullDeferredActions() {
-    Iterable<DeferredAction> actions = _deferredActions.toList();
-    _deferredActions.clear();
-    return actions;
-  }
-}
-
 /// A loader that builds a kernel IR representation of the component.
 ///
 /// It supports loading both .dart source files or pre-compiled .dill files.
@@ -897,24 +298,12 @@
 
   KernelToElementMapForImpactImpl get elementMap => _elementMap;
 
-  void reset({bool reuseLibrary(LibraryElement library)}) {
-    throw new UnimplementedError('KernelLibraryLoaderTask.reset');
-  }
-
-  Future resetAsync(Future<bool> reuseLibrary(LibraryElement library)) {
-    throw new UnimplementedError('KernelLibraryLoaderTask.resetAsync');
-  }
-
   Iterable<LibraryEntity> get libraries => _allLoadedLibraries;
 
   LibraryEntity lookupLibrary(Uri canonicalUri) {
     return _elementMap?.lookupLibrary(canonicalUri);
   }
 
-  Future<Null> resetLibraries(ReuseLibrariesFunction reuseLibraries) {
-    throw new UnimplementedError('KernelLibraryLoaderTask.reuseLibraries');
-  }
-
   void registerDeferredAction(DeferredAction action) {
     throw new UnimplementedError(
         'KernelLibraryLoaderTask.registerDeferredAction');
@@ -923,581 +312,6 @@
   Iterable<DeferredAction> pullDeferredActions() => const <DeferredAction>[];
 }
 
-/// A state machine for checking script tags come in the correct order.
-class TagState {
-  /// Initial state.
-  static const int NO_TAG_SEEN = 0;
-
-  /// Passed to [checkTag] when a library declaration (the syntax "library
-  /// name;") has been seen. Not an actual state.
-  static const int LIBRARY = 1;
-
-  /// The state after the first library declaration.
-  static const int AFTER_LIBRARY_DECLARATION = 2;
-
-  /// The state after a import or export declaration has been seen, but before
-  /// a part tag has been seen.
-  static const int IMPORT_OR_EXPORT = 3;
-
-  /// The state after a part tag has been seen.
-  static const int PART = 4;
-
-  /// Encodes transition function for state machine.
-  static const List<int> NEXT = const <int>[
-    NO_TAG_SEEN,
-    AFTER_LIBRARY_DECLARATION, // Only one library tag is allowed.
-    IMPORT_OR_EXPORT,
-    IMPORT_OR_EXPORT,
-    PART,
-  ];
-
-  int tagState = TagState.NO_TAG_SEEN;
-
-  bool hasLibraryDeclaration = false;
-
-  /// If [value] is less than [tagState] complain. Regardless, update
-  /// [tagState] using transition function for state machine.
-  void checkTag(int value, LibraryTag tag, DiagnosticReporter reporter) {
-    if (tagState > value) {
-      MessageKind kind;
-      switch (value) {
-        case LIBRARY:
-          if (hasLibraryDeclaration) {
-            kind = MessageKind.ONLY_ONE_LIBRARY_TAG;
-          } else {
-            kind = MessageKind.LIBRARY_TAG_MUST_BE_FIRST;
-          }
-          break;
-
-        case IMPORT_OR_EXPORT:
-          if (tag.isImport) {
-            kind = MessageKind.IMPORT_BEFORE_PARTS;
-          } else if (tag.isExport) {
-            kind = MessageKind.EXPORT_BEFORE_PARTS;
-          } else {
-            reporter.internalError(tag, "Expected import or export.");
-          }
-          break;
-
-        default:
-          reporter.internalError(tag, "Unexpected order of library tags.");
-      }
-      reporter.reportErrorMessage(tag, kind);
-    }
-    tagState = NEXT[value];
-    if (value == LIBRARY) {
-      hasLibraryDeclaration = true;
-    }
-  }
-}
-
-/**
- * An [import] tag and the [importedLibrary] imported through [import].
- */
-class ImportLink {
-  final ImportElementX import;
-  final LibraryElement importedLibrary;
-
-  ImportLink(this.import, this.importedLibrary);
-
-  /**
-   * Imports the library into the [importingLibrary].
-   */
-  void importLibrary(
-      DiagnosticReporter reporter, LibraryElementX importingLibrary) {
-    assert(importedLibrary.exportsHandled,
-        failedAt(importedLibrary, 'Exports not handled on $importedLibrary'));
-    Import tag = import.node;
-    CombinatorFilter combinatorFilter = new CombinatorFilter.fromTag(tag);
-    if (tag != null && tag.prefix != null) {
-      String prefix = tag.prefix.source;
-      Element existingElement = importingLibrary.find(prefix);
-      PrefixElementX prefixElement;
-      if (existingElement == null || !existingElement.isPrefix) {
-        prefixElement = new PrefixElementX(
-            prefix,
-            importingLibrary.entryCompilationUnit,
-            tag.getBeginToken(),
-            tag.isDeferred ? import : null);
-      } else {
-        prefixElement = existingElement;
-      }
-      importingLibrary.addToScope(prefixElement, reporter);
-      importedLibrary.forEachExport((Element element) {
-        if (combinatorFilter.exclude(element)) return;
-        prefixElement.addImport(element, import, reporter);
-      });
-      import.prefix = prefixElement;
-      if (prefixElement.isDeferred) {
-        prefixElement.addImport(
-            new DeferredLoaderGetterElementX(prefixElement), import, reporter);
-      }
-    } else {
-      importedLibrary.forEachExport((Element element) {
-        reporter.withCurrentElement(importingLibrary, () {
-          if (combinatorFilter.exclude(element)) return;
-          importingLibrary.addImport(element, import, reporter);
-        });
-      });
-    }
-  }
-}
-
-/**
- * The combinator filter computed from an export tag and the library dependency
- * node for the library that declared the export tag. This represents an edge in
- * the library dependency graph.
- */
-class ExportLink {
-  final ExportElementX export;
-  final CombinatorFilter combinatorFilter;
-  final LibraryDependencyNode exportNode;
-
-  ExportLink(ExportElementX export, LibraryDependencyNode this.exportNode)
-      : this.export = export,
-        this.combinatorFilter = new CombinatorFilter.fromTag(export.node);
-
-  /**
-   * Exports [element] to the dependent library unless [element] is filtered by
-   * the export combinators. Returns [:true:] if the set pending exports of the
-   * dependent library was modified.
-   */
-  bool exportElement(Element element) {
-    if (combinatorFilter.exclude(element)) return false;
-    return exportNode.addElementToPendingExports(element, export);
-  }
-}
-
-/**
- * A node in the library dependency graph.
- *
- * This class is used to collect the library dependencies expressed through
- * import and export tags, and as the work-list entry in computations of library
- * exports performed in [LibraryDependencyHandler.computeExports].
- */
-class LibraryDependencyNode {
-  final LibraryElementX library;
-
-  // Stored identity based hashCode for performance.
-  final int hashCode = _nextHash = (_nextHash + 100019).toUnsigned(30);
-  static int _nextHash = 0;
-
-  /**
-   * A linked list of the import tags that import [library] mapped to the
-   * corresponding libraries. This is used to propagate exports into imports
-   * after the export scopes have been computed.
-   */
-  Link<ImportLink> imports = const Link<ImportLink>();
-
-  /// A linked list of all libraries directly exported by [library].
-  Link<LibraryElement> exports = const Link<LibraryElement>();
-
-  /**
-   * A linked list of the export tags the dependent upon this node library.
-   * This is used to propagate exports during the computation of export scopes.
-   */
-  Link<ExportLink> dependencies = const Link<ExportLink>();
-
-  /**
-   * The export scope for [library] which is gradually computed by the work-list
-   * computation in [LibraryDependencyHandler.computeExports].
-   */
-  Map<String, Element> exportScope = <String, Element>{};
-
-  /// Map from exported elements to the export directives that exported them.
-  Map<Element, Link<ExportElement>> exporters =
-      <Element, Link<ExportElement>>{};
-
-  /**
-   * The set of exported elements that need to be propageted to dependent
-   * libraries as part of the work-list computation performed in
-   * [LibraryDependencyHandler.computeExports]. Each export element is mapped
-   * to a list of exports directives that export it.
-   */
-  Map<Element, Link<ExportElement>> pendingExportMap =
-      <Element, Link<ExportElement>>{};
-
-  LibraryDependencyNode(this.library);
-
-  /**
-   * Registers that the library of this node imports [importLibrary] through the
-   * [import] tag.
-   */
-  void registerImportDependency(
-      ImportElementX import, LibraryElement importedLibrary) {
-    imports = imports.prepend(new ImportLink(import, importedLibrary));
-  }
-
-  /**
-   * Registers that the library of this node is exported by
-   * [exportingLibraryNode] through the [export] tag.
-   */
-  void registerExportDependency(
-      ExportElementX export, LibraryDependencyNode exportingLibraryNode) {
-    // Register the exported library in the exporting library node.
-    exportingLibraryNode.exports =
-        exportingLibraryNode.exports.prepend(library);
-    // Register the export in the exported library node.
-    dependencies =
-        dependencies.prepend(new ExportLink(export, exportingLibraryNode));
-  }
-
-  /**
-   * Registers all non-private locally declared members of the library of this
-   * node to be exported. This forms the basis for the work-list computation of
-   * the export scopes performed in [LibraryDependencyHandler.computeExports].
-   */
-  void registerInitialExports() {
-    for (Element element in library.getNonPrivateElementsInScope()) {
-      pendingExportMap[element] = const Link<ExportElement>();
-    }
-  }
-
-  /// Register the already computed export scope of [exportedLibraryElement] to
-  /// export from the library of this node through the [export]  declaration
-  /// with the given combination [filter].
-  ///
-  /// Additionally, check that all names in the show/hide combinators are in the
-  /// export scope of [exportedLibraryElement].
-  void registerHandledExports(
-      DiagnosticReporter reporter,
-      LibraryElement exportedLibraryElement,
-      ExportElementX export,
-      CombinatorFilter filter) {
-    assert(exportedLibraryElement.exportsHandled, failedAt(library));
-    exportedLibraryElement.forEachExport((Element exportedElement) {
-      if (!filter.exclude(exportedElement)) {
-        Link<ExportElement> exports = pendingExportMap.putIfAbsent(
-            exportedElement, () => const Link<ExportElement>());
-        pendingExportMap[exportedElement] = exports.prepend(export);
-      }
-    });
-    if (!reporter.options.suppressHints) {
-      reporter.withCurrentElement(library, () {
-        checkLibraryDependency(reporter, export.node, exportedLibraryElement);
-      });
-    }
-  }
-
-  /**
-   * Registers the compute export scope with the node library.
-   */
-  void registerExports() {
-    library.setExports(exportScope.values.toList());
-  }
-
-  /**
-   * Registers the imports of the node library.
-   */
-  void registerImports(DiagnosticReporter reporter) {
-    for (ImportLink link in imports) {
-      link.importLibrary(reporter, library);
-    }
-  }
-
-  /**
-   * Copies and clears pending export set for this node.
-   */
-  Map<Element, Link<ExportElement>> pullPendingExports() {
-    Map<Element, Link<ExportElement>> pendingExports =
-        new Map<Element, Link<ExportElement>>.from(pendingExportMap);
-    pendingExportMap.clear();
-    return pendingExports;
-  }
-
-  /**
-   * Adds [element] to the export scope for this node. If the [element] name
-   * is a duplicate, an error element is inserted into the export scope.
-   */
-  Element addElementToExportScope(DiagnosticReporter reporter, Element element,
-      Link<ExportElement> exports) {
-    String name = element.name;
-    DiagnosticMessage error;
-    List<DiagnosticMessage> infos = <DiagnosticMessage>[];
-
-    void createDuplicateExportMessage(
-        Element duplicate, Link<ExportElement> duplicateExports) {
-      assert(
-          !duplicateExports.isEmpty,
-          failedAt(
-              library,
-              "No export for $duplicate from ${duplicate.library} "
-              "in $library."));
-      reporter.withCurrentElement(library, () {
-        for (ExportElement export in duplicateExports) {
-          if (error == null) {
-            error = reporter.createMessage(
-                export, MessageKind.DUPLICATE_EXPORT, {'name': name});
-          } else {
-            infos.add(reporter.createMessage(
-                export, MessageKind.DUPLICATE_EXPORT_CONT, {'name': name}));
-          }
-        }
-      });
-    }
-
-    void createDuplicateExportDeclMessage(
-        Element duplicate, Link<ExportElement> duplicateExports) {
-      assert(
-          !duplicateExports.isEmpty,
-          failedAt(
-              library,
-              "No export for $duplicate from ${duplicate.library} "
-              "in $library."));
-      infos.add(reporter.createMessage(
-          duplicate,
-          MessageKind.DUPLICATE_EXPORT_DECL,
-          {'name': name, 'uriString': duplicateExports.head.uri}));
-    }
-
-    Element existingElement = exportScope[name];
-    if (existingElement != null && existingElement != element) {
-      if (existingElement.isMalformed) {
-        createDuplicateExportMessage(element, exports);
-        createDuplicateExportDeclMessage(element, exports);
-        element = existingElement;
-      } else if (existingElement.library == library) {
-        // Do nothing. [existingElement] hides [element].
-      } else if (element.library == library) {
-        // [element] hides [existingElement].
-        exportScope[name] = element;
-        exporters[element] = exports;
-      } else {
-        // Declared elements hide exported elements.
-        Link<ExportElement> existingExports = exporters[existingElement];
-        createDuplicateExportMessage(existingElement, existingExports);
-        createDuplicateExportMessage(element, exports);
-        createDuplicateExportDeclMessage(existingElement, existingExports);
-        createDuplicateExportDeclMessage(element, exports);
-        element = exportScope[name] = new ErroneousElementX(
-            MessageKind.DUPLICATE_EXPORT, {'name': name}, name, library);
-      }
-    } else {
-      exportScope[name] = element;
-      exporters[element] = exports;
-    }
-    if (error != null) {
-      reporter.reportError(error, infos);
-    }
-    return element;
-  }
-
-  /**
-   * Propagates the exported [element] to all library nodes that depend upon
-   * this node. If the propagation updated any pending exports, [:true:] is
-   * returned.
-   */
-  bool propagateElement(Element element) {
-    bool change = false;
-    for (ExportLink link in dependencies) {
-      if (link.exportElement(element)) {
-        change = true;
-      }
-    }
-    return change;
-  }
-
-  /**
-   * Adds [element] to the pending exports of this node and returns [:true:] if
-   * the pending export set was modified. The combinators of [export] are used
-   * to filter the element.
-   */
-  bool addElementToPendingExports(Element element, ExportElement export) {
-    bool changed = false;
-    if (!identical(exportScope[element.name], element)) {
-      Link<ExportElement> exports = pendingExportMap.putIfAbsent(element, () {
-        changed = true;
-        return const Link<ExportElement>();
-      });
-      pendingExportMap[element] = exports.prepend(export);
-    }
-    return changed;
-  }
-
-  /// Check that all names in the show/hide combinators of imports and exports
-  /// are in the export scope of the imported/exported libraries.
-  void checkCombinators(DiagnosticReporter reporter) {
-    reporter.withCurrentElement(library, () {
-      for (ImportLink importLink in imports) {
-        checkLibraryDependency(
-            reporter, importLink.import.node, importLink.importedLibrary);
-      }
-    });
-    for (ExportLink exportLink in dependencies) {
-      reporter.withCurrentElement(exportLink.exportNode.library, () {
-        checkLibraryDependency(reporter, exportLink.export.node, library);
-      });
-    }
-  }
-
-  /// Check that all names in the show/hide combinators of [tag] are in the
-  /// export scope of [library].
-  void checkLibraryDependency(DiagnosticReporter reporter,
-      LibraryDependency tag, LibraryElement library) {
-    if (tag == null || tag.combinators == null) return;
-    for (Combinator combinator in tag.combinators) {
-      for (Identifier identifier in combinator.identifiers) {
-        String name = identifier.source;
-        Element element = library.findExported(name);
-        if (element == null) {
-          if (combinator.isHide) {
-            if (library.isPackageLibrary &&
-                reporter.options.hidePackageWarnings) {
-              // Only report hide hint on packages if we show warnings on these:
-              // The hide may be non-empty in some versions of the package, in
-              // which case you shouldn't remove the combinator.
-              continue;
-            }
-            reporter.reportHintMessage(identifier, MessageKind.EMPTY_HIDE,
-                {'uri': library.canonicalUri, 'name': name});
-          } else if (!library.isDartCore || name != 'dynamic') {
-            // TODO(sigmund): remove this condition, we don't report a hint for
-            // `import "dart:core" show dynamic;` until our tools match in
-            // semantics (see #29125).
-            reporter.reportHintMessage(identifier, MessageKind.EMPTY_SHOW,
-                {'uri': library.canonicalUri, 'name': name});
-          }
-        }
-      }
-    }
-  }
-}
-
-/**
- * Helper class used for computing the possibly cyclic import/export scopes of
- * a set of libraries.
- *
- * This class is used by [ScannerTask.scanLibrary] to collect all newly loaded
- * libraries and to compute their import/export scopes through a fixed-point
- * algorithm.
- */
-class LibraryDependencyHandler implements LibraryLoader {
-  final ResolutionLibraryLoaderTask task;
-  final List<LibraryElement> _newLibraries = <LibraryElement>[];
-
-  /**
-   * Newly loaded libraries and their corresponding node in the library
-   * dependency graph. Libraries that have already been fully loaded are not
-   * part of the dependency graph of this handler since their export scopes have
-   * already been computed.
-   */
-  Map<LibraryElement, LibraryDependencyNode> nodeMap =
-      new Map<LibraryElement, LibraryDependencyNode>();
-
-  LibraryDependencyHandler(this.task);
-
-  DiagnosticReporter get reporter => task.reporter;
-
-  /// The libraries created with this handler.
-  Iterable<LibraryElement> get newLibraries => _newLibraries;
-
-  /**
-   * Performs a fixed-point computation on the export scopes of all registered
-   * libraries and creates the import/export of the libraries based on the
-   * fixed-point.
-   */
-  void computeExports() {
-    bool changed = true;
-    while (changed) {
-      changed = false;
-      Map<LibraryDependencyNode, Map<Element, Link<ExportElement>>> tasks =
-          new Map<LibraryDependencyNode, Map<Element, Link<ExportElement>>>();
-
-      // Locally defined elements take precedence over exported
-      // elements.  So we must propagate local elements first.  We
-      // ensure this by pulling the pending exports before
-      // propagating.  This enforces that we handle exports
-      // breadth-first, with locally defined elements being level 0.
-      nodeMap.forEach((_, LibraryDependencyNode node) {
-        Map<Element, Link<ExportElement>> pendingExports =
-            node.pullPendingExports();
-        tasks[node] = pendingExports;
-      });
-      tasks.forEach((LibraryDependencyNode node,
-          Map<Element, Link<ExportElement>> pendingExports) {
-        pendingExports.forEach((Element element, Link<ExportElement> exports) {
-          element = node.addElementToExportScope(reporter, element, exports);
-          if (node.propagateElement(element)) {
-            changed = true;
-          }
-        });
-      });
-    }
-
-    // Setup export scopes. These have to be set before computing the import
-    // scopes to avoid accessing uncomputed export scopes during handling of
-    // imports.
-    nodeMap.forEach((LibraryElement library, LibraryDependencyNode node) {
-      node.registerExports();
-    });
-
-    // Setup import scopes.
-    nodeMap.forEach((LibraryElement library, LibraryDependencyNode node) {
-      node.registerImports(reporter);
-    });
-
-    if (!reporter.options.suppressHints) {
-      nodeMap.forEach((LibraryElement library, LibraryDependencyNode node) {
-        node.checkCombinators(reporter);
-      });
-    }
-  }
-
-  /// Registers that [library] depends on [loadedLibrary] through
-  /// [libraryDependency].
-  void registerDependency(
-      LibraryElementX library,
-      LibraryDependencyElementX libraryDependency,
-      LibraryElement loadedLibrary) {
-    if (libraryDependency.isExport) {
-      // [loadedLibrary] is exported by [library].
-      LibraryDependencyNode exportingNode = nodeMap[library];
-      if (loadedLibrary.exportsHandled) {
-        // Export scope already computed on [loadedLibrary].
-        CombinatorFilter combinatorFilter =
-            new CombinatorFilter.fromTag(libraryDependency.node);
-        exportingNode.registerHandledExports(
-            reporter, loadedLibrary, libraryDependency, combinatorFilter);
-        return;
-      }
-      LibraryDependencyNode exportedNode = nodeMap[loadedLibrary];
-      assert(exportedNode != null,
-          failedAt(loadedLibrary, "$loadedLibrary has not been registered"));
-      assert(exportingNode != null,
-          failedAt(library, "$library has not been registered"));
-      exportedNode.registerExportDependency(libraryDependency, exportingNode);
-    } else if (libraryDependency == null || libraryDependency.isImport) {
-      // [loadedLibrary] is imported by [library].
-      LibraryDependencyNode importingNode = nodeMap[library];
-      assert(importingNode != null,
-          failedAt(library, "$library has not been registered"));
-      importingNode.registerImportDependency(libraryDependency, loadedLibrary);
-    }
-  }
-
-  /**
-   * Registers [library] for the processing of its import/export scope.
-   */
-  void registerNewLibrary(LibraryElement library) {
-    _newLibraries.add(library);
-    if (!library.exportsHandled) {
-      nodeMap[library] = new LibraryDependencyNode(library);
-    }
-  }
-
-  /**
-   * Registers all top-level entities of [library] as starting point for the
-   * fixed-point computation of the import/export scopes.
-   */
-  void registerLibraryExports(LibraryElement library) {
-    nodeMap[library].registerInitialExports();
-  }
-
-  Future processLibraryTags(LibraryElement library) {
-    return task.processLibraryTags(this, library);
-  }
-}
-
 /// Information on the set libraries loaded as a result of a call to
 /// [LibraryLoader.loadLibrary].
 abstract class LoadedLibraries {
@@ -1526,104 +340,6 @@
       {bool callback(Link<Uri> importChainReversed)});
 }
 
-class _LoadedLibraries implements LoadedLibraries {
-  final LibraryElement rootLibrary;
-  final Map<Uri, LibraryElement> loadedLibraries = <Uri, LibraryElement>{};
-  final List<LibraryElement> _newLibraries;
-
-  _LoadedLibraries(this.rootLibrary, this._newLibraries) {
-    _newLibraries.forEach((LibraryElement loadedLibrary) {
-      loadedLibraries[loadedLibrary.canonicalUri] = loadedLibrary;
-    });
-    assert(rootLibrary != null);
-  }
-
-  bool containsLibrary(Uri uri) => loadedLibraries.containsKey(uri);
-
-  LibraryElement getLibrary(Uri uri) => loadedLibraries[uri];
-
-  void forEachLibrary(f(LibraryElement library)) => _newLibraries.forEach(f);
-
-  void forEachImportChain(Uri targetUri,
-      {bool callback(Link<Uri> importChainReversed)}) {
-    bool aborted = false;
-
-    /// Map from libraries to the set of (unreversed) paths to [uri].
-    Map<LibraryElement, Iterable<Link<Uri>>> suffixChainMap =
-        <LibraryElement, Iterable<Link<Uri>>>{};
-
-    /// Computes the set of (unreversed) paths to [targetUri].
-    ///
-    /// Finds all paths (suffixes) from the current library to [uri] and stores
-    /// it in [suffixChainMap].
-    ///
-    /// For every found suffix it prepends the given [prefix] and the canonical
-    /// uri of [library] and invokes the [callback] with the concatenated chain.
-    void computeSuffixes(LibraryElement library, Link<Uri> prefix) {
-      if (aborted) return;
-
-      Uri canonicalUri = library.canonicalUri;
-      prefix = prefix.prepend(canonicalUri);
-      if (suffixChainMap.containsKey(library)) return;
-      suffixChainMap[library] = const <Link<Uri>>[];
-      List<Link<Uri>> suffixes = [];
-      if (targetUri != canonicalUri) {
-        /// Process the import (or export) of [importedLibrary].
-        void processLibrary(LibraryElement importedLibrary) {
-          bool suffixesArePrecomputed =
-              suffixChainMap.containsKey(importedLibrary);
-
-          if (!suffixesArePrecomputed) {
-            computeSuffixes(importedLibrary, prefix);
-            if (aborted) return;
-          }
-
-          for (Link<Uri> suffix in suffixChainMap[importedLibrary]) {
-            suffixes.add(suffix.prepend(canonicalUri));
-
-            if (suffixesArePrecomputed) {
-              // Only report chains through [import] if the suffixes had already
-              // been computed, otherwise [computeSuffixes] have reported the
-              // paths through [prefix].
-              Link<Uri> chain = prefix;
-              while (!suffix.isEmpty) {
-                chain = chain.prepend(suffix.head);
-                suffix = suffix.tail;
-              }
-              if (!callback(chain)) {
-                aborted = true;
-                return;
-              }
-            }
-          }
-        }
-
-        for (ImportElement import in library.imports) {
-          processLibrary(import.importedLibrary);
-          if (aborted) return;
-        }
-        for (ExportElement export in library.exports) {
-          processLibrary(export.exportedLibrary);
-          if (aborted) return;
-        }
-      } else {
-        // Here `targetUri == canonicalUri`.
-        if (!callback(prefix)) {
-          aborted = true;
-          return;
-        }
-        suffixes.add(const Link<Uri>().prepend(canonicalUri));
-      }
-      suffixChainMap[library] = suffixes;
-      return;
-    }
-
-    computeSuffixes(rootLibrary, const Link<Uri>());
-  }
-
-  String toString() => 'root=$rootLibrary,libraries=${_newLibraries}';
-}
-
 /// Adapter class to mimic the behavior of LoadedLibraries for Kernel element
 /// behavior. Ultimately we'll just access worldBuilder instead.
 class _LoadedLibrariesAdapter implements LoadedLibraries {
@@ -1652,23 +368,3 @@
 
   String toString() => 'root=$rootLibrary,libraries=${_newLibraries}';
 }
-
-/// API used by the library loader to request scripts from the compiler system.
-abstract class ScriptLoader {
-  /// Load script from a readable [uri], report any errors using the location of
-  /// the given [spannable].
-  Future<Script> readScript(Uri uri, [Spannable spannable]);
-
-  /// Load a binary from a readable [uri], report any errors using the location
-  /// of the given [spannable].
-  Future<Binary> readBinary(Uri uri, [Spannable spannable]);
-}
-
-/// API used by the library loader to synchronously scan a library or
-/// compilation unit and ensure that their library tags are computed.
-abstract class ElementScanner {
-  void scanLibrary(LibraryElement library);
-  void scanUnit(CompilationUnitElement unit);
-}
-
-const _reuseLibrarySubtaskName = "Reuse library";
diff --git a/pkg/compiler/lib/src/mirrors_used.dart b/pkg/compiler/lib/src/mirrors_used.dart
deleted file mode 100644
index c295a27..0000000
--- a/pkg/compiler/lib/src/mirrors_used.dart
+++ /dev/null
@@ -1,578 +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.
-
-library dart2js.mirrors_used;
-
-import 'common/tasks.dart' show CompilerTask;
-import 'common.dart';
-import 'compile_time_constants.dart' show ConstantCompiler;
-import 'compiler.dart' show Compiler;
-import 'constants/expressions.dart';
-import 'constants/values.dart'
-    show
-        ConstantValue,
-        ConstructedConstantValue,
-        ListConstantValue,
-        StringConstantValue,
-        TypeConstantValue;
-import 'elements/resolution_types.dart'
-    show ResolutionDartType, ResolutionInterfaceType;
-import 'elements/elements.dart'
-    show
-        ClassElement,
-        Element,
-        FieldElement,
-        ImportElement,
-        LibraryElement,
-        MetadataAnnotation,
-        ScopeContainerElement;
-import 'elements/entities.dart';
-import 'resolution/tree_elements.dart' show TreeElements;
-import 'tree/tree.dart' show NamedArgument, NewExpression, Node;
-
-/**
- * Compiler task that analyzes MirrorsUsed annotations.
- *
- * When importing 'dart:mirrors', it is possible to annotate the import with
- * MirrorsUsed annotation.  This is a way to declare what elements will be
- * reflected on at runtime.  Such elements, even they would normally be
- * discarded by the implicit tree-shaking algorithm must be preserved in the
- * final output.
- *
- * Since some libraries cannot tell exactly what they will be reflecting on, it
- * is possible for one library to specify a MirrorsUsed annotation that applies
- * to another library. For example:
- *
- * Mirror utility library that cannot tell what it is reflecting on:
- * library mirror_utils;
- * import 'dart:mirrors';
- * ...
- *
- * The main app which knows how it use the mirror utility library:
- * library main_app;
- * @MirrorsUsed(override='mirror_utils')
- * import 'dart:mirrors';
- * import 'mirror_utils.dart';
- * ...
- *
- * In this case, we say that @MirrorsUsed in main_app overrides @MirrorsUsed in
- * mirror_utils.
- *
- * It is possible to override all libraries using override='*'.  If multiple
- * catch-all overrides like this, they are merged together.
- *
- * It is possible for library "a" to declare that it overrides library "b", and
- * vice versa. In this case, both annotations will be discarded and the
- * compiler will emit a hint (that is, a warning that is not specified by the
- * language specification).
- *
- * After applying all the overrides, we can iterate over libraries that import
- * 'dart:mirrors'. If a library does not have an associated MirrorsUsed
- * annotation, then we have to discard all MirrorsUsed annotations and assume
- * everything can be reflected on.
- *
- * On the other hand, if all libraries importing dart:mirrors have a
- * MirrorsUsed annotation, these annotations are merged.
- *
- * MERGING MIRRORSUSED
- *
- * TBD.
- */
-class MirrorUsageAnalyzerTask extends CompilerTask {
-  Set<LibraryElement> librariesWithUsage;
-  MirrorUsageAnalyzer analyzer;
-  final Compiler compiler;
-
-  MirrorUsageAnalyzerTask(Compiler compiler)
-      : compiler = compiler,
-        super(compiler.measurer) {
-    analyzer = new MirrorUsageAnalyzer(compiler, this);
-  }
-
-  /// Collect @MirrorsUsed annotations in all libraries.  Called by the
-  /// compiler after all libraries are loaded, but before resolution.
-  void analyzeUsage(LibraryEntity mainApp) {
-    if (mainApp == null ||
-        compiler.resolution.commonElements.mirrorsLibrary == null) {
-      return;
-    }
-    measure(analyzer.run);
-    List<String> symbols = analyzer.mergedMirrorUsage.symbols;
-    List<Element> targets = analyzer.mergedMirrorUsage.targets;
-    List<Element> metaTargets = analyzer.mergedMirrorUsage.metaTargets;
-    compiler.backend.mirrorsDataBuilder.registerMirrorUsage(
-        symbols == null ? null : new Set<String>.from(symbols),
-        targets == null ? null : new Set<Element>.from(targets),
-        metaTargets == null ? null : new Set<Element>.from(metaTargets));
-    librariesWithUsage = analyzer.librariesWithUsage;
-  }
-
-  /// Is there a @MirrorsUsed annotation in the library of [element]?  Used by
-  /// the resolver to suppress hints about using new Symbol or
-  /// MirrorSystem.getName.
-  bool hasMirrorUsage(Element element) {
-    LibraryElement library = element.library;
-    // Internal libraries always have implicit mirror usage.
-    return library.isInternalLibrary ||
-        (librariesWithUsage != null && librariesWithUsage.contains(library));
-  }
-
-  /// Call-back from the resolver to analyze MirrorsUsed annotations. The result
-  /// is stored in [analyzer] and later used to compute
-  /// [:analyzer.mergedMirrorUsage:].
-  void validate(NewExpression node, TreeElements mapping) {
-    for (Node argument in node.send.arguments) {
-      NamedArgument named = argument.asNamedArgument();
-      if (named == null) continue;
-      ConstantCompiler constantCompiler = compiler.resolver.constantCompiler;
-      ConstantValue value = constantCompiler.getConstantValue(
-          constantCompiler.compileNode(named.expression, mapping));
-
-      MirrorUsageBuilder builder = new MirrorUsageBuilder(analyzer,
-          mapping.analyzedElement.library, named.expression, value, mapping);
-
-      if (named.name.source == 'symbols') {
-        analyzer.cachedStrings[value] =
-            builder.convertConstantToUsageList(value, onlyStrings: true);
-      } else if (named.name.source == 'targets') {
-        analyzer.cachedElements[value] =
-            builder.resolveUsageList(builder.convertConstantToUsageList(value));
-      } else if (named.name.source == 'metaTargets') {
-        analyzer.cachedElements[value] =
-            builder.resolveUsageList(builder.convertConstantToUsageList(value));
-      } else if (named.name.source == 'override') {
-        analyzer.cachedElements[value] =
-            builder.resolveUsageList(builder.convertConstantToUsageList(value));
-      }
-    }
-  }
-}
-
-class MirrorUsageAnalyzer {
-  final Compiler compiler;
-  final MirrorUsageAnalyzerTask task;
-  List<LibraryElement> wildcard;
-  final Set<LibraryElement> librariesWithUsage;
-  final Map<ConstantValue, List<String>> cachedStrings;
-  final Map<ConstantValue, List<Element>> cachedElements;
-  MirrorUsage mergedMirrorUsage;
-
-  MirrorUsageAnalyzer(this.compiler, this.task)
-      : librariesWithUsage = new Set<LibraryElement>(),
-        cachedStrings = new Map<ConstantValue, List<String>>(),
-        cachedElements = new Map<ConstantValue, List<Element>>();
-
-  DiagnosticReporter get reporter => compiler.reporter;
-
-  /// Collect and merge all @MirrorsUsed annotations. As a side-effect, also
-  /// compute which libraries have the annotation (which is used by
-  /// [MirrorUsageAnalyzerTask.hasMirrorUsage]).
-  void run() {
-    wildcard = compiler.libraryLoader.libraries.toList();
-    Map<LibraryElement, List<MirrorUsage>> usageMap =
-        collectMirrorsUsedAnnotation();
-    propagateOverrides(usageMap);
-    Set<LibraryElement> librariesWithoutUsage = new Set<LibraryElement>();
-    usageMap.forEach((LibraryElement library, List<MirrorUsage> usage) {
-      if (usage.isEmpty) librariesWithoutUsage.add(library);
-    });
-    if (librariesWithoutUsage.isEmpty) {
-      mergedMirrorUsage = mergeUsages(usageMap);
-    } else {
-      mergedMirrorUsage = new MirrorUsage(null, null, null, null);
-    }
-  }
-
-  /// Collect all @MirrorsUsed from all libraries and represent them as
-  /// [MirrorUsage].
-  Map<LibraryElement, List<MirrorUsage>> collectMirrorsUsedAnnotation() {
-    Map<LibraryElement, List<MirrorUsage>> result =
-        new Map<LibraryElement, List<MirrorUsage>>();
-    for (LibraryElement library in compiler.libraryLoader.libraries) {
-      if (library.isInternalLibrary) continue;
-      for (ImportElement import in library.imports) {
-        reporter.withCurrentElement(library, () {
-          List<MirrorUsage> usages = mirrorsUsedOnLibraryTag(library, import);
-          if (usages != null) {
-            List<MirrorUsage> existing = result[library];
-            if (existing != null) {
-              existing.addAll(usages);
-            } else {
-              result[library] = usages;
-            }
-          }
-        });
-      }
-    }
-    return result;
-  }
-
-  /// Apply [MirrorUsage] with 'override' to libraries they override.
-  void propagateOverrides(Map<LibraryElement, List<MirrorUsage>> usageMap) {
-    Map<LibraryElement, List<MirrorUsage>> propagatedOverrides =
-        new Map<LibraryElement, List<MirrorUsage>>();
-    usageMap.forEach((LibraryElement library, List<MirrorUsage> usages) {
-      for (MirrorUsage usage in usages) {
-        List<Element> override = usage.override;
-        if (override == null) continue;
-        if (override == wildcard) {
-          for (LibraryElement overridden in wildcard) {
-            if (overridden != library) {
-              List<MirrorUsage> overriddenUsages = propagatedOverrides
-                  .putIfAbsent(overridden, () => <MirrorUsage>[]);
-              overriddenUsages.add(usage);
-            }
-          }
-        } else {
-          for (Element overridden in override) {
-            List<MirrorUsage> overriddenUsages = propagatedOverrides
-                .putIfAbsent(overridden, () => <MirrorUsage>[]);
-            overriddenUsages.add(usage);
-          }
-        }
-      }
-    });
-    propagatedOverrides.forEach(
-        (LibraryElement overridden, List<MirrorUsage> overriddenUsages) {
-      List<MirrorUsage> usages =
-          usageMap.putIfAbsent(overridden, () => <MirrorUsage>[]);
-      usages.addAll(overriddenUsages);
-    });
-  }
-
-  /// Find @MirrorsUsed annotations on the given import [tag] in [library]. The
-  /// annotations are represented as [MirrorUsage].
-  List<MirrorUsage> mirrorsUsedOnLibraryTag(
-      LibraryElement library, ImportElement import) {
-    LibraryElement importedLibrary = import.importedLibrary;
-    if (importedLibrary != compiler.resolution.commonElements.mirrorsLibrary) {
-      return null;
-    }
-    List<MirrorUsage> result = <MirrorUsage>[];
-    for (MetadataAnnotation metadata in import.metadata) {
-      metadata.ensureResolved(compiler.resolution);
-      ConstantValue value =
-          compiler.constants.getConstantValue(metadata.constant);
-      ResolutionDartType type =
-          value.getType(compiler.resolution.commonElements);
-      Element element = type.element;
-      if (element == compiler.resolution.commonElements.mirrorsUsedClass) {
-        result.add(buildUsage(value));
-      }
-    }
-    return result;
-  }
-
-  /// Merge all [MirrorUsage] instances across all libraries.
-  MirrorUsage mergeUsages(Map<LibraryElement, List<MirrorUsage>> usageMap) {
-    Set<MirrorUsage> usagesToMerge = new Set<MirrorUsage>();
-    usageMap.forEach((LibraryElement library, List<MirrorUsage> usages) {
-      librariesWithUsage.add(library);
-      usagesToMerge.addAll(usages);
-    });
-    if (usagesToMerge.isEmpty) {
-      return new MirrorUsage(null, wildcard, null, null);
-    } else {
-      MirrorUsage result = new MirrorUsage(null, null, null, null);
-      for (MirrorUsage usage in usagesToMerge) {
-        result = merge(result, usage);
-      }
-      return result;
-    }
-  }
-
-  /// Merge [a] with [b]. The resulting [MirrorUsage] simply has the symbols,
-  /// targets, and metaTargets of [a] and [b] concatenated. 'override' is
-  /// ignored.
-  MirrorUsage merge(MirrorUsage a, MirrorUsage b) {
-    // TOOO(ahe): Should be an instance method on MirrorUsage.
-    if (a.symbols == null && a.targets == null && a.metaTargets == null) {
-      return b;
-    } else if (b.symbols == null &&
-        b.targets == null &&
-        b.metaTargets == null) {
-      return a;
-    }
-    // TODO(ahe): Test the following cases.
-    List<String> symbols = a.symbols;
-    if (symbols == null) {
-      symbols = b.symbols;
-    } else if (b.symbols != null) {
-      symbols.addAll(b.symbols);
-    }
-    List<Element> targets = a.targets;
-    if (targets == null) {
-      targets = b.targets;
-    } else if (targets != wildcard && b.targets != null) {
-      targets.addAll(b.targets);
-    }
-    List<Element> metaTargets = a.metaTargets;
-    if (metaTargets == null) {
-      metaTargets = b.metaTargets;
-    } else if (metaTargets != wildcard && b.metaTargets != null) {
-      metaTargets.addAll(b.metaTargets);
-    }
-    return new MirrorUsage(symbols, targets, metaTargets, null);
-  }
-
-  /// Convert a [constant] to an instance of [MirrorUsage] using information
-  /// that was resolved during [MirrorUsageAnalyzerTask.validate].
-  MirrorUsage buildUsage(ConstructedConstantValue constant) {
-    Map<FieldElement, ConstantValue> fields = constant.fields;
-    ClassElement cls = compiler.resolution.commonElements.mirrorsUsedClass;
-    FieldElement symbolsField = cls.lookupLocalMember('symbols');
-    FieldElement targetsField = cls.lookupLocalMember('targets');
-    FieldElement metaTargetsField = cls.lookupLocalMember('metaTargets');
-    FieldElement overrideField = cls.lookupLocalMember('override');
-
-    return new MirrorUsage(
-        cachedStrings[fields[symbolsField]],
-        cachedElements[fields[targetsField]],
-        cachedElements[fields[metaTargetsField]],
-        cachedElements[fields[overrideField]]);
-  }
-}
-
-/// Used to represent a resolved MirrorsUsed constant.
-class MirrorUsage {
-  final List<String> symbols;
-  final List<Element> targets;
-  final List<Element> metaTargets;
-  final List<Element> override;
-
-  MirrorUsage(this.symbols, this.targets, this.metaTargets, this.override);
-
-  String toString() {
-    return 'MirrorUsage('
-        'symbols = $symbols, '
-        'targets = $targets, '
-        'metaTargets = $metaTargets, '
-        'override = $override'
-        ')';
-  }
-}
-
-class MirrorUsageBuilder {
-  final MirrorUsageAnalyzer analyzer;
-  final LibraryElement enclosingLibrary;
-  final Spannable spannable;
-  final ConstantValue constant;
-  final TreeElements elements;
-
-  MirrorUsageBuilder(this.analyzer, this.enclosingLibrary, this.spannable,
-      this.constant, this.elements);
-
-  Compiler get compiler => analyzer.compiler;
-
-  DiagnosticReporter get reporter => analyzer.reporter;
-
-  /// Convert a constant to a list of [String] and [Type] values. If the
-  /// constant is a single [String], it is assumed to be a comma-separated list
-  /// of qualified names. If the constant is a [Type] t, the result is [:[t]:].
-  /// Otherwise, the constant is assumed to represent a list of strings (each a
-  /// qualified name) and types, and such a list is constructed.  If
-  /// [onlyStrings] is true, the returned list is a [:List<String>:] and any
-  /// [Type] values are treated as an error (meaning that the value is ignored
-  /// and a hint is emitted).
-  List convertConstantToUsageList(ConstantValue constant,
-      {bool onlyStrings: false}) {
-    if (constant.isNull) {
-      return null;
-    } else if (constant.isList) {
-      ListConstantValue list = constant;
-      List result = onlyStrings ? <String>[] : [];
-      for (ConstantValue entry in list.entries) {
-        if (entry.isString) {
-          StringConstantValue string = entry;
-          result.add(string.stringValue);
-        } else if (!onlyStrings && entry.isType) {
-          TypeConstantValue type = entry;
-          result.add(type.representedType);
-        } else {
-          Spannable node = positionOf(entry);
-          MessageKind kind = onlyStrings
-              ? MessageKind.MIRRORS_EXPECTED_STRING
-              : MessageKind.MIRRORS_EXPECTED_STRING_OR_TYPE;
-          reporter.reportHintMessage(
-              node, kind, {'name': node, 'type': apiTypeOf(entry)});
-        }
-      }
-      return result;
-    } else if (!onlyStrings && constant.isType) {
-      TypeConstantValue type = constant;
-      return [type.representedType];
-    } else if (constant.isString) {
-      StringConstantValue string = constant;
-      var iterable = string.stringValue.split(',').map((e) => e.trim());
-      return onlyStrings ? new List<String>.from(iterable) : iterable.toList();
-    } else {
-      Spannable node = positionOf(constant);
-      MessageKind kind = onlyStrings
-          ? MessageKind.MIRRORS_EXPECTED_STRING_OR_LIST
-          : MessageKind.MIRRORS_EXPECTED_STRING_TYPE_OR_LIST;
-      reporter.reportHintMessage(
-          node, kind, {'name': node, 'type': apiTypeOf(constant)});
-      return null;
-    }
-  }
-
-  /// Find the first non-implementation interface of constant.
-  ResolutionDartType apiTypeOf(ConstantValue constant) {
-    ResolutionDartType type =
-        constant.getType(compiler.resolution.commonElements);
-    LibraryElement library = type.element.library;
-    if (type.isInterfaceType && library.isInternalLibrary) {
-      ResolutionInterfaceType interface = type;
-      ClassElement cls = type.element;
-      cls.ensureResolved(compiler.resolution);
-      for (ResolutionInterfaceType supertype in cls.allSupertypes) {
-        if (supertype.isInterfaceType &&
-            !supertype.element.library.isInternalLibrary) {
-          return interface.asInstanceOf(supertype.element);
-        }
-      }
-    }
-    return type;
-  }
-
-  /// Convert a list of strings and types to a list of elements. Types are
-  /// converted to their corresponding element, and strings are resolved as
-  /// follows:
-  ///
-  /// First find the longest library name that is a prefix of the string, if
-  /// there are none, resolve using [resolveExpression]. Otherwise, resolve the
-  /// rest of the string using [resolveLocalExpression].
-  List<Element> resolveUsageList(List list) {
-    if (list == null) return null;
-    if (list.length == 1 && list[0] == '*') {
-      return analyzer.wildcard;
-    }
-    List<Element> result = <Element>[];
-    for (var entry in list) {
-      if (entry is ResolutionDartType) {
-        ResolutionDartType type = entry;
-        result.add(type.element);
-      } else {
-        String string = entry;
-        LibraryElement libraryCandidate;
-        String libraryNameCandidate;
-        for (LibraryElement l in compiler.libraryLoader.libraries) {
-          if (l.hasLibraryName) {
-            String libraryName = l.libraryName;
-            if (string == libraryName) {
-              // Found an exact match.
-              libraryCandidate = l;
-              libraryNameCandidate = libraryName;
-              break;
-            } else if (string.startsWith('$libraryName.')) {
-              if (libraryNameCandidate == null ||
-                  libraryNameCandidate.length < libraryName.length) {
-                // Found a better candidate
-                libraryCandidate = l;
-                libraryNameCandidate = libraryName;
-              }
-            }
-          }
-        }
-        Element e;
-        if (libraryNameCandidate == string) {
-          e = libraryCandidate;
-        } else if (libraryNameCandidate != null) {
-          e = resolveLocalExpression(libraryCandidate,
-              string.substring(libraryNameCandidate.length + 1).split('.'));
-        } else {
-          e = resolveExpression(string);
-        }
-        if (e != null) result.add(e);
-      }
-    }
-    return result;
-  }
-
-  /// Resolve [expression] in [enclosingLibrary]'s import scope.
-  Element resolveExpression(String expression) {
-    List<String> identifiers = expression.split('.');
-    Element element = enclosingLibrary.find(identifiers[0]);
-    if (element == null) {
-      reporter.reportHintMessage(
-          spannable,
-          MessageKind.MIRRORS_CANNOT_RESOLVE_IN_CURRENT_LIBRARY,
-          {'name': expression});
-      return null;
-    } else {
-      if (identifiers.length == 1) return element;
-      return resolveLocalExpression(element, identifiers.sublist(1));
-    }
-  }
-
-  /// Resolve [identifiers] in [element]'s local members.
-  Element resolveLocalExpression(Element element, List<String> identifiers) {
-    Element current = element;
-    for (String identifier in identifiers) {
-      Element e = findLocalMemberIn(current, identifier);
-      if (e == null) {
-        if (current.isLibrary) {
-          LibraryElement library = current;
-          reporter.reportHintMessage(
-              spannable,
-              MessageKind.MIRRORS_CANNOT_RESOLVE_IN_LIBRARY,
-              {'name': identifiers[0], 'library': library.name});
-        } else {
-          reporter.reportHintMessage(
-              spannable,
-              MessageKind.MIRRORS_CANNOT_FIND_IN_ELEMENT,
-              {'name': identifier, 'element': current.name});
-        }
-        return current;
-      }
-      current = e;
-    }
-    return current;
-  }
-
-  /// Helper method to lookup members in a [ScopeContainerElement]. If
-  /// [element] is not a ScopeContainerElement, return null.
-  Element findLocalMemberIn(Element element, String name) {
-    if (element is ScopeContainerElement) {
-      ScopeContainerElement scope = element;
-      if (element.isClass) {
-        ClassElement cls = element;
-        cls.ensureResolved(compiler.resolution);
-      }
-      return scope.localLookup(name);
-    }
-    return null;
-  }
-
-  /// Attempt to find a [Spannable] corresponding to constant.
-  Spannable positionOf(ConstantValue constant) {
-    Node node;
-    elements.forEachConstantNode((Node n, ConstantExpression c) {
-      if (node == null && compiler.constants.getConstantValue(c) == constant) {
-        node = n;
-      }
-    });
-    if (node == null) {
-      // TODO(ahe): Returning [spannable] here leads to confusing error
-      // messages.  For example, consider:
-      // @MirrorsUsed(targets: fisk)
-      // import 'dart:mirrors';
-      //
-      // const fisk = const [main];
-      //
-      // main() {}
-      //
-      // The message is:
-      // example.dart:1:23: Hint: Can't use 'fisk' here because ...
-      // Did you forget to add quotes?
-      // @MirrorsUsed(targets: fisk)
-      //                       ^^^^
-      //
-      // Instead of saying 'fisk' should pretty print the problematic constant
-      // value.
-      return spannable;
-    }
-    return node;
-  }
-}
diff --git a/pkg/compiler/lib/src/native/behavior.dart b/pkg/compiler/lib/src/native/behavior.dart
index a862a9d..dc624c1 100644
--- a/pkg/compiler/lib/src/native/behavior.dart
+++ b/pkg/compiler/lib/src/native/behavior.dart
@@ -3,21 +3,13 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import '../common.dart';
-import '../common/backend_api.dart' show ForeignResolver;
-import '../common/resolution.dart' show ParsingContext, Resolution;
-import '../compiler.dart' show Compiler;
 import '../constants/values.dart';
 import '../common_elements.dart' show CommonElements, ElementEnvironment;
-import '../elements/elements.dart';
 import '../elements/entities.dart';
-import '../elements/resolution_types.dart';
 import '../elements/types.dart';
 import '../js/js.dart' as js;
 import '../js_backend/native_data.dart' show NativeBasicData;
-import '../resolution/resolution_strategy.dart';
-import '../tree/tree.dart';
 import '../universe/side_effects.dart' show SideEffects;
-import '../util/util.dart';
 import 'js.dart';
 
 typedef dynamic /*DartType|SpecialType*/ TypeLookup(String typeString,
@@ -495,61 +487,6 @@
     return sideEffects;
   }
 
-  /// Returns a [TypeLookup] that uses [resolver] to perform lookup and [node]
-  /// as position for errors.
-  static TypeLookup _typeLookup(
-      Node node, DiagnosticReporter reporter, ForeignResolver resolver) {
-    ResolutionDartType lookup(String name, {bool required}) {
-      ResolutionDartType type = resolver.resolveTypeFromString(node, name);
-      if (type == null && required) {
-        reporter.reportErrorMessage(
-            node, MessageKind.GENERIC, {'text': "Type '$name' not found."});
-      }
-      return type;
-    }
-
-    return lookup;
-  }
-
-  /// Compute the [NativeBehavior] for a [Send] node calling the 'JS' function.
-  static NativeBehavior ofJsCallSend(
-      Send jsCall,
-      DiagnosticReporter reporter,
-      ParsingContext parsing,
-      CommonElements commonElements,
-      ForeignResolver resolver) {
-    var argNodes = jsCall.arguments;
-    if (argNodes.isEmpty || argNodes.tail.isEmpty) {
-      reporter.reportErrorMessage(jsCall, MessageKind.WRONG_ARGUMENT_FOR_JS);
-      return new NativeBehavior();
-    }
-
-    dynamic specArgument = argNodes.head;
-    if (specArgument is! StringNode || specArgument.isInterpolation) {
-      reporter.reportErrorMessage(
-          specArgument, MessageKind.WRONG_ARGUMENT_FOR_JS_FIRST);
-      return new NativeBehavior();
-    }
-
-    dynamic codeArgument = argNodes.tail.head;
-    if (codeArgument is! StringNode || codeArgument.isInterpolation) {
-      reporter.reportErrorMessage(
-          codeArgument, MessageKind.WRONG_ARGUMENT_FOR_JS_SECOND);
-      return new NativeBehavior();
-    }
-
-    String specString = specArgument.dartString.slowToString();
-    String codeString = codeArgument.dartString.slowToString();
-
-    return ofJsCall(
-        specString,
-        codeString,
-        _typeLookup(specArgument, reporter, resolver),
-        specArgument,
-        reporter,
-        commonElements);
-  }
-
   /// Compute the [NativeBehavior] for a call to the 'JS' function with the
   /// given [specString] and [codeString] (first and second arguments).
   static NativeBehavior ofJsCall(
@@ -636,50 +573,6 @@
         nullType: commonElements.nullType);
   }
 
-  static NativeBehavior ofJsBuiltinCallSend(
-      Send jsBuiltinCall,
-      DiagnosticReporter reporter,
-      CommonElements commonElements,
-      ForeignResolver resolver) {
-    NativeBehavior behavior = new NativeBehavior();
-    behavior.sideEffects.setTo(new SideEffects());
-
-    // The first argument of a JS-embedded global call is a string encoding
-    // the type of the code.
-    //
-    //  'Type1|Type2'.  A union type.
-    //  '=Object'.      A JavaScript Object, no subtype.
-
-    Link<Node> argNodes = jsBuiltinCall.arguments;
-    if (argNodes.isEmpty) {
-      reporter.internalError(
-          jsBuiltinCall, "JS builtin expression has no type.");
-    }
-
-    // We don't check the given name. That needs to be done at a later point.
-    // This is, because we want to allow non-literals (like references to
-    // enums) as names.
-    if (argNodes.tail.isEmpty) {
-      reporter.internalError(jsBuiltinCall, "JS builtin is missing name.");
-    }
-
-    LiteralString specLiteral = argNodes.head.asLiteralString();
-    if (specLiteral == null) {
-      // TODO(sra): We could accept a type identifier? e.g. JS(bool, '1<2').  It
-      // is not very satisfactory because it does not work for void, dynamic.
-      reporter.internalError(argNodes.head, "Unexpected first argument.");
-    }
-
-    String specString = specLiteral.dartString.slowToString();
-
-    return ofJsBuiltinCall(
-        specString,
-        _typeLookup(jsBuiltinCall, reporter, resolver),
-        jsBuiltinCall,
-        reporter,
-        commonElements);
-  }
-
   static NativeBehavior ofJsBuiltinCall(
       String specString,
       TypeLookup lookupType,
@@ -693,60 +586,6 @@
     return behavior;
   }
 
-  static NativeBehavior ofJsEmbeddedGlobalCallSend(
-      Send jsEmbeddedGlobalCall,
-      DiagnosticReporter reporter,
-      CommonElements commonElements,
-      ForeignResolver resolver) {
-    NativeBehavior behavior = new NativeBehavior();
-    // TODO(sra): Allow the use site to override these defaults.
-    // Embedded globals are usually pre-computed data structures or JavaScript
-    // functions that never change.
-    behavior.sideEffects.setTo(new SideEffects.empty());
-    behavior.throwBehavior = NativeThrowBehavior.NEVER;
-
-    // The first argument of a JS-embedded global call is a string encoding
-    // the type of the code.
-    //
-    //  'Type1|Type2'.  A union type.
-    //  '=Object'.      A JavaScript Object, no subtype.
-
-    Link<Node> argNodes = jsEmbeddedGlobalCall.arguments;
-    if (argNodes.isEmpty) {
-      reporter.internalError(
-          jsEmbeddedGlobalCall, "JS embedded global expression has no type.");
-    }
-
-    // We don't check the given name. That needs to be done at a later point.
-    // This is, because we want to allow non-literals (like references to
-    // enums) as names.
-    if (argNodes.tail.isEmpty) {
-      reporter.internalError(
-          jsEmbeddedGlobalCall, "JS embedded global is missing name.");
-    }
-
-    if (!argNodes.tail.tail.isEmpty) {
-      reporter.internalError(argNodes.tail.tail.head,
-          'JS embedded global has more than 2 arguments');
-    }
-
-    LiteralString specLiteral = argNodes.head.asLiteralString();
-    if (specLiteral == null) {
-      // TODO(sra): We could accept a type identifier? e.g. JS(bool, '1<2').  It
-      // is not very satisfactory because it does not work for void, dynamic.
-      reporter.internalError(argNodes.head, "Unexpected first argument.");
-    }
-
-    String specString = specLiteral.dartString.slowToString();
-
-    return ofJsEmbeddedGlobalCall(
-        specString,
-        _typeLookup(jsEmbeddedGlobalCall, reporter, resolver),
-        jsEmbeddedGlobalCall,
-        reporter,
-        commonElements);
-  }
-
   static NativeBehavior ofJsEmbeddedGlobalCall(
       String specString,
       TypeLookup lookupType,
@@ -765,72 +604,11 @@
     return behavior;
   }
 
-  static NativeBehavior ofMethodElement(
-      MethodElement element, Compiler compiler,
-      {bool isJsInterop}) {
-    ResolutionFunctionType type = element.computeType(compiler.resolution);
-    List<ConstantValue> metadata = <ConstantValue>[];
-    for (MetadataAnnotation annotation in element.implementation.metadata) {
-      annotation.ensureResolved(compiler.resolution);
-      metadata.add(compiler.constants.getConstantValue(annotation.constant));
-    }
-
-    BehaviorBuilder builder = new ResolverBehaviorBuilder(
-        compiler, compiler.frontendStrategy.nativeBasicData);
-    return builder.buildMethodBehavior(
-        type, metadata, lookupFromElement(compiler.resolution, element),
-        isJsInterop: isJsInterop);
-  }
-
-  static NativeBehavior ofFieldElementLoad(
-      MemberElement element, Compiler compiler,
-      {bool isJsInterop}) {
-    Resolution resolution = compiler.resolution;
-    ResolutionDartType type = element.computeType(resolution);
-    List<ConstantValue> metadata = <ConstantValue>[];
-    for (MetadataAnnotation annotation in element.implementation.metadata) {
-      annotation.ensureResolved(compiler.resolution);
-      metadata.add(compiler.constants.getConstantValue(annotation.constant));
-    }
-
-    BehaviorBuilder builder = new ResolverBehaviorBuilder(
-        compiler, compiler.frontendStrategy.nativeBasicData);
-    return builder.buildFieldLoadBehavior(
-        type, metadata, lookupFromElement(resolution, element),
-        isJsInterop: isJsInterop);
-  }
-
-  static NativeBehavior ofFieldElementStore(
-      MemberElement field, Compiler compiler) {
-    BehaviorBuilder builder = new ResolverBehaviorBuilder(
-        compiler, compiler.frontendStrategy.nativeBasicData);
-    ResolutionDartType type = field.computeType(compiler.resolution);
-    return builder.buildFieldStoreBehavior(type);
-  }
-
-  static TypeLookup lookupFromElement(Resolution resolution, Element element) {
-    ResolutionDartType lookup(String name, {bool required}) {
-      Element e = element.buildScope().lookup(name);
-      if (e == null || e is! ClassElement) {
-        if (required) {
-          resolution.reporter.reportErrorMessage(element, MessageKind.GENERIC,
-              {'text': "Type '$name' not found."});
-        }
-        return null;
-      }
-      ClassElement cls = e;
-      cls.ensureResolved(resolution);
-      return cls.thisType;
-    }
-
-    return lookup;
-  }
-
   static dynamic /*DartType|SpecialType*/ _parseType(
       String typeString, TypeLookup lookupType) {
     if (typeString == '=Object') return SpecialType.JsObject;
     if (typeString == 'dynamic') {
-      return const ResolutionDynamicType();
+      return const DynamicType();
     }
     int index = typeString.indexOf('<');
     var type = lookupType(typeString, required: index == -1);
@@ -843,7 +621,7 @@
         return type;
       }
     }
-    return const ResolutionDynamicType();
+    return const DynamicType();
   }
 }
 
@@ -1025,26 +803,3 @@
     return _behavior;
   }
 }
-
-class ResolverBehaviorBuilder extends BehaviorBuilder {
-  final Compiler compiler;
-  final NativeBasicData nativeBasicData;
-
-  ResolverBehaviorBuilder(this.compiler, this.nativeBasicData);
-
-  @override
-  CommonElements get commonElements => compiler.resolution.commonElements;
-
-  @override
-  bool get trustJSInteropTypeAnnotations =>
-      compiler.options.trustJSInteropTypeAnnotations;
-
-  @override
-  DiagnosticReporter get reporter => compiler.reporter;
-
-  @override
-  ElementEnvironment get elementEnvironment {
-    ResolutionFrontEndStrategy frontendStrategy = compiler.frontendStrategy;
-    return frontendStrategy.elementEnvironment;
-  }
-}
diff --git a/pkg/compiler/lib/src/native/enqueue.dart b/pkg/compiler/lib/src/native/enqueue.dart
index c79894f..0de573e 100644
--- a/pkg/compiler/lib/src/native/enqueue.dart
+++ b/pkg/compiler/lib/src/native/enqueue.dart
@@ -5,11 +5,10 @@
 import '../common_elements.dart' show CommonElements, ElementEnvironment;
 import '../elements/entities.dart';
 import '../elements/types.dart';
-import '../js_backend/backend_usage.dart' show BackendUsageBuilder;
 import '../js_backend/native_data.dart' show NativeData;
 import '../js_emitter/js_emitter.dart' show CodeEmitterTask, NativeEmitter;
 import '../options.dart';
-import '../universe/use.dart' show StaticUse, TypeUse;
+import '../universe/use.dart' show TypeUse;
 import '../universe/world_impact.dart'
     show WorldImpact, WorldImpactBuilder, WorldImpactBuilderImpl;
 import 'behavior.dart';
@@ -150,18 +149,7 @@
     return _unusedClasses.where(predicate);
   }
 
-  void _registerBackendUse(FunctionEntity element) {}
-
   Iterable<ClassEntity> _onFirstNativeClass(WorldImpactBuilder impactBuilder) {
-    void staticUse(FunctionEntity element) {
-      impactBuilder.registerStaticUse(new StaticUse.implicitInvoke(element));
-      _registerBackendUse(element);
-    }
-
-    staticUse(_commonElements.defineProperty);
-    staticUse(_commonElements.toStringForNativeObject);
-    staticUse(_commonElements.hashCodeForNativeObject);
-    staticUse(_commonElements.closureConverter);
     return _findNativeExceptions();
   }
 
@@ -184,7 +172,6 @@
 
 class NativeResolutionEnqueuer extends NativeEnqueuerBase {
   final NativeClassFinder _nativeClassFinder;
-  final BackendUsageBuilder _backendUsageBuilder;
 
   /// The set of all native classes.  Each native class is in [nativeClasses]
   /// and exactly one of [unusedClasses] and [registeredClasses].
@@ -195,7 +182,6 @@
       ElementEnvironment elementEnvironment,
       CommonElements commonElements,
       DartTypes dartTypes,
-      this._backendUsageBuilder,
       this._nativeClassFinder)
       : super(options, elementEnvironment, commonElements, dartTypes);
 
@@ -205,11 +191,6 @@
 
   Iterable<ClassEntity> get liveNativeClasses => _registeredClasses;
 
-  void _registerBackendUse(FunctionEntity element) {
-    _backendUsageBuilder.registerBackendFunctionUse(element);
-    _backendUsageBuilder.registerGlobalFunctionDependency(element);
-  }
-
   WorldImpact processNativeClasses(Iterable<LibraryEntity> libraries) {
     WorldImpactBuilderImpl impactBuilder = new WorldImpactBuilderImpl();
     Iterable<ClassEntity> nativeClasses =
diff --git a/pkg/compiler/lib/src/native/native.dart b/pkg/compiler/lib/src/native/native.dart
index 5b50350..ae0ce99 100644
--- a/pkg/compiler/lib/src/native/native.dart
+++ b/pkg/compiler/lib/src/native/native.dart
@@ -7,8 +7,6 @@
 export 'behavior.dart';
 export 'enqueue.dart';
 export 'js.dart';
-export 'scanner.dart';
-export 'ssa.dart';
 
 const Iterable<String> _allowedDartSchemePaths = const <String>[
   'async',
diff --git a/pkg/compiler/lib/src/native/resolver.dart b/pkg/compiler/lib/src/native/resolver.dart
index 9f7ff83..5da0d2e 100644
--- a/pkg/compiler/lib/src/native/resolver.dart
+++ b/pkg/compiler/lib/src/native/resolver.dart
@@ -2,74 +2,17 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-import 'package:front_end/src/fasta/scanner.dart' show StringToken, Token;
-import 'package:front_end/src/fasta/scanner.dart' as Tokens show EOF_TOKEN;
-import 'package:front_end/src/scanner/token.dart' show BeginToken;
-
 import '../common.dart';
 import '../common_elements.dart' show CommonElements, ElementEnvironment;
-import '../common/backend_api.dart';
-import '../common/resolution.dart';
-import '../compiler.dart' show Compiler;
 import '../constants/values.dart';
-import '../elements/elements.dart'
-    show
-        ClassElement,
-        Element,
-        FieldElement,
-        MemberElement,
-        MetadataAnnotation,
-        MethodElement;
 import '../elements/entities.dart';
-import '../elements/modelx.dart' show FunctionElementX, MetadataAnnotationX;
-import '../elements/resolution_types.dart' show ResolutionDartType;
-import '../js_backend/js_backend.dart';
 import '../js_backend/native_data.dart';
-import '../patch_parser.dart';
-import '../tree/tree.dart';
 import 'behavior.dart';
 
 /// Interface for computing native members.
 abstract class NativeMemberResolver {
-  /// Computes whether [element] is native or JsInterop and, if so, registers
-  /// its [NativeBehavior]s to [registry].
-  void resolveNativeMember(MemberEntity element, [NativeRegistry registry]);
-}
-
-/// Interface for computing native members and [NativeBehavior]s in member code
-/// based on the AST.
-abstract class NativeDataResolver implements NativeMemberResolver {
-  /// Returns `true` if [element] is a JsInterop member.
-  bool isJsInteropMember(MemberElement element);
-
-  /// Computes the [NativeBehavior] for a `JS` call, which can be an
-  /// instantiation point for types.
-  ///
-  /// For example, the following code instantiates and returns native classes
-  /// that are `_DOMWindowImpl` or a subtype.
-  ///
-  ///    JS('_DOMWindowImpl', 'window')
-  ///
-  NativeBehavior resolveJsCall(Send node, ForeignResolver resolver);
-
-  /// Computes the [NativeBehavior] for a `JS_EMBEDDED_GLOBAL` call, which can
-  /// be an instantiation point for types.
-  ///
-  /// For example, the following code instantiates and returns a String class
-  ///
-  ///     JS_EMBEDDED_GLOBAL('String', 'foo')
-  ///
-  NativeBehavior resolveJsEmbeddedGlobalCall(
-      Send node, ForeignResolver resolver);
-
-  /// Computes the [NativeBehavior] for a `JS_BUILTIN` call, which can be an
-  /// instantiation point for types.
-  ///
-  /// For example, the following code instantiates and returns a String class
-  ///
-  ///     JS_BUILTIN('String', 'int2string', 0)
-  ///
-  NativeBehavior resolveJsBuiltinCall(Send node, ForeignResolver resolver);
+  /// Computes whether [element] is native or JsInterop.
+  void resolveNativeMember(MemberEntity element);
 }
 
 abstract class NativeMemberResolverBase implements NativeMemberResolver {
@@ -90,7 +33,7 @@
   NativeBehavior computeNativeFieldStoreBehavior(covariant FieldEntity field);
 
   @override
-  void resolveNativeMember(MemberEntity element, [NativeRegistry registry]) {
+  void resolveNativeMember(MemberEntity element) {
     bool isJsInterop = isJsInteropMember(element);
     if (element.isFunction ||
         element.isConstructor ||
@@ -102,7 +45,6 @@
         NativeBehavior behavior =
             computeNativeMethodBehavior(method, isJsInterop: isJsInterop);
         nativeDataBuilder.setNativeMethodBehavior(method, behavior);
-        registry?.registerNativeData(behavior);
       }
     } else if (element.isField) {
       FieldEntity field = element;
@@ -115,13 +57,6 @@
         nativeDataBuilder.setNativeFieldLoadBehavior(field, fieldLoadBehavior);
         nativeDataBuilder.setNativeFieldStoreBehavior(
             field, fieldStoreBehavior);
-
-        // TODO(sra): Process fields for storing separately.
-        // We have to handle both loading and storing to the field because we
-        // only get one look at each member and there might be a load or store
-        // we have not seen yet.
-        registry?.registerNativeData(fieldLoadBehavior);
-        registry?.registerNativeData(fieldStoreBehavior);
       }
     }
   }
@@ -208,180 +143,6 @@
   }
 }
 
-class NativeDataResolverImpl extends NativeMemberResolverBase
-    implements NativeDataResolver {
-  final Compiler _compiler;
-
-  NativeDataResolverImpl(this._compiler);
-
-  JavaScriptBackend get _backend => _compiler.backend;
-  DiagnosticReporter get _reporter => _compiler.reporter;
-  ElementEnvironment get elementEnvironment =>
-      _compiler.resolution.elementEnvironment;
-  CommonElements get commonElements => _compiler.resolution.commonElements;
-  NativeBasicData get nativeBasicData =>
-      _compiler.frontendStrategy.nativeBasicData;
-  NativeDataBuilder get nativeDataBuilder => _backend.nativeDataBuilder;
-
-  @override
-  bool isJsInteropMember(MemberElement element) {
-    // TODO(johnniwinther): Avoid computing this twice for external function;
-    // once from JavaScriptBackendTarget.resolveExternalFunction and once
-    // through JavaScriptBackendTarget.resolveNativeMember.
-    bool isJsInterop =
-        checkJsInteropMemberAnnotations(_compiler, element, nativeDataBuilder);
-    // TODO(johnniwinther): Avoid this duplication of logic from
-    // NativeData.isJsInterop.
-    if (!isJsInterop && element is MethodElement && element.isExternal) {
-      if (element.enclosingClass != null) {
-        isJsInterop = nativeBasicData.isJsInteropClass(element.enclosingClass);
-      } else {
-        isJsInterop = nativeBasicData.isJsInteropLibrary(element.library);
-      }
-    }
-    return isJsInterop;
-  }
-
-  @override
-  NativeBehavior computeNativeMethodBehavior(MethodElement function,
-      {bool isJsInterop}) {
-    return NativeBehavior.ofMethodElement(function, _compiler,
-        isJsInterop: isJsInterop);
-  }
-
-  @override
-  NativeBehavior computeNativeFieldLoadBehavior(FieldElement field,
-      {bool isJsInterop}) {
-    return NativeBehavior.ofFieldElementLoad(field, _compiler,
-        isJsInterop: isJsInterop);
-  }
-
-  @override
-  NativeBehavior computeNativeFieldStoreBehavior(FieldElement field) {
-    return NativeBehavior.ofFieldElementStore(field, _compiler);
-  }
-
-  @override
-  bool isNativeMethod(FunctionElementX element) {
-    if (!_backend.canLibraryUseNative(element.library)) return false;
-    // Native method?
-    return _reporter.withCurrentElement(element, () {
-      Node node = element.parseNode(_compiler.resolution.parsingContext);
-      if (node is! FunctionExpression) return false;
-      FunctionExpression functionExpression = node;
-      node = functionExpression.body;
-      Token token = node.getBeginToken();
-      if (identical(token.stringValue, 'native')) {
-        element.isMarkedNative = true;
-        return true;
-      }
-      return false;
-    });
-  }
-
-  @override
-  NativeBehavior resolveJsCall(Send node, ForeignResolver resolver) {
-    return NativeBehavior.ofJsCallSend(
-        node, _reporter, _compiler.parsingContext, commonElements, resolver);
-  }
-
-  @override
-  NativeBehavior resolveJsEmbeddedGlobalCall(
-      Send node, ForeignResolver resolver) {
-    return NativeBehavior.ofJsEmbeddedGlobalCallSend(
-        node, _reporter, commonElements, resolver);
-  }
-
-  @override
-  NativeBehavior resolveJsBuiltinCall(Send node, ForeignResolver resolver) {
-    return NativeBehavior.ofJsBuiltinCallSend(
-        node, _reporter, commonElements, resolver);
-  }
-}
-
-/// Annotation handler for pre-resolution detection of `@Native(...)`
-/// annotations.
-class NativeAnnotationHandler extends EagerAnnotationHandler<String> {
-  final NativeBasicDataBuilder _nativeBasicDataBuilder;
-
-  NativeAnnotationHandler(this._nativeBasicDataBuilder);
-
-  String getNativeAnnotation(MetadataAnnotationX annotation) {
-    if (annotation.beginToken != null &&
-        annotation.beginToken.next.lexeme == 'Native') {
-      // Skipping '@', 'Native', and '('.
-      Token argument = annotation.beginToken.next.next.next;
-      if (argument is StringToken) {
-        return argument.lexeme;
-      }
-    }
-    return null;
-  }
-
-  String apply(
-      Compiler compiler, Element element, MetadataAnnotation annotation) {
-    if (element.isClass) {
-      ClassElement cls = element;
-      String native = getNativeAnnotation(annotation);
-      if (native != null) {
-        String tagText = native.substring(1, native.length - 1);
-        _nativeBasicDataBuilder.setNativeClassTagInfo(cls, tagText);
-        return native;
-      }
-    }
-    return null;
-  }
-
-  void validate(Compiler compiler, Element element,
-      MetadataAnnotation annotation, ConstantValue constant) {
-    ResolutionDartType annotationType =
-        constant.getType(compiler.resolution.commonElements);
-    if (annotationType.element !=
-        compiler.resolution.commonElements.nativeAnnotationClass) {
-      DiagnosticReporter reporter = compiler.reporter;
-      reporter.internalError(annotation, 'Invalid @Native(...) annotation.');
-    }
-  }
-}
-
-bool checkJsInteropMemberAnnotations(Compiler compiler, MemberElement element,
-    NativeDataBuilder nativeDataBuilder) {
-  bool isJsInterop = EagerAnnotationHandler.checkAnnotation(
-      compiler, element, const JsInteropAnnotationHandler());
-  if (isJsInterop) {
-    nativeDataBuilder.markAsJsInteropMember(element);
-  }
-  return isJsInterop;
-}
-
-/// Annotation handler for pre-resolution detection of `@JS(...)`
-/// annotations.
-class JsInteropAnnotationHandler implements EagerAnnotationHandler<bool> {
-  const JsInteropAnnotationHandler();
-
-  bool hasJsNameAnnotation(MetadataAnnotationX annotation) =>
-      annotation.beginToken != null &&
-      annotation.beginToken.next.lexeme == 'JS';
-
-  bool apply(
-      Compiler compiler, Element element, MetadataAnnotation annotation) {
-    return hasJsNameAnnotation(annotation);
-  }
-
-  @override
-  void validate(Compiler compiler, Element element,
-      MetadataAnnotation annotation, ConstantValue constant) {
-    ResolutionDartType type =
-        constant.getType(compiler.resolution.commonElements);
-    if (type.element != compiler.resolution.commonElements.jsAnnotationClass) {
-      compiler.reporter
-          .internalError(annotation, 'Invalid @JS(...) annotation.');
-    }
-  }
-
-  bool get defaultResult => false;
-}
-
 /// Determines all native classes in a set of libraries.
 abstract class NativeClassFinder {
   /// Returns the set of all native classes declared in [libraries].
@@ -390,22 +151,16 @@
 
 class BaseNativeClassFinder implements NativeClassFinder {
   final ElementEnvironment _elementEnvironment;
-  final CommonElements _commonElements;
   final NativeBasicData _nativeBasicData;
 
   Map<String, ClassEntity> _tagOwner = new Map<String, ClassEntity>();
 
-  BaseNativeClassFinder(
-      this._elementEnvironment, this._commonElements, this._nativeBasicData);
+  BaseNativeClassFinder(this._elementEnvironment, this._nativeBasicData);
 
   Iterable<ClassEntity> computeNativeClasses(
       Iterable<LibraryEntity> libraries) {
     Set<ClassEntity> nativeClasses = new Set<ClassEntity>();
     libraries.forEach((l) => _processNativeClassesInLibrary(l, nativeClasses));
-    if (_commonElements.isolateHelperLibrary != null) {
-      _processNativeClassesInLibrary(
-          _commonElements.isolateHelperLibrary, nativeClasses);
-    }
     _processSubclassesOfNativeClasses(libraries, nativeClasses);
     return nativeClasses;
   }
@@ -502,98 +257,6 @@
   }
 }
 
-/// Native class finder that extends [BaseNativeClassFinder] to handle
-/// unresolved classes encountered during the native classes computation.
-class ResolutionNativeClassFinder extends BaseNativeClassFinder {
-  final DiagnosticReporter _reporter;
-  final Resolution _resolution;
-
-  ResolutionNativeClassFinder(
-      this._resolution,
-      this._reporter,
-      ElementEnvironment elementEnvironment,
-      CommonElements commonElements,
-      NativeBasicData nativeBasicData)
-      : super(elementEnvironment, commonElements, nativeBasicData);
-
-  void _processNativeClass(
-      ClassElement classElement, Set<ClassEntity> nativeClasses) {
-    // Resolve class to ensure the class has valid inheritance info.
-    classElement.ensureResolved(_resolution);
-    super._processNativeClass(classElement, nativeClasses);
-  }
-
-  /**
-   * Returns the source string of the class named in the extends clause, or
-   * `null` if there is no extends clause.
-   */
-  String _findExtendsNameOfClass(ClassElement classElement) {
-    if (classElement.isResolved) {
-      ClassElement superClass = classElement.superclass;
-      while (superClass != null) {
-        if (!superClass.isUnnamedMixinApplication) {
-          return superClass.name;
-        }
-        superClass = superClass.superclass;
-      }
-      return null;
-    }
-
-    //  "class B extends A ... {}"  --> "A"
-    //  "class B extends foo.A ... {}"  --> "A"
-    //  "class B<T> extends foo.A<T,T> with M1, M2 ... {}"  --> "A"
-
-    // We want to avoid calling classElement.parseNode on every class.  Doing so
-    // will slightly increase parse time and size and cause compiler errors and
-    // warnings to me emitted in more unused code.
-
-    // An alternative to this code is to extend the API of ClassElement to
-    // expose the name of the extended element.
-
-    // Pattern match the above cases in the token stream.
-    //  [abstract] class X extends [id.]* id
-
-    Token skipTypeParameters(Token token) {
-      BeginToken beginGroupToken = token;
-      Token endToken = beginGroupToken.endGroup;
-      return endToken.next;
-      //for (;;) {
-      //  token = token.next;
-      //  if (token.stringValue == '>') return token.next;
-      //  if (token.stringValue == '<') return skipTypeParameters(token);
-      //}
-    }
-
-    String scanForExtendsName(Token token) {
-      if (token.stringValue == 'abstract') token = token.next;
-      if (token.stringValue != 'class') return null;
-      token = token.next;
-      if (!token.isIdentifier) return null;
-      token = token.next;
-      //  class F<X extends B<X>> extends ...
-      if (token.stringValue == '<') {
-        token = skipTypeParameters(token);
-      }
-      if (token.stringValue != 'extends') return null;
-      token = token.next;
-      Token id = token;
-      while (token.kind != Tokens.EOF_TOKEN) {
-        token = token.next;
-        if (token.stringValue != '.') break;
-        token = token.next;
-        if (!token.isIdentifier) return null;
-        id = token;
-      }
-      // Should be at '{', 'with', 'implements', '<' or 'native'.
-      return id.lexeme;
-    }
-
-    return _reporter.withCurrentElement(classElement, () {
-      return scanForExtendsName(classElement.position);
-    });
-  }
-}
-
 /// Returns `true` if [value] is named annotation based on [annotationClass].
 bool isAnnotation(
     Spannable spannable, ConstantValue value, ClassEntity annotationClass) {
diff --git a/pkg/compiler/lib/src/native/scanner.dart b/pkg/compiler/lib/src/native/scanner.dart
deleted file mode 100644
index ee0edcb..0000000
--- a/pkg/compiler/lib/src/native/scanner.dart
+++ /dev/null
@@ -1,46 +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 '../common.dart';
-import '../parser/element_listener.dart' show ElementListener;
-import 'package:front_end/src/fasta/scanner.dart' show Token;
-import 'package:front_end/src/fasta/scanner/token_constants.dart' as Tokens
-    show STRING_TOKEN;
-import 'package:front_end/src/scanner/token.dart' show BeginToken;
-
-void checkAllowedLibrary(ElementListener listener, Token token) {
-  if (listener.scannerOptions.canUseNative) return;
-  listener.reportErrorFromToken(token, MessageKind.NATIVE_NOT_SUPPORTED);
-}
-
-Token handleNativeBlockToSkip(ElementListener listener, Token token) {
-  checkAllowedLibrary(listener, token);
-  token = token.next;
-  if (identical(token.kind, Tokens.STRING_TOKEN)) {
-    token = token.next;
-  }
-  if (identical(token.stringValue, '{')) {
-    BeginToken beginGroupToken = token;
-    token = beginGroupToken.endGroup;
-  }
-  return token;
-}
-
-Token handleNativeFunctionBody(ElementListener listener, Token token) {
-  checkAllowedLibrary(listener, token);
-  Token begin = token;
-  listener.beginReturnStatement(token);
-  token = token.next;
-  bool hasExpression = false;
-  if (identical(token.kind, Tokens.STRING_TOKEN)) {
-    hasExpression = true;
-    listener.beginLiteralString(token);
-    token = token.next;
-    listener.endLiteralString(0, token);
-  }
-  listener.endReturnStatement(hasExpression, begin, token);
-  // TODO(ngeoffray): expect a ';'.
-  // Currently there are method with both native marker and Dart body.
-  return token.next;
-}
diff --git a/pkg/compiler/lib/src/native/ssa.dart b/pkg/compiler/lib/src/native/ssa.dart
deleted file mode 100644
index 240df64..0000000
--- a/pkg/compiler/lib/src/native/ssa.dart
+++ /dev/null
@@ -1,122 +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 '../common.dart';
-import '../constants/values.dart';
-import '../elements/resolution_types.dart';
-import '../elements/elements.dart';
-import '../js/js.dart' as js;
-import '../js_emitter/js_emitter.dart' show NativeEmitter;
-import '../ssa/builder.dart' show SsaAstGraphBuilder;
-import '../ssa/nodes.dart' show HInstruction, HForeignCode, HReturn;
-import '../tree/tree.dart';
-import '../universe/side_effects.dart' show SideEffects;
-
-final RegExp nativeRedirectionRegExp = new RegExp(r'^[a-zA-Z][a-zA-Z_$0-9]*$');
-
-void handleSsaNative(SsaAstGraphBuilder builder, Expression nativeBody) {
-  MethodElement element = builder.target;
-  NativeEmitter nativeEmitter = builder.nativeEmitter;
-
-  HInstruction convertDartClosure(
-      ParameterElement parameter, ResolutionFunctionType type) {
-    HInstruction local = builder.localsHandler.readLocal(parameter);
-    ConstantValue arityConstant =
-        builder.constantSystem.createInt(type.parameterTypes.length);
-    HInstruction arity =
-        builder.graph.addConstant(arityConstant, builder.closedWorld);
-    // TODO(ngeoffray): For static methods, we could pass a method with a
-    // defined arity.
-    MethodElement helper = builder.commonElements.closureConverter;
-    builder.pushInvokeStatic(nativeBody, helper, [local, arity]);
-    HInstruction closure = builder.pop();
-    return closure;
-  }
-
-  // Check which pattern this native method follows:
-  // 1) foo() native;
-  //      hasBody = false
-  // 2) foo() native "bar";
-  //      No longer supported, this is now done with @JSName('foo') and case 1.
-  // 3) foo() native "return 42";
-  //      hasBody = true
-  bool hasBody = false;
-  assert(builder.nativeData.isNativeMember(element));
-  String nativeMethodName = builder.nativeData.getFixedBackendName(element);
-  if (nativeBody != null) {
-    LiteralString jsCode = nativeBody.asLiteralString();
-    String str = jsCode.dartString.slowToString();
-    if (nativeRedirectionRegExp.hasMatch(str)) {
-      failedAt(nativeBody, "Deprecated syntax, use @JSName('name') instead.");
-    }
-    hasBody = true;
-  }
-
-  if (!hasBody) {
-    nativeEmitter.nativeMethods.add(element);
-  }
-
-  FunctionSignature parameters = element.functionSignature;
-  if (!hasBody) {
-    List<String> arguments = <String>[];
-    List<HInstruction> inputs = <HInstruction>[];
-    String receiver = '';
-    if (element.isInstanceMember) {
-      receiver = '#.';
-      inputs.add(builder.localsHandler.readThis());
-    }
-    parameters.forEachParameter((_parameter) {
-      ParameterElement parameter = _parameter;
-      ResolutionDartType type = parameter.type.unaliased;
-      HInstruction input = builder.localsHandler.readLocal(parameter);
-      if (type is ResolutionFunctionType) {
-        // The parameter type is a function type either directly or through
-        // typedef(s).
-        input = convertDartClosure(parameter, type);
-      }
-      inputs.add(input);
-      arguments.add('#');
-    });
-
-    String foreignParameters = arguments.join(',');
-    String nativeMethodCall;
-    if (element.kind == ElementKind.FUNCTION) {
-      nativeMethodCall = '$receiver$nativeMethodName($foreignParameters)';
-    } else if (element.kind == ElementKind.GETTER) {
-      nativeMethodCall = '$receiver$nativeMethodName';
-    } else if (element.kind == ElementKind.SETTER) {
-      nativeMethodCall = '$receiver$nativeMethodName = $foreignParameters';
-    } else {
-      failedAt(element, 'Unexpected kind: "${element.kind}".');
-    }
-
-    builder.push(new HForeignCode(
-        // TODO(sra): This could be cached.  The number of templates should
-        // be proportional to the number of native methods, which is bounded
-        // by the dart: libraries.
-        js.js.uncachedExpressionTemplate(nativeMethodCall),
-        builder.commonMasks.dynamicType,
-        inputs,
-        effects: new SideEffects()));
-    // TODO(johnniwinther): Provide source information.
-    builder
-        .close(new HReturn(builder.abstractValueDomain, builder.pop(), null))
-        .addSuccessor(builder.graph.exit);
-  } else {
-    if (parameters.parameterCount != 0) {
-      failedAt(
-          nativeBody,
-          'native "..." syntax is restricted to '
-          'functions with zero parameters.');
-    }
-    LiteralString jsCode = nativeBody.asLiteralString();
-    builder.push(new HForeignCode.statement(
-        js.js.statementTemplateYielding(
-            new js.LiteralStatement(jsCode.dartString.slowToString())),
-        <HInstruction>[],
-        new SideEffects(),
-        null,
-        builder.commonMasks.dynamicType));
-  }
-}
diff --git a/pkg/compiler/lib/src/ordered_typeset.dart b/pkg/compiler/lib/src/ordered_typeset.dart
index 52b4d61..67c594a 100644
--- a/pkg/compiler/lib/src/ordered_typeset.dart
+++ b/pkg/compiler/lib/src/ordered_typeset.dart
@@ -6,9 +6,7 @@
 
 import 'common.dart';
 import 'diagnostics/diagnostic_listener.dart' show DiagnosticReporter;
-import 'elements/elements.dart' show ClassElement;
 import 'elements/entities.dart';
-import 'elements/resolution_types.dart';
 import 'elements/types.dart';
 import 'util/util.dart' show Link, LinkBuilder;
 import 'package:front_end/src/fasta/util/link_implementation.dart'
@@ -305,21 +303,3 @@
     return sb.toString();
   }
 }
-
-class ResolutionOrderedTypeSetBuilder extends OrderedTypeSetBuilderBase {
-  ResolutionOrderedTypeSetBuilder(ClassElement cls, InterfaceType objectType,
-      {DiagnosticReporter reporter})
-      : super(cls, objectType, reporter: reporter);
-
-  InterfaceType getThisType(ClassElement cls) => cls.thisType;
-
-  ResolutionInterfaceType substByContext(
-      ResolutionInterfaceType type, ResolutionInterfaceType context) {
-    return type.substByContext(context);
-  }
-
-  int getHierarchyDepth(ClassElement cls) => cls.hierarchyDepth;
-
-  OrderedTypeSet getOrderedTypeSet(ClassElement cls) =>
-      cls.allSupertypesAndSelf;
-}
diff --git a/pkg/compiler/lib/src/parser/diet_parser_task.dart b/pkg/compiler/lib/src/parser/diet_parser_task.dart
deleted file mode 100644
index 0e93cb0..0000000
--- a/pkg/compiler/lib/src/parser/diet_parser_task.dart
+++ /dev/null
@@ -1,52 +0,0 @@
-// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library dart2js.parser.diet.task;
-
-import '../common.dart';
-import '../common/tasks.dart' show CompilerTask, Measurer;
-import '../elements/elements.dart' show CompilationUnitElement;
-import '../js_backend/backend.dart' show JavaScriptBackend;
-import '../id_generator.dart';
-import 'package:front_end/src/fasta/scanner.dart' show Token;
-import 'element_listener.dart' show ElementListener, ScannerOptions;
-import 'package:front_end/src/fasta/parser.dart'
-    show Listener, MemberKind, ParserError, TopLevelParser;
-
-class PartialParser extends TopLevelParser {
-  PartialParser(Listener listener) : super(listener);
-
-  Token parseFormalParameters(Token token, MemberKind kind) {
-    return skipFormalParameters(token, kind);
-  }
-}
-
-class DietParserTask extends CompilerTask {
-  final IdGenerator _idGenerator;
-  final JavaScriptBackend _backend;
-  final DiagnosticReporter _reporter;
-
-  DietParserTask(
-      this._idGenerator, this._backend, this._reporter, Measurer measurer)
-      : super(measurer);
-
-  final String name = 'Diet Parser';
-
-  dietParse(CompilationUnitElement compilationUnit, Token tokens) {
-    measure(() {
-      ScannerOptions scannerOptions = new ScannerOptions(
-          canUseNative: _backend.canLibraryUseNative(compilationUnit.library));
-      ElementListener listener = new ElementListener(
-          scannerOptions, _reporter, compilationUnit, _idGenerator);
-      PartialParser parser = new PartialParser(listener);
-      try {
-        parser.parseUnit(tokens);
-      } on ParserError catch (_) {
-        // TODO(johnniwinther): assert that the error was reported once there is
-        // a [hasErrorBeenReported] field in [DiagnosticReporter]
-        // The error should have already been reported by the parser.
-      }
-    });
-  }
-}
diff --git a/pkg/compiler/lib/src/parser/element_listener.dart b/pkg/compiler/lib/src/parser/element_listener.dart
deleted file mode 100644
index 081a066..0000000
--- a/pkg/compiler/lib/src/parser/element_listener.dart
+++ /dev/null
@@ -1,1031 +0,0 @@
-// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library dart2js.parser.element_listener;
-
-import 'package:front_end/src/fasta/fasta_codes.dart' show Message;
-
-import 'package:front_end/src/fasta/fasta_codes.dart' as codes;
-
-import '../common.dart';
-import '../diagnostics/messages.dart' show MessageTemplate;
-import '../elements/elements.dart'
-    show Element, LibraryElement, MetadataAnnotation;
-import '../elements/modelx.dart'
-    show
-        CompilationUnitElementX,
-        DeclarationSite,
-        ElementX,
-        EnumClassElementX,
-        FieldElementX,
-        LibraryElementX,
-        MetadataAnnotationX,
-        NamedMixinApplicationElementX,
-        VariableList;
-import '../id_generator.dart';
-import '../native/native.dart' as native;
-import '../string_validator.dart' show StringValidator;
-import 'package:front_end/src/fasta/scanner.dart'
-    show ErrorToken, StringToken, Token;
-import 'package:front_end/src/fasta/scanner.dart' as Tokens show EOF_TOKEN;
-import '../tree/tree.dart';
-import '../util/util.dart' show Link, LinkBuilder;
-import 'package:front_end/src/fasta/parser.dart'
-    show Listener, ParserError, optional;
-import 'package:front_end/src/fasta/parser/identifier_context.dart'
-    show IdentifierContext;
-import 'package:front_end/src/scanner/token.dart' show KeywordToken, TokenType;
-import 'partial_elements.dart'
-    show
-        PartialClassElement,
-        PartialElement,
-        PartialFieldList,
-        PartialFunctionElement,
-        PartialMetadataAnnotation,
-        PartialTypedefElement;
-
-const bool VERBOSE = false;
-
-/// Options used for scanning.
-///
-/// Use this to conditionally support special tokens.
-///
-/// TODO(johnniwinther): This class should be renamed, it is not about options
-/// in the same sense as `CompilerOptions` or `DiagnosticOptions`.
-class ScannerOptions {
-  /// If `true` the pseudo keyword `native` is supported.
-  final bool canUseNative;
-
-  const ScannerOptions({this.canUseNative: false});
-}
-
-/**
- * A parser event listener designed to work with [PartialParser]. It
- * builds elements representing the top-level declarations found in
- * the parsed compilation unit and records them in
- * [compilationUnitElement].
- */
-class ElementListener extends Listener {
-  final IdGenerator idGenerator;
-  final DiagnosticReporter reporter;
-  final ScannerOptions scannerOptions;
-  final CompilationUnitElementX compilationUnitElement;
-  final StringValidator stringValidator;
-  Link<StringQuoting> interpolationScope;
-
-  Link<Node> nodes = const Link<Node>();
-
-  LinkBuilder<MetadataAnnotation> metadata =
-      new LinkBuilder<MetadataAnnotation>();
-
-  /// Indicates whether the parser is currently accepting a type variable.
-  bool inTypeVariable = false;
-
-  /// Records a stack of booleans for each member parsed (a stack is used to
-  /// support nested members which isn't currently possible, but it also serves
-  /// as a simple way to tell we're currently parsing a member). In this case,
-  /// member refers to members of a library or a class (but currently, classes
-  /// themselves are not considered members).  If the top of the stack
-  /// (memberErrors.head) is true, the current member has already reported at
-  /// least one parse error.
-  Link<bool> memberErrors = const Link<bool>();
-
-  bool suppressParseErrors = false;
-
-  /// Set to true each time we parse a native function body. It is reset in
-  /// [handleInvalidFunctionBody] which is called immediately after.
-  bool lastErrorWasNativeFunctionBody = false;
-
-  LiteralString nativeName;
-
-  ElementListener(this.scannerOptions, DiagnosticReporter reporter,
-      this.compilationUnitElement, this.idGenerator)
-      : this.reporter = reporter,
-        stringValidator = new StringValidator(reporter),
-        interpolationScope = const Link<StringQuoting>();
-
-  @override
-  Uri get uri => compilationUnitElement?.script?.resourceUri;
-
-  bool get currentMemberHasParseError {
-    return !memberErrors.isEmpty && memberErrors.head;
-  }
-
-  void pushQuoting(StringQuoting quoting) {
-    interpolationScope = interpolationScope.prepend(quoting);
-  }
-
-  StringQuoting popQuoting() {
-    StringQuoting result = interpolationScope.head;
-    interpolationScope = interpolationScope.tail;
-    return result;
-  }
-
-  StringNode popLiteralString() {
-    StringNode node = popNode();
-    // TODO(lrn): Handle interpolations in script tags.
-    if (node.isInterpolation) {
-      reporter.internalError(
-          node, "String interpolation not supported in library tags.");
-      return null;
-    }
-    return node;
-  }
-
-  bool allowLibraryTags() {
-    // Library tags are only allowed in the library file itself, not
-    // in sourced files.
-    LibraryElement library = compilationUnitElement.implementationLibrary;
-    return !compilationUnitElement.hasMembers &&
-        library.entryCompilationUnit == compilationUnitElement;
-  }
-
-  @override
-  void endLibraryName(Token libraryKeyword, Token semicolon) {
-    Expression name = popNode();
-    addLibraryTag(new LibraryName(
-        libraryKeyword, name, popMetadata(compilationUnitElement)));
-  }
-
-  @override
-  void handleImportPrefix(Token deferredKeyword, Token asKeyword) {
-    if (asKeyword == null) {
-      // If asKeyword is null, then no prefix has been pushed on the stack.
-      // Push a placeholder indicating that there is no prefix.
-      pushNode(null);
-    }
-    pushNode(deferredKeyword != null ? Flag.TRUE : Flag.FALSE);
-  }
-
-  @override
-  void endImport(Token importKeyword, Token semicolon) {
-    NodeList combinators = popNode();
-    Flag flag = popNode();
-    bool isDeferred = flag == Flag.TRUE;
-    Identifier prefix = popNode();
-    NodeList conditionalUris = popNode();
-    StringNode uri = popLiteralString();
-    addLibraryTag(new Import(importKeyword, uri, conditionalUris, prefix,
-        combinators, popMetadata(compilationUnitElement),
-        isDeferred: isDeferred));
-  }
-
-  @override
-  void handleRecoverImport(Token semicolon) {
-    popNode(); // combinators
-    popNode(); // isDeferred
-    popNode(); // prefix
-    popNode(); // conditionalUris
-    // TODO(danrubel): recover
-  }
-
-  @override
-  void handleDottedName(int count, Token token) {
-    NodeList identifiers = makeNodeList(count, null, null, '.');
-    pushNode(new DottedName(token, identifiers));
-  }
-
-  @override
-  void endConditionalUris(int count) {
-    if (count == 0) {
-      pushNode(null);
-    } else {
-      pushNode(makeNodeList(count, null, null, " "));
-    }
-  }
-
-  @override
-  void endConditionalUri(Token ifToken, Token leftParen, Token equalSign) {
-    StringNode uri = popNode();
-    LiteralString conditionValue = (equalSign != null) ? popNode() : null;
-    DottedName identifier = popNode();
-    pushNode(new ConditionalUri(ifToken, identifier, conditionValue, uri));
-  }
-
-  @override
-  void endEnum(Token enumKeyword, Token leftBrace, int count) {
-    NodeList names = makeNodeList(count, leftBrace, leftBrace?.endGroup, ",");
-    Identifier name = popNode();
-
-    int id = idGenerator.getNextFreeId();
-    Element enclosing = compilationUnitElement;
-    pushElement(new EnumClassElementX(
-        name.source, enclosing, id, new Enum(enumKeyword, name, names)));
-    rejectBuiltInIdentifier(name);
-  }
-
-  @override
-  void endExport(Token exportKeyword, Token semicolon) {
-    NodeList combinators = popNode();
-    NodeList conditionalUris = popNode();
-    StringNode uri = popNode();
-    addLibraryTag(new Export(exportKeyword, uri, conditionalUris, combinators,
-        popMetadata(compilationUnitElement)));
-  }
-
-  @override
-  void endCombinators(int count) {
-    if (0 == count) {
-      pushNode(null);
-    } else {
-      pushNode(makeNodeList(count, null, null, " "));
-    }
-  }
-
-  @override
-  void endHide(Token hideKeyword) => pushCombinator(hideKeyword);
-
-  @override
-  void endShow(Token showKeyword) => pushCombinator(showKeyword);
-
-  void pushCombinator(Token keywordToken) {
-    NodeList identifiers = popNode();
-    pushNode(new Combinator(identifiers, keywordToken));
-  }
-
-  @override
-  void handleIdentifierList(int count) {
-    pushNode(makeNodeList(count, null, null, ","));
-  }
-
-  @override
-  void endTypeList(int count) {
-    pushNode(makeNodeList(count, null, null, ","));
-  }
-
-  @override
-  void endPart(Token partKeyword, Token semicolon) {
-    StringNode uri = popLiteralString();
-    addLibraryTag(
-        new Part(partKeyword, uri, popMetadata(compilationUnitElement)));
-  }
-
-  @override
-  void endPartOf(
-      Token partKeyword, Token ofKeyword, Token semicolon, bool hasName) {
-    Expression name = popNode();
-    addPartOfTag(
-        new PartOf(partKeyword, name, popMetadata(compilationUnitElement)));
-  }
-
-  void addPartOfTag(PartOf tag) {
-    compilationUnitElement.setPartOf(tag, reporter);
-  }
-
-  @override
-  void endMetadata(Token beginToken, Token periodBeforeName, Token endToken) {
-    if (periodBeforeName != null) {
-      popNode(); // Discard name.
-    }
-    popNode(); // Discard type parameters
-    popNode(); // Discard identifier
-    // TODO(paulberry,ahe): type variable metadata should not be ignored.  See
-    // dartbug.com/5841.
-    if (!inTypeVariable) {
-      pushMetadata(new PartialMetadataAnnotation(beginToken, endToken));
-    }
-  }
-
-  @override
-  void endTopLevelDeclaration(Token token) {
-    if (!metadata.isEmpty) {
-      MetadataAnnotationX first = metadata.first;
-      recoverableError(reporter.spanFromToken(first.beginToken),
-          'Metadata not supported here.');
-      metadata.clear();
-    }
-  }
-
-  @override
-  void handleNativeFunctionBody(Token nativeToken, Token semicolon) {}
-
-  @override
-  void handleClassImplements(Token implementsKeyword, int interfacesCount) {
-    makeNodeList(interfacesCount, implementsKeyword, null, ","); // interfaces
-  }
-
-  @override
-  void handleRecoverClassHeader() {
-    popNode(); // superType
-  }
-
-  @override
-  void endClassDeclaration(Token beginToken, Token endToken) {
-    popNode(); // superType
-    popNode(); // typeParameters
-    Identifier name = popNode();
-    int id = idGenerator.getNextFreeId();
-    PartialClassElement element = new PartialClassElement(
-        name.source, beginToken, endToken, compilationUnitElement, id);
-    pushElement(element);
-    rejectBuiltInIdentifier(name);
-  }
-
-  void rejectBuiltInIdentifier(Identifier name) {
-    if (name.token is KeywordToken) {
-      TokenType type = name.token.type;
-      if (!type.isPseudo) {
-        recoverableError(name, "Illegal name '${type.lexeme}'.");
-      }
-    }
-  }
-
-  @override
-  void endFunctionTypeAlias(
-      Token typedefKeyword, Token equals, Token endToken) {
-    Identifier name;
-    if (equals == null) {
-      popNode(); // TODO(karlklose): do not throw away typeVariables.
-      name = popNode();
-      popNode(); // returnType
-    } else {
-      popNode(); // Function type.
-      popNode(); // TODO(karlklose): do not throw away typeVariables.
-      name = popNode();
-    }
-    pushElement(new PartialTypedefElement(
-        name.source, compilationUnitElement, typedefKeyword, endToken));
-    rejectBuiltInIdentifier(name);
-  }
-
-  @override
-  void beginNamedMixinApplication(
-      Token begin, Token abstractToken, Token name) {
-    if (abstractToken == null) {
-      pushNode(Modifiers.EMPTY);
-    } else {
-      Link<Node> poppedNodes = const Link<Node>();
-      poppedNodes = poppedNodes.prepend(new Identifier(abstractToken));
-      NodeList modifierNodes = new NodeList(null, poppedNodes, null, ' ');
-      pushNode(new Modifiers(modifierNodes));
-    }
-  }
-
-  @override
-  void endNamedMixinApplication(Token beginToken, Token classKeyword,
-      Token equals, Token implementsKeyword, Token endToken) {
-    NodeList interfaces = (implementsKeyword != null) ? popNode() : null;
-    MixinApplication mixinApplication = popNode();
-    Modifiers modifiers = popNode();
-    NodeList typeParameters = popNode();
-    Identifier name = popNode();
-    NamedMixinApplication namedMixinApplication = new NamedMixinApplication(
-        name,
-        typeParameters,
-        modifiers,
-        mixinApplication,
-        interfaces,
-        beginToken,
-        endToken);
-
-    int id = idGenerator.getNextFreeId();
-    Element enclosing = compilationUnitElement;
-    pushElement(new NamedMixinApplicationElementX(
-        name.source, enclosing, id, namedMixinApplication));
-    rejectBuiltInIdentifier(name);
-  }
-
-  @override
-  void endMixinApplication(Token withKeyword) {
-    NodeList mixins = popNode();
-    NominalTypeAnnotation superclass = popNode();
-    pushNode(new MixinApplication(superclass, mixins));
-  }
-
-  @override
-  void handleVoidKeyword(Token token) {
-    pushNode(new NominalTypeAnnotation(new Identifier(token), null));
-  }
-
-  @override
-  void beginTopLevelMethod(Token lastConsumed, Token externalToken) {
-    if (externalToken == null) {
-      pushNode(Modifiers.EMPTY);
-    } else {
-      Link<Node> poppedNodes = const Link<Node>();
-      poppedNodes = poppedNodes.prepend(new Identifier(externalToken));
-      NodeList modifierNodes = new NodeList(null, poppedNodes, null, ' ');
-      pushNode(new Modifiers(modifierNodes));
-    }
-  }
-
-  @override
-  void endTopLevelMethod(Token beginToken, Token getOrSet, Token endToken) {
-    bool hasParseError = currentMemberHasParseError;
-    memberErrors = memberErrors.tail;
-    popNode(); // typeVariables
-    Identifier name = popNode();
-    popNode(); // type
-    Modifiers modifiers = popNode();
-    PartialFunctionElement element = new PartialFunctionElement(name.source,
-        beginToken, getOrSet, endToken, modifiers, compilationUnitElement);
-    element.hasParseError = hasParseError;
-    pushElement(element);
-  }
-
-  @override
-  void endTopLevelFields(Token staticToken, Token covariantToken,
-      Token varFinalOrConst, int count, Token beginToken, Token endToken) {
-    bool hasParseError = currentMemberHasParseError;
-    memberErrors = memberErrors.tail;
-    void buildFieldElement(Identifier name, VariableList fields) {
-      pushElement(new FieldElementX(name, compilationUnitElement, fields));
-    }
-
-    NodeList variables = makeNodeList(count, null, null, ",");
-    popNode(); // type
-    Modifiers modifiers =
-        newFieldModifiers(staticToken, covariantToken, varFinalOrConst);
-    buildFieldElements(modifiers, variables, compilationUnitElement,
-        buildFieldElement, beginToken, endToken, hasParseError);
-  }
-
-  Modifiers newFieldModifiers(
-      Token staticToken, Token covariantToken, Token varFinalOrConst) {
-    Link<Node> modifierNodes = const Link<Node>();
-    if (varFinalOrConst != null) {
-      modifierNodes = modifierNodes.prepend(new Identifier(varFinalOrConst));
-    }
-    if (covariantToken != null) {
-      modifierNodes = modifierNodes.prepend(new Identifier(covariantToken));
-    }
-    if (staticToken != null) {
-      modifierNodes = modifierNodes.prepend(new Identifier(staticToken));
-    }
-    if (!modifierNodes.isNotEmpty) {
-      return Modifiers.EMPTY;
-    }
-    return new Modifiers(new NodeList(null, modifierNodes, null, ' '));
-  }
-
-  @override
-  void handleInvalidTopLevelDeclaration(Token endToken) {
-    memberErrors = memberErrors.tail;
-  }
-
-  void buildFieldElements(
-      Modifiers modifiers,
-      NodeList variables,
-      Element enclosingElement,
-      void buildFieldElement(Identifier name, VariableList fields),
-      Token beginToken,
-      Token endToken,
-      bool hasParseError) {
-    VariableList fields =
-        new PartialFieldList(beginToken, endToken, modifiers, hasParseError);
-    for (Link<Node> variableNodes = variables.nodes;
-        !variableNodes.isEmpty;
-        variableNodes = variableNodes.tail) {
-      Expression initializedIdentifier = variableNodes.head;
-      Identifier identifier = initializedIdentifier.asIdentifier();
-      if (identifier == null) {
-        identifier = initializedIdentifier.asSendSet().selector.asIdentifier();
-      }
-      buildFieldElement(identifier, fields);
-    }
-  }
-
-  @override
-  void handleIdentifier(Token token, IdentifierContext context) {
-    if (context == IdentifierContext.enumValueDeclaration) {
-      metadata.clear();
-    }
-    pushNode(new Identifier(token));
-  }
-
-  @override
-  void handleQualified(Token period) {
-    Identifier last = popNode();
-    Expression first = popNode();
-    pushNode(new Send(first, last));
-  }
-
-  @override
-  void handleNoConstructorReferenceContinuationAfterTypeArguments(
-      Token token) {}
-
-  @override
-  void handleNoType(Token lastConsumed) {
-    pushNode(null);
-  }
-
-  @override
-  void beginTypeVariable(Token token) {
-    inTypeVariable = true;
-  }
-
-  @override
-  void endTypeVariable(Token token, Token extendsOrSuper) {
-    inTypeVariable = false;
-    NominalTypeAnnotation bound = popNode();
-    Identifier name = popNode();
-    pushNode(new TypeVariable(name, extendsOrSuper, bound));
-    rejectBuiltInIdentifier(name);
-  }
-
-  @override
-  void endTypeVariables(int count, Token beginToken, Token endToken) {
-    pushNode(makeNodeList(count, beginToken, endToken, ','));
-  }
-
-  @override
-  void handleNoTypeVariables(Token token) {
-    pushNode(null);
-  }
-
-  @override
-  void endTypeArguments(int count, Token beginToken, Token endToken) {
-    pushNode(makeNodeList(count, beginToken, endToken, ','));
-  }
-
-  @override
-  void handleNoTypeArguments(Token token) {
-    pushNode(null);
-  }
-
-  @override
-  void handleType(Token beginToken, Token endToken) {
-    NodeList typeArguments = popNode();
-    Expression typeName = popNode();
-    pushNode(new NominalTypeAnnotation(typeName, typeArguments));
-  }
-
-  void handleNoName(Token token) {
-    pushNode(null);
-  }
-
-  @override
-  void endFunctionType(Token functionToken, Token endToken) {
-    popNode(); // Return type.
-    popNode(); // Type parameters.
-    pushNode(null);
-  }
-
-  @override
-  void handleParenthesizedExpression(Token token) {
-    Expression expression = popNode();
-    pushNode(new ParenthesizedExpression(expression, token));
-  }
-
-  @override
-  Token handleUnrecoverableError(Token token, Message message) {
-    Token next = handleError(token, message);
-    if (next == null &&
-        message.code != codes.codeUnterminatedComment &&
-        message.code != codes.codeUnterminatedString) {
-      throw new ParserError.fromTokens(token, token, message);
-    } else {
-      return next;
-    }
-  }
-
-  @override
-  void handleRecoverableError(
-      Message message, Token startToken, Token endToken) {
-    if (message == codes.messageNativeClauseShouldBeAnnotation) {
-      native.checkAllowedLibrary(this, startToken);
-      return;
-    }
-    handleError(startToken, message);
-  }
-
-  @override
-  void handleInvalidExpression(Token token) {
-    pushNode(new ErrorExpression(token));
-  }
-
-  @override
-  void handleInvalidFunctionBody(Token token) {
-    lastErrorWasNativeFunctionBody = false;
-  }
-
-  @override
-  void handleInvalidTypeReference(Token token) {
-    pushNode(null);
-  }
-
-  Token handleError(Token token, Message message) {
-    MessageKind errorCode;
-    Map<String, dynamic> arguments = message.arguments;
-
-    switch (message.code.dart2jsCode) {
-      case "MISSING_TOKEN_BEFORE_THIS":
-        String expected = arguments["string"];
-        // TODO(danrubel): This functionality is being replaced by
-        // the parser's ensureSemicolon method.
-        if (identical(";", expected)) {
-          // When a semicolon is missing, it often leads to an error on the
-          // following line. So we try to find the token preceding the semicolon
-          // and report that something is missing *after* it.
-          Token preceding = findPrecedingToken(token);
-          if (preceding == token) {
-            reportErrorFromToken(token, MessageKind.MISSING_TOKEN_BEFORE_THIS,
-                {'token': expected});
-          } else {
-            reportErrorFromToken(preceding,
-                MessageKind.MISSING_TOKEN_AFTER_THIS, {'token': expected});
-          }
-          return preceding;
-        } else {
-          reportFatalError(
-              reporter.spanFromToken(token),
-              MessageTemplate.TEMPLATES[MessageKind.MISSING_TOKEN_BEFORE_THIS]
-                  .message({'token': expected}, true).toString());
-          return null;
-        }
-        break;
-
-      case "EXPECTED_IDENTIFIER":
-        if (token is KeywordToken) {
-          reportErrorFromToken(
-              token,
-              MessageKind.EXPECTED_IDENTIFIER_NOT_RESERVED_WORD,
-              {'keyword': token.lexeme});
-        } else if (token is ErrorToken) {
-          // TODO(ahe): This is dead code.
-          return newSyntheticToken(synthesizeIdentifier(token));
-        } else {
-          reportFatalError(reporter.spanFromToken(token),
-              "Expected identifier, but got '${token.lexeme}'.");
-        }
-        return newSyntheticToken(token);
-
-      case "NATIVE_OR_BODY_EXPECTED":
-        if (optional("native", token)) {
-          return newSyntheticToken(native.handleNativeBlockToSkip(this, token));
-        } else {
-          errorCode = MessageKind.BODY_EXPECTED;
-        }
-        break;
-
-      case "NATIVE_OR_FATAL":
-        if (optional("native", token)) {
-          lastErrorWasNativeFunctionBody = true;
-          return newSyntheticToken(
-              native.handleNativeFunctionBody(this, token));
-        } else {
-          reportFatalError(reporter.spanFromToken(token), message.message);
-        }
-        return null;
-
-      case "UNMATCHED_TOKEN":
-        reportErrorFromToken(token, MessageKind.UNMATCHED_TOKEN,
-            {"end": arguments["string"], "begin": arguments["token"]});
-        Token next = token;
-        while (next.next is ErrorToken) {
-          next = next.next;
-        }
-        return next;
-
-      case "EMPTY_NAMED_PARAMETER_LIST":
-        errorCode = MessageKind.EMPTY_NAMED_PARAMETER_LIST;
-        break;
-
-      case "EMPTY_OPTIONAL_PARAMETER_LIST":
-        errorCode = MessageKind.EMPTY_OPTIONAL_PARAMETER_LIST;
-        break;
-
-      case "BODY_EXPECTED":
-        errorCode = MessageKind.BODY_EXPECTED;
-        break;
-
-      case "HEX_DIGIT_EXPECTED":
-        errorCode = MessageKind.HEX_DIGIT_EXPECTED;
-        break;
-
-      case "GENERIC":
-        errorCode = MessageKind.GENERIC;
-        arguments = {"text": message.message};
-        break;
-
-      case "EXTRANEOUS_MODIFIER":
-        errorCode = MessageKind.EXTRANEOUS_MODIFIER;
-        arguments = {"modifier": arguments["token"]};
-        break;
-
-      case "EXTRANEOUS_MODIFIER_REPLACE":
-        errorCode = MessageKind.EXTRANEOUS_MODIFIER_REPLACE;
-        arguments = {"modifier": arguments["token"]};
-        break;
-
-      case "INVALID_AWAIT_FOR":
-        errorCode = MessageKind.INVALID_AWAIT_FOR;
-        break;
-
-      case "BAD_INPUT_CHARACTER":
-        errorCode = MessageKind.BAD_INPUT_CHARACTER;
-        int codePoint = arguments["codePoint"];
-        String hex = codePoint.toRadixString(16);
-        String padding = "0000".substring(hex.length);
-        arguments = {'characterHex': padding};
-        break;
-
-      case "INVALID_INLINE_FUNCTION_TYPE":
-        errorCode = MessageKind.INVALID_INLINE_FUNCTION_TYPE;
-        break;
-
-      case "INVALID_SYNC_MODIFIER":
-        errorCode = MessageKind.INVALID_SYNC_MODIFIER;
-        break;
-
-      case "VOID_NOT_ALLOWED":
-        errorCode = MessageKind.VOID_NOT_ALLOWED;
-        break;
-
-      case "MALFORMED_STRING_LITERAL":
-        errorCode = MessageKind.MALFORMED_STRING_LITERAL;
-        break;
-
-      case "EXPONENT_MISSING":
-        errorCode = MessageKind.EXPONENT_MISSING;
-        break;
-
-      case "POSITIONAL_PARAMETER_WITH_EQUALS":
-        errorCode = MessageKind.POSITIONAL_PARAMETER_WITH_EQUALS;
-        break;
-
-      case "REQUIRED_PARAMETER_WITH_DEFAULT":
-        errorCode = MessageKind.REQUIRED_PARAMETER_WITH_DEFAULT;
-        break;
-
-      case "UNMATCHED_TOKEN":
-        errorCode = MessageKind.UNMATCHED_TOKEN;
-        break;
-
-      case "UNSUPPORTED_PREFIX_PLUS":
-        errorCode = MessageKind.UNSUPPORTED_PREFIX_PLUS;
-        break;
-
-      case "UNTERMINATED_COMMENT":
-        errorCode = MessageKind.UNTERMINATED_COMMENT;
-        break;
-
-      case "UNTERMINATED_STRING":
-        errorCode = MessageKind.UNTERMINATED_STRING;
-        arguments = {"quote": arguments["string"]};
-        break;
-
-      case "UNTERMINATED_TOKEN":
-        errorCode = MessageKind.UNTERMINATED_TOKEN;
-        break;
-
-      case "*fatal*":
-        // This is an error that Fasta can recover from, but dart2js can't.
-        reportFatalError(reporter.spanFromToken(token), message.message);
-        return null;
-
-      case "*ignored*":
-        // This is an error that Fasta reports as a recoverable error during
-        // parsing. For historical reasons, dart2js implements this in a later
-        // phase already, so we just ignore it. Another possibilty is that we
-        // wan't to avoid introducing a breaking change to dart2js.
-        return null;
-
-      default:
-        throw "Unexpected message code: ${message.code}";
-    }
-    SourceSpan span = reporter.spanFromToken(token);
-    reportError(span, errorCode, arguments);
-    return null;
-  }
-
-  /// Finds the preceding token via the begin token of the last AST node pushed
-  /// on the [nodes] stack.
-  Token findPrecedingToken(Token token) {
-    Token result;
-    Link<Node> nodes = this.nodes;
-    while (!nodes.isEmpty) {
-      result = findPrecedingTokenFromNode(nodes.head, token);
-      if (result != null) {
-        return result;
-      }
-      nodes = nodes.tail;
-    }
-    if (compilationUnitElement != null) {
-      if (compilationUnitElement is CompilationUnitElementX) {
-        CompilationUnitElementX unit = compilationUnitElement;
-        Link<Element> members = unit.localMembers;
-        while (!members.isEmpty) {
-          ElementX member = members.head;
-          DeclarationSite site = member.declarationSite;
-          if (site is PartialElement) {
-            result = findPrecedingTokenFromToken(site.endToken, token);
-            if (result != null) {
-              return result;
-            }
-          }
-          members = members.tail;
-        }
-        result =
-            findPrecedingTokenFromNode(compilationUnitElement.partTag, token);
-        if (result != null) {
-          return result;
-        }
-      }
-    }
-    return token;
-  }
-
-  Token findPrecedingTokenFromNode(Node node, Token token) {
-    if (node != null) {
-      return findPrecedingTokenFromToken(node.getBeginToken(), token);
-    }
-    return null;
-  }
-
-  Token findPrecedingTokenFromToken(Token start, Token token) {
-    if (start != null) {
-      Token current = start;
-      while (current.kind != Tokens.EOF_TOKEN && current.next != token) {
-        current = current.next;
-      }
-      if (current.kind != Tokens.EOF_TOKEN) {
-        return current;
-      }
-    }
-    return null;
-  }
-
-  /// Finds the preceding token via the begin token of the last AST node pushed
-  /// on the [nodes] stack.
-  Token synthesizeIdentifier(Token token) {
-    Token synthesizedToken =
-        new StringToken.fromString(TokenType.IDENTIFIER, '?', token.charOffset);
-    synthesizedToken.setNext(token.next);
-    return synthesizedToken;
-  }
-
-  void recoverableError(Spannable node, String message) {
-    // TODO(johnniwinther): Make recoverable errors non-fatal.
-    reportFatalError(node, message);
-  }
-
-  void pushElement(ElementX element) {
-    assert(element.declarationSite != null,
-        failedAt(element, 'Missing declaration site for $element.'));
-    popMetadata(element);
-    compilationUnitElement.addMember(element, reporter);
-  }
-
-  List<MetadataAnnotation> popMetadata(ElementX element) {
-    List<MetadataAnnotation> result = metadata.toList();
-    element.metadata = result;
-    metadata.clear();
-    return result;
-  }
-
-  void pushMetadata(MetadataAnnotation annotation) {
-    metadata.addLast(annotation);
-  }
-
-  void addLibraryTag(LibraryTag tag) {
-    if (!allowLibraryTags()) {
-      recoverableError(tag, 'Library tags not allowed here.');
-    }
-    LibraryElementX implementationLibrary =
-        compilationUnitElement.implementationLibrary;
-    implementationLibrary.addTag(tag, reporter);
-  }
-
-  void pushNode(Node node) {
-    nodes = nodes.prepend(node);
-    if (VERBOSE) log("push $nodes");
-  }
-
-  Node popNode() {
-    assert(!nodes.isEmpty);
-    Node node = nodes.head;
-    nodes = nodes.tail;
-    if (VERBOSE) log("pop $nodes");
-    return node;
-  }
-
-  void log(message) {
-    print(message);
-  }
-
-  NodeList makeNodeList(
-      int count, Token beginToken, Token endToken, String delimiter) {
-    Link<Node> poppedNodes = const Link<Node>();
-    for (; count > 0; --count) {
-      // This effectively reverses the order of nodes so they end up
-      // in correct (source) order.
-      poppedNodes = poppedNodes.prepend(popNode());
-    }
-    return new NodeList(beginToken, poppedNodes, endToken, delimiter);
-  }
-
-  @override
-  void beginLiteralString(Token token) {
-    String source = token.lexeme;
-    StringQuoting quoting = StringValidator.quotingFromString(source);
-    pushQuoting(quoting);
-    // Just wrap the token for now. At the end of the interpolation,
-    // when we know how many there are, go back and validate the tokens.
-    pushNode(new LiteralString(token, null));
-  }
-
-  @override
-  void handleStringPart(Token token) {
-    // Just push an unvalidated token now, and replace it when we know the
-    // end of the interpolation.
-    pushNode(new LiteralString(token, null));
-  }
-
-  @override
-  void endLiteralString(int interpolationCount, Token endToken) {
-    StringQuoting quoting = popQuoting();
-
-    Link<StringInterpolationPart> parts = const Link<StringInterpolationPart>();
-    // Parts of the string interpolation are popped in reverse order,
-    // starting with the last literal string part.
-    bool isLast = true;
-    for (int i = 0; i < interpolationCount; i++) {
-      LiteralString string = popNode();
-      DartString validation = stringValidator.validateInterpolationPart(
-          string.token, quoting,
-          isFirst: false, isLast: isLast);
-      // Replace the unvalidated LiteralString with a new LiteralString
-      // object that has the validation result included.
-      string = new LiteralString(string.token, validation);
-      Expression expression = popNode();
-      parts = parts.prepend(new StringInterpolationPart(expression, string));
-      isLast = false;
-    }
-
-    LiteralString string = popNode();
-    DartString validation = stringValidator.validateInterpolationPart(
-        string.token, quoting,
-        isFirst: true, isLast: isLast);
-    string = new LiteralString(string.token, validation);
-    if (isLast) {
-      pushNode(string);
-    } else {
-      NodeList partNodes = new NodeList(null, parts, null, "");
-      pushNode(new StringInterpolation(string, partNodes));
-    }
-  }
-
-  @override
-  void handleNativeClause(Token nativeToken, bool hasName) {
-    if (hasName) {
-      nativeName = popNode(); // LiteralString
-    } else {
-      nativeName = null;
-    }
-  }
-
-  @override
-  void handleStringJuxtaposition(int stringCount) {
-    assert(stringCount != 0);
-    Expression accumulator = popNode();
-    stringCount--;
-    while (stringCount > 0) {
-      Expression expression = popNode();
-      accumulator = new StringJuxtaposition(expression, accumulator);
-      stringCount--;
-    }
-    pushNode(accumulator);
-  }
-
-  @override
-  void beginMember() {
-    memberErrors = memberErrors.prepend(false);
-  }
-
-  @override
-  void beginTopLevelMember(Token token) {
-    beginMember();
-  }
-
-  @override
-  void endMember() {
-    memberErrors = memberErrors.tail;
-  }
-
-  /// Don't call this method. Should only be used as a last resort when there
-  /// is no feasible way to recover from a parser error.
-  void reportFatalError(Spannable spannable, String message) {
-    reportError(spannable, MessageKind.GENERIC, {'text': message});
-    // Some parse errors are infeasible to recover from, so we throw an error.
-    SourceSpan span = reporter.spanFromSpannable(spannable);
-    throw new ParserError(
-        span.begin, span.end, codes.templateUnspecified.withArguments(message));
-  }
-
-  void reportError(Spannable spannable, MessageKind errorCode,
-      [Map arguments = const {}]) {
-    if (currentMemberHasParseError) return; // Error already reported.
-    if (suppressParseErrors) return;
-    if (!memberErrors.isEmpty) {
-      memberErrors = memberErrors.tail.prepend(true);
-    }
-    reporter.reportErrorMessage(spannable, errorCode, arguments);
-  }
-
-  void reportErrorFromToken(Token token, MessageKind errorCode,
-      [Map arguments = const {}]) {
-    reportError(reporter.spanFromToken(token), errorCode, arguments);
-  }
-}
diff --git a/pkg/compiler/lib/src/parser/member_listener.dart b/pkg/compiler/lib/src/parser/member_listener.dart
deleted file mode 100644
index 3d1ed39..0000000
--- a/pkg/compiler/lib/src/parser/member_listener.dart
+++ /dev/null
@@ -1,167 +0,0 @@
-// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library dart2js.parser.member_listener;
-
-import '../common.dart';
-import '../elements/elements.dart' show Element, ElementKind, Elements;
-import '../elements/modelx.dart'
-    show ClassElementX, ElementX, FieldElementX, VariableList;
-import 'package:front_end/src/fasta/scanner.dart' show Token;
-import '../tree/tree.dart';
-import 'element_listener.dart' show ScannerOptions;
-import 'node_listener.dart' show NodeListener;
-import 'partial_elements.dart'
-    show
-        PartialConstructorElement,
-        PartialFunctionElement,
-        PartialMetadataAnnotation;
-
-class MemberListener extends NodeListener {
-  final ClassElementX enclosingClass;
-
-  MemberListener(ScannerOptions scannerOptions, DiagnosticReporter listener,
-      ClassElementX enclosingElement)
-      : this.enclosingClass = enclosingElement,
-        super(scannerOptions, listener, enclosingElement.compilationUnit);
-
-  bool isConstructorName(Node nameNode) {
-    if (enclosingClass == null || enclosingClass.kind != ElementKind.CLASS) {
-      return false;
-    }
-    String name;
-    if (nameNode.asIdentifier() != null) {
-      name = nameNode.asIdentifier().source;
-    } else {
-      Send send = nameNode.asSend();
-      name = send.receiver.asIdentifier().source;
-    }
-    return enclosingClass.name == name;
-  }
-
-  // TODO(johnniwinther): Remove this method.
-  String getMethodNameHack(Node methodName) {
-    Send send = methodName.asSend();
-    if (send == null) {
-      if (isConstructorName(methodName)) return '';
-      return methodName.asIdentifier().source;
-    }
-    Identifier receiver = send.receiver.asIdentifier();
-    Identifier selector = send.selector.asIdentifier();
-    Operator operator = selector.asOperator();
-    if (operator != null) {
-      assert(identical(receiver.source, 'operator'));
-      // TODO(ahe): It is a hack to compare to ')', but it beats
-      // parsing the node.
-      bool isUnary = identical(operator.token.next.next.stringValue, ')');
-      return Elements.constructOperatorName(operator.source, isUnary);
-    } else {
-      if (receiver == null || receiver.source != enclosingClass.name) {
-        reporter.reportErrorMessage(
-            send.receiver,
-            MessageKind.INVALID_CONSTRUCTOR_NAME,
-            {'name': enclosingClass.name});
-      }
-      return selector.source;
-    }
-  }
-
-  @override
-  void endMethod(
-      Token getOrSet, Token beginToken, Token beginParam, Token endToken) {
-    super.endMethod(getOrSet, beginToken, beginParam, endToken);
-    FunctionExpression method = popNode();
-    pushNode(null);
-    bool isConstructor = isConstructorName(method.name);
-    String name = getMethodNameHack(method.name);
-    Element memberElement;
-    if (isConstructor) {
-      if (getOrSet != null) {
-        recoverableError(reporter.spanFromToken(getOrSet), 'illegal modifier');
-      }
-      memberElement = new PartialConstructorElement(name, beginToken, endToken,
-          ElementKind.GENERATIVE_CONSTRUCTOR, method.modifiers, enclosingClass);
-    } else {
-      memberElement = new PartialFunctionElement(name, beginToken, getOrSet,
-          endToken, method.modifiers, enclosingClass,
-          hasBody: method.hasBody);
-    }
-    addMember(memberElement);
-  }
-
-  @override
-  void endFactoryMethod(
-      Token beginToken, Token factoryKeyword, Token endToken) {
-    super.endFactoryMethod(beginToken, factoryKeyword, endToken);
-    FunctionExpression method = popNode();
-    pushNode(null);
-    String name = getMethodNameHack(method.name);
-    Identifier singleIdentifierName = method.name.asIdentifier();
-    if (singleIdentifierName != null && singleIdentifierName.source == name) {
-      if (name != enclosingClass.name) {
-        reporter.reportErrorMessage(
-            singleIdentifierName,
-            MessageKind.INVALID_UNNAMED_CONSTRUCTOR_NAME,
-            {'name': enclosingClass.name});
-      }
-    }
-    Element memberElement = new PartialConstructorElement(
-        name,
-        beginToken,
-        endToken,
-        ElementKind.FACTORY_CONSTRUCTOR,
-        method.modifiers,
-        enclosingClass);
-    addMember(memberElement);
-  }
-
-  @override
-  void endFields(Token staticToken, Token covariantToken, Token varFinalOrConst,
-      int count, Token beginToken, Token endToken) {
-    bool hasParseError = memberErrors.head;
-    super.endFields(staticToken, covariantToken, varFinalOrConst, count,
-        beginToken, endToken);
-    VariableDefinitions variableDefinitions = popNode();
-    Modifiers modifiers = variableDefinitions.modifiers;
-    pushNode(null);
-    void buildFieldElement(Identifier name, VariableList fields) {
-      Element element = new FieldElementX(name, enclosingClass, fields);
-      addMember(element);
-    }
-
-    buildFieldElements(modifiers, variableDefinitions.definitions,
-        enclosingClass, buildFieldElement, beginToken, endToken, hasParseError);
-  }
-
-  @override
-  void endFieldInitializer(Token assignmentOperator, Token token) {
-    pushNode(null); // Super expects an expression, but
-    // ClassElementParser just skips expressions.
-    super.endFieldInitializer(assignmentOperator, token);
-  }
-
-  @override
-  void endInitializers(int count, Token beginToken, Token endToken) {
-    pushNode(null);
-  }
-
-  void addMetadata(ElementX memberElement) {
-    memberElement.metadata = metadata.toList();
-  }
-
-  void addMember(ElementX memberElement) {
-    addMetadata(memberElement);
-    enclosingClass.addMember(memberElement, reporter);
-  }
-
-  @override
-  void endMetadata(Token beginToken, Token periodBeforeName, Token endToken) {
-    super.endMetadata(beginToken, periodBeforeName, endToken);
-    // TODO(paulberry,ahe): type variable metadata should not be ignored.  See
-    // dartbug.com/5841.
-    if (!inTypeVariable) {
-      pushMetadata(new PartialMetadataAnnotation(beginToken, endToken));
-    }
-  }
-}
diff --git a/pkg/compiler/lib/src/parser/node_listener.dart b/pkg/compiler/lib/src/parser/node_listener.dart
deleted file mode 100644
index 4ac6f34..0000000
--- a/pkg/compiler/lib/src/parser/node_listener.dart
+++ /dev/null
@@ -1,1254 +0,0 @@
-// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library dart2js.parser.node_listener;
-
-import 'package:front_end/src/fasta/parser.dart'
-    show FormalParameterKind, IdentifierContext, MemberKind;
-import 'package:front_end/src/fasta/scanner.dart' show Token;
-import 'package:front_end/src/scanner/token.dart' show TokenType;
-
-import '../common.dart';
-import '../elements/elements.dart' show CompilationUnitElement;
-import '../tree/tree.dart';
-import '../util/util.dart' show Link;
-import 'element_listener.dart' show ElementListener, ScannerOptions;
-
-import 'package:front_end/src/fasta/parser.dart' as fasta show Assert;
-
-class NodeListener extends ElementListener {
-  int invalidTopLevelDeclarationCount = 0;
-  int invalidMemberCount = 0;
-
-  NodeListener(ScannerOptions scannerOptions, DiagnosticReporter reporter,
-      CompilationUnitElement element)
-      : super(scannerOptions, reporter, element, null);
-
-  @override
-  void addLibraryTag(LibraryTag tag) {
-    pushNode(tag);
-  }
-
-  @override
-  void addPartOfTag(PartOf tag) {
-    pushNode(tag);
-  }
-
-  @override
-  void endLibraryName(Token libraryKeyword, Token semicolon) {
-    Expression name = popNode();
-    pushNode(new LibraryName(
-        libraryKeyword,
-        name,
-        // TODO(sigmund): Import AST nodes have pointers to MetadataAnnotation
-        // (element) instead of Metatada (node).
-        null));
-  }
-
-  @override
-  void endImport(Token importKeyword, Token semicolon) {
-    NodeList combinators = popNode();
-    Flag flag = popNode();
-    bool isDeferred = flag == Flag.TRUE;
-    Identifier prefix = popNode();
-    NodeList conditionalUris = popNode();
-    StringNode uri = popLiteralString();
-    pushNode(new Import(
-        importKeyword,
-        uri,
-        conditionalUris,
-        prefix,
-        combinators,
-        // TODO(sigmund): Import AST nodes have pointers to MetadataAnnotation
-        // (element) instead of Metatada (node).
-        null,
-        isDeferred: isDeferred));
-  }
-
-  @override
-  void endExport(Token exportKeyword, Token semicolon) {
-    NodeList combinators = popNode();
-    NodeList conditionalUris = popNode();
-    StringNode uri = popLiteralString();
-    pushNode(new Export(
-        exportKeyword,
-        uri,
-        conditionalUris,
-        combinators,
-        // TODO(sigmund): Import AST nodes have pointers to MetadataAnnotation
-        // (element) instead of Metatada (node).
-        null));
-  }
-
-  @override
-  void endPart(Token partKeyword, Token semicolon) {
-    StringNode uri = popLiteralString();
-    pushNode(new Part(
-        partKeyword,
-        uri,
-        // TODO(sigmund): Import AST nodes have pointers to MetadataAnnotation
-        // (element) instead of Metatada (node).
-        null));
-  }
-
-  @override
-  void endPartOf(
-      Token partKeyword, Token ofKeyword, Token semicolon, bool hasName) {
-    Expression name = popNode(); // name
-    pushNode(new PartOf(
-        partKeyword,
-        name,
-        // TODO(sigmund): Import AST nodes have pointers to MetadataAnnotation
-        // (element) instead of Metatada (node).
-        null));
-  }
-
-  @override
-  void handleClassExtends(Token extendsKeyword) {
-    pushNode(new TokenNode(extendsKeyword));
-  }
-
-  @override
-  void handleClassImplements(Token implementsKeyword, int interfacesCount) {
-    pushNode(makeNodeList(interfacesCount, implementsKeyword, null, ","));
-  }
-
-  @override
-  void handleRecoverClassHeader() {
-    popNode(); // interfaces
-    popNode(); // extendsNode
-    popNode(); // supertype
-  }
-
-  @override
-  void beginClassDeclaration(Token begin, Token abstractToken, Token name) {
-    if (abstractToken == null) {
-      pushNode(Modifiers.EMPTY);
-    } else {
-      Link<Node> poppedNodes = const Link<Node>();
-      poppedNodes = poppedNodes.prepend(new Identifier(abstractToken));
-      NodeList modifierNodes = new NodeList(null, poppedNodes, null, ' ');
-      pushNode(new Modifiers(modifierNodes));
-    }
-  }
-
-  @override
-  void endClassDeclaration(Token beginToken, Token endToken) {
-    NodeList body = popNode();
-    NodeList interfaces = popNode();
-    TokenNode extendsNode = popNode();
-    Node supertype = popNode();
-    Modifiers modifiers = popNode();
-    NodeList typeParameters = popNode();
-    Identifier name = popNode();
-    // TODO(danrubel): can we remove the extends keyword from ClassNode ?
-    pushNode(new ClassNode(modifiers, name, typeParameters, supertype,
-        interfaces, beginToken, extendsNode.token, body, endToken));
-  }
-
-  @override
-  void handleInvalidTopLevelDeclaration(Token endToken) {
-    ++invalidTopLevelDeclarationCount;
-  }
-
-  @override
-  void endTopLevelDeclaration(Token token) {
-    // TODO(sigmund): consider moving metadata into each declaration
-    // element instead.
-    Node node = popNode(); // top-level declaration
-    popNode(); // Discard metadata
-    pushNode(node);
-    super.endTopLevelDeclaration(token);
-  }
-
-  @override
-  void beginCompilationUnit(Token token) {
-    invalidTopLevelDeclarationCount = 0;
-  }
-
-  @override
-  void endCompilationUnit(int count, Token token) {
-    pushNode(makeNodeList(
-        count - invalidTopLevelDeclarationCount, null, null, '\n'));
-  }
-
-  @override
-  void endFunctionTypeAlias(
-      Token typedefKeyword, Token equals, Token endToken) {
-    bool isGeneralizedTypeAlias;
-    NodeList templateParameters;
-    TypeAnnotation returnType;
-    Identifier name;
-    NodeList typeParameters;
-    NodeList formals;
-    if (equals == null) {
-      isGeneralizedTypeAlias = false;
-      formals = popNode();
-      templateParameters = popNode();
-      name = popNode();
-      returnType = popNode();
-    } else {
-      // TODO(floitsch): keep using the `FunctionTypeAnnotation' node.
-      isGeneralizedTypeAlias = true;
-      Node type = popNode();
-      if (type.asFunctionTypeAnnotation() == null) {
-        // TODO(floitsch): The parser should diagnose this problem, not
-        // this listener.
-        // However, this problem goes away, when we allow aliases for
-        // non-function types too.
-        reportFatalError(type, 'Expected a function type.');
-      }
-      FunctionTypeAnnotation functionType = type;
-      templateParameters = popNode();
-      name = popNode();
-      returnType = functionType.returnType;
-      typeParameters = functionType.typeParameters;
-      formals = functionType.formals;
-    }
-    pushNode(new Typedef(isGeneralizedTypeAlias, templateParameters, returnType,
-        name, typeParameters, formals, typedefKeyword, endToken));
-  }
-
-  void handleNoName(Token token) {
-    pushNode(null);
-  }
-
-  @override
-  void endFunctionType(Token functionToken, Token endToken) {
-    NodeList formals = popNode();
-    TypeAnnotation returnType = popNode();
-    NodeList typeParameters = popNode();
-    pushNode(new FunctionTypeAnnotation(
-        returnType, functionToken, typeParameters, formals));
-  }
-
-  @override
-  void endNamedMixinApplication(Token beginToken, Token classKeyword,
-      Token equals, Token implementsKeyword, Token endToken) {
-    NodeList interfaces = (implementsKeyword != null) ? popNode() : null;
-    Node mixinApplication = popNode();
-    Modifiers modifiers = popNode();
-    NodeList typeParameters = popNode();
-    Identifier name = popNode();
-    pushNode(new NamedMixinApplication(name, typeParameters, modifiers,
-        mixinApplication, interfaces, beginToken, endToken));
-  }
-
-  @override
-  void endEnum(Token enumKeyword, Token leftBrace, int count) {
-    NodeList names = makeNodeList(count, leftBrace, leftBrace?.endGroup, ",");
-    Identifier name = popNode();
-    pushNode(new Enum(enumKeyword, name, names));
-  }
-
-  @override
-  void endClassBody(int memberCount, Token beginToken, Token endToken) {
-    pushNode(makeNodeList(
-        memberCount - invalidMemberCount, beginToken, endToken, null));
-    invalidMemberCount = 0;
-  }
-
-  @override
-  void endTopLevelFields(Token staticToken, Token covariantToken,
-      Token varFinalOrConst, int count, Token beginToken, Token endToken) {
-    NodeList variables = makeNodeList(count, null, endToken, ",");
-    TypeAnnotation type = popNode();
-    Modifiers modifiers =
-        newFieldModifiers(staticToken, covariantToken, varFinalOrConst);
-    pushNode(new VariableDefinitions(type, modifiers, variables));
-  }
-
-  @override
-  void endTopLevelMethod(Token beginToken, Token getOrSet, Token endToken) {
-    Statement body = popNode();
-    AsyncModifier asyncModifier = popNode();
-    NodeList formals = popNode();
-    NodeList typeVariables = popNode();
-    Identifier name = popNode();
-    TypeAnnotation type = popNode();
-    Modifiers modifiers = popNode();
-    pushNode(new FunctionExpression(name, typeVariables, formals, body, type,
-        modifiers, null, getOrSet, asyncModifier));
-  }
-
-  @override
-  void beginFormalParameter(Token token, MemberKind kind, Token covariantToken,
-      Token varFinalOrConst) {
-    if (covariantToken == null && varFinalOrConst == null) {
-      pushNode(Modifiers.EMPTY);
-    } else {
-      Link<Node> poppedNodes = const Link<Node>();
-      if (covariantToken != null) {
-        poppedNodes = poppedNodes.prepend(new Identifier(covariantToken));
-      }
-      if (varFinalOrConst != null) {
-        poppedNodes = poppedNodes.prepend(new Identifier(varFinalOrConst));
-      }
-      NodeList modifierNodes = new NodeList(null, poppedNodes, null, ' ');
-      pushNode(new Modifiers(modifierNodes));
-    }
-  }
-
-  @override
-  void endFormalParameter(Token thisKeyword, Token periodAfterThis,
-      Token nameToken, FormalParameterKind kind, MemberKind memberKind) {
-    Expression name = popNode();
-    if (thisKeyword != null) {
-      Identifier thisIdentifier = new Identifier(thisKeyword);
-      if (name.asSend() == null) {
-        name = new Send(thisIdentifier, name);
-      } else {
-        name = name.asSend().copyWithReceiver(thisIdentifier, false);
-      }
-    }
-    TypeAnnotation type = popNode();
-    Modifiers modifiers = popNode();
-    NodeList metadata = popNode();
-    pushNode(new VariableDefinitions.forParameter(
-        metadata, type, modifiers, new NodeList.singleton(name)));
-  }
-
-  @override
-  void endFormalParameters(
-      int count, Token beginToken, Token endToken, MemberKind kind) {
-    pushNode(makeNodeList(count, beginToken, endToken, ","));
-  }
-
-  @override
-  void handleNoFormalParameters(Token token, MemberKind kind) {
-    pushNode(null);
-  }
-
-  @override
-  void endArguments(int count, Token beginToken, Token endToken) {
-    pushNode(makeNodeList(count, beginToken, endToken, ","));
-  }
-
-  @override
-  void handleNoArguments(Token token) {
-    pushNode(null);
-  }
-
-  @override
-  void endConstructorReference(
-      Token start, Token periodBeforeName, Token endToken) {
-    Identifier name = null;
-    if (periodBeforeName != null) {
-      name = popNode();
-    }
-    NodeList typeArguments = popNode();
-    Node classReference = popNode();
-    if (typeArguments != null) {
-      classReference = new NominalTypeAnnotation(classReference, typeArguments);
-    } else {
-      Identifier identifier = classReference.asIdentifier();
-      Send send = classReference.asSend();
-      if (identifier != null) {
-        // TODO(ahe): Should be:
-        // classReference = new Send(null, identifier);
-        classReference = identifier;
-      } else if (send != null) {
-        classReference = send;
-      } else {
-        internalError(node: classReference);
-      }
-    }
-    Node constructor = classReference;
-    if (name != null) {
-      // Either typeName<args>.name or x.y.name.
-      constructor = new Send(classReference, name);
-    }
-    pushNode(constructor);
-  }
-
-  @override
-  void endRedirectingFactoryBody(Token beginToken, Token endToken) {
-    pushNode(new RedirectingFactoryBody(beginToken, endToken, popNode()));
-  }
-
-  @override
-  void handleNativeFunctionBody(Token nativeToken, Token semicolon) {
-    pushNode(new Return(nativeToken, semicolon, nativeName));
-  }
-
-  @override
-  void handleEmptyFunctionBody(Token semicolon) {
-    endBlockFunctionBody(0, null, semicolon);
-  }
-
-  void handleExpressionFunctionBody(Token arrowToken, Token endToken) {
-    endReturnStatement(true, arrowToken, endToken);
-  }
-
-  @override
-  void endReturnStatement(
-      bool hasExpression, Token beginToken, Token endToken) {
-    Expression expression = hasExpression ? popNode() : null;
-    pushNode(new Return(beginToken, endToken, expression));
-  }
-
-  @override
-  void endYieldStatement(Token yieldToken, Token starToken, Token endToken) {
-    Expression expression = popNode();
-    pushNode(new Yield(yieldToken, starToken, expression, endToken));
-  }
-
-  @override
-  void endExpressionStatement(Token token) {
-    pushNode(new ExpressionStatement(popNode(), token));
-  }
-
-  void handleOnError(Token token, var errorInformation) {
-    reporter.internalError(reporter.spanFromToken(token),
-        "'${token.lexeme}': ${errorInformation}");
-  }
-
-  @override
-  void handleLiteralInt(Token token) {
-    pushNode(new LiteralInt(token, (t, e) => handleOnError(t, e)));
-  }
-
-  @override
-  void handleLiteralDouble(Token token) {
-    pushNode(new LiteralDouble(token, (t, e) => handleOnError(t, e)));
-  }
-
-  @override
-  void handleLiteralBool(Token token) {
-    pushNode(new LiteralBool(token, (t, e) => handleOnError(t, e)));
-  }
-
-  @override
-  void handleLiteralNull(Token token) {
-    pushNode(new LiteralNull(token));
-  }
-
-  @override
-  void endLiteralSymbol(Token hashToken, int identifierCount) {
-    NodeList identifiers = makeNodeList(identifierCount, null, null, '.');
-    pushNode(new LiteralSymbol(hashToken, identifiers));
-  }
-
-  @override
-  void endBinaryExpression(Token token) {
-    Node argument = popNode();
-    Node receiver = popNode();
-    String tokenString = token.stringValue;
-    if (identical(tokenString, '.') ||
-        identical(tokenString, '..') ||
-        identical(tokenString, '?.')) {
-      Send argumentSend = argument.asSend();
-      if (argumentSend == null) {
-        // TODO(ahe): The parser should diagnose this problem, not
-        // this listener.
-        reportFatalError(
-            reporter.spanFromSpannable(argument), "Expected an identifier.");
-      }
-      if (argumentSend.receiver != null) internalError(node: argument);
-      if (argument is SendSet) internalError(node: argument);
-      pushNode(argument
-          .asSend()
-          .copyWithReceiver(receiver, identical(tokenString, '?.')));
-    } else {
-      NodeList arguments = new NodeList.singleton(argument);
-      pushNode(new Send(receiver, new Operator(token), arguments));
-    }
-    if (identical(tokenString, '===')) {
-      reporter.reportErrorMessage(reporter.spanFromToken(token),
-          MessageKind.UNSUPPORTED_EQ_EQ_EQ, {'lhs': receiver, 'rhs': argument});
-    }
-    if (identical(tokenString, '!==')) {
-      reporter.reportErrorMessage(
-          reporter.spanFromToken(token),
-          MessageKind.UNSUPPORTED_BANG_EQ_EQ,
-          {'lhs': receiver, 'rhs': argument});
-    }
-  }
-
-  @override
-  void beginCascade(Token token) {
-    pushNode(new CascadeReceiver(popNode(), token));
-  }
-
-  @override
-  void endCascade() {
-    pushNode(new Cascade(popNode()));
-  }
-
-  @override
-  void handleAsOperator(Token operator, Token endToken) {
-    TypeAnnotation type = popNode();
-    Expression expression = popNode();
-    NodeList arguments = new NodeList.singleton(type);
-    pushNode(new Send(expression, new Operator(operator), arguments));
-  }
-
-  @override
-  void handleAssignmentExpression(Token token) {
-    Node arg = popNode();
-    Node node = popNode();
-    Send send = node.asSend();
-    if (send == null || !(send.isPropertyAccess || send.isIndex)) {
-      reportNotAssignable(node);
-    }
-    var tokenString = token.stringValue;
-    if (tokenString == '||=' || tokenString == '&&=') {
-      reporter.reportErrorMessage(reporter.spanFromToken(token),
-          MessageKind.UNSUPPORTED_OPERATOR, {'operator': tokenString});
-      pushNode(arg);
-      return;
-    }
-    if (send.asSendSet() != null) internalError(node: send);
-    NodeList arguments;
-    if (send.isIndex) {
-      Link<Node> link = const Link<Node>().prepend(arg);
-      link = link.prepend(send.arguments.head);
-      arguments = new NodeList(null, link);
-    } else {
-      arguments = new NodeList.singleton(arg);
-    }
-    Operator op = new Operator(token);
-    pushNode(new SendSet(
-        send.receiver, send.selector, op, arguments, send.isConditional));
-  }
-
-  void reportNotAssignable(Node node) {
-    // TODO(ahe): The parser should diagnose this problem, not this
-    // listener.
-    reportFatalError(reporter.spanFromSpannable(node), "Not assignable.");
-  }
-
-  @override
-  void endConditionalExpression(Token question, Token colon) {
-    Node elseExpression = popNode();
-    Node thenExpression = popNode();
-    Node condition = popNode();
-    pushNode(new Conditional(
-        condition, thenExpression, elseExpression, question, colon));
-  }
-
-  @override
-  void handleSend(Token beginToken, Token endToken) {
-    NodeList arguments = popNode();
-    NodeList typeArguments = popNode();
-    Node selector = popNode();
-    // TODO(ahe): Handle receiver.
-    pushNode(new Send(null, selector, arguments, typeArguments));
-  }
-
-  @override
-  void endBlockFunctionBody(int count, Token beginToken, Token endToken) {
-    if (count == 0 && beginToken == null) {
-      pushNode(new EmptyStatement(endToken));
-    } else {
-      pushNode(new Block(makeNodeList(count, beginToken, endToken, null)));
-    }
-  }
-
-  @override
-  void handleAsyncModifier(Token asyncToken, Token starToken) {
-    if (asyncToken != null) {
-      pushNode(new AsyncModifier(asyncToken, starToken));
-    } else {
-      pushNode(null);
-    }
-  }
-
-  @override
-  void handleFunctionBodySkipped(Token token, bool isExpressionBody) {
-    pushNode(new Block(new NodeList.empty()));
-  }
-
-  @override
-  void handleNativeFunctionBodyIgnored(Token nativeToken, Token semicolon) {}
-
-  @override
-  void handleNativeFunctionBodySkipped(Token nativeToken, Token semicolon) {
-    pushNode(new Block(new NodeList.empty()));
-  }
-
-  @override
-  void handleNoFunctionBody(Token token) {
-    pushNode(new EmptyStatement(token));
-  }
-
-  @override
-  void endNamedFunctionExpression(Token endToken) {
-    Statement body = popNode();
-    AsyncModifier asyncModifier = popNode();
-    NodeList initializers = popNode();
-    NodeList formals = popNode();
-    // The name can be an identifier or a send in case of named constructors.
-    Expression name = popNode();
-    TypeAnnotation type = popNode();
-    Modifiers modifiers = new Modifiers(new NodeList.empty());
-    NodeList typeVariables = popNode();
-    pushNode(new FunctionExpression(name, typeVariables, formals, body, type,
-        modifiers, initializers, null, asyncModifier));
-  }
-
-  @override
-  void endLocalFunctionDeclaration(Token endToken) {
-    Statement body = popNode();
-    AsyncModifier asyncModifier = popNode();
-    NodeList initializers = popNode();
-    NodeList formals = popNode();
-    // The name can be an identifier or a send in case of named constructors.
-    Expression name = popNode();
-    TypeAnnotation type = popNode();
-    Modifiers modifiers = new Modifiers(new NodeList.empty());
-    NodeList typeVariables = popNode();
-    popNode(); // Metadata.
-    pushNode(new FunctionDeclaration(new FunctionExpression(name, typeVariables,
-        formals, body, type, modifiers, initializers, null, asyncModifier)));
-  }
-
-  @override
-  void beginVariablesDeclaration(Token token, Token varFinalOrConst) {
-    if (varFinalOrConst == null) {
-      pushNode(Modifiers.EMPTY);
-    } else {
-      Link<Node> nodes =
-          const Link<Node>().prepend(new Identifier(varFinalOrConst));
-      pushNode(new Modifiers(new NodeList(null, nodes, null, ' ')));
-    }
-  }
-
-  @override
-  void endVariablesDeclaration(int count, Token endToken) {
-    // TODO(ahe): Pick one name for this concept, either
-    // VariablesDeclaration or VariableDefinitions.
-    NodeList variables = makeNodeList(count, null, endToken, ",");
-    Modifiers modifiers = popNode();
-    TypeAnnotation type = popNode();
-    popNode();
-    pushNode(new VariableDefinitions(type, modifiers, variables));
-  }
-
-  @override
-  void endVariableInitializer(Token assignmentOperator) {
-    Expression initializer = popNode();
-    NodeList arguments =
-        initializer == null ? null : new NodeList.singleton(initializer);
-    Expression name = popNode();
-    Operator op = new Operator(assignmentOperator);
-    pushNode(new SendSet(null, name, op, arguments));
-  }
-
-  @override
-  void endFieldInitializer(Token assignmentOperator, Token token) {
-    endVariableInitializer(assignmentOperator);
-  }
-
-  @override
-  void endIfStatement(Token ifToken, Token elseToken) {
-    Statement elsePart = (elseToken == null) ? null : popNode();
-    Statement thenPart = popNode();
-    ParenthesizedExpression condition = popNode();
-    pushNode(new If(condition, thenPart, elsePart, ifToken, elseToken));
-  }
-
-  @override
-  void endForStatement(Token forKeyword, Token leftParen, Token leftSeparator,
-      int updateExpressionCount, Token endToken) {
-    Statement body = popNode();
-    NodeList updates = makeNodeList(updateExpressionCount, null, null, ',');
-    Statement condition = popNode();
-    Node initializer = popNode();
-    pushNode(new For(initializer, condition, updates, body, forKeyword));
-  }
-
-  @override
-  void handleNoExpression(Token token) {
-    pushNode(null);
-  }
-
-  @override
-  void endDoWhileStatement(
-      Token doKeyword, Token whileKeyword, Token endToken) {
-    Expression condition = popNode();
-    Statement body = popNode();
-    pushNode(new DoWhile(body, condition, doKeyword, whileKeyword, endToken));
-  }
-
-  @override
-  void endWhileStatement(Token whileKeyword, Token endToken) {
-    Statement body = popNode();
-    Expression condition = popNode();
-    pushNode(new While(condition, body, whileKeyword));
-  }
-
-  @override
-  void endBlock(int count, Token beginToken, Token endToken) {
-    pushNode(new Block(makeNodeList(count, beginToken, endToken, null)));
-  }
-
-  void handleInvalidTopLevelBlock(Token token) {
-    popNode(); // block
-  }
-
-  @override
-  void handleThrowExpression(Token throwToken, Token endToken) {
-    Expression expression = popNode();
-    pushNode(new Throw(expression, throwToken, endToken));
-  }
-
-  @override
-  void endAwaitExpression(Token awaitToken, Token endToken) {
-    Expression expression = popNode();
-    pushNode(new Await(awaitToken, expression));
-  }
-
-  @override
-  void endRethrowStatement(Token throwToken, Token endToken) {
-    pushNode(new Rethrow(throwToken, endToken));
-    if (identical(throwToken.stringValue, 'throw')) {
-      reporter.reportErrorMessage(reporter.spanFromToken(throwToken),
-          MessageKind.MISSING_EXPRESSION_IN_THROW);
-    }
-  }
-
-  @override
-  void handleUnaryPrefixExpression(Token token) {
-    pushNode(new Send.prefix(popNode(), new Operator(token)));
-  }
-
-  @override
-  void handleSuperExpression(Token token, IdentifierContext context) {
-    pushNode(new Identifier(token));
-  }
-
-  @override
-  void handleThisExpression(Token token, IdentifierContext context) {
-    pushNode(new Identifier(token));
-  }
-
-  void handleUnaryAssignmentExpression(Token token, bool isPrefix) {
-    Node node = popNode();
-    Send send = node.asSend();
-    if (send == null) {
-      reportNotAssignable(node);
-    }
-    if (!(send.isPropertyAccess || send.isIndex)) {
-      reportNotAssignable(node);
-    }
-    if (send.asSendSet() != null) internalError(node: send);
-    Node argument = null;
-    if (send.isIndex) argument = send.arguments.head;
-    Operator op = new Operator(token);
-
-    if (isPrefix) {
-      pushNode(new SendSet.prefix(
-          send.receiver, send.selector, op, argument, send.isConditional));
-    } else {
-      pushNode(new SendSet.postfix(
-          send.receiver, send.selector, op, argument, send.isConditional));
-    }
-  }
-
-  @override
-  void handleUnaryPostfixAssignmentExpression(Token token) {
-    handleUnaryAssignmentExpression(token, false);
-  }
-
-  @override
-  void handleUnaryPrefixAssignmentExpression(Token token) {
-    handleUnaryAssignmentExpression(token, true);
-  }
-
-  @override
-  void endInitializers(int count, Token beginToken, Token endToken) {
-    pushNode(makeNodeList(count, beginToken, null, ','));
-  }
-
-  @override
-  void handleNoInitializers() {
-    pushNode(null);
-  }
-
-  @override
-  void handleInvalidMember(Token endToken) {
-    popNode(); // Discard metadata
-    ++invalidMemberCount;
-  }
-
-  @override
-  void endMember() {
-    // TODO(sigmund): consider moving metadata into each declaration
-    // element instead.
-    Node node = popNode(); // member
-    popNode(); // Discard metadata
-    pushNode(node);
-    super.endMember();
-  }
-
-  @override
-  void endFields(Token staticToken, Token covariantToken, Token varFinalOrConst,
-      int count, Token beginToken, Token endToken) {
-    NodeList variables = makeNodeList(count, null, endToken, ",");
-    TypeAnnotation type = popNode();
-    Modifiers modifiers =
-        newFieldModifiers(staticToken, covariantToken, varFinalOrConst);
-    pushNode(new VariableDefinitions(type, modifiers, variables));
-  }
-
-  @override
-  void beginMethod(Token externalToken, Token staticToken, Token covariantToken,
-      Token varFinalOrConst, Token name) {
-    Link<Node> modifiers = const Link<Node>();
-    if (varFinalOrConst != null) {
-      modifiers = modifiers.prepend(new Identifier(varFinalOrConst));
-    }
-    if (covariantToken != null) {
-      modifiers = modifiers.prepend(new Identifier(covariantToken));
-    }
-    if (staticToken != null) {
-      modifiers = modifiers.prepend(new Identifier(staticToken));
-    }
-    if (externalToken != null) {
-      modifiers = modifiers.prepend(new Identifier(externalToken));
-    }
-    if (modifiers.isEmpty) {
-      pushNode(Modifiers.EMPTY);
-    } else {
-      pushNode(new Modifiers(new NodeList(null, modifiers, null, ' ')));
-    }
-  }
-
-  @override
-  void endMethod(
-      Token getOrSet, Token beginToken, Token beginParam, Token endToken) {
-    Statement body = popNode();
-    AsyncModifier asyncModifier = popNode();
-    NodeList initializers = popNode();
-    NodeList formalParameters = popNode();
-    NodeList typeVariables = popNode();
-    Expression name = popNode();
-    TypeAnnotation returnType = popNode();
-    Modifiers modifiers = popNode();
-    pushNode(new FunctionExpression(name, typeVariables, formalParameters, body,
-        returnType, modifiers, initializers, getOrSet, asyncModifier));
-  }
-
-  @override
-  void handleLiteralMap(
-      int count, Token beginToken, Token constKeyword, Token endToken) {
-    NodeList entries = makeNodeList(count, beginToken, endToken, ',');
-    NodeList typeArguments = popNode();
-    pushNode(new LiteralMap(typeArguments, entries, constKeyword));
-  }
-
-  @override
-  void endLiteralMapEntry(Token colon, Token endToken) {
-    Expression value = popNode();
-    Expression key = popNode();
-    pushNode(new LiteralMapEntry(key, colon, value));
-  }
-
-  @override
-  void handleLiteralList(
-      int count, Token beginToken, Token constKeyword, Token endToken) {
-    NodeList elements = makeNodeList(count, beginToken, endToken, ',');
-    pushNode(new LiteralList(popNode(), elements, constKeyword));
-  }
-
-  @override
-  void handleIndexedExpression(
-      Token openSquareBracket, Token closeSquareBracket) {
-    NodeList arguments =
-        makeNodeList(1, openSquareBracket, closeSquareBracket, null);
-    Node receiver = popNode();
-    Token token = new Token(TokenType.INDEX, openSquareBracket.charOffset);
-    Node selector = new Operator(token);
-    pushNode(new Send(receiver, selector, arguments));
-  }
-
-  @override
-  void endNewExpression(Token token) {
-    NodeList arguments = popNode();
-    Node name = popNode();
-    pushNode(new NewExpression(token, new Send(null, name, arguments)));
-  }
-
-  @override
-  void endConstExpression(Token token) {
-    // [token] carries the 'const' information.
-    endNewExpression(token);
-  }
-
-  @override
-  void handleOperator(Token token) {
-    pushNode(new Operator(token));
-  }
-
-  @override
-  void handleSymbolVoid(Token token) {
-    logEvent('SymbolVoid');
-  }
-
-  @override
-  void handleOperatorName(Token operatorKeyword, Token token) {
-    Operator op = new Operator(token);
-    pushNode(new Send(new Identifier(operatorKeyword), op, null));
-  }
-
-  @override
-  void handleInvalidOperatorName(Token operatorKeyword, Token token) {
-    Operator op = new Operator(token);
-    pushNode(new Send(new Identifier(operatorKeyword), op, null));
-  }
-
-  @override
-  void handleNamedArgument(Token colon) {
-    Expression expression = popNode();
-    Identifier name = popNode();
-    pushNode(new NamedArgument(name, colon, expression));
-  }
-
-  @override
-  void endOptionalFormalParameters(
-      int count, Token beginToken, Token endToken) {
-    pushNode(makeNodeList(count, beginToken, endToken, ','));
-  }
-
-  @override
-  void handleIdentifier(Token token, IdentifierContext context) {
-    if (IdentifierContext.formalParameterDeclaration == context ||
-        IdentifierContext.fieldInitializer == context) {
-      var typeAnnotation = popNode();
-      if (typeAnnotation is FunctionExpression) {
-        pushNode(null); // Signal "no type" to endFormalParameter.
-        pushNode(new FunctionExpression(
-            new Identifier(token),
-            typeAnnotation.typeVariables,
-            typeAnnotation.parameters,
-            null,
-            typeAnnotation.returnType,
-            typeAnnotation.modifiers,
-            null,
-            null,
-            null));
-        return;
-      } else {
-        pushNode(typeAnnotation);
-      }
-    } else if (context == IdentifierContext.enumValueDeclaration) {
-      popNode();
-    }
-    pushNode(new Identifier(token));
-  }
-
-  @override
-  void endFunctionTypedFormalParameter() {
-    NodeList formals = popNode();
-    TypeAnnotation returnType = popNode();
-    NodeList typeVariables = popNode();
-    pushNode(new FunctionExpression(null, typeVariables, formals, null,
-        returnType, Modifiers.EMPTY, null, null, null));
-  }
-
-  @override
-  void handleValuedFormalParameter(Token equals, Token token) {
-    Expression defaultValue = popNode();
-    Expression parameterName = popNode();
-    pushNode(new SendSet(null, parameterName, new Operator(equals),
-        new NodeList.singleton(defaultValue)));
-  }
-
-  @override
-  void handleFormalParameterWithoutValue(Token token) {}
-
-  @override
-  void endTryStatement(int catchCount, Token tryKeyword, Token finallyKeyword) {
-    Block finallyBlock = null;
-    if (finallyKeyword != null) {
-      finallyBlock = popNode();
-    }
-    NodeList catchBlocks = makeNodeList(catchCount, null, null, null);
-    Block tryBlock = popNode();
-    pushNode(new TryStatement(
-        tryBlock, catchBlocks, finallyBlock, tryKeyword, finallyKeyword));
-  }
-
-  @override
-  void handleCaseMatch(Token caseKeyword, Token colon) {
-    pushNode(new CaseMatch(caseKeyword, popNode(), colon));
-  }
-
-  @override
-  void handleCatchBlock(Token onKeyword, Token catchKeyword, Token comma) {
-    Block block = popNode();
-    NodeList formals = catchKeyword != null ? popNode() : null;
-    TypeAnnotation type = onKeyword != null ? popNode() : null;
-    pushNode(new CatchBlock(type, formals, block, onKeyword, catchKeyword));
-  }
-
-  @override
-  void endSwitchStatement(Token switchKeyword, Token endToken) {
-    NodeList cases = popNode();
-    ParenthesizedExpression expression = popNode();
-    pushNode(new SwitchStatement(expression, cases, switchKeyword));
-  }
-
-  @override
-  void endSwitchBlock(int caseCount, Token beginToken, Token endToken) {
-    Link<Node> caseNodes = const Link<Node>();
-    while (caseCount > 0) {
-      SwitchCase switchCase = popNode();
-      caseNodes = caseNodes.prepend(switchCase);
-      caseCount--;
-    }
-    pushNode(new NodeList(beginToken, caseNodes, endToken, null));
-  }
-
-  @override
-  void endSwitchCase(
-      int labelCount,
-      int caseCount,
-      Token defaultKeyword,
-      Token colonAfterDefault,
-      int statementCount,
-      Token firstToken,
-      Token endToken) {
-    NodeList statements = makeNodeList(statementCount, null, null, null);
-    NodeList labelsAndCases =
-        makeNodeList(labelCount + caseCount, null, null, null);
-    pushNode(
-        new SwitchCase(labelsAndCases, defaultKeyword, statements, firstToken));
-  }
-
-  @override
-  void handleBreakStatement(
-      bool hasTarget, Token breakKeyword, Token endToken) {
-    Identifier target = null;
-    if (hasTarget) {
-      target = popNode();
-    }
-    pushNode(new BreakStatement(target, breakKeyword, endToken));
-  }
-
-  @override
-  void handleContinueStatement(
-      bool hasTarget, Token continueKeyword, Token endToken) {
-    Identifier target = null;
-    if (hasTarget) {
-      target = popNode();
-    }
-    pushNode(new ContinueStatement(target, continueKeyword, endToken));
-  }
-
-  @override
-  void handleEmptyStatement(Token token) {
-    pushNode(new EmptyStatement(token));
-  }
-
-  @override
-  void beginFactoryMethod(
-      Token lastConsumed, Token externalToken, Token constToken) {
-    if (externalToken != null) {
-      Link<Node> poppedNodes = const Link<Node>();
-      if (constToken != null) {
-        poppedNodes = poppedNodes.prepend(new Identifier(constToken));
-      }
-      poppedNodes = poppedNodes.prepend(new Identifier(externalToken));
-      NodeList modifierNodes = new NodeList(null, poppedNodes, null, ' ');
-      pushNode(new Modifiers(modifierNodes));
-    } else if (constToken != null) {
-      Link<Node> poppedNodes = const Link<Node>();
-      poppedNodes = poppedNodes.prepend(new Identifier(constToken));
-      NodeList modifierNodes = new NodeList(null, poppedNodes, null, ' ');
-      pushNode(new Modifiers(modifierNodes));
-    } else {
-      pushNode(Modifiers.EMPTY);
-    }
-  }
-
-  @override
-  void endFactoryMethod(
-      Token beginToken, Token factoryKeyword, Token endToken) {
-    super.endFactoryMethod(beginToken, factoryKeyword, endToken);
-    Statement body = popNode();
-    AsyncModifier asyncModifier = popNode();
-    NodeList formals = popNode();
-    Node name = popNode();
-    Modifiers modifiers = popNode();
-
-    // The parser does not report `factory` as a modifier,
-    // but NodeListener considers it to be a modifier.
-    // We cannot simply add all tokens from beginToken to factoryToken
-    // inclusive because there may be invalid tokens that the parser
-    // has skipped and the factoryKeyword may itself be out of order.
-    // Because modifiers may be out of order, and some code relies
-    // on the order of the nodes in modifiers, we must insert the factory
-    // keyword in the correct place by rebuilding the modifiers.
-    int modifierCount = 0;
-    Identifier factoryNode = new Identifier(factoryKeyword);
-    modifiers.nodes.nodes.forEach((Node node) {
-      if (factoryNode != null &&
-          factoryNode.token.charOffset < node.getBeginToken().charOffset) {
-        pushNode(factoryNode);
-        ++modifierCount;
-        factoryNode = null;
-      }
-      pushNode(node);
-      ++modifierCount;
-    });
-    if (factoryNode != null) {
-      pushNode(factoryNode);
-      ++modifierCount;
-    }
-    if (modifierCount == 0) {
-      pushNode(Modifiers.EMPTY);
-    } else {
-      NodeList modifierNodes = makeNodeList(modifierCount, null, null, ' ');
-      pushNode(new Modifiers(modifierNodes));
-    }
-    modifiers = popNode();
-
-    pushNode(new FunctionExpression(
-        name, null, formals, body, null, modifiers, null, null, asyncModifier));
-  }
-
-  @override
-  void endForIn(Token awaitToken, Token forToken, Token leftParenthesis,
-      Token inKeyword, Token endToken) {
-    Statement body = popNode();
-    Expression expression = popNode();
-    Node declaredIdentifier = popNode();
-    if (awaitToken == null) {
-      pushNode(new SyncForIn(
-          declaredIdentifier, expression, body, forToken, inKeyword));
-    } else {
-      pushNode(new AsyncForIn(declaredIdentifier, expression, body, awaitToken,
-          forToken, inKeyword));
-    }
-  }
-
-  @override
-  void endMetadataStar(int count) {
-    if (0 == count) {
-      pushNode(null);
-    } else {
-      pushNode(makeNodeList(count, null, null, ' '));
-    }
-  }
-
-  @override
-  void endMetadata(Token beginToken, Token periodBeforeName, Token endToken) {
-    NodeList arguments = popNode();
-    if (arguments == null) {
-      // This is a constant expression.
-      Identifier name;
-      if (periodBeforeName != null) {
-        name = popNode();
-      }
-      NodeList typeArguments = popNode();
-      Node receiver = popNode();
-      if (typeArguments != null) {
-        receiver = new NominalTypeAnnotation(receiver, typeArguments);
-        recoverableError(typeArguments, 'Type arguments are not allowed here.');
-      } else {
-        Identifier identifier = receiver.asIdentifier();
-        Send send = receiver.asSend();
-        if (identifier != null) {
-          receiver = new Send(null, identifier);
-        } else if (send == null) {
-          internalError(node: receiver);
-        }
-      }
-      Send send = receiver;
-      if (name != null) {
-        send = new Send(receiver, name);
-      }
-      pushNode(new Metadata(beginToken, send));
-    } else {
-      // This is a const constructor call.
-      endConstructorReference(beginToken, periodBeforeName, endToken);
-      Node constructor = popNode();
-      pushNode(new Metadata(beginToken,
-          new NewExpression(null, new Send(null, constructor, arguments))));
-    }
-  }
-
-  @override
-  void endAssert(Token assertKeyword, fasta.Assert kind, Token leftParenthesis,
-      Token commaToken, Token semicolonToken) {
-    Node message;
-    Node condition;
-    if (commaToken != null) {
-      message = popNode();
-    }
-    condition = popNode();
-    pushNode(new Assert(assertKeyword, condition, message, semicolonToken));
-  }
-
-  @override
-  void endFunctionExpression(Token beginToken, Token token) {
-    Statement body = popNode();
-    AsyncModifier asyncModifier = popNode();
-    NodeList formals = popNode();
-    NodeList typeVariables = popNode();
-    pushNode(new FunctionExpression(null, typeVariables, formals, body, null,
-        Modifiers.EMPTY, null, null, asyncModifier));
-  }
-
-  @override
-  void handleIsOperator(Token operator, Token not, Token endToken) {
-    TypeAnnotation type = popNode();
-    Expression expression = popNode();
-    Node argument;
-    if (not != null) {
-      argument = new Send.prefix(type, new Operator(not));
-    } else {
-      argument = type;
-    }
-
-    NodeList arguments = new NodeList.singleton(argument);
-    pushNode(new Send(expression, new Operator(operator), arguments));
-  }
-
-  @override
-  void handleLabel(Token colon) {
-    Identifier name = popNode();
-    pushNode(new Label(name, colon));
-  }
-
-  @override
-  void endLabeledStatement(int labelCount) {
-    Statement statement = popNode();
-    NodeList labels = makeNodeList(labelCount, null, null, null);
-    pushNode(new LabeledStatement(labels, statement));
-  }
-
-  @override
-  void endTypeVariable(Token token, Token extendsOrSuper) {
-    inTypeVariable = false;
-    NominalTypeAnnotation bound = popNode();
-    Identifier name = popNode();
-    // TODO(paulberry): type variable metadata should not be ignored.  See
-    // dartbug.com/5841.
-    popNode(); // Metadata
-    pushNode(new TypeVariable(name, extendsOrSuper, bound));
-    rejectBuiltInIdentifier(name);
-  }
-
-  @override
-  void log(message) {
-    reporter.log(message);
-  }
-
-  @override
-  void handleInvalidFunctionBody(Token token) {
-    if (!lastErrorWasNativeFunctionBody) {
-      pushNode(null);
-    }
-    lastErrorWasNativeFunctionBody = false;
-  }
-
-  void internalError({Token token, Node node}) {
-    // TODO(ahe): This should call reporter.internalError.
-    Spannable spannable = (token == null) ? node : token;
-    failedAt(spannable, 'Internal error in parser.');
-  }
-}
diff --git a/pkg/compiler/lib/src/parser/parser_task.dart b/pkg/compiler/lib/src/parser/parser_task.dart
deleted file mode 100644
index cc101ce..0000000
--- a/pkg/compiler/lib/src/parser/parser_task.dart
+++ /dev/null
@@ -1,47 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library dart2js.parser.task;
-
-import '../common.dart';
-import '../common/tasks.dart' show CompilerTask;
-import '../compiler.dart' show Compiler;
-import '../elements/modelx.dart' show ElementX;
-import 'package:front_end/src/fasta/scanner.dart' show Token;
-import '../tree/tree.dart' show Node;
-import 'element_listener.dart' show ScannerOptions;
-import 'package:front_end/src/fasta/parser.dart' show Parser, ParserError;
-import 'node_listener.dart' show NodeListener;
-
-class ParserTask extends CompilerTask {
-  final Compiler compiler;
-
-  ParserTask(Compiler compiler)
-      : compiler = compiler,
-        super(compiler.measurer);
-
-  String get name => 'Parser';
-
-  Node parse(ElementX element) {
-    return measure(() => element.parseNode(compiler.parsingContext));
-  }
-
-  Node parseCompilationUnit(Token token) {
-    return measure(() {
-      NodeListener listener =
-          new NodeListener(const ScannerOptions(), compiler.reporter, null);
-      Parser parser = new Parser(listener);
-      try {
-        parser.parseUnit(token);
-      } on ParserError catch (_) {
-        assert(compiler.compilationFailed,
-            failedAt(compiler.reporter.spanFromToken(token)));
-        return listener.makeNodeList(0, null, null, '\n');
-      }
-      Node result = listener.popNode();
-      assert(listener.nodes.isEmpty);
-      return result;
-    });
-  }
-}
diff --git a/pkg/compiler/lib/src/parser/partial_elements.dart b/pkg/compiler/lib/src/parser/partial_elements.dart
deleted file mode 100644
index 8207794..0000000
--- a/pkg/compiler/lib/src/parser/partial_elements.dart
+++ /dev/null
@@ -1,465 +0,0 @@
-// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library dart2js.parser.partial_elements;
-
-import '../common.dart';
-import '../common/resolution.dart' show ParsingContext, Resolution;
-import '../elements/resolution_types.dart' show ResolutionDynamicType;
-import '../elements/elements.dart'
-    show
-        CompilationUnitElement,
-        Element,
-        ElementKind,
-        GetterElement,
-        MetadataAnnotation,
-        SetterElement,
-        STATE_NOT_STARTED,
-        STATE_DONE;
-import '../elements/modelx.dart'
-    show
-        BaseFunctionElementX,
-        ClassElementX,
-        ConstructorElementX,
-        DeclarationSite,
-        ElementX,
-        GetterElementX,
-        MetadataAnnotationX,
-        MethodElementX,
-        SetterElementX,
-        TypedefElementX,
-        VariableList;
-import '../elements/visitor.dart' show ElementVisitor;
-import 'package:front_end/src/fasta/scanner.dart' show Token;
-import 'package:front_end/src/fasta/scanner.dart' as Tokens show EOF_TOKEN;
-import '../tree/tree.dart';
-import 'package:front_end/src/fasta/parser.dart'
-    show ClassMemberParser, Listener, MemberKind, Parser, ParserError;
-import 'member_listener.dart' show MemberListener;
-import 'node_listener.dart' show NodeListener;
-
-class ClassElementParser extends ClassMemberParser {
-  ClassElementParser(Listener listener) : super(listener);
-
-  Token parseFormalParameters(Token token, MemberKind kind) {
-    return skipFormalParameters(token, kind);
-  }
-}
-
-abstract class PartialElement implements DeclarationSite {
-  Token beginToken;
-  Token endToken;
-
-  bool hasParseError = false;
-
-  bool get isMalformed => hasParseError;
-
-  DeclarationSite get declarationSite => this;
-}
-
-abstract class PartialFunctionMixin implements BaseFunctionElementX {
-  FunctionExpression cachedNode;
-  Modifiers get modifiers;
-  Token beginToken;
-  Token getOrSet;
-  Token endToken;
-
-  /**
-   * The position is computed in the constructor using [findMyName]. Computing
-   * it on demand fails in case tokens are GC'd.
-   */
-  Token _position;
-
-  void init(Token beginToken, Token getOrSet, Token endToken) {
-    this.beginToken = beginToken;
-    this.getOrSet = getOrSet;
-    this.endToken = endToken;
-    _position = ElementX.findNameToken(
-        beginToken,
-        modifiers.isFactory || isGenerativeConstructor,
-        name,
-        enclosingElement.name);
-  }
-
-  bool get hasNode => cachedNode != null;
-
-  FunctionExpression get node {
-    assert(cachedNode != null,
-        failedAt(this, "Node has not been computed for $this."));
-    return cachedNode;
-  }
-
-  FunctionExpression parseNode(ParsingContext parsing) {
-    if (cachedNode != null) return cachedNode;
-    parseFunction(Parser p) {
-      if (isClassMember) {
-        p.parseClassMember(beginToken);
-      } else {
-        p.parseTopLevelMemberImpl(p.syntheticPreviousToken(beginToken));
-      }
-    }
-
-    cachedNode = parse(parsing, this, declarationSite, parseFunction);
-    return cachedNode;
-  }
-
-  Token get position => _position;
-
-  void reusePartialFunctionMixin() {
-    cachedNode = null;
-  }
-
-  DeclarationSite get declarationSite;
-}
-
-abstract class PartialFunctionElement
-    implements PartialElement, PartialFunctionMixin {
-  factory PartialFunctionElement(String name, Token beginToken, Token getOrSet,
-      Token endToken, Modifiers modifiers, Element enclosingElement,
-      {bool hasBody: true}) {
-    if (getOrSet == null) {
-      return new PartialMethodElement(
-          name, beginToken, endToken, modifiers, enclosingElement,
-          hasBody: hasBody);
-    } else if (identical(getOrSet.stringValue, 'get')) {
-      return new PartialGetterElement(
-          name, beginToken, getOrSet, endToken, modifiers, enclosingElement,
-          hasBody: hasBody);
-    } else {
-      assert(identical(getOrSet.stringValue, 'set'));
-      return new PartialSetterElement(
-          name, beginToken, getOrSet, endToken, modifiers, enclosingElement,
-          hasBody: hasBody);
-    }
-  }
-
-  PartialFunctionElement copyWithEnclosing(Element enclosing);
-}
-
-// ignore: STRONG_MODE_INVALID_METHOD_OVERRIDE_FROM_BASE
-class PartialMethodElement extends MethodElementX
-    with PartialElement, PartialFunctionMixin
-    implements PartialFunctionElement {
-  PartialMethodElement(String name, Token beginToken, Token endToken,
-      Modifiers modifiers, Element enclosing,
-      {bool hasBody: true})
-      : super(name, ElementKind.FUNCTION, modifiers, enclosing, hasBody) {
-    init(beginToken, null, endToken);
-  }
-
-  void reuseElement() {
-    super.reuseElement();
-    reusePartialFunctionMixin();
-  }
-
-  PartialMethodElement copyWithEnclosing(Element enclosing) {
-    return new PartialMethodElement(
-        name, beginToken, endToken, modifiers, enclosing,
-        hasBody: hasBody);
-  }
-}
-
-// ignore: STRONG_MODE_INVALID_METHOD_OVERRIDE_FROM_BASE
-class PartialGetterElement extends GetterElementX
-    with PartialElement, PartialFunctionMixin
-    implements GetterElement, PartialFunctionElement {
-  PartialGetterElement(String name, Token beginToken, Token getToken,
-      Token endToken, Modifiers modifiers, Element enclosing,
-      {bool hasBody: true})
-      : super(name, modifiers, enclosing, hasBody) {
-    init(beginToken, getToken, endToken);
-  }
-
-  @override
-  SetterElement get setter => abstractField.setter;
-
-  void reuseElement() {
-    super.reuseElement();
-    reusePartialFunctionMixin();
-  }
-
-  PartialGetterElement copyWithEnclosing(Element enclosing) {
-    return new PartialGetterElement(
-        name, beginToken, getOrSet, endToken, modifiers, enclosing,
-        hasBody: hasBody);
-  }
-}
-
-// ignore: STRONG_MODE_INVALID_METHOD_OVERRIDE_FROM_BASE
-class PartialSetterElement extends SetterElementX
-    with PartialElement, PartialFunctionMixin
-    implements SetterElement, PartialFunctionElement {
-  PartialSetterElement(String name, Token beginToken, Token setToken,
-      Token endToken, Modifiers modifiers, Element enclosing,
-      {bool hasBody: true})
-      : super(name, modifiers, enclosing, hasBody) {
-    init(beginToken, setToken, endToken);
-  }
-
-  @override
-  GetterElement get getter => abstractField.getter;
-
-  void reuseElement() {
-    super.reuseElement();
-    reusePartialFunctionMixin();
-  }
-
-  PartialSetterElement copyWithEnclosing(Element enclosing) {
-    return new PartialSetterElement(
-        name, beginToken, getOrSet, endToken, modifiers, enclosing,
-        hasBody: hasBody);
-  }
-}
-
-// TODO(johnniwinther): Create [PartialGenerativeConstructor] and
-// [PartialFactoryConstructor] subclasses and make this abstract.
-class PartialConstructorElement extends ConstructorElementX
-    with PartialElement, PartialFunctionMixin {
-  PartialConstructorElement(String name, Token beginToken, Token endToken,
-      ElementKind kind, Modifiers modifiers, Element enclosing)
-      : super(name, kind, modifiers, enclosing) {
-    init(beginToken, null, endToken);
-  }
-
-  void reuseElement() {
-    super.reuseElement();
-    reusePartialFunctionMixin();
-  }
-}
-
-class PartialFieldList extends VariableList with PartialElement {
-  PartialFieldList(
-      Token beginToken, Token endToken, Modifiers modifiers, bool hasParseError)
-      : super(modifiers) {
-    super.beginToken = beginToken;
-    super.endToken = endToken;
-    super.hasParseError = hasParseError;
-  }
-
-  VariableDefinitions parseNode(Element element, ParsingContext parsing) {
-    if (definitions != null) return definitions;
-    DiagnosticReporter reporter = parsing.reporter;
-    reporter.withCurrentElement(element, () {
-      definitions = parse(parsing, element, declarationSite,
-          (Parser parser) => parser.parseClassMember(beginToken));
-
-      if (!hasParseError &&
-          !definitions.modifiers.isVar &&
-          !definitions.modifiers.isFinal &&
-          !definitions.modifiers.isConst &&
-          definitions.type == null &&
-          !definitions.isErroneous) {
-        reporter.reportErrorMessage(definitions, MessageKind.GENERIC, {
-          'text': 'A field declaration must start with var, final, '
-              'const, or a type annotation.'
-        });
-      }
-    });
-    return definitions;
-  }
-
-  computeType(Element element, Resolution resolution) {
-    if (type != null) return type;
-    // TODO(johnniwinther): Compute this in the resolver.
-    VariableDefinitions node = parseNode(element, resolution.parsingContext);
-    if (node.type != null) {
-      type = resolution.reporter.withCurrentElement(element, () {
-        return resolution.resolveTypeAnnotation(element, node.type);
-      });
-    } else {
-      type = const ResolutionDynamicType();
-    }
-    assert(type != null);
-    return type;
-  }
-}
-
-class PartialTypedefElement extends TypedefElementX with PartialElement {
-  PartialTypedefElement(
-      String name, Element enclosing, Token beginToken, Token endToken)
-      : super(name, enclosing) {
-    this.beginToken = beginToken;
-    this.endToken = endToken;
-  }
-
-  Token get token => beginToken;
-
-  Node parseNode(ParsingContext parsing) {
-    if (cachedNode != null) return cachedNode;
-    cachedNode = parse(parsing, this, declarationSite,
-        (p) => p.parseTopLevelDeclaration(token));
-    return cachedNode;
-  }
-
-  Token get position => findMyName(token);
-}
-
-/// A [MetadataAnnotation] which is constructed on demand.
-class PartialMetadataAnnotation extends MetadataAnnotationX
-    implements PartialElement {
-  Token beginToken; // TODO(ahe): Make this final when issue 22065 is fixed.
-
-  final Token tokenAfterEndToken;
-
-  Expression cachedNode;
-
-  bool hasParseError = false;
-
-  PartialMetadataAnnotation(this.beginToken, this.tokenAfterEndToken);
-
-  bool get isMalformed => hasParseError;
-
-  DeclarationSite get declarationSite => this;
-
-  Token get endToken {
-    Token token = beginToken;
-    while (token.kind != Tokens.EOF_TOKEN) {
-      if (identical(token.next, tokenAfterEndToken)) break;
-      token = token.next;
-    }
-    assert(token != null);
-    return token;
-  }
-
-  void set endToken(_) {
-    throw new UnsupportedError("endToken=");
-  }
-
-  Node parseNode(ParsingContext parsing) {
-    if (cachedNode != null) return cachedNode;
-    var metadata = parse(parsing, annotatedElement, declarationSite,
-        (p) => p.parseMetadata(p.syntheticPreviousToken(beginToken)).next);
-    if (metadata is Metadata) {
-      cachedNode = metadata.expression;
-      return cachedNode;
-    } else {
-      assert(metadata is ErrorNode);
-      return metadata;
-    }
-  }
-
-  bool get hasNode => cachedNode != null;
-
-  Node get node {
-    assert(hasNode, failedAt(this));
-    return cachedNode;
-  }
-}
-
-class PartialClassElement extends ClassElementX with PartialElement {
-  ClassNode cachedNode;
-
-  PartialClassElement(
-      String name, Token beginToken, Token endToken, Element enclosing, int id)
-      : super(name, enclosing, id, STATE_NOT_STARTED) {
-    this.beginToken = beginToken;
-    this.endToken = endToken;
-  }
-
-  void set supertypeLoadState(int state) {
-    assert(state == STATE_NOT_STARTED || state == supertypeLoadState + 1);
-    assert(state <= STATE_DONE);
-    super.supertypeLoadState = state;
-  }
-
-  void set resolutionState(int state) {
-    assert(state == STATE_NOT_STARTED || state == resolutionState + 1);
-    assert(state <= STATE_DONE);
-    super.resolutionState = state;
-  }
-
-  bool get hasNode => cachedNode != null;
-
-  ClassNode get node {
-    assert(cachedNode != null,
-        failedAt(this, "Node has not been computed for $this."));
-    return cachedNode;
-  }
-
-  ClassNode parseNode(ParsingContext parsing) {
-    if (cachedNode != null) return cachedNode;
-    DiagnosticReporter reporter = parsing.reporter;
-    reporter.withCurrentElement(this, () {
-      parsing.measure(() {
-        MemberListener listener = new MemberListener(
-            parsing.getScannerOptionsFor(this), reporter, this);
-        Parser parser = new ClassElementParser(listener);
-        try {
-          Token token = parser.parseTopLevelDeclaration(beginToken);
-          assert(identical(token, endToken.next));
-          cachedNode = listener.popNode();
-          assert(
-              listener.nodes.isEmpty,
-              failedAt(reporter.spanFromToken(beginToken),
-                  "Non-empty listener stack: ${listener.nodes}"));
-        } on ParserError {
-          // TODO(ahe): Often, a ParserError is thrown while parsing the class
-          // body. This means that the stack actually contains most of the
-          // information synthesized below. Consider rewriting the parser so
-          // endClassDeclaration is called before parsing the class body.
-          Identifier name = new Identifier(findMyName(beginToken));
-          NodeList typeParameters = null;
-          Node supertype = null;
-          NodeList interfaces = listener.makeNodeList(0, null, null, ",");
-          Token extendsKeyword = null;
-          NodeList body = listener.makeNodeList(0, beginToken, endToken, null);
-          cachedNode = new ClassNode(
-              Modifiers.EMPTY,
-              name,
-              typeParameters,
-              supertype,
-              interfaces,
-              beginToken,
-              extendsKeyword,
-              body,
-              endToken);
-          hasParseError = true;
-        }
-      });
-      if (isPatched) {
-        parsing.parsePatchClass(patch);
-      }
-    });
-    return cachedNode;
-  }
-
-  Token get position => beginToken;
-
-  // TODO(johnniwinther): Ensure that modifiers are always available.
-  Modifiers get modifiers =>
-      cachedNode != null ? cachedNode.modifiers : Modifiers.EMPTY;
-
-  accept(ElementVisitor visitor, arg) {
-    return visitor.visitClassElement(this, arg);
-  }
-
-  PartialClassElement copyWithEnclosing(CompilationUnitElement enclosing) {
-    return new PartialClassElement(name, beginToken, endToken, enclosing, id);
-  }
-}
-
-Node parse(ParsingContext parsing, ElementX element, PartialElement partial,
-    doParse(Parser parser)) {
-  DiagnosticReporter reporter = parsing.reporter;
-  return parsing.measure(() {
-    return reporter.withCurrentElement(element, () {
-      CompilationUnitElement unit = element.compilationUnit;
-      NodeListener listener = new NodeListener(
-          parsing.getScannerOptionsFor(element), reporter, unit);
-      listener.memberErrors = listener.memberErrors.prepend(false);
-      try {
-        if (partial.hasParseError) {
-          listener.suppressParseErrors = true;
-        }
-        doParse(new Parser(listener));
-      } on ParserError catch (e) {
-        partial.hasParseError = true;
-        return new ErrorNode(element.position, e.message);
-      }
-      Node node = listener.popNode();
-      assert(listener.nodes.isEmpty);
-      return node;
-    });
-  });
-}
diff --git a/pkg/compiler/lib/src/patch_parser.dart b/pkg/compiler/lib/src/patch_parser.dart
deleted file mode 100644
index 00cb3d7..0000000
--- a/pkg/compiler/lib/src/patch_parser.dart
+++ /dev/null
@@ -1,507 +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.
-
-/**
- * This library contains the infrastructure to parse and integrate patch files.
- *
- * Three types of elements can be patched: [LibraryElement], [ClassElement],
- * [FunctionElement]. Patches are introduced in patch libraries which are loaded
- * together with the corresponding origin library. Which libraries that are
- * patched is determined by the dart2jsPatchPath field of LibraryInfo found
- * in [:lib/_internal/sdk_library_metadata/lib/libraries.dart:].
- *
- * Patch libraries are parsed like regular library and thus provided with their
- * own elements. These elements which are distinct from the elements from the
- * patched library and the relation between patched and patch elements is
- * established through the [:patch:] and [:origin:] fields found on
- * [LibraryElement], [ClassElement] and [FunctionElement]. The [:patch:] fields
- * are set on the patched elements to point to their corresponding patch
- * element, and the [:origin:] elements are set on the patch elements to point
- * their corresponding patched elements.
- *
- * The fields [Element.isPatched] and [Element.isPatch] can be used to determine
- * whether the [:patch:] or [:origin:] field, respectively, has been set on an
- * element, regardless of whether the element is one of the three patchable
- * element types or not.
- *
- * ## Variants of classes and functions ##
- *
- * With patches there are four variants of classes and function:
- *
- * Regular: A class or function which is not declared in a patch library and
- *   which has no corresponding patch.
- * Origin: A class or function which is not declared in a patch library and
- *   which has a corresponding patch. Origin functions must use the [:external:]
- *   modifier and can have no body. Origin classes and functions are also
- *   called 'patched'.
- * Patch: A class or function which is declared in a patch library and which
- *   has a corresponding origin. Both patch classes and patch functions must use
- *   the [:patch:] modifier.
- * Injected: A class or function (or even field) which is declared in a
- *   patch library and which has no corresponding origin. An injected element
- *   cannot use the [:patch:] modifier. Injected elements are never visible from
- *   outside the patch library in which they have been declared. For this
- *   reason, injected elements are often declared private and therefore called
- *   also called 'patch private'.
- *
- * Examples of the variants is shown in the code below:
- *
- *     // In the origin library:
- *     class RegularClass { // A regular class.
- *       void regularMethod() {} // A regular method.
- *     }
- *     class PatchedClass { // An origin class.
- *       int regularField; // A regular field.
- *       void regularMethod() {} // A regular method.
- *       external void patchedMethod(); // An origin method.
- *     }
- *
- *     // In the patch library:
- *     class _InjectedClass { // An injected class.
- *       void _injectedMethod() {} // An injected method.
- *     }
- *     @patch class PatchedClass { // A patch class.
- *       int _injectedField; { // An injected field.
- *       @patch void patchedMethod() {} // A patch method.
- *     }
- *
- *
- * ## Declaration and implementation ##
- *
- * With patches we have two views on elements: as the 'declaration' which
- * introduces the entity and defines its interface, and as the 'implementation'
- * which defines the actual implementation of the entity.
- *
- * Every element has a 'declaration' and an 'implementation' element. For
- * regular and injected elements these are the same. For origin elements the
- * declaration is the element itself and the implementation is the patch element
- * found through its [:patch:] field. For patch elements the implementation is
- * the element itself and the declaration is the origin element found through
- * its [:origin:] field. The declaration and implementation of any element is
- * conveniently available through the [Element.declaration] and
- * [Element.implementation] getters.
- *
- * Most patch-related invariants enforced through-out the compiler are defined
- * in terms of 'declaration' and 'implementation', and tested through the
- * predicate getters [Element.isDeclaration] and [Element.isImplementation].
- * Patch invariants are stated both in comments and as assertions.
- *
- *
- * ## General invariant guidelines ##
- *
- * For [LibraryElement] we always use declarations. This means the
- * [Element.getLibrary] method will only return library declarations. Patch
- * library implementations are only accessed through calls to
- * [Element.getImplementationLibrary] which is used to setup the correct
- * [Element.enclosingElement] relation between patch/injected elements and the
- * patch library.
- *
- * For [ClassElement] and [FunctionElement] we use declarations for determining
- * identity and implementations for work based on the AST nodes, such as
- * resolution, type-checking, type inference, building SSA graphs, etc.
- * - Worklist only contain declaration elements.
- * - Most maps and sets use declarations exclusively, and their individual
- *   invariants are stated in the field comments.
- * - [tree.TreeElements] only map to patch elements from inside a patch library.
- *   TODO(johnniwinther): Simplify this invariant to use only declarations in
- *   [tree.TreeElements].
- * - Builders shift between declaration and implementation depending on usages.
- * - Compile-time constants use constructor implementation exclusively.
- * - Work on function parameters is performed on the declaration of the function
- *   element.
- */
-
-library dart2js.patchparser;
-
-import 'dart:async';
-
-import 'package:front_end/src/fasta/parser.dart'
-    show Listener, Parser, ParserError;
-import 'package:front_end/src/fasta/scanner.dart' show Token;
-
-import 'common/tasks.dart' show CompilerTask;
-import 'common.dart';
-import 'compiler.dart' show Compiler;
-import 'constants/values.dart' show ConstantValue;
-import 'elements/resolution_types.dart' show ResolutionDartType;
-import 'elements/elements.dart';
-import 'elements/modelx.dart'
-    show
-        BaseFunctionElementX,
-        ClassElementX,
-        GetterElementX,
-        LibraryElementX,
-        MetadataAnnotationX,
-        SetterElementX;
-import 'elements/names.dart';
-import 'enqueue.dart' show DeferredAction;
-import 'id_generator.dart';
-import 'library_loader.dart' show LibraryLoader;
-import 'parser/element_listener.dart' show ElementListener;
-import 'parser/member_listener.dart' show MemberListener;
-import 'parser/partial_elements.dart'
-    show ClassElementParser, PartialClassElement;
-import 'parser/diet_parser_task.dart' show PartialParser;
-import 'script.dart';
-
-class PatchParserTask extends CompilerTask {
-  final String name = "Patching Parser";
-  final Compiler compiler;
-  DiagnosticReporter get reporter => compiler.reporter;
-
-  PatchParserTask(Compiler compiler)
-      : compiler = compiler,
-        super(compiler.measurer);
-
-  /**
-   * Scans a library patch file, applies the method patches and
-   * injections to the library, and returns a list of class
-   * patches.
-   */
-  Future patchLibrary(
-      LibraryLoader loader, Uri patchUri, LibraryElement originLibrary) {
-    return compiler.readScript(patchUri, originLibrary).then((Script script) {
-      var patchLibrary = new LibraryElementX(script, null, originLibrary);
-      return reporter.withCurrentElement(patchLibrary, () {
-        loader.registerNewLibrary(patchLibrary);
-        reporter.withCurrentElement(patchLibrary.entryCompilationUnit, () {
-          // This patches the elements of the patch library into [library].
-          // Injected elements are added directly under the compilation unit.
-          // Patch elements are stored on the patched functions or classes.
-          scanLibraryElements(patchLibrary.entryCompilationUnit);
-        });
-        return loader.processLibraryTags(patchLibrary);
-      });
-    });
-  }
-
-  void scanLibraryElements(CompilationUnitElement compilationUnit) {
-    measure(() {
-      // TODO(johnniwinther): Test that parts and exports are handled correctly.
-      Script script = compilationUnit.script;
-      Token tokens = compiler.scanner.scanFile(script.file);
-      Listener patchListener = new PatchElementListener(
-          compiler, compilationUnit, compiler.idGenerator);
-      try {
-        new PartialParser(patchListener).parseUnit(tokens);
-      } on ParserError catch (e) {
-        // No need to recover from a parser error in platform libraries, user
-        // will never see this if the libraries are tested correctly.
-        reporter.internalError(
-            compilationUnit, "Parser error in patch file: $e");
-      }
-    });
-  }
-
-  void parsePatchClassNode(PartialClassElement cls) {
-    // Parse [PartialClassElement] using a "patch"-aware parser instead
-    // of calling its [parseNode] method.
-    if (cls.cachedNode != null) return;
-
-    measure(() => reporter.withCurrentElement(cls, () {
-          MemberListener listener = new PatchMemberListener(compiler, cls);
-          Parser parser = new ClassElementParser(listener);
-          try {
-            Token token = parser.parseTopLevelDeclaration(cls.beginToken);
-            assert(identical(token, cls.endToken.next));
-          } on ParserError catch (e) {
-            // No need to recover from a parser error in platform libraries,
-            // user will never see this if the libraries are tested correctly.
-            reporter.internalError(cls, "Parser error in patch file: $e");
-          }
-          cls.cachedNode = listener.popNode();
-          assert(listener.nodes.isEmpty);
-        }));
-  }
-}
-
-class PatchMemberListener extends MemberListener {
-  final Compiler compiler;
-
-  PatchMemberListener(Compiler compiler, ClassElement enclosingClass)
-      : this.compiler = compiler,
-        super(compiler.parsingContext.getScannerOptionsFor(enclosingClass),
-            compiler.reporter, enclosingClass);
-
-  @override
-  void addMember(Element patch) {
-    addMetadata(patch);
-
-    if (_isMarkedAsPatch(compiler, patch)) {
-      Element origin = enclosingClass.origin.localLookup(patch.name);
-      patchElement(compiler, reporter, origin, patch);
-      enclosingClass.addMember(patch, reporter);
-    } else {
-      if (Name.isPublicName(patch.name)) {
-        reporter.reportErrorMessage(patch, MessageKind.INJECTED_PUBLIC_MEMBER);
-      }
-      enclosingClass.addMember(patch, reporter);
-    }
-  }
-}
-
-/**
- * Extension of [ElementListener] for parsing patch files.
- */
-class PatchElementListener extends ElementListener implements Listener {
-  final Compiler compiler;
-
-  PatchElementListener(Compiler compiler, CompilationUnitElement patchElement,
-      IdGenerator idGenerator)
-      : this.compiler = compiler,
-        super(compiler.parsingContext.getScannerOptionsFor(patchElement),
-            compiler.reporter, patchElement, idGenerator);
-
-  @override
-  void pushElement(Element patch) {
-    popMetadata(patch);
-
-    if (_isMarkedAsPatch(compiler, patch)) {
-      LibraryElement originLibrary = compilationUnitElement.library;
-      assert(originLibrary.isPatched);
-      Element origin = originLibrary.localLookup(patch.name);
-      patchElement(compiler, reporter, origin, patch);
-      compilationUnitElement.addMember(patch, reporter);
-    } else {
-      if (Name.isPublicName(patch.name)) {
-        reporter.reportErrorMessage(patch, MessageKind.INJECTED_PUBLIC_MEMBER);
-      }
-      compilationUnitElement.addMember(patch, reporter);
-    }
-  }
-}
-
-void patchElement(Compiler compiler, DiagnosticReporter reporter,
-    Element origin, Element patch) {
-  if (origin == null) {
-    reporter.reportErrorMessage(
-        patch, MessageKind.PATCH_NON_EXISTING, {'name': patch.name});
-    return;
-  }
-
-  if (!(origin.isClass ||
-      origin.isConstructor ||
-      origin.isFunction ||
-      origin.isAbstractField)) {
-    // TODO(ahe): Remove this error when the parser rejects all bad modifiers.
-    reporter.reportErrorMessage(origin, MessageKind.PATCH_NONPATCHABLE);
-    return;
-  }
-  if (patch.isClass) {
-    tryPatchClass(compiler, reporter, origin, patch);
-  } else if (patch.isGetter) {
-    tryPatchGetter(reporter, origin, patch);
-  } else if (patch.isSetter) {
-    tryPatchSetter(reporter, origin, patch);
-  } else if (patch.isConstructor) {
-    tryPatchConstructor(reporter, origin, patch);
-  } else if (patch.isFunction) {
-    tryPatchFunction(reporter, origin, patch);
-  } else {
-    // TODO(ahe): Remove this error when the parser rejects all bad modifiers.
-    reporter.reportErrorMessage(patch, MessageKind.PATCH_NONPATCHABLE);
-  }
-}
-
-void tryPatchClass(Compiler compiler, DiagnosticReporter reporter,
-    Element origin, ClassElement patch) {
-  if (!origin.isClass) {
-    reporter.reportError(
-        reporter.createMessage(
-            origin, MessageKind.PATCH_NON_CLASS, {'className': patch.name}),
-        <DiagnosticMessage>[
-          reporter.createMessage(patch, MessageKind.PATCH_POINT_TO_CLASS,
-              {'className': patch.name}),
-        ]);
-    return;
-  }
-  patchClass(compiler, reporter, origin, patch);
-}
-
-void patchClass(Compiler compiler, DiagnosticReporter reporter,
-    ClassElementX origin, ClassElementX patch) {
-  if (origin.isPatched) {
-    reporter.internalError(origin, "Patching the same class more than once.");
-  }
-  origin.applyPatch(patch);
-}
-
-/// Abstract interface for pre-resolution detection of metadata.
-///
-/// The detection is handled in two steps:
-/// - match the annotation syntactically and assume that the annotation is valid
-///   if it looks correct,
-/// - setup a deferred action to check that the annotation has a valid constant
-///   value and report an internal error if not.
-abstract class EagerAnnotationHandler<T> {
-  const EagerAnnotationHandler();
-
-  /// Checks that [annotation] looks like a matching annotation and optionally
-  /// applies actions on [element]. Returns a non-null annotation marker if the
-  /// annotation matched and should be validated.
-  T apply(Compiler compiler, Element element, MetadataAnnotation annotation);
-
-  /// Checks that the annotation value is valid.
-  void validate(Compiler compiler, Element element,
-      MetadataAnnotation annotation, ConstantValue constant);
-
-  /// Checks [element] for metadata matching the [handler]. Return a non-null
-  /// annotation marker matching metadata was found.
-  static T checkAnnotation<T>(
-      Compiler compiler, Element element, EagerAnnotationHandler<T> handler) {
-    for (MetadataAnnotation annotation in element.implementation.metadata) {
-      T result = handler.apply(compiler, element, annotation);
-      if (result != handler.defaultResult) {
-        // TODO(johnniwinther): Perform this check in
-        // [Compiler.processLoadedLibraries].
-        compiler.libraryLoader
-            .registerDeferredAction(new DeferredAction(element, () {
-          annotation.ensureResolved(compiler.resolution);
-          handler.validate(compiler, element, annotation,
-              compiler.constants.getConstantValue(annotation.constant));
-        }));
-        return result;
-      }
-    }
-    return handler.defaultResult;
-  }
-
-  /// Result that signals the absence of annotations.
-  T get defaultResult => null;
-}
-
-/// Annotation handler for pre-resolution detection of `@patch` annotations.
-class PatchAnnotationHandler extends EagerAnnotationHandler<bool> {
-  const PatchAnnotationHandler();
-
-  @override
-  bool apply(
-      Compiler compiler, Element element, MetadataAnnotation annotation) {
-    MetadataAnnotationX meta = annotation;
-    if (meta.beginToken?.next?.lexeme == 'patch') {
-      return true;
-    }
-    return null;
-  }
-
-  @override
-  void validate(Compiler compiler, Element element,
-      MetadataAnnotation annotation, ConstantValue constant) {
-    ResolutionDartType annotationType =
-        constant.getType(compiler.resolution.commonElements);
-    if (annotationType.element !=
-        compiler.resolution.commonElements.patchAnnotationClass) {
-      DiagnosticReporter reporter = compiler.reporter;
-      reporter.internalError(annotation, 'Invalid patch annotation.');
-    }
-  }
-}
-
-void tryPatchGetter(
-    DiagnosticReporter reporter, Element origin, FunctionElement patch) {
-  if (!origin.isAbstractField) {
-    reporter.reportError(
-        reporter.createMessage(
-            origin, MessageKind.PATCH_NON_GETTER, {'name': origin.name}),
-        <DiagnosticMessage>[
-          reporter.createMessage(patch, MessageKind.PATCH_POINT_TO_GETTER,
-              {'getterName': patch.name}),
-        ]);
-    return;
-  }
-  AbstractFieldElement originField = origin;
-  if (originField.getter == null) {
-    reporter.reportError(
-        reporter.createMessage(
-            origin, MessageKind.PATCH_NO_GETTER, {'getterName': patch.name}),
-        <DiagnosticMessage>[
-          reporter.createMessage(patch, MessageKind.PATCH_POINT_TO_GETTER,
-              {'getterName': patch.name}),
-        ]);
-    return;
-  }
-  GetterElementX getter = originField.getter;
-  patchFunction(reporter, getter, patch);
-}
-
-void tryPatchSetter(
-    DiagnosticReporter reporter, Element origin, FunctionElement patch) {
-  if (!origin.isAbstractField) {
-    reporter.reportError(
-        reporter.createMessage(
-            origin, MessageKind.PATCH_NON_SETTER, {'name': origin.name}),
-        <DiagnosticMessage>[
-          reporter.createMessage(patch, MessageKind.PATCH_POINT_TO_SETTER,
-              {'setterName': patch.name}),
-        ]);
-    return;
-  }
-  AbstractFieldElement originField = origin;
-  if (originField.setter == null) {
-    reporter.reportError(
-        reporter.createMessage(
-            origin, MessageKind.PATCH_NO_SETTER, {'setterName': patch.name}),
-        <DiagnosticMessage>[
-          reporter.createMessage(patch, MessageKind.PATCH_POINT_TO_SETTER,
-              {'setterName': patch.name}),
-        ]);
-    return;
-  }
-  SetterElementX setter = originField.setter;
-  patchFunction(reporter, setter, patch);
-}
-
-void tryPatchConstructor(
-    DiagnosticReporter reporter, Element origin, FunctionElement patch) {
-  if (!origin.isConstructor) {
-    reporter.reportError(
-        reporter.createMessage(origin, MessageKind.PATCH_NON_CONSTRUCTOR,
-            {'constructorName': patch.name}),
-        <DiagnosticMessage>[
-          reporter.createMessage(patch, MessageKind.PATCH_POINT_TO_CONSTRUCTOR,
-              {'constructorName': patch.name}),
-        ]);
-    return;
-  }
-  patchFunction(reporter, origin, patch);
-}
-
-void tryPatchFunction(
-    DiagnosticReporter reporter, Element origin, FunctionElement patch) {
-  if (!origin.isFunction) {
-    reporter.reportError(
-        reporter.createMessage(origin, MessageKind.PATCH_NON_FUNCTION,
-            {'functionName': patch.name}),
-        <DiagnosticMessage>[
-          reporter.createMessage(patch, MessageKind.PATCH_POINT_TO_FUNCTION,
-              {'functionName': patch.name}),
-        ]);
-    return;
-  }
-  patchFunction(reporter, origin, patch);
-}
-
-void patchFunction(DiagnosticReporter reporter, BaseFunctionElementX origin,
-    BaseFunctionElementX patch) {
-  if (!origin.modifiers.isExternal) {
-    reporter.reportError(
-        reporter.createMessage(origin, MessageKind.PATCH_NON_EXTERNAL),
-        <DiagnosticMessage>[
-          reporter.createMessage(patch, MessageKind.PATCH_POINT_TO_FUNCTION,
-              {'functionName': patch.name}),
-        ]);
-    return;
-  }
-  if (origin.isPatched) {
-    reporter.internalError(
-        origin, "Trying to patch a function more than once.");
-  }
-  origin.applyPatch(patch);
-}
-
-bool _isMarkedAsPatch(Compiler compiler, Element element) {
-  return EagerAnnotationHandler.checkAnnotation(
-          compiler, element, const PatchAnnotationHandler()) ==
-      true;
-}
diff --git a/pkg/compiler/lib/src/resolution/access_semantics.dart b/pkg/compiler/lib/src/resolution/access_semantics.dart
deleted file mode 100644
index 647e14d..0000000
--- a/pkg/compiler/lib/src/resolution/access_semantics.dart
+++ /dev/null
@@ -1,486 +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.
-
-/**
- * Code for classifying the semantics of identifiers appearing in a Dart file.
- */
-library dart2js.access_semantics;
-
-import '../constants/expressions.dart';
-import '../elements/resolution_types.dart';
-import '../elements/elements.dart';
-import '../elements/names.dart';
-
-/// Enum representing the different kinds of destinations which a property
-/// access or method or function invocation might refer to.
-enum AccessKind {
-  /// The destination of the conditional access is an instance method, property,
-  /// or field of a class, and thus must be determined dynamically.
-  CONDITIONAL_DYNAMIC_PROPERTY,
-
-  /// The destination of the access is an instance method, property, or field
-  /// of a class, and thus must be determined dynamically.
-  DYNAMIC_PROPERTY,
-
-  // TODO(johnniwinther): Split these cases into captured and non-captured
-  // local access.
-  /// The destination of the access is a function that is defined locally within
-  /// an enclosing function or method.
-  LOCAL_FUNCTION,
-
-  /// The destination of the access is a non-final variable that is defined
-  /// locally within an enclosing function or method.
-  LOCAL_VARIABLE,
-
-  /// The destination of the access is a final variable that is defined locally
-  /// within an enclosing function or method.
-  FINAL_LOCAL_VARIABLE,
-
-  /// The destination of the access is a variable that is defined as a non-final
-  /// parameter to an enclosing function or method.
-  PARAMETER,
-
-  /// The destination of the access is a variable that is defined as a final
-  /// parameter to an enclosing function or method.
-  FINAL_PARAMETER,
-
-  /// The destination of the access is a non-final field that is defined
-  /// statically within a class.
-  STATIC_FIELD,
-
-  /// The destination of the access is a final field that is defined statically
-  /// within a class.
-  FINAL_STATIC_FIELD,
-
-  /// The destination of the access is a method that is defined statically
-  /// within a class.
-  STATIC_METHOD,
-
-  /// The destination of the access is a property getter that is defined
-  /// statically within a class.
-  STATIC_GETTER,
-
-  /// The destination of the access is a property setter that is defined
-  /// statically within a class.
-  STATIC_SETTER,
-
-  /// The destination of the access is a non-final top level variable defined
-  /// within a library.
-  TOPLEVEL_FIELD,
-
-  /// The destination of the access is a final top level variable defined within
-  /// a library.
-  FINAL_TOPLEVEL_FIELD,
-
-  /// The destination of the access is a top level method defined within a
-  /// library.
-  TOPLEVEL_METHOD,
-
-  /// The destination of the access is a top level property getter defined
-  /// within a library.
-  TOPLEVEL_GETTER,
-
-  /// The destination of the access is a top level property setter defined
-  /// within a library.
-  TOPLEVEL_SETTER,
-
-  /// The destination of the access is a toplevel class, or named mixin
-  /// application.
-  CLASS_TYPE_LITERAL,
-
-  /// The destination of the access is a function typedef.
-  TYPEDEF_TYPE_LITERAL,
-
-  /// The destination of the access is the built-in type "dynamic".
-  DYNAMIC_TYPE_LITERAL,
-
-  /// The destination of the access is a type parameter of the enclosing class.
-  TYPE_PARAMETER_TYPE_LITERAL,
-
-  /// The destination of the access is a (complex) expression. For instance the
-  /// function expression `(){}` in the function expression invocation `(){}()`.
-  EXPRESSION,
-
-  /// The destination of the access is `this` of the enclosing class.
-  THIS,
-
-  /// The destination of the access is an instance method, property, or field
-  /// of the enclosing class.
-  THIS_PROPERTY,
-
-  /// The destination of the access is a non-final field of the super class of
-  /// the enclosing class.
-  SUPER_FIELD,
-
-  /// The destination of the access is a final field of the super class of the
-  /// enclosing class.
-  SUPER_FINAL_FIELD,
-
-  /// The destination of the access is a method of the super class of the
-  /// enclosing class.
-  SUPER_METHOD,
-
-  /// The destination of the access is a getter of the super class of the
-  /// enclosing class.
-  SUPER_GETTER,
-
-  /// The destination of the access is a setter of the super class of the
-  /// enclosing class.
-  SUPER_SETTER,
-
-  /// Compound access where read and write access different elements.
-  /// See [CompoundAccessKind].
-  COMPOUND,
-
-  /// The destination of the access is a compile-time constant.
-  CONSTANT,
-
-  /// The destination of the access is unresolved in a static context.
-  UNRESOLVED,
-
-  /// The destination of the access is unresolved super access.
-  UNRESOLVED_SUPER,
-
-  /// The destination is invalid as an access. For instance a prefix used
-  /// as an expression.
-  INVALID,
-}
-
-enum CompoundAccessKind {
-  /// Read from a static getter and write to a static setter.
-  STATIC_GETTER_SETTER,
-
-  /// Read from a static method (closurize) and write to a static setter.
-  STATIC_METHOD_SETTER,
-
-  /// Read from an unresolved static getter and write to a static setter.
-  UNRESOLVED_STATIC_GETTER,
-
-  /// Read from a static getter and write to an unresolved static setter.
-  UNRESOLVED_STATIC_SETTER,
-
-  /// Read from a top level getter and write to a top level setter.
-  TOPLEVEL_GETTER_SETTER,
-
-  /// Read from a top level method (closurize) and write to top level setter.
-  TOPLEVEL_METHOD_SETTER,
-
-  /// Read from an unresolved top level getter and write to a top level setter.
-  UNRESOLVED_TOPLEVEL_GETTER,
-
-  /// Read from a top level getter and write to an unresolved top level setter.
-  UNRESOLVED_TOPLEVEL_SETTER,
-
-  /// Read from one superclass field and write to another.
-  SUPER_FIELD_FIELD,
-
-  /// Read from a superclass field and write to a superclass setter.
-  SUPER_FIELD_SETTER,
-
-  /// Read from a superclass getter and write to a superclass setter.
-  SUPER_GETTER_SETTER,
-
-  /// Read from a superclass method (closurize) and write to a superclass
-  /// setter.
-  SUPER_METHOD_SETTER,
-
-  /// Read from a superclass getter and write to a superclass field.
-  SUPER_GETTER_FIELD,
-
-  /// Read from a superclass where the getter is unresolved.
-  // TODO(johnniwinther): Use [AccessKind.SUPER_GETTER] when the erroneous
-  // element is no longer needed.
-  UNRESOLVED_SUPER_GETTER,
-
-  /// Read from a superclass getter and write to an unresolved setter.
-  // TODO(johnniwinther): Use [AccessKind.SUPER_SETTER] when the erroneous
-  // element is no longer needed.
-  UNRESOLVED_SUPER_SETTER,
-}
-
-/**
- * Data structure used to classify the semantics of a property access or method
- * or function invocation.
- */
-abstract class AccessSemantics {
-  /**
-   * The kind of access.
-   */
-  final AccessKind kind;
-
-  /**
-   * The element being accessed, if statically known.  This will be null if
-   * [kind] is DYNAMIC or if the element is undefined (e.g. an attempt to
-   * access a non-existent static method in a class).
-   */
-  Element get element => null;
-
-  ConstantExpression get constant => null;
-
-  /// The element for the getter in case of a compound access,
-  /// [element] otherwise.
-  Element get getter => element;
-
-  /// The element for the setter in case of a compound access,
-  /// [element] otherwise.
-  Element get setter => element;
-
-  Name get name => null;
-
-  const AccessSemantics._(this.kind);
-
-  String toString() {
-    StringBuffer sb = new StringBuffer();
-    sb.write('AccessSemantics[');
-    sb.write('kind=$kind,');
-    if (element != null) {
-      if (getter != setter) {
-        sb.write('getter=');
-        sb.write('${getter}');
-        sb.write(',setter=');
-        sb.write('${setter}');
-      } else {
-        sb.write('element=');
-        sb.write('${element}');
-      }
-    } else if (name != null) {
-      sb.write('name=');
-      sb.write(name);
-    }
-    sb.write(']');
-    return sb.toString();
-  }
-}
-
-class DynamicAccess extends AccessSemantics {
-  final Name name;
-
-  const DynamicAccess.expression()
-      : name = null,
-        super._(AccessKind.EXPRESSION);
-
-  const DynamicAccess.thisAccess()
-      : name = null,
-        super._(AccessKind.THIS);
-
-  const DynamicAccess.thisProperty(this.name)
-      : super._(AccessKind.THIS_PROPERTY);
-
-  const DynamicAccess.dynamicProperty(this.name)
-      : super._(AccessKind.DYNAMIC_PROPERTY);
-
-  const DynamicAccess.ifNotNullProperty(this.name)
-      : super._(AccessKind.CONDITIONAL_DYNAMIC_PROPERTY);
-}
-
-class ConstantAccess extends AccessSemantics {
-  final ConstantExpression constant;
-
-  ConstantAccess(AccessKind kind, this.constant) : super._(kind);
-
-  ConstantAccess.classTypeLiteral(this.constant)
-      : super._(AccessKind.CLASS_TYPE_LITERAL);
-
-  ConstantAccess.typedefTypeLiteral(this.constant)
-      : super._(AccessKind.TYPEDEF_TYPE_LITERAL);
-
-  ConstantAccess.dynamicTypeLiteral(this.constant)
-      : super._(AccessKind.DYNAMIC_TYPE_LITERAL);
-}
-
-class StaticAccess extends AccessSemantics {
-  final Element element;
-
-  StaticAccess.internal(AccessKind kind, this.element) : super._(kind);
-
-  StaticAccess.superSetter(MethodElement this.element)
-      : super._(AccessKind.SUPER_SETTER);
-
-  StaticAccess.superField(FieldElement this.element)
-      : super._(AccessKind.SUPER_FIELD);
-
-  StaticAccess.superFinalField(FieldElement this.element)
-      : super._(AccessKind.SUPER_FINAL_FIELD);
-
-  StaticAccess.superMethod(MethodElement this.element)
-      : super._(AccessKind.SUPER_METHOD);
-
-  StaticAccess.superGetter(MethodElement this.element)
-      : super._(AccessKind.SUPER_GETTER);
-
-  StaticAccess.typeParameterTypeLiteral(TypeVariableElement this.element)
-      : super._(AccessKind.TYPE_PARAMETER_TYPE_LITERAL);
-
-  StaticAccess.localFunction(LocalFunctionElement this.element)
-      : super._(AccessKind.LOCAL_FUNCTION);
-
-  StaticAccess.localVariable(LocalVariableElement this.element)
-      : super._(AccessKind.LOCAL_VARIABLE);
-
-  StaticAccess.finalLocalVariable(LocalVariableElement this.element)
-      : super._(AccessKind.FINAL_LOCAL_VARIABLE);
-
-  StaticAccess.parameter(ParameterElement this.element)
-      : super._(AccessKind.PARAMETER);
-
-  StaticAccess.finalParameter(ParameterElement this.element)
-      : super._(AccessKind.FINAL_PARAMETER);
-
-  StaticAccess.staticField(FieldElement this.element)
-      : super._(AccessKind.STATIC_FIELD);
-
-  StaticAccess.finalStaticField(FieldElement this.element)
-      : super._(AccessKind.FINAL_STATIC_FIELD);
-
-  StaticAccess.staticMethod(MethodElement this.element)
-      : super._(AccessKind.STATIC_METHOD);
-
-  StaticAccess.staticGetter(MethodElement this.element)
-      : super._(AccessKind.STATIC_GETTER);
-
-  StaticAccess.staticSetter(MethodElement this.element)
-      : super._(AccessKind.STATIC_SETTER);
-
-  StaticAccess.topLevelField(FieldElement this.element)
-      : super._(AccessKind.TOPLEVEL_FIELD);
-
-  StaticAccess.finalTopLevelField(FieldElement this.element)
-      : super._(AccessKind.FINAL_TOPLEVEL_FIELD);
-
-  StaticAccess.topLevelMethod(MethodElement this.element)
-      : super._(AccessKind.TOPLEVEL_METHOD);
-
-  StaticAccess.topLevelGetter(MethodElement this.element)
-      : super._(AccessKind.TOPLEVEL_GETTER);
-
-  StaticAccess.topLevelSetter(MethodElement this.element)
-      : super._(AccessKind.TOPLEVEL_SETTER);
-
-  StaticAccess.unresolved(this.element) : super._(AccessKind.UNRESOLVED);
-
-  StaticAccess.unresolvedSuper(this.element)
-      : super._(AccessKind.UNRESOLVED_SUPER);
-
-  StaticAccess.invalid(this.element) : super._(AccessKind.INVALID);
-}
-
-class CompoundAccessSemantics extends AccessSemantics {
-  final CompoundAccessKind compoundAccessKind;
-  final Element getter;
-  final Element setter;
-
-  CompoundAccessSemantics(this.compoundAccessKind, this.getter, this.setter)
-      : super._(AccessKind.COMPOUND);
-
-  Element get element => setter;
-
-  String toString() {
-    StringBuffer sb = new StringBuffer();
-    sb.write('CompoundAccessSemantics[');
-    sb.write('kind=$compoundAccessKind');
-    if (getter != null) {
-      sb.write(',getter=');
-      sb.write('${getter}');
-    }
-    if (setter != null) {
-      sb.write(',setter=');
-      sb.write('${setter}');
-    }
-    sb.write(']');
-    return sb.toString();
-  }
-}
-
-/// Enum representing the different kinds of destinations which a constructor
-/// invocation might refer to.
-enum ConstructorAccessKind {
-  /// An invocation of a (redirecting) generative constructor.
-  ///
-  /// For instance
-  ///     class C {
-  ///       C();
-  ///       C.redirect() : this();
-  ///     }
-  ///     m1() => new C();
-  ///     m2() => new C.redirect();
-  ///
-  GENERATIVE,
-
-  /// An invocation of a (redirecting) factory constructor.
-  ///
-  /// For instance
-  ///     class C {
-  ///       factory C() => new C._();
-  ///       factory C.redirect() => C._;
-  ///       C._();
-  ///     }
-  ///     m1() => new C();
-  ///     m2() => new C.redirect();
-  ///
-  FACTORY,
-
-  /// An invocation of a (redirecting) generative constructor of an abstract
-  /// class.
-  ///
-  /// For instance
-  ///     abstract class C {
-  ///       C();
-  ///     }
-  ///     m() => new C();
-  ///
-  ABSTRACT,
-
-  /// An invocation of a constructor on an unresolved type.
-  ///
-  /// For instance
-  ///     m() => new Unresolved();
-  ///
-  UNRESOLVED_TYPE,
-
-  /// An invocation of an unresolved constructor.
-  ///
-  /// For instance
-  ///     class C {
-  ///       C();
-  ///     }
-  ///     m() => new C.unresolved();
-  ///
-  UNRESOLVED_CONSTRUCTOR,
-
-  /// An const invocation of an non-constant constructor.
-  ///
-  /// For instance
-  ///     class C {
-  ///       C();
-  ///     }
-  ///     m() => const C();
-  ///
-  NON_CONSTANT_CONSTRUCTOR,
-
-  /// An invocation of a constructor with incompatible arguments.
-  ///
-  /// For instance
-  ///     class C {
-  ///       C();
-  ///     }
-  ///     m() => new C(true);
-  ///
-  INCOMPATIBLE,
-}
-
-/// Data structure used to classify the semantics of a constructor invocation.
-class ConstructorAccessSemantics {
-  /// The kind of constructor invocation.
-  final ConstructorAccessKind kind;
-
-  /// The invoked constructor.
-  final Element element;
-
-  /// The type on which the constructor is invoked.
-  final ResolutionDartType type;
-
-  ConstructorAccessSemantics(this.kind, this.element, this.type);
-
-  String toString() => 'ConstructorAccessSemantics($kind, $element, $type)';
-}
diff --git a/pkg/compiler/lib/src/resolution/class_hierarchy.dart b/pkg/compiler/lib/src/resolution/class_hierarchy.dart
deleted file mode 100644
index 30e5f0d..0000000
--- a/pkg/compiler/lib/src/resolution/class_hierarchy.dart
+++ /dev/null
@@ -1,660 +0,0 @@
-// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library dart2js.resolution.class_hierarchy;
-
-import '../common.dart';
-import '../common/resolution.dart' show Resolution;
-import '../common_elements.dart' show CommonElements;
-import '../elements/resolution_types.dart';
-import '../elements/elements.dart';
-import '../elements/modelx.dart'
-    show
-        BaseClassElementX,
-        ErroneousElementX,
-        MixinApplicationElementX,
-        SynthesizedConstructorElementX,
-        TypeVariableElementX,
-        UnnamedMixinApplicationElementX;
-import '../elements/names.dart';
-import '../ordered_typeset.dart'
-    show OrderedTypeSet, ResolutionOrderedTypeSetBuilder;
-import '../tree/tree.dart';
-import '../universe/call_structure.dart' show CallStructure;
-import '../universe/feature.dart' show Feature;
-import '../util/util.dart' show Link, Setlet;
-import 'enum_creator.dart';
-import 'members.dart' show lookupInScope;
-import 'registry.dart' show ResolutionRegistry;
-import 'resolution_common.dart' show CommonResolverVisitor, MappingVisitor;
-import 'scope.dart' show Scope, TypeDeclarationScope;
-import 'type_resolver.dart' show FunctionTypeParameterScope;
-
-class TypeDefinitionVisitor extends MappingVisitor<ResolutionDartType> {
-  Scope scope;
-  final TypeDeclarationElement enclosingElement;
-  TypeDeclarationElement get element => enclosingElement;
-
-  TypeDefinitionVisitor(Resolution resolution, TypeDeclarationElement element,
-      ResolutionRegistry registry)
-      : this.enclosingElement = element,
-        scope = Scope.buildEnclosingScope(element),
-        super(resolution, registry);
-
-  CommonElements get commonElements => resolution.commonElements;
-
-  ResolutionInterfaceType get objectType => commonElements.objectType;
-
-  void resolveTypeVariableBounds(NodeList node) {
-    if (node == null) return;
-
-    Setlet<String> nameSet = new Setlet<String>();
-    // Resolve the bounds of type variables.
-    Iterator<ResolutionDartType> types = element.typeVariables.iterator;
-    Link<Node> nodeLink = node.nodes;
-    while (!nodeLink.isEmpty) {
-      types.moveNext();
-      ResolutionTypeVariableType typeVariable = types.current;
-      String typeName = typeVariable.name;
-      TypeVariable typeNode = nodeLink.head;
-      registry.useType(typeNode, typeVariable);
-      if (nameSet.contains(typeName)) {
-        reporter.reportErrorMessage(
-            typeNode,
-            MessageKind.DUPLICATE_TYPE_VARIABLE_NAME,
-            {'typeVariableName': typeName});
-      }
-      nameSet.add(typeName);
-
-      TypeVariableElementX variableElement = typeVariable.element;
-      if (typeNode.bound != null) {
-        ResolutionDartType boundType =
-            typeResolver.resolveNominalTypeAnnotation(
-                this, typeNode.bound, const FunctionTypeParameterScope());
-        variableElement.boundCache = boundType;
-
-        void checkTypeVariableBound() {
-          Link<TypeVariableElement> seenTypeVariables =
-              const Link<TypeVariableElement>();
-          seenTypeVariables = seenTypeVariables.prepend(variableElement);
-          ResolutionDartType bound = boundType;
-          while (bound.isTypeVariable) {
-            TypeVariableElement element = bound.element;
-            if (seenTypeVariables.contains(element)) {
-              if (identical(element, variableElement)) {
-                // Only report an error on the checked type variable to avoid
-                // generating multiple errors for the same cyclicity.
-                reporter.reportWarningMessage(
-                    typeNode.name,
-                    MessageKind.CYCLIC_TYPE_VARIABLE,
-                    {'typeVariableName': variableElement.name});
-              }
-              break;
-            }
-            seenTypeVariables = seenTypeVariables.prepend(element);
-            bound = element.bound;
-          }
-        }
-
-        addDeferredAction(element, checkTypeVariableBound);
-      } else {
-        variableElement.boundCache = objectType;
-      }
-      nodeLink = nodeLink.tail;
-    }
-    assert(!types.moveNext());
-  }
-}
-
-/**
- * The implementation of [ResolverTask.resolveClass].
- *
- * This visitor has to be extra careful as it is building the basic
- * element information, and cannot safely look at other elements as
- * this may lead to cycles.
- *
- * This visitor can assume that the supertypes have already been
- * resolved, but it cannot call [ResolverTask.resolveClass] directly
- * or indirectly (through [ClassElement.ensureResolved]) for any other
- * types.
- */
-class ClassResolverVisitor extends TypeDefinitionVisitor {
-  BaseClassElementX get element => enclosingElement;
-
-  ClassResolverVisitor(Resolution resolution, ClassElement classElement,
-      ResolutionRegistry registry)
-      : super(resolution, classElement, registry);
-
-  ResolutionDartType visitClassNode(ClassNode node) {
-    if (element == null) {
-      throw reporter.internalError(node, 'element is null');
-    }
-    if (element.resolutionState != STATE_STARTED) {
-      throw reporter.internalError(
-          element, 'cyclic resolution of class $element');
-    }
-
-    element.computeType(resolution);
-    scope = new TypeDeclarationScope(scope, element);
-    // TODO(ahe): It is not safe to call resolveTypeVariableBounds yet.
-    // As a side-effect, this may get us back here trying to
-    // resolve this class again.
-    resolveTypeVariableBounds(node.typeParameters);
-
-    // Setup the supertype for the element (if there is a cycle in the
-    // class hierarchy, it has already been set to Object).
-    if (element.supertype == null && node.superclass != null) {
-      MixinApplication superMixin = node.superclass.asMixinApplication();
-      if (superMixin != null) {
-        element.supertype = createMixins(element, superMixin);
-      } else {
-        element.supertype = resolveSupertype(element, node.superclass);
-      }
-    }
-    // If the super type isn't specified, we provide a default.  The language
-    // specifies [Object] but the backend can pick a specific 'implementation'
-    // of Object - the JavaScript backend chooses between Object and
-    // Interceptor.
-    if (element.supertype == null) {
-      ClassElement superElement = registry.defaultSuperclass(element);
-      // Avoid making the superclass (usually Object) extend itself.
-      if (element != superElement) {
-        if (superElement == null) {
-          reporter.internalError(
-              node, "Cannot resolve default superclass for $element.");
-        } else {
-          superElement.ensureResolved(resolution);
-        }
-        element.supertype = superElement.computeType(resolution);
-      }
-    }
-
-    if (element.interfaces == null) {
-      element.interfaces = resolveInterfaces(node.interfaces, node.superclass);
-    } else {
-      assert(element.hasIncompleteHierarchy, failedAt(element));
-    }
-    calculateAllSupertypes(element);
-
-    if (!element.hasConstructor) {
-      Element superMember = element.superclass.localLookup('');
-      if (superMember == null) {
-        MessageKind kind = MessageKind.CANNOT_FIND_UNNAMED_CONSTRUCTOR;
-        Map arguments = {'className': element.superclass.name};
-        // TODO(ahe): Why is this a compile-time error? Or if it is an error,
-        // why do we bother to registerThrowNoSuchMethod below?
-        reporter.reportErrorMessage(node, kind, arguments);
-        superMember = new ErroneousElementX(kind, arguments, '', element);
-        registry.registerFeature(Feature.THROW_NO_SUCH_METHOD);
-      } else if (!superMember.isGenerativeConstructor) {
-        MessageKind kind = MessageKind.SUPER_CALL_TO_FACTORY;
-        Map arguments = {'className': element.superclass.name};
-        // TODO(ahe): Why is this a compile-time error? Or if it is an error,
-        // why do we bother to registerThrowNoSuchMethod below?
-        reporter.reportErrorMessage(node, kind, arguments);
-        superMember = new ErroneousElementX(kind, arguments, '', element);
-        registry.registerFeature(Feature.THROW_NO_SUCH_METHOD);
-      } else {
-        ConstructorElement superConstructor = superMember;
-        superConstructor.computeType(resolution);
-        if (!CallStructure.NO_ARGS
-            .signatureApplies(superConstructor.parameterStructure)) {
-          MessageKind kind = MessageKind.NO_MATCHING_CONSTRUCTOR_FOR_IMPLICIT;
-          reporter.reportErrorMessage(node, kind);
-          superMember = new ErroneousElementX(kind, {}, '', element);
-        }
-      }
-      FunctionElement constructor =
-          new SynthesizedConstructorElementX.forDefault(superMember, element);
-      if (superMember.isMalformed) {
-        ErroneousElement erroneousElement = superMember;
-        resolution.registerCompileTimeError(
-            constructor,
-            reporter.createMessage(node, erroneousElement.messageKind,
-                erroneousElement.messageArguments));
-      }
-      element.setDefaultConstructor(constructor, reporter);
-    }
-    return element.computeType(resolution);
-  }
-
-  @override
-  ResolutionDartType visitEnum(Enum node) {
-    if (element == null) {
-      throw reporter.internalError(node, 'element is null');
-    }
-    if (element.resolutionState != STATE_STARTED) {
-      throw reporter.internalError(
-          element, 'cyclic resolution of class $element');
-    }
-
-    ResolutionInterfaceType enumType = element.computeType(resolution);
-    element.supertype = objectType;
-    element.interfaces = const Link<ResolutionDartType>();
-    calculateAllSupertypes(element);
-
-    if (node.names.nodes.isEmpty) {
-      reporter.reportErrorMessage(
-          node, MessageKind.EMPTY_ENUM_DECLARATION, {'enumName': element.name});
-    }
-
-    EnumCreator creator =
-        new EnumCreator(reporter, resolution.commonElements, element);
-    creator.createMembers();
-    return enumType;
-  }
-
-  /// Resolves the mixed type for [mixinNode] and checks that the mixin type
-  /// is a valid, non-blacklisted interface type. The mixin type is returned.
-  ResolutionDartType checkMixinType(NominalTypeAnnotation mixinNode) {
-    ResolutionDartType mixinType = resolveNominalType(mixinNode);
-    if (isBlackListed(mixinType)) {
-      reporter.reportErrorMessage(
-          mixinNode, MessageKind.CANNOT_MIXIN, {'type': mixinType});
-    } else if (mixinType.isTypeVariable) {
-      reporter.reportErrorMessage(mixinNode, MessageKind.CLASS_NAME_EXPECTED);
-    } else if (mixinType.isMalformed) {
-      reporter.reportErrorMessage(mixinNode, MessageKind.CANNOT_MIXIN_MALFORMED,
-          {'className': element.name, 'malformedType': mixinType});
-    } else if (mixinType.isEnumType) {
-      reporter.reportErrorMessage(mixinNode, MessageKind.CANNOT_MIXIN_ENUM,
-          {'className': element.name, 'enumType': mixinType});
-    }
-    return mixinType;
-  }
-
-  ResolutionDartType visitNamedMixinApplication(NamedMixinApplication node) {
-    if (element == null) {
-      throw reporter.internalError(node, 'element is null');
-    }
-    if (element.resolutionState != STATE_STARTED) {
-      throw reporter.internalError(
-          element, 'cyclic resolution of class $element');
-    }
-
-    element.computeType(resolution);
-    scope = new TypeDeclarationScope(scope, element);
-    resolveTypeVariableBounds(node.typeParameters);
-
-    // Generate anonymous mixin application elements for the
-    // intermediate mixin applications (excluding the last).
-    createMixins(element, node, isNamed: true);
-    return element.computeType(resolution);
-  }
-
-  ResolutionDartType createMixins(ClassElement element, MixinApplication node,
-      {bool isNamed: false}) {
-    ResolutionDartType supertype = resolveSupertype(element, node.superclass);
-    Link<Node> link = node.mixins.nodes;
-    while (!link.isEmpty) {
-      if (isNamed && link.tail.isEmpty) {
-        doApplyMixinTo(element, supertype, checkMixinType(link.head));
-        return supertype;
-      }
-      supertype = applyMixin(supertype, checkMixinType(link.head), link.head);
-      link = link.tail;
-    }
-    return supertype;
-  }
-
-  ResolutionDartType applyMixin(
-      ResolutionDartType supertype, ResolutionDartType mixinType, Node node) {
-    String superName = supertype.name;
-    String mixinName = mixinType.name;
-    MixinApplicationElementX mixinApplication =
-        new UnnamedMixinApplicationElementX("${superName}+${mixinName}",
-            element, resolution.idGenerator.getNextFreeId(), node);
-    // Create synthetic type variables for the mixin application.
-    List<ResolutionDartType> typeVariables = <ResolutionDartType>[];
-    int index = 0;
-    for (ResolutionTypeVariableType type in element.typeVariables) {
-      TypeVariableElementX typeVariableElement = new TypeVariableElementX(
-          type.name, mixinApplication, index, type.element.node);
-      ResolutionTypeVariableType typeVariable =
-          new ResolutionTypeVariableType(typeVariableElement);
-      typeVariables.add(typeVariable);
-      index++;
-    }
-    // Setup bounds on the synthetic type variables.
-    for (ResolutionTypeVariableType type in element.typeVariables) {
-      ResolutionTypeVariableType typeVariable =
-          typeVariables[type.element.index];
-      TypeVariableElementX typeVariableElement = typeVariable.element;
-      typeVariableElement.typeCache = typeVariable;
-      typeVariableElement.boundCache =
-          type.element.bound.subst(typeVariables, element.typeVariables);
-    }
-    // Setup this and raw type for the mixin application.
-    mixinApplication.computeThisAndRawType(resolution, typeVariables);
-    // Substitute in synthetic type variables in super and mixin types.
-    supertype = supertype.subst(typeVariables, element.typeVariables);
-    mixinType = mixinType.subst(typeVariables, element.typeVariables);
-
-    doApplyMixinTo(mixinApplication, supertype, mixinType);
-    mixinApplication.resolutionState = STATE_DONE;
-    mixinApplication.supertypeLoadState = STATE_DONE;
-    // Replace the synthetic type variables by the original type variables in
-    // the returned type (which should be the type actually extended).
-    ResolutionInterfaceType mixinThisType = mixinApplication.thisType;
-    return mixinThisType.subst(
-        element.typeVariables, mixinThisType.typeArguments);
-  }
-
-  bool isDefaultConstructor(FunctionElement constructor) {
-    if (constructor.name != '') return false;
-    constructor.computeType(resolution);
-    return constructor.functionSignature.parameterCount == 0;
-  }
-
-  FunctionElement createForwardingConstructor(
-      ConstructorElement target, ClassElement enclosing) {
-    FunctionElement constructor =
-        new SynthesizedConstructorElementX.notForDefault(
-            target.name, target, enclosing);
-    constructor.computeType(resolution);
-    return constructor;
-  }
-
-  void doApplyMixinTo(MixinApplicationElementX mixinApplication,
-      ResolutionDartType supertype, ResolutionDartType mixinType) {
-    Node node = mixinApplication.parseNode(resolution.parsingContext);
-
-    if (mixinApplication.supertype != null) {
-      // [supertype] is not null if there was a cycle.
-      assert(reporter.hasReportedError, failedAt(node));
-      supertype = mixinApplication.supertype;
-      assert(supertype.isObject, failedAt(node));
-    } else {
-      mixinApplication.supertype = supertype;
-    }
-
-    // Named mixin application may have an 'implements' clause.
-    NamedMixinApplication namedMixinApplication =
-        node.asNamedMixinApplication();
-    Link<ResolutionDartType> interfaces = (namedMixinApplication != null)
-        ? resolveInterfaces(
-            namedMixinApplication.interfaces, namedMixinApplication.superclass)
-        : const Link<ResolutionDartType>();
-
-    // The class that is the result of a mixin application implements
-    // the interface of the class that was mixed in so always prepend
-    // that to the interface list.
-    if (mixinApplication.interfaces == null) {
-      if (mixinType.isInterfaceType) {
-        // Avoid malformed types in the interfaces.
-        interfaces = interfaces.prepend(mixinType);
-      }
-      mixinApplication.interfaces = interfaces;
-    } else {
-      assert(
-          mixinApplication.hasIncompleteHierarchy, failedAt(mixinApplication));
-    }
-
-    ClassElement superclass = supertype.element;
-    if (mixinType.kind != ResolutionTypeKind.INTERFACE) {
-      mixinApplication.hasIncompleteHierarchy = true;
-      mixinApplication.allSupertypesAndSelf = superclass.allSupertypesAndSelf;
-      return;
-    }
-
-    assert(mixinApplication.mixinType == null);
-    mixinApplication.mixinType = resolveMixinFor(mixinApplication, mixinType);
-
-    // Create forwarding constructors for constructor defined in the superclass
-    // because they are now hidden by the mixin application.
-    superclass.forEachLocalMember((Element member) {
-      if (!member.isGenerativeConstructor) return;
-      FunctionElement forwarder =
-          createForwardingConstructor(member, mixinApplication);
-      if (Name.isPrivateName(member.name) &&
-          mixinApplication.library != superclass.library) {
-        // Do not create a forwarder to the super constructor, because the mixin
-        // application is in a different library than the constructor in the
-        // super class and it is not possible to call that constructor from the
-        // library using the mixin application.
-        return;
-      }
-      mixinApplication.addConstructor(forwarder);
-    });
-    calculateAllSupertypes(mixinApplication);
-  }
-
-  ResolutionInterfaceType resolveMixinFor(
-      MixinApplicationElement mixinApplication, ResolutionDartType mixinType) {
-    ClassElement mixin = mixinType.element;
-    mixin.ensureResolved(resolution);
-
-    // Check for cycles in the mixin chain.
-    ClassElement previous = mixinApplication; // For better error messages.
-    ClassElement current = mixin;
-    while (current != null && current.isMixinApplication) {
-      MixinApplicationElement currentMixinApplication = current;
-      if (currentMixinApplication == mixinApplication) {
-        reporter.reportErrorMessage(
-            mixinApplication,
-            MessageKind.ILLEGAL_MIXIN_CYCLE,
-            {'mixinName1': current.name, 'mixinName2': previous.name});
-        // We have found a cycle in the mixin chain. Return null as
-        // the mixin for this application to avoid getting into
-        // infinite recursion when traversing members.
-        return null;
-      }
-      previous = current;
-      current = currentMixinApplication.mixin;
-    }
-    return mixinType;
-  }
-
-  ResolutionDartType resolveNominalType(NominalTypeAnnotation node) {
-    return typeResolver.resolveNominalTypeAnnotation(
-        this, node, const FunctionTypeParameterScope());
-  }
-
-  ResolutionDartType resolveSupertype(
-      ClassElement cls, NominalTypeAnnotation superclass) {
-    ResolutionDartType supertype = resolveNominalType(superclass);
-    if (supertype != null) {
-      if (supertype.isMalformed) {
-        reporter.reportErrorMessage(
-            superclass,
-            MessageKind.CANNOT_EXTEND_MALFORMED,
-            {'className': element.name, 'malformedType': supertype});
-        return objectType;
-      } else if (supertype.isEnumType) {
-        reporter.reportErrorMessage(superclass, MessageKind.CANNOT_EXTEND_ENUM,
-            {'className': element.name, 'enumType': supertype});
-        return objectType;
-      } else if (!supertype.isInterfaceType) {
-        reporter.reportErrorMessage(
-            superclass.typeName, MessageKind.CLASS_NAME_EXPECTED);
-        return objectType;
-      } else if (isBlackListed(supertype)) {
-        reporter.reportErrorMessage(
-            superclass, MessageKind.CANNOT_EXTEND, {'type': supertype});
-        return objectType;
-      }
-    }
-    return supertype;
-  }
-
-  Link<ResolutionDartType> resolveInterfaces(
-      NodeList interfaces, Node superclass) {
-    Link<ResolutionDartType> result = const Link<ResolutionDartType>();
-    if (interfaces == null) return result;
-    for (Link<Node> link = interfaces.nodes; !link.isEmpty; link = link.tail) {
-      ResolutionDartType interfaceType = resolveNominalType(link.head);
-      if (interfaceType != null) {
-        if (interfaceType.isMalformed) {
-          reporter.reportErrorMessage(
-              link.head,
-              MessageKind.CANNOT_IMPLEMENT_MALFORMED,
-              {'className': element.name, 'malformedType': interfaceType});
-        } else if (interfaceType.isEnumType) {
-          reporter.reportErrorMessage(
-              link.head,
-              MessageKind.CANNOT_IMPLEMENT_ENUM,
-              {'className': element.name, 'enumType': interfaceType});
-        } else if (!interfaceType.isInterfaceType) {
-          // TODO(johnniwinther): Handle dynamic.
-          NominalTypeAnnotation typeAnnotation = link.head;
-          reporter.reportErrorMessage(
-              typeAnnotation.typeName, MessageKind.CLASS_NAME_EXPECTED);
-        } else {
-          if (interfaceType == element.supertype) {
-            reporter.reportErrorMessage(
-                superclass,
-                MessageKind.DUPLICATE_EXTENDS_IMPLEMENTS,
-                {'type': interfaceType});
-            reporter.reportErrorMessage(
-                link.head,
-                MessageKind.DUPLICATE_EXTENDS_IMPLEMENTS,
-                {'type': interfaceType});
-          }
-          if (result.contains(interfaceType)) {
-            reporter.reportErrorMessage(link.head,
-                MessageKind.DUPLICATE_IMPLEMENTS, {'type': interfaceType});
-          }
-          result = result.prepend(interfaceType);
-          if (isBlackListed(interfaceType)) {
-            reporter.reportErrorMessage(link.head, MessageKind.CANNOT_IMPLEMENT,
-                {'type': interfaceType});
-          }
-        }
-      }
-    }
-    return result;
-  }
-
-  /**
-   * Compute the list of all supertypes.
-   *
-   * The elements of this list are ordered as follows: first the supertype that
-   * the class extends, then the implemented interfaces, and then the supertypes
-   * of these.  The class [Object] appears only once, at the end of the list.
-   *
-   * For example, for a class `class C extends S implements I1, I2`, we compute
-   *   supertypes(C) = [S, I1, I2] ++ supertypes(S) ++ supertypes(I1)
-   *                   ++ supertypes(I2),
-   * where ++ stands for list concatenation.
-   *
-   * This order makes sure that if a class implements an interface twice with
-   * different type arguments, the type used in the most specific class comes
-   * first.
-   */
-  void calculateAllSupertypes(BaseClassElementX cls) {
-    if (cls.allSupertypesAndSelf != null) return;
-    final ResolutionInterfaceType supertype = cls.supertype;
-    if (supertype != null) {
-      cls.allSupertypesAndSelf = new ResolutionOrderedTypeSetBuilder(
-              cls, commonElements.objectType,
-              reporter: reporter)
-          .createOrderedTypeSet(supertype, cls.interfaces);
-    } else {
-      assert(cls == resolution.commonElements.objectClass);
-      cls.allSupertypesAndSelf =
-          new OrderedTypeSet.singleton(cls.computeType(resolution));
-    }
-  }
-
-  isBlackListed(ResolutionDartType type) {
-    LibraryElement lib = element.library;
-    return !identical(lib, resolution.commonElements.coreLibrary) &&
-        !resolution.target.isTargetSpecificLibrary(lib) &&
-        (type.isDynamic ||
-            type == commonElements.boolType ||
-            type == commonElements.numType ||
-            type == commonElements.intType ||
-            type == commonElements.doubleType ||
-            type == commonElements.stringType ||
-            type == commonElements.nullType);
-  }
-}
-
-class ClassSupertypeResolver extends CommonResolverVisitor {
-  Scope context;
-  ClassElement classElement;
-
-  ClassSupertypeResolver(Resolution resolution, ClassElement cls)
-      : context = Scope.buildEnclosingScope(cls),
-        this.classElement = cls,
-        super(resolution);
-
-  CommonElements get commonElements => resolution.commonElements;
-
-  void loadSupertype(ClassElement element, Node from) {
-    if (!element.isResolved) {
-      resolution.resolver.loadSupertypes(element, from);
-      element.ensureResolved(resolution);
-    }
-  }
-
-  void visitNodeList(NodeList node) {
-    if (node != null) {
-      for (Link<Node> link = node.nodes; !link.isEmpty; link = link.tail) {
-        link.head.accept(this);
-      }
-    }
-  }
-
-  void visitClassNode(ClassNode node) {
-    if (node.superclass == null) {
-      if (classElement != commonElements.objectClass) {
-        loadSupertype(commonElements.objectClass, node);
-      }
-    } else {
-      node.superclass.accept(this);
-    }
-    visitNodeList(node.interfaces);
-  }
-
-  void visitEnum(Enum node) {
-    loadSupertype(commonElements.objectClass, node);
-  }
-
-  void visitMixinApplication(MixinApplication node) {
-    node.superclass.accept(this);
-    visitNodeList(node.mixins);
-  }
-
-  void visitNamedMixinApplication(NamedMixinApplication node) {
-    node.superclass.accept(this);
-    visitNodeList(node.mixins);
-    visitNodeList(node.interfaces);
-  }
-
-  void visitNominalTypeAnnotation(NominalTypeAnnotation node) {
-    node.typeName.accept(this);
-  }
-
-  void visitIdentifier(Identifier node) {
-    Element element = lookupInScope(reporter, node, context, node.source);
-    if (element != null && element.isClass) {
-      loadSupertype(element, node);
-    }
-  }
-
-  void visitSend(Send node) {
-    Identifier prefix = node.receiver.asIdentifier();
-    if (prefix == null) {
-      reporter.reportErrorMessage(
-          node.receiver, MessageKind.NOT_A_PREFIX, {'node': node.receiver});
-      return;
-    }
-    Element element = lookupInScope(reporter, prefix, context, prefix.source);
-    if (element == null || !identical(element.kind, ElementKind.PREFIX)) {
-      reporter.reportErrorMessage(
-          node.receiver, MessageKind.NOT_A_PREFIX, {'node': node.receiver});
-      return;
-    }
-    PrefixElement prefixElement = element;
-    Identifier selector = node.selector.asIdentifier();
-    var e = prefixElement.lookupLocalMember(selector.source);
-    if (e == null || !e.impliesType) {
-      reporter.reportErrorMessage(node.selector,
-          MessageKind.CANNOT_RESOLVE_TYPE, {'typeName': node.selector});
-      return;
-    }
-    loadSupertype(e, node);
-  }
-}
diff --git a/pkg/compiler/lib/src/resolution/class_members.dart b/pkg/compiler/lib/src/resolution/class_members.dart
deleted file mode 100644
index c3063f3..0000000
--- a/pkg/compiler/lib/src/resolution/class_members.dart
+++ /dev/null
@@ -1,974 +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.
-
-library dart2js.resolution.compute_members;
-
-import '../common.dart';
-import '../common/names.dart' show Identifiers, Names;
-import '../common/resolution.dart' show Resolution;
-import '../elements/elements.dart'
-    show
-        ClassElement,
-        Element,
-        LibraryElement,
-        Member,
-        MemberElement,
-        MemberSignature,
-        MixinApplicationElement;
-import '../elements/resolution_types.dart';
-import '../elements/types.dart';
-import '../elements/names.dart';
-import '../util/util.dart';
-
-part 'member_impl.dart';
-
-abstract class MembersCreator {
-  final ClassElement cls;
-  final Resolution resolution;
-
-  final Iterable<String> computedMemberNames;
-  final Map<Name, Member> classMembers;
-
-  Map<dynamic /* Member | Element */, Set<MessageKind>> reportedMessages =
-      new Map<dynamic, Set<MessageKind>>();
-
-  MembersCreator(
-      this.resolution, this.cls, this.computedMemberNames, this.classMembers) {
-    assert(cls.isDeclaration,
-        failedAt(cls, "Members may only be computed on declarations."));
-  }
-
-  DiagnosticReporter get reporter => resolution.reporter;
-
-  void reportMessage(var marker, MessageKind kind, report()) {
-    Set<MessageKind> messages =
-        reportedMessages.putIfAbsent(marker, () => new Set<MessageKind>());
-    if (messages.add(kind)) {
-      report();
-    }
-  }
-
-  bool shouldSkipMember(MemberSignature member) {
-    return member == null || shouldSkipName(member.name.text);
-  }
-
-  bool shouldSkipName(String name) {
-    return computedMemberNames != null &&
-        // 'call' is implicitly contained in [computedMemberNames].
-        (name == Identifiers.call || computedMemberNames.contains(name));
-  }
-
-  /// Compute all members of [cls] with the given names.
-  void computeMembersByName(String name, Setlet<Name> names) {
-    computeMembers(name, names);
-  }
-
-  /// Compute all members of [cls] and checked that [cls] implements its
-  /// interface unless it is abstract or declares a `noSuchMethod` method.
-  void computeAllMembers() {
-    computeMembers(null, null);
-    if (!cls.isAbstract) {
-      Member member = classMembers[Names.noSuchMethod_];
-      if (member != null &&
-          !resolution.target.isDefaultNoSuchMethod(member.element)) {
-        return;
-      }
-      // Check for unimplemented members on concrete classes that neither have
-      // a `@proxy` annotation nor declare a `noSuchMethod` method.
-      checkInterfaceImplementation();
-    }
-  }
-
-  /// Compute declared and inherited members of [cls] and return a map of the
-  /// declared members.
-  ///
-  /// If [name] and [names] are not null, the computation is restricted to
-  /// members with these names.
-  Map<Name, Member> computeMembers(String name, Setlet<Name> names);
-
-  /// Compute the members of the super type(s) of [cls] and store them in
-  /// [classMembers].
-  ///
-  /// If [name] and [names] are not null, the computation is restricted to
-  /// members with these names.
-  void computeSuperMembers(String name, Setlet<Name> names);
-
-  /// Compute the members of the super class of [cls] and store them in
-  /// [classMembers].
-  ///
-  /// If [name] and [names] are not null, the computation is restricted to
-  /// members with these names.
-  void computeSuperClassMembers(String name, Setlet<Name> names) {
-    ResolutionInterfaceType supertype = cls.supertype;
-    if (supertype == null) return;
-    ClassElement superclass = supertype.element;
-
-    // Inherit class and interface members from superclass.
-    void inheritClassMember(Member _member) {
-      DeclaredMember member = _member;
-      if (shouldSkipMember(member)) return;
-      if (!member.isStatic) {
-        DeclaredMember inherited = member.inheritFrom(supertype);
-        classMembers[member.name] = inherited;
-      }
-    }
-
-    if (names != null) {
-      _computeClassMember(resolution, superclass, name, names);
-      for (Name memberName in names) {
-        inheritClassMember(superclass.lookupClassMember(memberName));
-      }
-    } else {
-      computeAllClassMembers(resolution, superclass);
-      superclass.forEachClassMember(inheritClassMember);
-    }
-  }
-
-  /// Compute the members declared or directly mixed in [cls].
-  ///
-  /// If [name] and [names] are not null, the computation is restricted to
-  /// members with these names.
-  Map<Name, Member> computeClassMembers(String nameText, Setlet<Name> names) {
-    Map<Name, Member> declaredMembers = new Map<Name, Member>();
-
-    if (cls.isMixinApplication) {
-      MixinApplicationElement mixinApplication = cls;
-      if (mixinApplication.mixin != null) {
-        // Only mix in class members when the mixin type is not malformed.
-
-        void inheritMixinMember(Member _member) {
-          DeclaredMember member = _member;
-          if (shouldSkipMember(member)) return;
-          Name name = member.name;
-          if (!member.isAbstract && !member.isStatic) {
-            // Abstract and static members are not mixed in.
-            DeclaredMember mixedInMember =
-                member.inheritFrom(mixinApplication.mixinType);
-            DeclaredMember inherited = classMembers[name];
-            classMembers[name] = mixedInMember;
-            checkValidOverride(mixedInMember, inherited);
-          }
-        }
-
-        if (names != null) {
-          _computeClassMember(
-              resolution, mixinApplication.mixin, nameText, names);
-          for (Name memberName in names) {
-            inheritMixinMember(
-                mixinApplication.mixin.lookupClassMember(memberName));
-          }
-        } else {
-          computeAllClassMembers(resolution, mixinApplication.mixin);
-          mixinApplication.mixin.forEachClassMember(inheritMixinMember);
-        }
-      }
-    } else {
-      LibraryElement library = cls.library;
-      ResolutionInterfaceType thisType = cls.thisType;
-
-      void createMember(Element _element) {
-        MemberElement element = _element;
-        if (element.isConstructor) return;
-        String elementName = element.name;
-        if (shouldSkipName(elementName)) return;
-        if (nameText != null && elementName != nameText) return;
-
-        void addDeclaredMember(Name name, ResolutionDartType type,
-            ResolutionFunctionType functionType) {
-          DeclaredMember inherited = classMembers[name];
-          DeclaredMember declared;
-          if (element.isAbstract) {
-            declared = new DeclaredAbstractMember(
-                name, element, thisType, type, functionType, inherited);
-          } else {
-            declared =
-                new DeclaredMember(name, element, thisType, type, functionType);
-          }
-          declaredMembers[name] = declared;
-          classMembers[name] = declared;
-          checkValidOverride(declared, inherited);
-        }
-
-        Name name = new Name(element.name, library);
-        if (element.isField) {
-          ResolutionDartType type = element.computeType(resolution);
-          addDeclaredMember(
-              name, type, new ResolutionFunctionType.synthesized(type));
-          if (!element.isConst && !element.isFinal) {
-            addDeclaredMember(
-                name.setter,
-                type,
-                new ResolutionFunctionType.synthesized(
-                    const ResolutionVoidType(), <ResolutionDartType>[type]));
-          }
-        } else if (element.isGetter) {
-          ResolutionFunctionType functionType = element.computeType(resolution);
-          ResolutionDartType type = functionType.returnType;
-          addDeclaredMember(name, type, functionType);
-        } else if (element.isSetter) {
-          ResolutionFunctionType functionType = element.computeType(resolution);
-          ResolutionDartType type;
-          if (!functionType.parameterTypes.isEmpty) {
-            type = functionType.parameterTypes.first;
-          } else {
-            type = const ResolutionDynamicType();
-          }
-          name = name.setter;
-          addDeclaredMember(name, type, functionType);
-        } else {
-          assert(element.isFunction, failedAt(element));
-          ResolutionFunctionType type = element.computeType(resolution);
-          addDeclaredMember(name, type, type);
-        }
-      }
-
-      cls.forEachLocalMember(createMember);
-      if (cls.isPatched) {
-        cls.implementation.forEachLocalMember((Element element) {
-          if (element.isDeclaration) {
-            createMember(element);
-          }
-        });
-      }
-    }
-
-    return declaredMembers;
-  }
-
-  /// Checks that [classMember] is a valid implementation for [interfaceMember].
-  void checkInterfaceMember(
-      Name name, MemberSignature interfaceMember, Member classMember) {
-    if (classMember != null) {
-      // TODO(johnniwinther): Check that the class member is a valid override
-      // of the interface member.
-      return;
-    }
-    if (interfaceMember is DeclaredMember &&
-        interfaceMember.declarer.element == cls) {
-      // Abstract method declared in [cls].
-      MessageKind kind = MessageKind.ABSTRACT_METHOD;
-      if (interfaceMember.isSetter) {
-        kind = MessageKind.ABSTRACT_SETTER;
-      } else if (interfaceMember.isGetter) {
-        kind = MessageKind.ABSTRACT_GETTER;
-      }
-      reportMessage(interfaceMember.element, MessageKind.ABSTRACT_METHOD, () {
-        reporter.reportWarningMessage(interfaceMember.element, kind,
-            {'class': cls.name, 'name': name.text});
-      });
-    } else {
-      reportWarning(MessageKind singleKind, MessageKind multipleKind,
-          MessageKind explicitlyDeclaredKind,
-          [MessageKind implicitlyDeclaredKind]) {
-        Member inherited = interfaceMember.declarations.first;
-        reportMessage(interfaceMember, MessageKind.UNIMPLEMENTED_METHOD, () {
-          DiagnosticMessage warning = reporter.createMessage(
-              cls,
-              interfaceMember.declarations.length == 1
-                  ? singleKind
-                  : multipleKind,
-              {
-                'class': cls.name,
-                'name': name.text,
-                'method': interfaceMember,
-                'declarer': inherited.declarer
-              });
-          List<DiagnosticMessage> infos = <DiagnosticMessage>[];
-          for (Member inherited in interfaceMember.declarations) {
-            infos.add(reporter.createMessage(
-                inherited.element,
-                inherited.isDeclaredByField
-                    ? implicitlyDeclaredKind
-                    : explicitlyDeclaredKind,
-                {'class': inherited.declarer.name, 'name': name.text}));
-          }
-          reporter.reportWarning(warning, infos);
-        });
-      }
-
-      if (interfaceMember.isSetter) {
-        reportWarning(
-            MessageKind.UNIMPLEMENTED_SETTER_ONE,
-            MessageKind.UNIMPLEMENTED_SETTER,
-            MessageKind.UNIMPLEMENTED_EXPLICIT_SETTER,
-            MessageKind.UNIMPLEMENTED_IMPLICIT_SETTER);
-      } else if (interfaceMember.isGetter) {
-        reportWarning(
-            MessageKind.UNIMPLEMENTED_GETTER_ONE,
-            MessageKind.UNIMPLEMENTED_GETTER,
-            MessageKind.UNIMPLEMENTED_EXPLICIT_GETTER,
-            MessageKind.UNIMPLEMENTED_IMPLICIT_GETTER);
-      } else if (interfaceMember.isMethod) {
-        reportWarning(
-            MessageKind.UNIMPLEMENTED_METHOD_ONE,
-            MessageKind.UNIMPLEMENTED_METHOD,
-            MessageKind.UNIMPLEMENTED_METHOD_CONT);
-      }
-    }
-    // TODO(johnniwinther): If [cls] is not abstract, check that for all
-    // interface members, there is a class member whose type is a subtype of
-    // the interface member.
-  }
-
-  /// Checks that [cls], if it implements Function, has defined call().
-  void checkImplementsFunctionWithCall() {
-    assert(!cls.isAbstract);
-
-    ClassElement functionClass = resolution.commonElements.functionClass;
-    functionClass.ensureResolved(resolution);
-    if (cls.asInstanceOf(functionClass) == null) return;
-    if (cls.lookupMember(Identifiers.call) != null) return;
-    // TODO(johnniwinther): Make separate methods for backend exceptions.
-    // Avoid warnings on backend implementation classes for closures.
-    if (resolution.target.isTargetSpecificLibrary(cls.library)) return;
-
-    reportMessage(functionClass, MessageKind.UNIMPLEMENTED_METHOD, () {
-      reporter.reportWarningMessage(cls, MessageKind.UNIMPLEMENTED_METHOD_ONE, {
-        'class': cls.name,
-        'name': Identifiers.call,
-        'method': Identifiers.call,
-        'declarer': functionClass.name
-      });
-    });
-  }
-
-  /// Checks that a class member exists for every interface member.
-  void checkInterfaceImplementation();
-
-  /// Check that [declared] is a valid override of [superMember].
-  void checkValidOverride(Member declared, MemberSignature superMember) {
-    if (superMember == null) {
-      // No override.
-      if (!declared.isStatic) {
-        ClassElement superclass = cls.superclass;
-        while (superclass != null) {
-          Member superMember = superclass.lookupClassMember(declared.name);
-          if (superMember != null && superMember.isStatic) {
-            reportMessage(superMember, MessageKind.INSTANCE_STATIC_SAME_NAME,
-                () {
-              reporter.reportWarning(
-                  reporter.createMessage(
-                      declared.element, MessageKind.INSTANCE_STATIC_SAME_NAME, {
-                    'memberName': declared.name,
-                    'className': superclass.name
-                  }),
-                  <DiagnosticMessage>[
-                    reporter.createMessage(superMember.element,
-                        MessageKind.INSTANCE_STATIC_SAME_NAME_CONT),
-                  ]);
-            });
-            break;
-          }
-          superclass = superclass.superclass;
-        }
-      }
-    } else {
-      assert(declared.name == superMember.name);
-
-      if (declared.isStatic) {
-        for (Member inherited in superMember.declarations) {
-          if (cls == inherited.declarer.element) {
-            // An error should already have been reported.
-            assert(resolution.reporter.hasReportedError,
-                failedAt(declared.element));
-            continue;
-          }
-
-          reportMessage(inherited.element, MessageKind.NO_STATIC_OVERRIDE, () {
-            reportErrorWithContext(
-                declared.element,
-                MessageKind.NO_STATIC_OVERRIDE,
-                inherited.element,
-                MessageKind.NO_STATIC_OVERRIDE_CONT);
-          });
-        }
-      }
-
-      ResolutionDartType declaredType = declared.functionType;
-      for (Member inherited in superMember.declarations) {
-        if (inherited.element == declared.element) {
-          // TODO(ahe): For some reason, "call" elements are repeated in
-          // superMember.declarations. Investigate why.
-        } else if (cls == inherited.declarer.element) {
-          // An error should already have been reported.
-          assert(
-              resolution.reporter.hasReportedError,
-              failedAt(
-                  declared.element,
-                  "Member $inherited inherited from its "
-                  "declaring class: ${cls}."));
-          continue;
-        }
-
-        void reportError(MessageKind errorKind, MessageKind infoKind) {
-          reportMessage(inherited.element, MessageKind.INVALID_OVERRIDE_METHOD,
-              () {
-            reporter.reportError(
-                reporter.createMessage(declared.element, errorKind, {
-                  'name': declared.name.text,
-                  'class': cls.thisType,
-                  'inheritedClass': inherited.declarer
-                }),
-                <DiagnosticMessage>[
-                  reporter.createMessage(inherited.element, infoKind, {
-                    'name': declared.name.text,
-                    'class': inherited.declarer
-                  }),
-                ]);
-          });
-        }
-
-        if (declared.isDeclaredByField && inherited.isMethod) {
-          reportError(MessageKind.CANNOT_OVERRIDE_METHOD_WITH_FIELD,
-              MessageKind.CANNOT_OVERRIDE_METHOD_WITH_FIELD_CONT);
-        } else if (declared.isMethod && inherited.isDeclaredByField) {
-          reportError(MessageKind.CANNOT_OVERRIDE_FIELD_WITH_METHOD,
-              MessageKind.CANNOT_OVERRIDE_FIELD_WITH_METHOD_CONT);
-        } else if (declared.isGetter && inherited.isMethod) {
-          reportError(MessageKind.CANNOT_OVERRIDE_METHOD_WITH_GETTER,
-              MessageKind.CANNOT_OVERRIDE_METHOD_WITH_GETTER_CONT);
-        } else if (declared.isMethod && inherited.isGetter) {
-          reportError(MessageKind.CANNOT_OVERRIDE_GETTER_WITH_METHOD,
-              MessageKind.CANNOT_OVERRIDE_GETTER_WITH_METHOD_CONT);
-        } else {
-          ResolutionDartType inheritedType = inherited.functionType;
-          if (!resolution.types.isSubtype(declaredType, inheritedType)) {
-            void reportWarning(
-                var marker, MessageKind warningKind, MessageKind infoKind) {
-              reportMessage(marker, MessageKind.INVALID_OVERRIDE_METHOD, () {
-                reporter.reportWarning(
-                    reporter.createMessage(declared.element, warningKind, {
-                      'declaredType': declared.type,
-                      'name': declared.name.text,
-                      'class': cls.thisType,
-                      'inheritedType': inherited.type,
-                      'inheritedClass': inherited.declarer
-                    }),
-                    <DiagnosticMessage>[
-                      reporter.createMessage(inherited.element, infoKind, {
-                        'name': declared.name.text,
-                        'class': inherited.declarer
-                      }),
-                    ]);
-              });
-            }
-
-            if (declared.isDeclaredByField) {
-              if (inherited.isDeclaredByField) {
-                reportWarning(
-                    inherited.element,
-                    MessageKind.INVALID_OVERRIDE_FIELD,
-                    MessageKind.INVALID_OVERRIDDEN_FIELD);
-              } else if (inherited.isGetter) {
-                reportWarning(
-                    inherited,
-                    MessageKind.INVALID_OVERRIDE_GETTER_WITH_FIELD,
-                    MessageKind.INVALID_OVERRIDDEN_GETTER);
-              } else if (inherited.isSetter) {
-                reportWarning(
-                    inherited,
-                    MessageKind.INVALID_OVERRIDE_SETTER_WITH_FIELD,
-                    MessageKind.INVALID_OVERRIDDEN_SETTER);
-              }
-            } else if (declared.isGetter) {
-              if (inherited.isDeclaredByField) {
-                reportWarning(
-                    inherited,
-                    MessageKind.INVALID_OVERRIDE_FIELD_WITH_GETTER,
-                    MessageKind.INVALID_OVERRIDDEN_FIELD);
-              } else {
-                reportWarning(inherited, MessageKind.INVALID_OVERRIDE_GETTER,
-                    MessageKind.INVALID_OVERRIDDEN_GETTER);
-              }
-            } else if (declared.isSetter) {
-              if (inherited.isDeclaredByField) {
-                reportWarning(
-                    inherited,
-                    MessageKind.INVALID_OVERRIDE_FIELD_WITH_SETTER,
-                    MessageKind.INVALID_OVERRIDDEN_FIELD);
-              } else {
-                reportWarning(inherited, MessageKind.INVALID_OVERRIDE_SETTER,
-                    MessageKind.INVALID_OVERRIDDEN_SETTER);
-              }
-            } else {
-              reportWarning(inherited, MessageKind.INVALID_OVERRIDE_METHOD,
-                  MessageKind.INVALID_OVERRIDDEN_METHOD);
-            }
-          }
-        }
-      }
-    }
-  }
-
-  void reportErrorWithContext(
-      Element errorneousElement,
-      MessageKind errorMessage,
-      Element contextElement,
-      MessageKind contextMessage) {
-    reporter.reportError(
-        reporter.createMessage(errorneousElement, errorMessage, {
-          'memberName': contextElement.name,
-          'className': contextElement.enclosingClass.name
-        }),
-        <DiagnosticMessage>[
-          reporter.createMessage(contextElement, contextMessage),
-        ]);
-  }
-
-  /// Compute all class and interface names by the [name] in [cls].
-  static void computeClassMembersByName(
-      Resolution resolution, ClassMemberMixin cls, String name) {
-    if (cls.isMemberComputed(name)) return;
-    LibraryElement library = cls.library;
-    _computeClassMember(
-        resolution,
-        cls,
-        name,
-        new Setlet<Name>()
-          ..add(new Name(name, library))
-          ..add(new Name(name, library, isSetter: true)));
-  }
-
-  static void _computeClassMember(Resolution resolution, ClassMemberMixin cls,
-      String name, Setlet<Name> names) {
-    cls.computeClassMember(resolution, name, names);
-  }
-
-  /// Compute all class and interface names in [cls].
-  static void computeAllClassMembers(
-      Resolution resolution, ClassMemberMixin cls) {
-    cls.computeAllClassMembers(resolution);
-  }
-}
-
-/// Class member creator for classes where the interface members are known to
-/// be a subset of the class members.
-class ClassMembersCreator extends MembersCreator {
-  ClassMembersCreator(Resolution resolution, ClassElement cls,
-      Iterable<String> computedMemberNames, Map<Name, Member> classMembers)
-      : super(resolution, cls, computedMemberNames, classMembers);
-
-  Map<Name, Member> computeMembers(String name, Setlet<Name> names) {
-    computeSuperMembers(name, names);
-    return computeClassMembers(name, names);
-  }
-
-  void computeSuperMembers(String name, Setlet<Name> names) {
-    computeSuperClassMembers(name, names);
-  }
-
-  void checkInterfaceImplementation() {
-    LibraryElement library = cls.library;
-    classMembers.forEach((Name name, Member classMember) {
-      if (!name.isAccessibleFrom(library)) return;
-      checkInterfaceMember(name, classMember, classMember.implementation);
-    });
-  }
-}
-
-/// Class Member creator for classes where the interface members might be
-/// different from the class members.
-class InterfaceMembersCreator extends MembersCreator {
-  final Map<Name, MemberSignature> interfaceMembers;
-
-  InterfaceMembersCreator(
-      Resolution resolution,
-      ClassElement cls,
-      Iterable<String> computedMemberNames,
-      Map<Name, Member> classMembers,
-      Map<Name, MemberSignature> this.interfaceMembers)
-      : super(resolution, cls, computedMemberNames, classMembers);
-
-  Map<Name, Member> computeMembers(String name, Setlet<Name> names) {
-    Map<Name, Setlet<Member>> inheritedInterfaceMembers =
-        computeSuperMembers(name, names);
-    Map<Name, Member> declaredMembers = computeClassMembers(name, names);
-    computeInterfaceMembers(inheritedInterfaceMembers, declaredMembers);
-    return declaredMembers;
-  }
-
-  /// Compute the members of the super type(s) of [cls]. The class members are
-  /// stored if the [classMembers] map and the inherited interface members are
-  /// returned.
-  ///
-  /// If [name] and [names] are not null, the computation is restricted to
-  /// members with these names.
-  Map<Name, Setlet<Member>> computeSuperMembers(
-      String name, Setlet<Name> names) {
-    computeSuperClassMembers(name, names);
-    return computeSuperInterfaceMembers(name, names);
-  }
-
-  Map<Name, Setlet<Member>> computeSuperInterfaceMembers(
-      String name, Setlet<Name> names) {
-    ResolutionInterfaceType supertype = cls.supertype;
-    assert(supertype != null,
-        failedAt(cls, "Interface members computed for $cls."));
-    ClassElement superclass = supertype.element;
-
-    Map<Name, Setlet<Member>> inheritedInterfaceMembers =
-        new Map<Name, Setlet<Member>>();
-
-    void inheritInterfaceMember(
-        ResolutionInterfaceType supertype, MemberSignature member) {
-      if (shouldSkipMember(member)) return;
-      Setlet<Member> members = inheritedInterfaceMembers.putIfAbsent(
-          member.name, () => new Setlet<Member>());
-      for (DeclaredMember declaredMember in member.declarations) {
-        members.add(declaredMember.inheritFrom(supertype));
-      }
-    }
-
-    void inheritInterfaceMembers(ResolutionInterfaceType supertype) {
-      supertype.element.forEachInterfaceMember((MemberSignature member) {
-        inheritInterfaceMember(supertype, member);
-      });
-    }
-
-    if (names != null) {
-      for (Name memberName in names) {
-        inheritInterfaceMember(
-            supertype, superclass.lookupInterfaceMember(memberName));
-      }
-    } else {
-      inheritInterfaceMembers(supertype);
-    }
-
-    // Inherit interface members from superinterfaces.
-    for (Link<ResolutionDartType> link = cls.interfaces;
-        !link.isEmpty;
-        link = link.tail) {
-      ResolutionInterfaceType superinterface = link.head;
-      if (names != null) {
-        MembersCreator._computeClassMember(
-            resolution, superinterface.element, name, names);
-        for (Name memberName in names) {
-          inheritInterfaceMember(superinterface,
-              superinterface.element.lookupInterfaceMember(memberName));
-        }
-      } else {
-        MembersCreator.computeAllClassMembers(
-            resolution, superinterface.element);
-        inheritInterfaceMembers(superinterface);
-      }
-    }
-
-    return inheritedInterfaceMembers;
-  }
-
-  /// Checks that a class member exists for every interface member.
-  void checkInterfaceImplementation() {
-    LibraryElement library = cls.library;
-    checkImplementsFunctionWithCall();
-    interfaceMembers.forEach((Name name, MemberSignature interfaceMember) {
-      if (!name.isAccessibleFrom(library)) return;
-      Member classMember = classMembers[name];
-      if (classMember != null) classMember = classMember.implementation;
-      checkInterfaceMember(name, interfaceMember, classMember);
-    });
-  }
-
-  /// Compute the interface members of [cls] given the set of inherited
-  /// interface members [inheritedInterfaceMembers] and declared members
-  /// [declaredMembers]. The computed members are stored in [interfaceMembers].
-  void computeInterfaceMembers(
-      Map<Name, Setlet<Member>> inheritedInterfaceMembers,
-      Map<Name, Member> declaredMembers) {
-    ResolutionInterfaceType thisType = cls.thisType;
-    // Compute the interface members by overriding the inherited members with
-    // a declared member or by computing a single, possibly synthesized,
-    // inherited member.
-    inheritedInterfaceMembers
-        .forEach((Name name, Setlet<Member> inheritedMembers) {
-      Member declared = declaredMembers[name];
-      if (declared != null) {
-        // Check that [declaredMember] is a valid override
-        for (Member inherited in inheritedMembers) {
-          checkValidOverride(declared, inherited);
-        }
-        if (!declared.isStatic) {
-          interfaceMembers[name] = declared;
-        }
-      } else if (inheritedMembers.length == 1) {
-        interfaceMembers[name] = inheritedMembers.single;
-      } else {
-        bool someAreGetters = false;
-        bool allAreGetters = true;
-        Map<ResolutionDartType, Setlet<Member>> subtypesOfAllInherited =
-            new Map<ResolutionDartType, Setlet<Member>>();
-        outer:
-        for (Member inherited in inheritedMembers) {
-          if (inherited.isGetter) {
-            someAreGetters = true;
-            if (!allAreGetters) break outer;
-          } else {
-            allAreGetters = false;
-            if (someAreGetters) break outer;
-          }
-          for (MemberSignature other in inheritedMembers) {
-            if (!resolution.types
-                .isSubtype(inherited.functionType, other.functionType)) {
-              continue outer;
-            }
-          }
-          subtypesOfAllInherited
-              .putIfAbsent(inherited.functionType, () => new Setlet<Member>())
-              .add(inherited);
-        }
-        if (someAreGetters && !allAreGetters) {
-          DiagnosticMessage warning = reporter.createMessage(
-              cls,
-              MessageKind.INHERIT_GETTER_AND_METHOD,
-              {'class': thisType, 'name': name.text});
-          List<DiagnosticMessage> infos = <DiagnosticMessage>[];
-          for (Member inherited in inheritedMembers) {
-            MessageKind kind;
-            if (inherited.isMethod) {
-              kind = MessageKind.INHERITED_METHOD;
-            } else {
-              assert(
-                  inherited.isGetter,
-                  failedAt(cls,
-                      'Conflicting member is neither a method nor a getter.'));
-              if (inherited.isDeclaredByField) {
-                kind = MessageKind.INHERITED_IMPLICIT_GETTER;
-              } else {
-                kind = MessageKind.INHERITED_EXPLICIT_GETTER;
-              }
-            }
-            infos.add(reporter.createMessage(inherited.element, kind,
-                {'class': inherited.declarer, 'name': name.text}));
-          }
-          reporter.reportWarning(warning, infos);
-          interfaceMembers[name] = new ErroneousMember(inheritedMembers);
-        } else if (subtypesOfAllInherited.length == 1) {
-          // All signatures have the same type.
-          Setlet<Member> members = subtypesOfAllInherited.values.first;
-          MemberSignature inherited = members.first;
-          if (members.length != 1) {
-            // Multiple signatures with the same type => return a
-            // synthesized signature.
-            inherited = new SyntheticMember(
-                members, inherited.type, inherited.functionType);
-          }
-          interfaceMembers[name] = inherited;
-        } else {
-          _inheritedSynthesizedMember(name, inheritedMembers);
-        }
-      }
-    });
-
-    // Add the non-overriding instance methods to the interface members.
-    declaredMembers.forEach((Name name, Member member) {
-      if (!member.isStatic) {
-        interfaceMembers.putIfAbsent(name, () => member);
-      }
-    });
-  }
-
-  /// Create and inherit a synthesized member for [inheritedMembers].
-  void _inheritedSynthesizedMember(Name name, Setlet<Member> inheritedMembers) {
-    // Multiple signatures with different types => create the synthesized
-    // version.
-    int minRequiredParameters;
-    int maxPositionalParameters;
-    Set<String> names = new Set<String>();
-    for (MemberSignature member in inheritedMembers) {
-      int requiredParameters = 0;
-      int optionalParameters = 0;
-      if (member.isSetter) {
-        requiredParameters = 1;
-      }
-      if (member.type.isFunctionType) {
-        ResolutionFunctionType type = member.type;
-        type.namedParameters.forEach((String name) => names.add(name));
-        requiredParameters = type.parameterTypes.length;
-        optionalParameters = type.optionalParameterTypes.length;
-      }
-      int positionalParameters = requiredParameters + optionalParameters;
-      if (minRequiredParameters == null ||
-          minRequiredParameters > requiredParameters) {
-        minRequiredParameters = requiredParameters;
-      }
-      if (maxPositionalParameters == null ||
-          maxPositionalParameters < positionalParameters) {
-        maxPositionalParameters = positionalParameters;
-      }
-    }
-    int optionalParameters = maxPositionalParameters - minRequiredParameters;
-    // TODO(johnniwinther): Support function types with both optional
-    // and named parameters?
-    if (optionalParameters == 0 || names.isEmpty) {
-      ResolutionDartType dynamic = const ResolutionDynamicType();
-      List<ResolutionDartType> requiredParameterTypes =
-          new List.filled(minRequiredParameters, dynamic);
-      List<ResolutionDartType> optionalParameterTypes =
-          new List.filled(optionalParameters, dynamic);
-      List<String> namedParameters = names.toList()
-        ..sort((a, b) => a.compareTo(b));
-      List<ResolutionDartType> namedParameterTypes =
-          new List.filled(namedParameters.length, dynamic);
-      ResolutionFunctionType memberType =
-          new ResolutionFunctionType.synthesized(
-              const ResolutionDynamicType(),
-              requiredParameterTypes,
-              optionalParameterTypes,
-              namedParameters,
-              namedParameterTypes);
-      ResolutionDartType type = memberType;
-      if (inheritedMembers.first.isGetter || inheritedMembers.first.isSetter) {
-        type = const ResolutionDynamicType();
-      }
-      interfaceMembers[name] =
-          new SyntheticMember(inheritedMembers, type, memberType);
-    }
-  }
-}
-
-abstract class ClassMemberMixin implements ClassElement {
-  /// When [classMembers] and [interfaceMembers] have not been fully computed
-  /// [computedMembersNames] holds the names for which members have already been
-  /// computed.
-  ///
-  /// If [computedMemberNames], [classMembers] and [interfaceMembers] are `null`
-  /// no members have been computed, if only [computedMemberNames] is `null` all
-  /// members have been computed. A non-null [computedMemberNames] implicitly
-  /// includes `call`.
-  Iterable<String> computedMemberNames;
-
-  bool _interfaceMembersAreClassMembers;
-
-  /// Compute value of the [_interfaceMembersAreClassMembers] for this class
-  /// and its superclasses.
-  void _computeInterfaceMembersAreClassMembers(Resolution resolution) {
-    if (_interfaceMembersAreClassMembers == null) {
-      ensureResolved(resolution);
-      ClassMemberMixin superclass = this.superclass;
-      if (superclass != null) {
-        superclass._computeInterfaceMembersAreClassMembers(resolution);
-      }
-      if ((superclass != null &&
-              (!superclass.interfaceMembersAreClassMembers ||
-                  superclass.isMixinApplication)) ||
-          !interfaces.isEmpty) {
-        _interfaceMembersAreClassMembers = false;
-      } else {
-        _interfaceMembersAreClassMembers = true;
-      }
-    }
-  }
-
-  /// If `true` interface members are the non-static class member.
-  bool get interfaceMembersAreClassMembers => _interfaceMembersAreClassMembers;
-
-  Map<Name, Member> classMembers;
-  Map<Name, MemberSignature> interfaceMembers;
-
-  /// Creates the necessary maps and [MembersCreator] for compute members of
-  /// this class.
-  MembersCreator _prepareCreator(Resolution resolution) {
-    if (classMembers == null) {
-      _computeInterfaceMembersAreClassMembers(resolution);
-      classMembers = new Map<Name, Member>();
-      if (!interfaceMembersAreClassMembers) {
-        interfaceMembers = new Map<Name, MemberSignature>();
-      }
-    }
-    return interfaceMembersAreClassMembers
-        ? new ClassMembersCreator(
-            resolution, this, computedMemberNames, classMembers)
-        : new InterfaceMembersCreator(resolution, this, computedMemberNames,
-            classMembers, interfaceMembers);
-  }
-
-  static Iterable<String> _EMPTY_MEMBERS_NAMES = const <String>[];
-
-  /// Compute the members by the name [name] for this class. [names] collects
-  /// the set of possible variations of [name], including getter, setter and
-  /// and private names.
-  void computeClassMember(
-      Resolution resolution, String name, Setlet<Name> names) {
-    // TODO(johnniwinther): Should we assert that the class has been resolved
-    // instead?
-    ensureResolved(resolution);
-    if (isMemberComputed(name)) return;
-    if (Name.isPrivateName(name)) {
-      names
-        ..add(new Name(name, library))
-        ..add(new Name(name, library, isSetter: true));
-    }
-    MembersCreator creator = _prepareCreator(resolution);
-    creator.computeMembersByName(name, names);
-    if (computedMemberNames == null) {
-      computedMemberNames = _EMPTY_MEMBERS_NAMES;
-    }
-    if (name != Identifiers.call) {
-      Setlet<String> set;
-      if (identical(computedMemberNames, _EMPTY_MEMBERS_NAMES)) {
-        computedMemberNames = set = new Setlet<String>();
-      } else {
-        set = computedMemberNames;
-      }
-      set.add(name);
-    }
-  }
-
-  void computeAllClassMembers(Resolution resolution) {
-    // TODO(johnniwinther): Should we assert that the class has been resolved
-    // instead?
-    ensureResolved(resolution);
-    if (areAllMembersComputed()) return;
-    MembersCreator creator = _prepareCreator(resolution);
-    creator.computeAllMembers();
-    computedMemberNames = null;
-    assert(areAllMembersComputed(), failedAt(this));
-  }
-
-  bool areAllMembersComputed() {
-    return computedMemberNames == null && classMembers != null;
-  }
-
-  bool isMemberComputed(String name) {
-    if (computedMemberNames == null) {
-      return classMembers != null;
-    } else {
-      return name == Identifiers.call || computedMemberNames.contains(name);
-    }
-  }
-
-  Member lookupClassMember(Name name) {
-    assert(isMemberComputed(name.text),
-        failedAt(this, "Member ${name} has not been computed for $this."));
-    return classMembers[name];
-  }
-
-  void forEachClassMember(f(Member member)) {
-    assert(areAllMembersComputed(),
-        failedAt(this, "Members have not been fully computed for $this."));
-    classMembers.forEach((_, member) => f(member));
-  }
-
-  MemberSignature lookupInterfaceMember(Name name) {
-    assert(isMemberComputed(name.text),
-        failedAt(this, "Member ${name.text} has not been computed for $this."));
-    if (interfaceMembersAreClassMembers) {
-      Member member = classMembers[name];
-      if (member != null && member.isStatic) return null;
-      return member;
-    }
-    return interfaceMembers[name];
-  }
-
-  void forEachInterfaceMember(f(MemberSignature member)) {
-    assert(areAllMembersComputed(),
-        failedAt(this, "Members have not been fully computed for $this."));
-    if (interfaceMembersAreClassMembers) {
-      classMembers.forEach((_, member) {
-        if (!member.isStatic) f(member);
-      });
-    } else {
-      interfaceMembers.forEach((_, member) => f(member));
-    }
-  }
-}
diff --git a/pkg/compiler/lib/src/resolution/constructors.dart b/pkg/compiler/lib/src/resolution/constructors.dart
deleted file mode 100644
index ba5ec7b..0000000
--- a/pkg/compiler/lib/src/resolution/constructors.dart
+++ /dev/null
@@ -1,910 +0,0 @@
-// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library dart2js.resolution.constructors;
-
-import '../common.dart';
-import '../common/resolution.dart' show Resolution;
-import '../constants/constructors.dart'
-    show
-        GenerativeConstantConstructor,
-        RedirectingGenerativeConstantConstructor;
-import '../constants/expressions.dart';
-import '../elements/resolution_types.dart';
-import '../elements/elements.dart';
-import '../elements/modelx.dart'
-    show
-        ConstructorElementX,
-        ErroneousConstructorElementX,
-        ErroneousElementX,
-        ErroneousFieldElementX,
-        FieldElementX,
-        InitializingFormalElementX,
-        ParameterElementX;
-import '../elements/names.dart';
-import '../tree/tree.dart';
-import '../universe/call_structure.dart' show CallStructure;
-import '../universe/feature.dart' show Feature;
-import '../universe/use.dart' show StaticUse;
-import '../util/util.dart' show Link;
-import 'members.dart' show lookupInScope, ResolverVisitor;
-import 'registry.dart' show ResolutionRegistry;
-import 'resolution_common.dart' show CommonResolverVisitor;
-import 'resolution_result.dart';
-import 'scope.dart' show Scope, ExtensionScope;
-
-class InitializerResolver {
-  final ResolverVisitor visitor;
-  final ConstructorElementX constructor;
-  final FunctionExpression functionNode;
-  final Map<FieldElement, Node> initialized = <FieldElement, Node>{};
-  final Map<FieldElement, ConstantExpression> fieldInitializers =
-      <FieldElement, ConstantExpression>{};
-  Link<Node> initializers;
-  bool hasSuper = false;
-  bool isValidAsConstant = true;
-
-  bool get isConst => constructor.isConst;
-
-  InitializerResolver(this.visitor, this.constructor, this.functionNode);
-
-  ResolutionRegistry get registry => visitor.registry;
-
-  DiagnosticReporter get reporter => visitor.reporter;
-
-  bool isFieldInitializer(SendSet node) {
-    if (node.selector.asIdentifier() == null) return false;
-    if (node.receiver == null) return true;
-    if (node.receiver.asIdentifier() == null) return false;
-    return node.receiver.asIdentifier().isThis();
-  }
-
-  reportDuplicateInitializerError(
-      Element field, Node init, Spannable existing) {
-    reporter.reportError(
-        reporter.createMessage(
-            init, MessageKind.DUPLICATE_INITIALIZER, {'fieldName': field.name}),
-        <DiagnosticMessage>[
-          reporter.createMessage(existing, MessageKind.ALREADY_INITIALIZED,
-              {'fieldName': field.name}),
-        ]);
-    isValidAsConstant = false;
-  }
-
-  void checkForDuplicateInitializers(FieldElementX field, Node init) {
-    // [field] can be null if it could not be resolved.
-    if (field == null) return;
-    if (initialized.containsKey(field)) {
-      reportDuplicateInitializerError(field, init, initialized[field]);
-    } else if (field.isFinal) {
-      field.parseNode(visitor.resolution.parsingContext);
-      Expression initializer = field.initializer;
-      if (initializer != null) {
-        reportDuplicateInitializerError(
-            field,
-            init,
-            reporter.withCurrentElement(
-                field, () => reporter.spanFromSpannable(initializer)));
-      }
-    }
-    initialized[field] = init;
-  }
-
-  void resolveFieldInitializer(SendSet init) {
-    // init is of the form [this.]field = value.
-    final Node selector = init.selector;
-    final String name = selector.asIdentifier().source;
-    // Lookup target field.
-    Element target;
-    FieldElement field;
-    if (isFieldInitializer(init)) {
-      // Use [enclosingElement] instead of [enclosingClass] to ensure lookup in
-      // patch class when necessary.
-      ClassElement cls = constructor.enclosingElement;
-      target = cls.lookupLocalMember(name);
-      if (target == null) {
-        reporter.reportErrorMessage(
-            selector, MessageKind.CANNOT_RESOLVE, {'name': name});
-        target = new ErroneousFieldElementX(
-            selector.asIdentifier(), constructor.enclosingClass);
-      } else if (target.kind != ElementKind.FIELD) {
-        reporter.reportErrorMessage(
-            selector, MessageKind.NOT_A_FIELD, {'fieldName': name});
-        target = new ErroneousFieldElementX(
-            selector.asIdentifier(), constructor.enclosingClass);
-      } else if (!target.isInstanceMember) {
-        reporter.reportErrorMessage(
-            selector, MessageKind.INIT_STATIC_FIELD, {'fieldName': name});
-      } else {
-        field = target;
-      }
-    } else {
-      reporter.reportErrorMessage(
-          init, MessageKind.INVALID_RECEIVER_IN_INITIALIZER);
-    }
-    if (target != null) {
-      registry.useElement(init, target);
-      checkForDuplicateInitializers(target, init);
-    }
-    if (field != null) {
-      registry.registerStaticUse(new StaticUse.fieldInit(field));
-    }
-    // Resolve initializing value.
-    ResolutionResult result = visitor.visitInStaticContext(init.arguments.head,
-        inConstantInitializer: isConst);
-    if (isConst) {
-      if (result.isConstant && field != null) {
-        // TODO(johnniwinther): Report error if `result.constant` is `null`.
-        fieldInitializers[field] = result.constant;
-      } else {
-        isValidAsConstant = false;
-      }
-    }
-  }
-
-  ResolutionInterfaceType getSuperOrThisLookupTarget(Node diagnosticNode,
-      {bool isSuperCall}) {
-    if (isSuperCall) {
-      // Calculate correct lookup target and constructor name.
-      if (constructor.enclosingClass.isObject) {
-        reporter.reportErrorMessage(
-            diagnosticNode, MessageKind.SUPER_INITIALIZER_IN_OBJECT);
-        isValidAsConstant = false;
-      } else {
-        return constructor.enclosingClass.supertype;
-      }
-    }
-    return constructor.enclosingClass.thisType;
-  }
-
-  ResolutionResult resolveSuperOrThisForSend(Send node) {
-    // Resolve the selector and the arguments.
-    ArgumentsResult argumentsResult = visitor.inStaticContext(() {
-      // TODO(johnniwinther): Remove this when [SendStructure] is used directly.
-      visitor.resolveSelector(node, null);
-      return visitor.resolveArguments(node.argumentsNode);
-    }, inConstantInitializer: isConst);
-
-    bool isSuperCall = Initializers.isSuperConstructorCall(node);
-    ResolutionInterfaceType targetType =
-        getSuperOrThisLookupTarget(node, isSuperCall: isSuperCall);
-    ClassElement lookupTarget = targetType.element;
-    String constructorName =
-        visitor.getRedirectingThisOrSuperConstructorName(node).text;
-    ConstructorElement foundConstructor =
-        findConstructor(constructor.library, lookupTarget, constructorName);
-
-    final String className = lookupTarget.name;
-    CallStructure callStructure = argumentsResult.callStructure;
-    ConstructorElement calledConstructor = verifyThatConstructorMatchesCall(
-        node, foundConstructor, callStructure, className,
-        constructorName: constructorName,
-        isThisCall: !isSuperCall,
-        isImplicitSuperCall: false);
-    // TODO(johnniwinther): Remove this when information is pulled from an
-    // [InitializerStructure].
-    registry.useElement(node, calledConstructor);
-    if (!calledConstructor.isError) {
-      registry.registerStaticUse(new StaticUse.superConstructorInvoke(
-          calledConstructor, callStructure));
-    }
-    if (isConst) {
-      if (isValidAsConstant &&
-          calledConstructor.isConst &&
-          argumentsResult.isValidAsConstant) {
-        List<ConstantExpression> arguments = argumentsResult.constantArguments;
-        return new ConstantResult(
-            node,
-            new ConstructedConstantExpression(
-                targetType, calledConstructor, callStructure, arguments),
-            element: calledConstructor);
-      } else {
-        isValidAsConstant = false;
-      }
-    }
-    return new ResolutionResult.forElement(calledConstructor);
-  }
-
-  ConstructedConstantExpression resolveImplicitSuperConstructorSend() {
-    // If the class has a super resolve the implicit super call.
-    ClassElement classElement = constructor.enclosingClass;
-    ClassElement superClass = classElement.superclass;
-    if (!classElement.isObject) {
-      assert(superClass != null);
-      assert(superClass.isResolved);
-
-      ResolutionInterfaceType targetType =
-          getSuperOrThisLookupTarget(functionNode, isSuperCall: true);
-      ClassElement lookupTarget = targetType.element;
-      ConstructorElement calledConstructor =
-          findConstructor(constructor.library, lookupTarget, '');
-
-      final String className = lookupTarget.name;
-      CallStructure callStructure = CallStructure.NO_ARGS;
-      ConstructorElement result = verifyThatConstructorMatchesCall(
-          functionNode, calledConstructor, callStructure, className,
-          isImplicitSuperCall: true);
-      if (!result.isError) {
-        registry.registerStaticUse(new StaticUse.superConstructorInvoke(
-            calledConstructor, callStructure));
-      }
-
-      if (isConst && isValidAsConstant) {
-        return new ConstructedConstantExpression(targetType, result,
-            CallStructure.NO_ARGS, const <ConstantExpression>[]);
-      }
-    }
-    return null;
-  }
-
-  ConstructorElement reportAndCreateErroneousConstructor(
-      Spannable diagnosticNode, String name, MessageKind kind, Map arguments) {
-    isValidAsConstant = false;
-    reporter.reportErrorMessage(diagnosticNode, kind, arguments);
-    return new ErroneousConstructorElementX(
-        kind, arguments, name, visitor.currentClass);
-  }
-
-  /// Checks that [lookedupConstructor] is valid as a target for the super/this
-  /// constructor call using with the given [callStructure].
-  ///
-  /// If [lookedupConstructor] is valid it is returned, otherwise an error is
-  /// reported and an [ErroneousConstructorElement] is returned.
-  ConstructorElement verifyThatConstructorMatchesCall(
-      Node node,
-      ConstructorElement lookedupConstructor,
-      CallStructure callStructure,
-      String className,
-      {String constructorName: '',
-      bool isImplicitSuperCall: false,
-      bool isThisCall: false}) {
-    Element result = lookedupConstructor;
-    if (lookedupConstructor == null) {
-      String fullConstructorName =
-          Elements.constructorNameForDiagnostics(className, constructorName);
-      MessageKind kind = isImplicitSuperCall
-          ? MessageKind.CANNOT_RESOLVE_CONSTRUCTOR_FOR_IMPLICIT
-          : MessageKind.CANNOT_RESOLVE_CONSTRUCTOR;
-      result = reportAndCreateErroneousConstructor(node, constructorName, kind,
-          {'constructorName': fullConstructorName});
-    } else if (!lookedupConstructor.isGenerativeConstructor) {
-      MessageKind kind = isThisCall
-          ? MessageKind.THIS_CALL_TO_FACTORY
-          : MessageKind.SUPER_CALL_TO_FACTORY;
-      result =
-          reportAndCreateErroneousConstructor(node, constructorName, kind, {});
-    } else {
-      lookedupConstructor.computeType(visitor.resolution);
-      if (!callStructure
-          .signatureApplies(lookedupConstructor.parameterStructure)) {
-        MessageKind kind = isImplicitSuperCall
-            ? MessageKind.NO_MATCHING_CONSTRUCTOR_FOR_IMPLICIT
-            : MessageKind.NO_MATCHING_CONSTRUCTOR;
-        result = reportAndCreateErroneousConstructor(
-            node, constructorName, kind, {});
-      } else if (constructor.isConst && !lookedupConstructor.isConst) {
-        MessageKind kind = isImplicitSuperCall
-            ? MessageKind.CONST_CALLS_NON_CONST_FOR_IMPLICIT
-            : MessageKind.CONST_CALLS_NON_CONST;
-        result = reportAndCreateErroneousConstructor(
-            node, constructorName, kind, {});
-      }
-    }
-    return result;
-  }
-
-  /**
-   * Resolve all initializers of this constructor. In the case of a redirecting
-   * constructor, the resolved constructor's function element is returned.
-   */
-  ConstructorElement resolveInitializers() {
-    Map<dynamic /*String|int*/, ConstantExpression> defaultValues =
-        <dynamic /*String|int*/, ConstantExpression>{};
-    ConstructedConstantExpression constructorInvocation;
-    // Keep track of all "this.param" parameters specified for constructor so
-    // that we can ensure that fields are initialized only once.
-    FunctionSignature functionParameters = constructor.functionSignature;
-    Scope oldScope = visitor.scope;
-    // In order to get the correct detection of name clashes between all
-    // parameters (regular ones and initializing formals) we must extend
-    // the parameter scope rather than adding a new nested scope.
-    visitor.scope = new ExtensionScope(visitor.scope);
-    Link<Node> parameterNodes = (functionNode?.parameters == null)
-        ? const Link<Node>()
-        : functionNode.parameters.nodes;
-    functionParameters.forEachParameter((FormalElement _element) {
-      ParameterElementX element = _element;
-      List<Element> optionals = functionParameters.optionalParameters;
-      if (!optionals.isEmpty && element == optionals.first) {
-        NodeList nodes = parameterNodes.head;
-        parameterNodes = nodes.nodes;
-      }
-      if (isConst) {
-        if (element.isOptional) {
-          if (element.constantCache == null) {
-            // TODO(johnniwinther): Remove this when all constant expressions
-            // can be computed during resolution.
-            isValidAsConstant = false;
-          } else {
-            ConstantExpression defaultValue = element.constant;
-            if (defaultValue != null) {
-              if (element.isNamed) {
-                defaultValues[element.name] = defaultValue;
-              } else {
-                int index =
-                    element.functionDeclaration.parameters.indexOf(element);
-                defaultValues[index] = defaultValue;
-              }
-            } else {
-              isValidAsConstant = false;
-            }
-          }
-        }
-      }
-      if (element.isInitializingFormal) {
-        VariableDefinitions variableDefinitions = parameterNodes.head;
-        Node parameterNode = variableDefinitions.definitions.nodes.head;
-        InitializingFormalElementX initializingFormal = element;
-        FieldElement field = initializingFormal.fieldElement;
-        if (!field.isMalformed) {
-          registry.registerStaticUse(new StaticUse.fieldInit(field));
-        }
-        checkForDuplicateInitializers(field, parameterNode);
-        visitor.defineLocalVariable(parameterNode, initializingFormal);
-        visitor.addToScope(initializingFormal);
-        if (isConst) {
-          if (element.isNamed) {
-            fieldInitializers[field] = new NamedArgumentReference(element.name);
-          } else {
-            int index = element.functionDeclaration.parameters.indexOf(element);
-            fieldInitializers[field] = new PositionalArgumentReference(index);
-          }
-        } else {
-          isValidAsConstant = false;
-        }
-      }
-      parameterNodes = parameterNodes.tail;
-    });
-
-    if (functionNode?.initializers == null) {
-      initializers = const Link<Node>();
-    } else {
-      initializers = functionNode.initializers.nodes;
-    }
-    bool resolvedSuper = false;
-    for (Link<Node> link = initializers; !link.isEmpty; link = link.tail) {
-      if (link.head.asSendSet() != null) {
-        final SendSet init = link.head.asSendSet();
-        resolveFieldInitializer(init);
-      } else if (link.head.asSend() != null) {
-        final Send call = link.head.asSend();
-        if (call.argumentsNode == null) {
-          reporter.reportErrorMessage(
-              link.head, MessageKind.INVALID_INITIALIZER);
-          continue;
-        }
-        if (Initializers.isSuperConstructorCall(call)) {
-          if (resolvedSuper) {
-            reporter.reportErrorMessage(
-                call, MessageKind.DUPLICATE_SUPER_INITIALIZER);
-          }
-          ResolutionResult result = resolveSuperOrThisForSend(call);
-          if (isConst) {
-            if (result.isConstant) {
-              constructorInvocation = result.constant;
-            } else {
-              isValidAsConstant = false;
-            }
-          }
-          resolvedSuper = true;
-        } else if (Initializers.isConstructorRedirect(call)) {
-          // Check that there is no body (Language specification 7.5.1).  If the
-          // constructor is also const, we already reported an error in
-          // [resolveMethodElement].
-          if (functionNode.hasBody && !constructor.isConst) {
-            reporter.reportErrorMessage(
-                functionNode, MessageKind.REDIRECTING_CONSTRUCTOR_HAS_BODY);
-          }
-          // Check that there are no other initializers.
-          if (!initializers.tail.isEmpty) {
-            reporter.reportErrorMessage(
-                call, MessageKind.REDIRECTING_CONSTRUCTOR_HAS_INITIALIZER);
-          } else {
-            constructor.isRedirectingGenerativeInternal = true;
-          }
-          // Check that there are no field initializing parameters.
-          FunctionSignature signature = constructor.functionSignature;
-          signature.forEachParameter((FormalElement parameter) {
-            if (parameter.isInitializingFormal) {
-              Node node = parameter.node;
-              reporter.reportErrorMessage(
-                  node, MessageKind.INITIALIZING_FORMAL_NOT_ALLOWED);
-              isValidAsConstant = false;
-            }
-          });
-          ResolutionResult result = resolveSuperOrThisForSend(call);
-          if (isConst) {
-            if (result.isConstant) {
-              constructorInvocation = result.constant;
-            } else {
-              isValidAsConstant = false;
-            }
-            if (isConst && isValidAsConstant) {
-              constructor.constantConstructor =
-                  new RedirectingGenerativeConstantConstructor(
-                      defaultValues, constructorInvocation);
-            }
-          }
-          return result.element;
-        } else {
-          reporter.reportErrorMessage(
-              call, MessageKind.CONSTRUCTOR_CALL_EXPECTED);
-          return null;
-        }
-      } else {
-        reporter.reportErrorMessage(link.head, MessageKind.INVALID_INITIALIZER);
-      }
-    }
-    if (!resolvedSuper) {
-      constructorInvocation = resolveImplicitSuperConstructorSend();
-    }
-    constructor.enclosingClass
-        .forEachInstanceField((ClassElement declarer, FieldElement field) {
-      if (declarer != constructor.enclosingClass) return;
-
-      if (!initialized.containsKey(field)) {
-        visitor.resolution.ensureResolved(field);
-        if (field.isFinal && field.initializer == null) {
-          registry.registerStaticUse(new StaticUse.fieldInit(field));
-          registry.registerConstantLiteral(new NullConstantExpression());
-        }
-      }
-    });
-
-    if (isConst && isValidAsConstant) {
-      constructor.enclosingClass.forEachInstanceField((_, FieldElement field) {
-        if (!fieldInitializers.containsKey(field)) {
-          visitor.resolution.ensureResolved(field);
-          // TODO(johnniwinther): Report error if `field.constant` is `null`.
-          if (field.constant != null) {
-            fieldInitializers[field] = field.constant;
-          } else {
-            isValidAsConstant = false;
-          }
-        }
-      });
-      if (isValidAsConstant) {
-        constructor.constantConstructor = new GenerativeConstantConstructor(
-            constructor.enclosingClass.thisType,
-            defaultValues,
-            fieldInitializers,
-            const <AssertConstantExpression>[],
-            constructorInvocation);
-      }
-    }
-    visitor.scope = oldScope;
-    return null; // If there was no redirection always return null.
-  }
-}
-
-class ConstructorResolver extends CommonResolverVisitor<ConstructorResult> {
-  final ResolverVisitor resolver;
-  final bool inConstContext;
-
-  ConstructorResolver(Resolution resolution, this.resolver,
-      {bool this.inConstContext: false})
-      : super(resolution);
-
-  ResolutionRegistry get registry => resolver.registry;
-
-  Element get context => resolver.enclosingElement;
-
-  visitNode(Node node) {
-    throw 'not supported';
-  }
-
-  ConstructorResult reportAndCreateErroneousConstructorElement(
-      Spannable diagnosticNode,
-      ConstructorResultKind resultKind,
-      ResolutionDartType type,
-      String name,
-      MessageKind kind,
-      Map arguments,
-      {bool isError: false,
-      bool missingConstructor: false,
-      List<DiagnosticMessage> infos: const <DiagnosticMessage>[]}) {
-    if (missingConstructor) {
-      registry.registerFeature(Feature.THROW_NO_SUCH_METHOD);
-    } else {
-      registry.registerFeature(Feature.THROW_RUNTIME_ERROR);
-    }
-    DiagnosticMessage message =
-        reporter.createMessage(diagnosticNode, kind, arguments);
-    if (isError || inConstContext) {
-      reporter.reportError(message, infos);
-    } else {
-      reporter.reportWarning(message, infos);
-    }
-    ErroneousElement error =
-        new ErroneousConstructorElementX(kind, arguments, name, context);
-    if (type == null) {
-      type = new MalformedType(error, null);
-    }
-    return new ConstructorResult.forError(resultKind, error, type);
-  }
-
-  ConstructorResult resolveConstructor(
-      PrefixElement prefix,
-      ResolutionInterfaceType type,
-      Node diagnosticNode,
-      String constructorName) {
-    ClassElement cls = type.element;
-    cls.ensureResolved(resolution);
-    ConstructorElement constructor =
-        findConstructor(context.library, cls, constructorName);
-    if (constructor == null) {
-      MessageKind kind = constructorName.isEmpty
-          ? MessageKind.CANNOT_FIND_UNNAMED_CONSTRUCTOR
-          : MessageKind.CANNOT_FIND_CONSTRUCTOR;
-      return reportAndCreateErroneousConstructorElement(
-          diagnosticNode,
-          ConstructorResultKind.UNRESOLVED_CONSTRUCTOR,
-          type,
-          constructorName,
-          kind,
-          {'className': cls.name, 'constructorName': constructorName},
-          missingConstructor: true);
-    } else if (inConstContext && !constructor.isConst) {
-      reporter.reportErrorMessage(
-          diagnosticNode, MessageKind.CONSTRUCTOR_IS_NOT_CONST);
-      return new ConstructorResult(
-          ConstructorResultKind.NON_CONSTANT, prefix, constructor, type);
-    } else {
-      if (cls.isEnumClass && resolver.currentClass != cls) {
-        return reportAndCreateErroneousConstructorElement(
-            diagnosticNode,
-            ConstructorResultKind.INVALID_TYPE,
-            type,
-            constructorName,
-            MessageKind.CANNOT_INSTANTIATE_ENUM,
-            {'enumName': cls.name},
-            isError: true);
-      }
-      if (constructor.isGenerativeConstructor) {
-        if (cls.isAbstract) {
-          reporter.reportWarningMessage(
-              diagnosticNode, MessageKind.ABSTRACT_CLASS_INSTANTIATION);
-          registry.registerFeature(Feature.ABSTRACT_CLASS_INSTANTIATION);
-          return new ConstructorResult(
-              ConstructorResultKind.ABSTRACT, prefix, constructor, type);
-        } else {
-          return new ConstructorResult(
-              ConstructorResultKind.GENERATIVE, prefix, constructor, type);
-        }
-      } else {
-        assert(constructor.isFactoryConstructor,
-            failedAt(diagnosticNode, "Unexpected constructor $constructor."));
-        return new ConstructorResult(
-            ConstructorResultKind.FACTORY, prefix, constructor, type);
-      }
-    }
-  }
-
-  ConstructorResult visitNewExpression(NewExpression node) {
-    Node selector = node.send.selector;
-    ConstructorResult result = visit(selector);
-    assert(result != null,
-        failedAt(selector, 'No result returned for $selector.'));
-    return finishConstructorReference(result, node.send.selector, node);
-  }
-
-  /// Finishes resolution of a constructor reference and records the
-  /// type of the constructed instance on [expression].
-  ConstructorResult finishConstructorReference(
-      ConstructorResult result, Node diagnosticNode, Node expression) {
-    assert(result != null,
-        failedAt(diagnosticNode, 'No result returned for $diagnosticNode.'));
-
-    if (result.kind != null) {
-      resolver.registry.setType(expression, result.type);
-      return result;
-    }
-
-    // Find the unnamed constructor if the reference resolved to a
-    // class.
-    if (result.type != null) {
-      // The unnamed constructor may not exist, so [e] may become unresolved.
-      result =
-          resolveConstructor(result.prefix, result.type, diagnosticNode, '');
-    } else {
-      Element element = result.element;
-      if (element.isMalformed) {
-        result = constructorResultForErroneous(diagnosticNode, element);
-      } else {
-        result = reportAndCreateErroneousConstructorElement(
-            diagnosticNode,
-            ConstructorResultKind.INVALID_TYPE,
-            null,
-            element.name,
-            MessageKind.NOT_A_TYPE,
-            {'node': diagnosticNode});
-      }
-    }
-    resolver.registry.setType(expression, result.type);
-    return result;
-  }
-
-  ConstructorResult visitNominalTypeAnnotation(NominalTypeAnnotation node) {
-    // This is not really resolving a type-annotation, but the name of the
-    // constructor. Therefore we allow deferred types.
-    ResolutionDartType type = resolver.resolveTypeAnnotation(node,
-        malformedIsError: inConstContext,
-        deferredIsMalformed: false,
-        registerCheckedModeCheck: false);
-    Send send = node.typeName.asSend();
-    PrefixElement prefix;
-    if (send != null) {
-      // The type name is of the form [: prefix . identifier :].
-      String name = send.receiver.asIdentifier().source;
-      Element element = lookupInScope(reporter, send, resolver.scope, name);
-      if (element != null && element.isPrefix) {
-        prefix = element;
-      }
-    }
-    return constructorResultForType(node, type, prefix: prefix);
-  }
-
-  ConstructorResult visitSend(Send node) {
-    ConstructorResult receiver = visit(node.receiver);
-    assert(receiver != null,
-        failedAt(node.receiver, 'No result returned for $node.receiver.'));
-    if (receiver.kind != null) {
-      assert(receiver.element.isMalformed,
-          failedAt(node, "Unexpected prefix result: $receiver."));
-      // We have already found an error.
-      return receiver;
-    }
-
-    Identifier name = node.selector.asIdentifier();
-    if (name == null) {
-      reporter.internalError(node.selector, 'unexpected node');
-    }
-
-    if (receiver.type != null) {
-      if (receiver.type.isInterfaceType) {
-        return resolveConstructor(
-            receiver.prefix, receiver.type, name, name.source);
-      } else {
-        // TODO(johnniwinther): Update the message for the different types.
-        return reportAndCreateErroneousConstructorElement(
-            name,
-            ConstructorResultKind.INVALID_TYPE,
-            null,
-            name.source,
-            MessageKind.NOT_A_TYPE,
-            {'node': name});
-      }
-    } else if (receiver.element.isPrefix) {
-      PrefixElement prefix = receiver.element;
-      Element member = prefix.lookupLocalMember(name.source);
-      return constructorResultForElement(node, name.source, member,
-          prefix: prefix);
-    } else {
-      return reporter.internalError(
-          node.receiver, 'unexpected receiver $receiver');
-    }
-  }
-
-  ConstructorResult visitIdentifier(Identifier node) {
-    String name = node.source;
-    Element element = lookupInScope(reporter, node, resolver.scope, name);
-    registry.useElement(node, element);
-    return constructorResultForElement(node, name, element);
-  }
-
-  /// Assumed to be called by [resolveRedirectingFactory].
-  ConstructorResult visitRedirectingFactoryBody(RedirectingFactoryBody node) {
-    Node constructorReference = node.constructorReference;
-    return finishConstructorReference(
-        visit(constructorReference), constructorReference, node);
-  }
-
-  ConstructorResult constructorResultForElement(
-      Node node, String name, Element element,
-      {PrefixElement prefix}) {
-    element = Elements.unwrap(element, reporter, node);
-    if (element == null) {
-      return reportAndCreateErroneousConstructorElement(
-          node,
-          ConstructorResultKind.INVALID_TYPE,
-          null,
-          name,
-          MessageKind.CANNOT_RESOLVE,
-          {'name': name});
-    } else if (element.isAmbiguous) {
-      AmbiguousElement ambiguous = element;
-      return reportAndCreateErroneousConstructorElement(
-          node,
-          ConstructorResultKind.INVALID_TYPE,
-          null,
-          name,
-          ambiguous.messageKind,
-          ambiguous.messageArguments,
-          infos: ambiguous.computeInfos(context, reporter));
-    } else if (element.isMalformed) {
-      return constructorResultForErroneous(node, element);
-    } else if (element.isClass) {
-      ClassElement cls = element;
-      cls.computeType(resolution);
-      return constructorResultForType(node, cls.rawType, prefix: prefix);
-    } else if (element.isPrefix) {
-      return new ConstructorResult.forPrefix(element);
-    } else if (element.isTypedef) {
-      TypedefElement typdef = element;
-      typdef.ensureResolved(resolution);
-      return constructorResultForType(node, typdef.rawType);
-    } else if (element.isTypeVariable) {
-      TypeVariableElement typeVariableElement = element;
-      return constructorResultForType(node, typeVariableElement.type);
-    } else {
-      return reportAndCreateErroneousConstructorElement(
-          node,
-          ConstructorResultKind.INVALID_TYPE,
-          null,
-          name,
-          MessageKind.NOT_A_TYPE,
-          {'node': name});
-    }
-  }
-
-  ConstructorResult constructorResultForErroneous(Node node, Element error) {
-    if (error is! ErroneousElementX) {
-      // Parser error. The error has already been reported.
-      error = new ErroneousConstructorElementX(
-          MessageKind.NOT_A_TYPE, {'node': node}, error.name, error);
-      registry.registerFeature(Feature.THROW_RUNTIME_ERROR);
-    }
-    return new ConstructorResult.forError(ConstructorResultKind.INVALID_TYPE,
-        error, new MalformedType(error, null));
-  }
-
-  ConstructorResult constructorResultForType(Node node, ResolutionDartType type,
-      {PrefixElement prefix}) {
-    String name = type.name;
-    if (type.isTypeVariable) {
-      return reportAndCreateErroneousConstructorElement(
-          node,
-          ConstructorResultKind.INVALID_TYPE,
-          type,
-          name,
-          MessageKind.CANNOT_INSTANTIATE_TYPE_VARIABLE,
-          {'typeVariableName': name});
-    } else if (type.isMalformed) {
-      // `type is MalformedType`: `MethodTypeVariableType` is handled above.
-      return new ConstructorResult.forError(
-          ConstructorResultKind.INVALID_TYPE, type.element, type);
-    } else if (type.isInterfaceType) {
-      return new ConstructorResult.forType(prefix, type);
-    } else if (type.isTypedef) {
-      return reportAndCreateErroneousConstructorElement(
-          node,
-          ConstructorResultKind.INVALID_TYPE,
-          type,
-          name,
-          MessageKind.CANNOT_INSTANTIATE_TYPEDEF,
-          {'typedefName': name});
-    }
-    return reporter.internalError(node, "Unexpected constructor type $type");
-  }
-}
-
-/// The kind of constructor found by the [ConstructorResolver].
-enum ConstructorResultKind {
-  /// A generative or redirecting generative constructor.
-  GENERATIVE,
-
-  /// A factory or redirecting factory constructor.
-  FACTORY,
-
-  /// A generative or redirecting generative constructor on an abstract class.
-  ABSTRACT,
-
-  /// No constructor was found because the type was invalid, for instance
-  /// unresolved, an enum class, a type variable, a typedef or a non-type.
-  INVALID_TYPE,
-
-  /// No constructor of the sought name was found on the class.
-  UNRESOLVED_CONSTRUCTOR,
-
-  /// A non-constant constructor was found for a const constructor invocation.
-  NON_CONSTANT,
-}
-
-/// The (partial) result of the resolution of a new expression used in
-/// [ConstructorResolver].
-class ConstructorResult {
-  /// The prefix used to access the constructor. For instance `prefix` in `new
-  /// prefix.Class.constructorName()`.
-  final PrefixElement prefix;
-
-  /// The kind of the found constructor.
-  final ConstructorResultKind kind;
-
-  /// The currently found element. Since [ConstructorResult] is used for partial
-  /// results, this might be a [PrefixElement], a [ClassElement], a
-  /// [ConstructorElement] or in the negative cases an [ErroneousElement].
-  final Element element;
-
-  /// The type of the new expression. For instance `Foo<String>` in
-  /// `new prefix.Foo<String>.constructorName()`.
-  final ResolutionDartType type;
-
-  /// Creates a fully resolved constructor access where [element] is resolved
-  /// to a constructor and [type] to an interface type.
-  ConstructorResult(this.kind, this.prefix, ConstructorElement this.element,
-      ResolutionInterfaceType this.type);
-
-  /// Creates a fully resolved constructor access where [element] is an
-  /// [ErroneousElement].
-  // TODO(johnniwinther): Do we still need the prefix for cases like
-  // `new deferred.Class.unresolvedConstructor()` ?
-  ConstructorResult.forError(
-      this.kind, ErroneousElement this.element, this.type)
-      : prefix = null;
-
-  /// Creates a constructor access that is partially resolved to a prefix. For
-  /// instance `prefix` of `new prefix.Class()`.
-  ConstructorResult.forPrefix(this.element)
-      : prefix = null,
-        kind = null,
-        type = null;
-
-  /// Creates a constructor access that is partially resolved to a type. For
-  /// instance `Foo<String>` of `new Foo<String>.constructorName()`.
-  ConstructorResult.forType(this.prefix, this.type)
-      : kind = null,
-        element = null;
-
-  bool get isDeferred => prefix != null && prefix.isDeferred;
-
-  String toString() {
-    StringBuffer sb = new StringBuffer();
-    sb.write('ConstructorResult(');
-    if (kind != null) {
-      sb.write('kind=$kind,');
-      if (prefix != null) {
-        sb.write('prefix=$prefix,');
-      }
-      sb.write('element=$element,');
-      sb.write('type=$type');
-    } else if (element != null) {
-      sb.write('element=$element');
-    } else {
-      if (prefix != null) {
-        sb.write('prefix=$prefix,');
-      }
-      sb.write('type=$type');
-    }
-    sb.write(')');
-    return sb.toString();
-  }
-}
-
-/// Lookup the [constructorName] constructor in [cls] and normalize the result
-/// with respect to privacy and patching.
-ConstructorElement findConstructor(
-    LibraryElement currentLibrary, ClassElement cls, String constructorName) {
-  if (Name.isPrivateName(constructorName) &&
-      currentLibrary.library != cls.library) {
-    // TODO(johnniwinther): Report a special error on unaccessible private
-    // constructors.
-    return null;
-  }
-  // TODO(johnniwinther): Use [Name] for lookup.
-  ConstructorElement constructor = cls.lookupConstructor(constructorName);
-  if (constructor != null) {
-    constructor = constructor.declaration;
-  }
-  return constructor;
-}
diff --git a/pkg/compiler/lib/src/resolution/deferred_load.dart b/pkg/compiler/lib/src/resolution/deferred_load.dart
deleted file mode 100644
index e826a25..0000000
--- a/pkg/compiler/lib/src/resolution/deferred_load.dart
+++ /dev/null
@@ -1,376 +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.
-
-library resolution.deferred_load;
-
-import '../common.dart';
-import '../compiler.dart' show Compiler;
-import '../constants/expressions.dart' show ConstantExpression;
-import '../constants/values.dart'
-    show ConstantValue, ConstructedConstantValue, StringConstantValue;
-import '../deferred_load.dart';
-import '../elements/elements.dart'
-    show
-        AstElement,
-        AccessorElement,
-        ClassElement,
-        ConstructorElement,
-        Element,
-        ExportElement,
-        ImportElement,
-        LibraryElement,
-        MemberElement,
-        MetadataAnnotation,
-        PrefixElement,
-        ResolvedAstKind,
-        TypedefElement;
-import '../elements/resolution_types.dart';
-import '../js_backend/js_backend.dart' show JavaScriptBackend;
-import '../resolution/resolution.dart' show AnalyzableElementX;
-import '../resolution/tree_elements.dart' show TreeElements;
-import '../tree/tree.dart' as ast;
-import '../util/util.dart' show Setlet;
-import 'tree_elements.dart' show TreeElements;
-
-class AstDeferredLoadTask extends DeferredLoadTask {
-  /// DeferredLibrary from dart:async
-  ClassElement get deferredLibraryClass =>
-      compiler.resolution.commonElements.deferredLibraryClass;
-
-  JavaScriptBackend get backend => compiler.backend;
-
-  AstDeferredLoadTask(Compiler compiler) : super(compiler);
-
-  Iterable<ImportElement> importsTo(
-      covariant Element element, covariant LibraryElement library) {
-    if (element.isClassMember) {
-      element = element.enclosingClass;
-    }
-    if (element.isAccessor) {
-      element = (element as AccessorElement).abstractField;
-    }
-    return library.getImportsFor(element);
-  }
-
-  void checkForDeferredErrorCases(covariant LibraryElement library) {
-    var usedPrefixes = new Setlet<String>();
-    // The last deferred import we saw with a given prefix (if any).
-    var prefixDeferredImport = new Map<String, ImportElement>();
-    for (ImportElement import in library.imports) {
-      _detectOldSyntax(import);
-      _detectDuplicateErrorCases(import, usedPrefixes, prefixDeferredImport);
-    }
-  }
-
-  /// Give an error if the old annotation-based syntax has been used.
-  void _detectOldSyntax(ImportElement import) {
-    List<MetadataAnnotation> metadataList = import.metadata;
-    if (metadataList != null) {
-      for (MetadataAnnotation metadata in metadataList) {
-        metadata.ensureResolved(compiler.resolution);
-        ConstantValue value =
-            compiler.constants.getConstantValue(metadata.constant);
-        ResolutionDartType type =
-            value.getType(compiler.resolution.commonElements);
-        Element element = type.element;
-        if (element == deferredLibraryClass) {
-          reporter.reportErrorMessage(import, MessageKind.DEFERRED_OLD_SYNTAX);
-        }
-      }
-    }
-  }
-
-  /// Detect duplicate prefixes of deferred libraries.
-  ///
-  /// There are 4 cases of duplicate prefixes:
-  ///   1.
-  ///       import "lib.dart" deferred as a;
-  ///       import "lib2.dart" deferred as a;
-  ///
-  ///   2.
-  ///       import "lib.dart" deferred as a;
-  ///       import "lib2.dart" as a;
-  ///
-  ///   3.
-  ///       import "lib.dart" as a;
-  ///       import "lib2.dart" deferred as a;
-  ///
-  ///   4.
-  ///       import "lib.dart" as a;
-  ///       import "lib2.dart" as a;
-  ///
-  /// We must be able to signal error for case 1, 2, 3, but accept case 4.
-  void _detectDuplicateErrorCases(
-      ImportElement import,
-      Set<String> usedPrefixes,
-      Map<String, ImportElement> prefixDeferredImport) {
-    String prefix = import.name;
-    // The last import we saw with the same prefix.
-    ImportElement previousDeferredImport = prefixDeferredImport[prefix];
-    if (import.isDeferred) {
-      if (prefix == null) {
-        reporter.reportErrorMessage(
-            import, MessageKind.DEFERRED_LIBRARY_WITHOUT_PREFIX);
-      } else {
-        prefixDeferredImport[prefix] = import;
-      }
-    }
-    if (prefix != null) {
-      if (previousDeferredImport != null ||
-          (import.isDeferred && usedPrefixes.contains(prefix))) {
-        ImportElement failingImport =
-            (previousDeferredImport != null) ? previousDeferredImport : import;
-        reporter.reportErrorMessage(failingImport.prefix,
-            MessageKind.DEFERRED_LIBRARY_DUPLICATE_PREFIX);
-      }
-      usedPrefixes.add(prefix);
-    }
-  }
-
-  @override
-  void collectConstantsFromMetadata(
-      covariant AstElement element, Set<ConstantValue> constants) {
-    for (MetadataAnnotation metadata in element.metadata) {
-      ConstantValue constant =
-          backend.constants.getConstantValueForMetadata(metadata);
-      if (constant != null) constants.add(constant);
-    }
-  }
-
-  @override
-  void collectConstantsInBody(
-      covariant AstElement element, Set<ConstantValue> constants) {
-    if (element.resolvedAst.kind != ResolvedAstKind.PARSED) return;
-
-    TreeElements treeElements = element.resolvedAst.elements;
-    assert(treeElements != null);
-
-    Set<ast.Node> metadataNodes = element.implementation.metadata
-        .map((m) => m.node)
-        .toSet()
-          ..addAll(element.declaration.metadata.map((m) => m.node));
-
-    // TODO(johnniwinther): Add only expressions that are actually needed.
-    // Currently we have some noise here: Some potential expressions are
-    // seen that should never be added (for instance field initializers
-    // in constant constructors, like `this.field = parameter`). And some
-    // implicit constant expression are seen that we should be able to add
-    // (like primitive constant literals like `true`, `"foo"` and `0`).
-    // See dartbug.com/26406 for context.
-    treeElements
-        .forEachConstantNode((ast.Node node, ConstantExpression expression) {
-      if (metadataNodes.contains(node)) return;
-
-      // Explicitly depend on the backend constants.
-      if (backend.constants.hasConstantValue(expression)) {
-        ConstantValue value = backend.constants.getConstantValue(expression);
-        assert(
-            value != null,
-            failedAt(
-                node,
-                "Constant expression without value: "
-                "${expression.toStructuredText()}."));
-        constants.add(value);
-      } else {
-        assert(
-            expression.isImplicit || expression.isPotential,
-            failedAt(
-                node,
-                "Unexpected unevaluated constant expression: "
-                "${expression.toStructuredText()}."));
-      }
-    });
-  }
-
-  void addDeferredMirrorElements(WorkQueue queue) {
-    for (ImportElement deferredImport in allDeferredImports) {
-      addMirrorElementsForLibrary(queue, deferredImport.importedLibrary,
-          importSets.singleton(deferredImport));
-    }
-  }
-
-  void addMirrorElementsForLibrary(
-      WorkQueue queue, covariant LibraryElement root, ImportSet newSet) {
-    void handleElementIfResolved(Element element) {
-      // If an element is the target of a MirrorsUsed annotation but never used
-      // It will not be resolved, and we should not call isNeededForReflection.
-      // TODO(sigurdm): Unresolved elements should just answer false when
-      // asked isNeededForReflection. Instead an internal error is triggered.
-      // So we have to filter them out here.
-      if (element is AnalyzableElementX && !element.hasTreeElements) return;
-
-      bool isAccessibleByReflection(Element element) {
-        if (element.isLibrary) {
-          return false;
-        } else if (element.isClass) {
-          ClassElement cls = element;
-          return compiler.backend.mirrorsData
-              .isClassAccessibleByReflection(cls);
-        } else if (element.isTypedef) {
-          TypedefElement typedef = element;
-          return compiler.backend.mirrorsData
-              .isTypedefAccessibleByReflection(typedef);
-        } else {
-          MemberElement member = element;
-          return compiler.backend.mirrorsData
-              .isMemberAccessibleByReflection(member);
-        }
-      }
-
-      if (isAccessibleByReflection(element)) {
-        queue.addElement(element, newSet, isMirrorUsage: true);
-      }
-    }
-
-    // For each deferred import we analyze all elements reachable from the
-    // imported library through non-deferred imports.
-    void handleLibrary(LibraryElement library) {
-      library.implementation.forEachLocalMember((Element element) {
-        handleElementIfResolved(element);
-      });
-
-      void processMetadata(Element element) {
-        for (MetadataAnnotation metadata in element.metadata) {
-          ConstantValue constant =
-              backend.constants.getConstantValueForMetadata(metadata);
-          if (constant != null) {
-            queue.addConstant(constant, newSet);
-          }
-        }
-      }
-
-      processMetadata(library);
-      library.imports.forEach(processMetadata);
-      library.exports.forEach(processMetadata);
-    }
-
-    _nonDeferredReachableLibraries(root).forEach(handleLibrary);
-  }
-
-  /// Returns the transitive closure of all libraries that are imported
-  /// from root without DeferredLibrary annotations.
-  Set<LibraryElement> _nonDeferredReachableLibraries(LibraryElement root) {
-    Set<LibraryElement> result = new Set<LibraryElement>();
-
-    void traverseLibrary(LibraryElement library) {
-      if (result.contains(library)) return;
-      result.add(library);
-
-      iterateDependencies(LibraryElement library) {
-        for (ImportElement import in library.imports) {
-          if (!import.isDeferred) {
-            LibraryElement importedLibrary = import.importedLibrary;
-            traverseLibrary(importedLibrary);
-          }
-        }
-        for (ExportElement export in library.exports) {
-          LibraryElement exportedLibrary = export.exportedLibrary;
-          traverseLibrary(exportedLibrary);
-        }
-      }
-
-      iterateDependencies(library);
-      if (library.isPatched) {
-        iterateDependencies(library.implementation);
-      }
-    }
-
-    traverseLibrary(root);
-    result.add(compiler.resolution.commonElements.coreLibrary);
-    return result;
-  }
-
-  /// If [send] is a static send with a deferred element, returns the
-  /// [PrefixElement] that the first prefix of the send resolves to.
-  /// Otherwise returns null.
-  ///
-  /// Precondition: send must be static.
-  ///
-  /// Example:
-  ///
-  /// import "a.dart" deferred as a;
-  ///
-  /// main() {
-  ///   print(a.loadLibrary.toString());
-  ///   a.loadLibrary().then((_) {
-  ///     a.run();
-  ///     a.foo.method();
-  ///   });
-  /// }
-  ///
-  /// Returns null for a.loadLibrary() (the special
-  /// function loadLibrary is not deferred). And returns the PrefixElement for
-  /// a.run() and a.foo.
-  /// a.loadLibrary.toString() and a.foo.method() are dynamic sends - and
-  /// this functions should not be called on them.
-  ImportElement deferredImportElement(ast.Send send, TreeElements elements) {
-    Element element = elements[send];
-    // The DeferredLoaderGetter is not deferred, therefore we do not return the
-    // prefix.
-    if (element != null && element.isDeferredLoaderGetter) return null;
-
-    ast.Node firstNode(ast.Node node) {
-      if (node is! ast.Send) {
-        return node;
-      } else {
-        ast.Send send = node;
-        ast.Node receiver = send.receiver;
-        ast.Node receiverFirst = firstNode(receiver);
-        if (receiverFirst != null) {
-          return receiverFirst;
-        } else {
-          return firstNode(send.selector);
-        }
-      }
-    }
-
-    ast.Node first = firstNode(send);
-    ast.Node identifier = first.asIdentifier();
-    if (identifier == null) return null;
-    Element maybePrefix = elements[identifier];
-    if (maybePrefix != null && maybePrefix.isPrefix) {
-      PrefixElement prefixElement = maybePrefix;
-      if (prefixElement.isDeferred) {
-        return prefixElement.deferredImport;
-      }
-    }
-    return null;
-  }
-
-  /// Returns a name for a deferred import.
-  // TODO(sigmund): delete support for the old annotation-style syntax.
-  String computeImportDeferName(
-      covariant ImportElement declaration, Compiler compiler) {
-    if (declaration.isDeferred) {
-      return super.computeImportDeferName(declaration, compiler);
-    }
-
-    String result;
-    // Finds the first argument to the [DeferredLibrary] annotation
-    List<MetadataAnnotation> metadatas = declaration.metadata;
-    assert(metadatas != null);
-    for (MetadataAnnotation metadata in metadatas) {
-      metadata.ensureResolved(compiler.resolution);
-      ConstantValue value =
-          compiler.constants.getConstantValue(metadata.constant);
-      ResolutionDartType type =
-          value.getType(compiler.resolution.commonElements);
-      Element element = type.element;
-      if (element == compiler.resolution.commonElements.deferredLibraryClass) {
-        ConstructedConstantValue constant = value;
-        StringConstantValue s = constant.fields.values.single;
-        result = s.stringValue;
-        break;
-      }
-    }
-    assert(result != null);
-    return result;
-  }
-
-  bool ignoreEntityInDump(covariant Element element) =>
-      // origin element will already be dumped.
-      element.isPatch ||
-      // redirecting factories are not visible to the kernel ir
-      element is ConstructorElement && element.isRedirectingFactory;
-}
diff --git a/pkg/compiler/lib/src/resolution/enum_creator.dart b/pkg/compiler/lib/src/resolution/enum_creator.dart
deleted file mode 100644
index 72781d4..0000000
--- a/pkg/compiler/lib/src/resolution/enum_creator.dart
+++ /dev/null
@@ -1,359 +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.
-
-library dart2js.resolution.enum_creator;
-
-import '../common.dart';
-import '../common_elements.dart' show CommonElements;
-import '../elements/resolution_types.dart';
-import '../elements/elements.dart';
-import '../elements/modelx.dart';
-import 'package:front_end/src/fasta/scanner.dart';
-import 'package:front_end/src/scanner/token.dart' show KeywordToken, TokenType;
-import '../tree/tree.dart';
-import '../util/util.dart';
-
-// TODO(johnniwinther): Merge functionality with the `TreePrinter`.
-class AstBuilder {
-  final int charOffset;
-
-  AstBuilder(this.charOffset);
-
-  Modifiers modifiers(
-      {bool isConst: false, bool isFinal: false, bool isStatic: false}) {
-    List identifiers = [];
-    int flags = 0;
-    if (isConst) {
-      identifiers.add(identifier('const'));
-      flags |= Modifiers.FLAG_CONST;
-    }
-    if (isFinal) {
-      identifiers.add(identifier('final'));
-      flags |= Modifiers.FLAG_FINAL;
-    }
-    if (isStatic) {
-      identifiers.add(identifier('static'));
-      flags |= Modifiers.FLAG_STATIC;
-    }
-    return new Modifiers.withFlags(
-        new NodeList(null, linkedList(identifiers), null, ''), flags);
-  }
-
-  Token keywordToken(String text) {
-    return new KeywordToken(Keyword.keywords[text], charOffset);
-  }
-
-  Token stringToken(String text) {
-    return new StringToken.fromString(TokenType.IDENTIFIER, text, charOffset);
-  }
-
-  Token symbolToken(TokenType type) {
-    return new Token(type, charOffset);
-  }
-
-  Identifier identifier(String text) {
-    Keyword keyword = Keyword.keywords[text];
-    Token token;
-    if (keyword != null) {
-      token = new KeywordToken(keyword, charOffset);
-    } else {
-      token = stringToken(text);
-    }
-    return new Identifier(token);
-  }
-
-  Link linkedList(List elements) {
-    LinkBuilder builder = new LinkBuilder();
-    elements.forEach((e) => builder.addLast(e));
-    return builder.toLink();
-  }
-
-  NodeList argumentList(List<Node> nodes) {
-    return new NodeList(symbolToken(TokenType.OPEN_PAREN), linkedList(nodes),
-        symbolToken(TokenType.CLOSE_PAREN), ',');
-  }
-
-  Return returnStatement(Expression expression) {
-    return new Return(
-        keywordToken('return'), symbolToken(TokenType.SEMICOLON), expression);
-  }
-
-  FunctionExpression functionExpression(Modifiers modifiers, String name,
-      NodeList typeVariables, NodeList argumentList, Statement body,
-      [TypeAnnotation returnType]) {
-    return new FunctionExpression(
-        identifier(name),
-        typeVariables,
-        argumentList,
-        body,
-        returnType,
-        modifiers,
-        null, // Initializer.
-        null, // get/set.
-        null // Async modifier.
-        );
-  }
-
-  EmptyStatement emptyStatement() {
-    return new EmptyStatement(symbolToken(TokenType.COMMA));
-  }
-
-  LiteralInt literalInt(int value) {
-    return new LiteralInt(stringToken('$value'), null);
-  }
-
-  LiteralString literalString(String text,
-      {String prefix: '"', String suffix: '"'}) {
-    return new LiteralString(
-        stringToken('$prefix$text$suffix'), new DartString.literal(text));
-  }
-
-  LiteralList listLiteral(List<Node> elements, {bool isConst: false}) {
-    return new LiteralList(
-        null,
-        new NodeList(
-            symbolToken(TokenType.OPEN_SQUARE_BRACKET),
-            linkedList(elements),
-            symbolToken(TokenType.CLOSE_SQUARE_BRACKET),
-            ','),
-        isConst ? keywordToken('const') : null);
-  }
-
-  Node createDefinition(Identifier name, Expression initializer) {
-    if (initializer == null) return name;
-    return new SendSet(null, name, new Operator(symbolToken(TokenType.EQ)),
-        new NodeList.singleton(initializer));
-  }
-
-  VariableDefinitions initializingFormal(String fieldName) {
-    return new VariableDefinitions.forParameter(
-        new NodeList.empty(),
-        null,
-        Modifiers.EMPTY,
-        new NodeList.singleton(
-            new Send(identifier('this'), identifier(fieldName))));
-  }
-
-  NewExpression newExpression(String typeName, NodeList arguments,
-      {bool isConst: false}) {
-    return new NewExpression(keywordToken(isConst ? 'const' : 'new'),
-        new Send(null, identifier(typeName), arguments));
-  }
-
-  Send reference(Identifier identifier) {
-    return new Send(null, identifier);
-  }
-
-  Send indexGet(Expression receiver, Expression index) {
-    return new Send(receiver, new Operator(symbolToken(TokenType.INDEX)),
-        new NodeList.singleton(index));
-  }
-
-  LiteralMapEntry mapLiteralEntry(Expression key, Expression value) {
-    return new LiteralMapEntry(key, symbolToken(TokenType.COLON), value);
-  }
-
-  LiteralMap mapLiteral(List<LiteralMapEntry> entries, {bool isConst: false}) {
-    return new LiteralMap(
-        null, // Type arguments.
-        new NodeList(
-            symbolToken(TokenType.OPEN_CURLY_BRACKET),
-            linkedList(entries),
-            symbolToken(TokenType.CLOSE_CURLY_BRACKET),
-            ','),
-        isConst ? keywordToken('const') : null);
-  }
-}
-
-/// This class generates the model for an enum class.
-///
-/// For instance
-///
-///     enum A { b, c, }
-///
-/// is modelled as
-///
-///     class A {
-///       final int index;
-///       final String _name;
-///
-///       const A(this.index);
-///
-///       String toString() {
-///         return _name;
-///       }
-///
-///       static const A b = const A(0, "A.b");
-///       static const A c = const A(1, "A.v");
-///
-///       static const List<A> values = const <A>[b, c];
-///     }
-///
-// TODO(johnniwinther): Avoid creating synthesized ASTs for enums when SSA is
-// removed.
-class EnumCreator {
-  final DiagnosticReporter reporter;
-  final CommonElements commonElements;
-  final EnumClassElementX enumClass;
-
-  EnumCreator(this.reporter, this.commonElements, this.enumClass);
-
-  /// Whether to use a constant-map to encode the result of toString on an enum
-  /// value.
-  ///
-  /// Dart2js by default uses a compact representation of enum values that
-  /// include their name. The spec and the kernel-based implementation use a
-  /// const-map to encode the result of toString. This flag is used to disable
-  /// the default representation, and instead match the kernel representation to
-  /// make it easier to test the equivalence of resolution-based and
-  /// kernel-based world builders.
-  static bool matchKernelRepresentationForTesting = false;
-
-  void createMembers() {
-    Enum node = enumClass.node;
-    ResolutionInterfaceType enumType = enumClass.thisType;
-    AstBuilder builder = new AstBuilder(enumClass.position.charOffset);
-
-    ResolutionInterfaceType intType = commonElements.intType;
-    ResolutionInterfaceType stringType = commonElements.stringType;
-
-    EnumFieldElementX addInstanceMember(
-        String name, ResolutionInterfaceType type) {
-      Identifier identifier = builder.identifier(name);
-      VariableList variableList =
-          new VariableList(builder.modifiers(isFinal: true));
-      variableList.type = type;
-      EnumFieldElementX variable = new EnumFieldElementX(
-          identifier, enumClass, variableList, identifier);
-      enumClass.addMember(variable, reporter);
-      return variable;
-    }
-
-    EnumFieldElementX indexVariable = addInstanceMember('index', intType);
-    EnumFieldElementX nameVariable;
-
-    VariableDefinitions indexDefinition = builder.initializingFormal('index');
-    VariableDefinitions nameDefinition;
-
-    List<Node> constructorInitializers = <Node>[indexDefinition];
-    if (!matchKernelRepresentationForTesting) {
-      nameVariable = addInstanceMember('_name', stringType);
-      nameDefinition = builder.initializingFormal('_name');
-      constructorInitializers.add(nameDefinition);
-    }
-    FunctionExpression constructorNode = builder.functionExpression(
-        builder.modifiers(isConst: true),
-        enumClass.name,
-        null, // typeVariables
-        builder.argumentList(constructorInitializers),
-        builder.emptyStatement());
-
-    EnumConstructorElementX constructor = new EnumConstructorElementX(
-        enumClass, builder.modifiers(isConst: true), constructorNode);
-
-    EnumFormalElementX indexFormal = new EnumFormalElementX(constructor,
-        indexDefinition, builder.identifier('index'), indexVariable);
-
-    EnumFormalElementX nameFormal;
-
-    List<FormalElement> parameters = <FormalElement>[indexFormal];
-    List<ResolutionDartType> parameterTypes = <ResolutionDartType>[intType];
-    if (!matchKernelRepresentationForTesting) {
-      nameFormal = new EnumFormalElementX(constructor, nameDefinition,
-          builder.identifier('_name'), nameVariable);
-      parameters.add(nameFormal);
-      parameterTypes.add(stringType);
-    }
-    FunctionSignatureX constructorSignature = new FunctionSignatureX(
-        requiredParameters: parameters,
-        requiredParameterCount: parameters.length,
-        type: new ResolutionFunctionType(
-            constructor, const ResolutionDynamicType(), parameterTypes));
-    constructor.functionSignature = constructorSignature;
-    enumClass.addMember(constructor, reporter);
-
-    List<EnumConstantElement> enumValues = <EnumConstantElement>[];
-    int index = 0;
-    List<Node> valueReferences = <Node>[];
-    List<LiteralMapEntry> mapEntries;
-    if (matchKernelRepresentationForTesting) {
-      mapEntries = <LiteralMapEntry>[];
-    }
-    for (Link<Node> link = node.names.nodes; !link.isEmpty; link = link.tail) {
-      Identifier name = link.head;
-      AstBuilder valueBuilder = new AstBuilder(name.token.charOffset);
-      VariableList variableList = new VariableList(
-          valueBuilder.modifiers(isStatic: true, isConst: true));
-      variableList.type = enumType;
-
-      // Add reference for the `values` field.
-      valueReferences.add(valueBuilder.reference(name));
-
-      Node indexValue = valueBuilder.literalInt(index);
-      Node nameValue =
-          valueBuilder.literalString('${enumClass.name}.${name.source}');
-      Expression initializer;
-      if (matchKernelRepresentationForTesting) {
-        // Add map entry for `toString` implementation.
-        mapEntries.add(valueBuilder.mapLiteralEntry(indexValue, nameValue));
-
-        initializer = valueBuilder.newExpression(
-            enumClass.name, valueBuilder.argumentList([indexValue]),
-            isConst: true);
-      } else {
-        initializer = valueBuilder.newExpression(
-            enumClass.name, valueBuilder.argumentList([indexValue, nameValue]),
-            isConst: true);
-      }
-      SendSet definition = valueBuilder.createDefinition(name, initializer);
-
-      EnumConstantElementX field = new EnumConstantElementX(
-          name, enumClass, variableList, definition, initializer, index);
-      enumValues.add(field);
-      enumClass.addMember(field, reporter);
-      index++;
-    }
-
-    VariableList valuesVariableList =
-        new VariableList(builder.modifiers(isStatic: true, isConst: true));
-    ResolutionInterfaceType valuesType = commonElements.listType(enumType);
-    valuesVariableList.type = valuesType;
-
-    Identifier valuesIdentifier = builder.identifier('values');
-    // TODO(28340): Add type argument.
-    Expression initializer =
-        builder.listLiteral(valueReferences, isConst: true);
-
-    Node definition = builder.createDefinition(valuesIdentifier, initializer);
-
-    EnumFieldElementX valuesVariable = new EnumFieldElementX(valuesIdentifier,
-        enumClass, valuesVariableList, definition, initializer);
-
-    enumClass.addMember(valuesVariable, reporter);
-
-    Node toStringValue;
-    if (matchKernelRepresentationForTesting) {
-      toStringValue = builder.indexGet(
-          builder.mapLiteral(mapEntries, isConst: true),
-          builder.reference(builder.identifier('index')));
-    } else {
-      toStringValue = builder.reference(builder.identifier('_name'));
-    }
-    FunctionExpression toStringNode = builder.functionExpression(
-        Modifiers.EMPTY,
-        'toString',
-        null, // typeVariables
-        builder.argumentList([]),
-        builder.returnStatement(toStringValue));
-
-    EnumMethodElementX toString = new EnumMethodElementX(
-        'toString', enumClass, Modifiers.EMPTY, toStringNode);
-    FunctionSignatureX toStringSignature = new FunctionSignatureX(
-        type: new ResolutionFunctionType(toString, stringType));
-    toString.functionSignature = toStringSignature;
-    enumClass.addMember(toString, reporter);
-
-    enumClass.enumValues = enumValues;
-  }
-}
diff --git a/pkg/compiler/lib/src/resolution/label_scope.dart b/pkg/compiler/lib/src/resolution/label_scope.dart
deleted file mode 100644
index beb888c..0000000
--- a/pkg/compiler/lib/src/resolution/label_scope.dart
+++ /dev/null
@@ -1,104 +0,0 @@
-// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library dart2js.resolution.label_scope;
-
-import '../elements/jumps.dart';
-import '../util/util.dart' show Link;
-
-abstract class LabelScope {
-  LabelScope get outer;
-  LabelDefinition lookup(String label);
-}
-
-class LabeledStatementLabelScope implements LabelScope {
-  final LabelScope outer;
-  final Map<String, LabelDefinition> labels;
-  LabeledStatementLabelScope(this.outer, this.labels);
-  LabelDefinition lookup(String labelName) {
-    LabelDefinition label = labels[labelName];
-    if (label != null) return label;
-    return outer.lookup(labelName);
-  }
-}
-
-class SwitchLabelScope implements LabelScope {
-  final LabelScope outer;
-  final Map<String, LabelDefinition> caseLabels;
-
-  SwitchLabelScope(this.outer, this.caseLabels);
-
-  LabelDefinition lookup(String labelName) {
-    LabelDefinition result = caseLabels[labelName];
-    if (result != null) return result;
-    return outer.lookup(labelName);
-  }
-}
-
-class EmptyLabelScope implements LabelScope {
-  const EmptyLabelScope();
-  LabelDefinition lookup(String label) => null;
-  LabelScope get outer {
-    throw 'internal error: empty label scope has no outer';
-  }
-}
-
-class StatementScope {
-  LabelScope labels;
-  Link<JumpTarget> breakTargetStack;
-  Link<JumpTarget> continueTargetStack;
-  // Used to provide different numbers to statements if one is inside the other.
-  // Can be used to make otherwise duplicate labels unique.
-  int nestingLevel = 0;
-
-  StatementScope()
-      : labels = const EmptyLabelScope(),
-        breakTargetStack = const Link<JumpTarget>(),
-        continueTargetStack = const Link<JumpTarget>();
-
-  LabelDefinition lookupLabel(String label) {
-    return labels.lookup(label);
-  }
-
-  JumpTarget currentBreakTarget() =>
-      breakTargetStack.isEmpty ? null : breakTargetStack.head;
-
-  JumpTarget currentContinueTarget() =>
-      continueTargetStack.isEmpty ? null : continueTargetStack.head;
-
-  void enterLabelScope(Map<String, LabelDefinition> elements) {
-    labels = new LabeledStatementLabelScope(labels, elements);
-    nestingLevel++;
-  }
-
-  void exitLabelScope() {
-    nestingLevel--;
-    labels = labels.outer;
-  }
-
-  void enterLoop(JumpTarget element) {
-    breakTargetStack = breakTargetStack.prepend(element);
-    continueTargetStack = continueTargetStack.prepend(element);
-    nestingLevel++;
-  }
-
-  void exitLoop() {
-    nestingLevel--;
-    breakTargetStack = breakTargetStack.tail;
-    continueTargetStack = continueTargetStack.tail;
-  }
-
-  void enterSwitch(
-      JumpTarget breakElement, Map<String, LabelDefinition> continueElements) {
-    breakTargetStack = breakTargetStack.prepend(breakElement);
-    labels = new SwitchLabelScope(labels, continueElements);
-    nestingLevel++;
-  }
-
-  void exitSwitch() {
-    nestingLevel--;
-    breakTargetStack = breakTargetStack.tail;
-    labels = labels.outer;
-  }
-}
diff --git a/pkg/compiler/lib/src/resolution/member_impl.dart b/pkg/compiler/lib/src/resolution/member_impl.dart
deleted file mode 100644
index e454c83..0000000
--- a/pkg/compiler/lib/src/resolution/member_impl.dart
+++ /dev/null
@@ -1,256 +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.
-
-part of dart2js.resolution.compute_members;
-
-class DeclaredMember implements Member {
-  final Name name;
-  final MemberElement element;
-  final ResolutionInterfaceType declarer;
-  final ResolutionDartType type;
-  final ResolutionFunctionType functionType;
-
-  DeclaredMember(
-      this.name, this.element, this.declarer, this.type, this.functionType);
-
-  bool get isStatic => !element.isInstanceMember;
-
-  bool get isGetter => element.isGetter || (!isSetter && element.isField);
-
-  bool get isSetter => name.isSetter;
-
-  bool get isMethod => element.isFunction;
-
-  bool get isDeclaredByField => element.isField;
-
-  bool get isAbstract => false;
-
-  Member get implementation => this;
-
-  /// Returns this member as inherited from [instance].
-  ///
-  /// For instance:
-  ///   class A<T> { T m() {} }
-  ///   class B<S> extends A<S> {}
-  ///   class C<U> extends B<U> {}
-  /// The member `T m()` is declared in `A<T>` and inherited from `A<S>` into
-  /// `B` as `S m()`, and further from `B<U>` into `C` as `U m()`.
-  DeclaredMember inheritFrom(ResolutionInterfaceType instance) {
-    // If the member is declared in a non-generic class its type cannot change
-    // as a result of inheritance.
-    if (!declarer.isGeneric) return this;
-    assert(declarer.element == instance.element);
-    return _newInheritedMember(instance);
-  }
-
-  InheritedMember _newInheritedMember(ResolutionInterfaceType instance) {
-    return new InheritedMember(this, instance);
-  }
-
-  Iterable<Member> get declarations => <Member>[this];
-
-  int get hashCode => element.hashCode + 13 * isSetter.hashCode;
-
-  bool operator ==(other) {
-    if (other is! Member) return false;
-    return element == other.element && isSetter == other.isSetter;
-  }
-
-  String toString() {
-    StringBuffer sb = new StringBuffer();
-    printOn(sb, type);
-    return sb.toString();
-  }
-
-  void printOn(StringBuffer sb, ResolutionDartType type) {
-    if (isStatic) {
-      sb.write('static ');
-    }
-    if (isAbstract) {
-      sb.write('abstract ');
-    }
-    if (isGetter) {
-      sb.write(type);
-      sb.write(' get ');
-      sb.write(name);
-    } else if (isSetter) {
-      sb.write('void set ');
-      sb.write(name.getter);
-      sb.write('(');
-      sb.write(type);
-      sb.write(' _)');
-    } else {
-      sb.write(type.getStringAsDeclared('$name'));
-    }
-  }
-}
-
-class DeclaredAbstractMember extends DeclaredMember {
-  final DeclaredMember implementation;
-
-  DeclaredAbstractMember(
-      Name name,
-      Element element,
-      ResolutionInterfaceType declarer,
-      ResolutionDartType type,
-      ResolutionFunctionType functionType,
-      this.implementation)
-      : super(name, element, declarer, type, functionType);
-
-  bool get isAbstract => true;
-
-  InheritedMember _newInheritedMember(ResolutionInterfaceType instance) {
-    return new InheritedAbstractMember(this, instance,
-        implementation != null ? implementation.inheritFrom(instance) : null);
-  }
-}
-
-class InheritedMember implements DeclaredMember {
-  final DeclaredMember declaration;
-  final ResolutionInterfaceType instance;
-
-  InheritedMember(
-      DeclaredMember this.declaration, ResolutionInterfaceType this.instance) {
-    assert(instance.isGeneric);
-    assert(!declaration.isStatic);
-  }
-
-  MemberElement get element => declaration.element;
-
-  Name get name => declaration.name;
-
-  ResolutionInterfaceType get declarer => instance;
-
-  bool get isStatic => false;
-
-  bool get isSetter => declaration.isSetter;
-
-  bool get isGetter => declaration.isGetter;
-
-  bool get isMethod => declaration.isMethod;
-
-  bool get isDeclaredByField => declaration.isDeclaredByField;
-
-  bool get isAbstract => false;
-
-  Member get implementation => this;
-
-  ResolutionDartType get type => declaration.type.substByContext(instance);
-
-  ResolutionFunctionType get functionType {
-    return declaration.functionType.substByContext(instance);
-  }
-
-  DeclaredMember inheritFrom(ResolutionInterfaceType newInstance) {
-    assert(() {
-      // Assert that if [instance] contains type variables, then these are
-      // defined in the declaration of [newInstance] and will therefore be
-      // substituted into the context of [newInstance] in the created member.
-      ClassElement contextClass = DartTypes.getClassContext(instance);
-      return contextClass == null || contextClass == newInstance.element;
-    }(),
-        failedAt(
-            declaration.element,
-            "Context mismatch: Context class "
-            "${DartTypes.getClassContext(instance)} from $instance does match "
-            "the new instance $newInstance."));
-    return _newInheritedMember(newInstance);
-  }
-
-  InheritedMember _newInheritedMember(ResolutionInterfaceType newInstance) {
-    return new InheritedMember(
-        declaration, instance.substByContext(newInstance));
-  }
-
-  Iterable<Member> get declarations => <Member>[this];
-
-  int get hashCode => declaration.hashCode + 17 * instance.hashCode;
-
-  bool operator ==(other) {
-    if (other is! InheritedMember) return false;
-    return declaration == other.declaration && instance == other.instance;
-  }
-
-  void printOn(StringBuffer sb, ResolutionDartType type) {
-    declaration.printOn(sb, type);
-    sb.write(' inherited from $instance');
-  }
-
-  String toString() {
-    StringBuffer sb = new StringBuffer();
-    printOn(sb, type);
-    return sb.toString();
-  }
-}
-
-class InheritedAbstractMember extends InheritedMember {
-  final DeclaredMember implementation;
-
-  InheritedAbstractMember(DeclaredMember declaration,
-      ResolutionInterfaceType instance, this.implementation)
-      : super(declaration, instance);
-
-  bool get isAbstract => true;
-
-  InheritedMember _newInheritedMember(ResolutionInterfaceType newInstance) {
-    return new InheritedAbstractMember(
-        declaration,
-        instance.substByContext(newInstance),
-        implementation != null
-            ? implementation.inheritFrom(newInstance)
-            : null);
-  }
-}
-
-abstract class AbstractSyntheticMember implements MemberSignature {
-  final Setlet<Member> inheritedMembers;
-
-  AbstractSyntheticMember(this.inheritedMembers);
-
-  Member get member => inheritedMembers.first;
-
-  Iterable<Member> get declarations => inheritedMembers;
-
-  Name get name => member.name;
-}
-
-class SyntheticMember extends AbstractSyntheticMember {
-  final ResolutionDartType type;
-  final ResolutionFunctionType functionType;
-
-  SyntheticMember(Setlet<Member> inheritedMembers, this.type, this.functionType)
-      : super(inheritedMembers);
-
-  bool get isSetter => member.isSetter;
-
-  bool get isGetter => member.isGetter;
-
-  bool get isMethod => member.isMethod;
-
-  bool get isMalformed => false;
-
-  String toString() => '${type.getStringAsDeclared('$name')} synthesized '
-      'from ${inheritedMembers}';
-}
-
-class ErroneousMember extends AbstractSyntheticMember {
-  ErroneousMember(Setlet<Member> inheritedMembers) : super(inheritedMembers);
-
-  ResolutionDartType get type => functionType;
-
-  ResolutionFunctionType get functionType {
-    throw new UnsupportedError('Erroneous members have no type.');
-  }
-
-  bool get isSetter => false;
-
-  bool get isGetter => false;
-
-  bool get isMethod => false;
-
-  bool get isMalformed => true;
-
-  String toString() => "erroneous member '$name' synthesized "
-      "from ${inheritedMembers}";
-}
diff --git a/pkg/compiler/lib/src/resolution/members.dart b/pkg/compiler/lib/src/resolution/members.dart
deleted file mode 100644
index abda55c..0000000
--- a/pkg/compiler/lib/src/resolution/members.dart
+++ /dev/null
@@ -1,4836 +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.
-
-library dart2js.resolution.members;
-
-import 'package:front_end/src/fasta/scanner.dart' show isUserDefinableOperator;
-
-import '../common.dart';
-import '../common/names.dart' show Selectors;
-import '../common/resolution.dart' show Resolution;
-import '../compile_time_constants.dart';
-import '../constants/constructors.dart'
-    show RedirectingFactoryConstantConstructor;
-import '../constants/expressions.dart';
-import '../constants/values.dart';
-import '../common_elements.dart';
-import '../elements/elements.dart';
-import '../elements/entities.dart' show AsyncMarker;
-import '../elements/modelx.dart'
-    show
-        ConstructorElementX,
-        ErroneousElementX,
-        FunctionElementX,
-        JumpTargetX,
-        LabelDefinitionX,
-        LocalFunctionElementX,
-        LocalParameterElementX,
-        ParameterElementX,
-        VariableElementX,
-        VariableList;
-import '../elements/jumps.dart';
-import '../elements/names.dart';
-import '../elements/operators.dart';
-import '../elements/resolution_types.dart';
-import '../options.dart';
-import '../tree/tree.dart';
-import '../universe/call_structure.dart' show CallStructure;
-import '../universe/feature.dart' show Feature;
-import '../universe/selector.dart' show Selector;
-import '../universe/use.dart' show DynamicUse, StaticUse, TypeUse;
-import '../util/util.dart' show Link;
-import 'access_semantics.dart';
-import 'class_members.dart' show MembersCreator;
-import 'constructors.dart'
-    show ConstructorResolver, ConstructorResult, ConstructorResultKind;
-import 'label_scope.dart' show StatementScope;
-import 'registry.dart' show ResolutionRegistry;
-import 'resolution.dart' show ResolverTask;
-import 'resolution_common.dart' show MappingVisitor;
-import 'resolution_result.dart';
-import 'scope.dart' show BlockScope, MethodScope, Scope;
-import 'send_structure.dart';
-import 'signatures.dart' show SignatureResolver;
-import 'type_resolver.dart' show FunctionTypeParameterScope;
-import 'variables.dart' show VariableDefinitionsVisitor;
-
-/// The state of constants in resolutions.
-enum ConstantState {
-  /// Expressions are not required to be constants.
-  NON_CONSTANT,
-
-  /// Expressions are required to be constants.
-  ///
-  /// For instance the values of a constant list literal.
-  CONSTANT,
-
-  /// Expressions are required to be constants and parameter references are
-  /// also considered constant.
-  ///
-  /// This is used for resolving constructor initializers of constant
-  /// constructors.
-  CONSTANT_INITIALIZER,
-}
-
-/**
- * Core implementation of resolution.
- *
- * Do not subclass or instantiate this class outside this library
- * except for testing.
- */
-class ResolverVisitor extends MappingVisitor<ResolutionResult> {
-  /**
-   * The current enclosing element for the visited AST nodes.
-   *
-   * This field is updated when nested closures are visited.
-   */
-  Element enclosingElement;
-
-  /// Whether we are in a context where `this` is accessible (this will be false
-  /// in static contexts, factory methods, and field initializers).
-  bool inInstanceContext;
-  bool inCheckContext;
-  bool inCatchParameters = false;
-  bool inCatchBlock;
-  ConstantState constantState;
-
-  Scope scope;
-  ClassElement currentClass;
-  ExpressionStatement currentExpressionStatement;
-
-  /// `true` if a [Send] or [SendSet] is visited as the prefix of member access.
-  /// For instance `Class` in `Class.staticField` or `prefix.Class` in
-  /// `prefix.Class.staticMethod()`.
-  bool sendIsMemberAccess = false;
-
-  StatementScope statementScope;
-  int allowedCategory = ElementCategory.VARIABLE |
-      ElementCategory.FUNCTION |
-      ElementCategory.IMPLIES_TYPE;
-
-  /// When visiting the type declaration of the variable in a [ForIn] loop,
-  /// the initializer of the variable is implicit and we should not emit an
-  /// error when verifying that all final variables are initialized.
-  bool inLoopVariable = false;
-
-  /// The nodes for which variable access and mutation must be registered in
-  /// order to determine when the static type of variables types is promoted.
-  Link<Node> promotionScope = const Link<Node>();
-
-  bool isPotentiallyMutableTarget(Element target) {
-    if (target == null) return false;
-    return (target.isVariable || target.isRegularParameter) &&
-        !(target.isFinal || target.isConst);
-  }
-
-  // TODO(ahe): Find a way to share this with runtime implementation.
-  static final RegExp symbolValidationPattern =
-      new RegExp(r'^(?:[a-zA-Z$][a-zA-Z$0-9_]*\.)*(?:[a-zA-Z$][a-zA-Z$0-9_]*=?|'
-          r'-|'
-          r'unary-|'
-          r'\[\]=|'
-          r'~|'
-          r'==|'
-          r'\[\]|'
-          r'\*|'
-          r'/|'
-          r'%|'
-          r'~/|'
-          r'\+|'
-          r'<<|'
-          r'>>|'
-          r'>=|'
-          r'>|'
-          r'<=|'
-          r'<|'
-          r'&|'
-          r'\^|'
-          r'\|'
-          r')$');
-
-  ResolverVisitor(
-      Resolution resolution, Element element, ResolutionRegistry registry,
-      {Scope scope, bool useEnclosingScope: false})
-      : this.enclosingElement = element,
-        // When the element is a field, we are actually resolving its
-        // initial value, which should not have access to instance
-        // fields.
-        inInstanceContext = (element.isInstanceMember && !element.isField) ||
-            element.isGenerativeConstructor,
-        this.currentClass =
-            element.isClassMember ? element.enclosingClass : null,
-        this.statementScope = new StatementScope(),
-        this.scope = scope ??
-            (useEnclosingScope
-                ? Scope.buildEnclosingScope(element)
-                : element.buildScope()),
-        // The type annotations on a typedef do not imply type checks.
-        // TODO(karlklose): clean this up (dartbug.com/8870).
-        inCheckContext = resolution.options.enableTypeAssertions &&
-            !element.isLibrary &&
-            !element.isTypedef &&
-            !element.enclosingElement.isTypedef,
-        inCatchBlock = false,
-        constantState = element.isConst
-            ? ConstantState.CONSTANT
-            : ConstantState.NON_CONSTANT,
-        super(resolution, registry);
-
-  CommonElements get commonElements => resolution.commonElements;
-  ConstantEnvironment get constants => resolution.constants;
-  ResolverTask get resolver => resolution.resolver;
-  CompilerOptions get options => resolution.options;
-
-  AsyncMarker get currentAsyncMarker {
-    if (enclosingElement is FunctionElement) {
-      FunctionElement function = enclosingElement;
-      return function.asyncMarker;
-    }
-    return AsyncMarker.SYNC;
-  }
-
-  Element reportLookupErrorIfAny(Element result, Node node, String name) {
-    if (!Elements.isUnresolved(result)) {
-      if (!inInstanceContext && result.isInstanceMember) {
-        reporter.reportErrorMessage(
-            node, MessageKind.NO_INSTANCE_AVAILABLE, {'name': name});
-        return new ErroneousElementX(MessageKind.NO_INSTANCE_AVAILABLE,
-            {'name': name}, name, enclosingElement);
-      } else if (result.isAmbiguous) {
-        AmbiguousElement ambiguous = result;
-        return reportAndCreateErroneousElement(
-            node, name, ambiguous.messageKind, ambiguous.messageArguments,
-            infos: ambiguous.computeInfos(enclosingElement, reporter),
-            isError: true);
-      }
-    }
-    return result;
-  }
-
-  // Create, or reuse an already created, target element for a statement.
-  JumpTarget getOrDefineTarget(Node statement) {
-    JumpTarget element = registry.getTargetDefinition(statement);
-    if (element == null) {
-      element = new JumpTargetX(
-          statement, statementScope.nestingLevel, enclosingElement);
-      registry.defineTarget(statement, element);
-    }
-    return element;
-  }
-
-  doInPromotionScope(Node node, action()) {
-    promotionScope = promotionScope.prepend(node);
-    var result = action();
-    promotionScope = promotionScope.tail;
-    return result;
-  }
-
-  inStaticContext(action(), {bool inConstantInitializer: false}) {
-    bool wasInstanceContext = inInstanceContext;
-    ConstantState oldConstantState = constantState;
-    constantState = inConstantInitializer
-        ? ConstantState.CONSTANT_INITIALIZER
-        : constantState;
-    inInstanceContext = false;
-    var result = action();
-    inInstanceContext = wasInstanceContext;
-    constantState = oldConstantState;
-    return result;
-  }
-
-  ResolutionResult visitInStaticContext(Node node,
-      {bool inConstantInitializer: false}) {
-    return inStaticContext(() => visit(node),
-        inConstantInitializer: inConstantInitializer);
-  }
-
-  /// Execute [action] where the constant state is `ConstantState.CONSTANT` if
-  /// not already `ConstantState.CONSTANT_INITIALIZER`.
-  inConstantContext(action()) {
-    ConstantState oldConstantState = constantState;
-    if (constantState != ConstantState.CONSTANT_INITIALIZER) {
-      constantState = ConstantState.CONSTANT;
-    }
-    var result = action();
-    constantState = oldConstantState;
-    return result;
-  }
-
-  /// Visit [node] where the constant state is `ConstantState.CONSTANT` if
-  /// not already `ConstantState.CONSTANT_INITIALIZER`.
-  ResolutionResult visitInConstantContext(Node node) {
-    ResolutionResult result = inConstantContext(() => visit(node));
-    assert(result != null, failedAt(node, "No resolution result for $node."));
-
-    return result;
-  }
-
-  ErroneousElement reportAndCreateErroneousElement(
-      Node node, String name, MessageKind kind, Map arguments,
-      {List<DiagnosticMessage> infos: const <DiagnosticMessage>[],
-      bool isError: false}) {
-    if (isError) {
-      reporter.reportError(
-          reporter.createMessage(node, kind, arguments), infos);
-    } else {
-      reporter.reportWarning(
-          reporter.createMessage(node, kind, arguments), infos);
-    }
-    // TODO(ahe): Use [allowedCategory] to synthesize a more precise subclass
-    // of [ErroneousElementX]. For example, [ErroneousFieldElementX],
-    // [ErroneousConstructorElementX], etc.
-    return new ErroneousElementX(kind, arguments, name, enclosingElement);
-  }
-
-  /// Report a warning or error on an unresolved access in non-instance context.
-  ///
-  /// The [ErroneousElement] corresponding to the message is returned.
-  ErroneousElement reportCannotResolve(Node node, String name) {
-    assert(
-        !inInstanceContext,
-        failedAt(
-            node,
-            "ResolverVisitor.reportCannotResolve must not be called in "
-            "instance context."));
-
-    // We report an error within initializers because `this` is implicitly
-    // accessed when unqualified identifiers are not resolved.  For
-    // details, see section 16.14.3 of the spec (2nd edition):
-    //   An unqualified invocation `i` of the form `id(a1, ...)`
-    //   ...
-    //   If `i` does not occur inside a top level or static function, `i`
-    //   is equivalent to `this.id(a1 , ...)`.
-    bool inInitializer = enclosingElement.isGenerativeConstructor ||
-        (enclosingElement.isInstanceMember && enclosingElement.isField);
-    MessageKind kind;
-    Map arguments = {'name': name};
-    if (inInitializer) {
-      kind = MessageKind.CANNOT_RESOLVE_IN_INITIALIZER;
-    } else if (name == 'await') {
-      var functionName = enclosingElement.name;
-      if (functionName == '') {
-        kind = MessageKind.CANNOT_RESOLVE_AWAIT_IN_CLOSURE;
-      } else {
-        kind = MessageKind.CANNOT_RESOLVE_AWAIT;
-        arguments['functionName'] = functionName;
-      }
-    } else {
-      kind = MessageKind.CANNOT_RESOLVE;
-    }
-    registry.registerFeature(Feature.THROW_NO_SUCH_METHOD);
-    return reportAndCreateErroneousElement(node, name, kind, arguments,
-        isError: inInitializer);
-  }
-
-  ResolutionResult visitIdentifier(Identifier node) {
-    if (node.isThis()) {
-      if (!inInstanceContext) {
-        reporter.reportErrorMessage(
-            node, MessageKind.NO_INSTANCE_AVAILABLE, {'name': node});
-      }
-      return const NoneResult();
-    } else if (node.isSuper()) {
-      if (!inInstanceContext) {
-        reporter.reportErrorMessage(node, MessageKind.NO_SUPER_IN_STATIC);
-      }
-      if ((ElementCategory.SUPER & allowedCategory) == 0) {
-        reporter.reportErrorMessage(node, MessageKind.INVALID_USE_OF_SUPER);
-      }
-      return const NoneResult();
-    } else {
-      String name = node.source;
-      Element element = lookupInScope(reporter, node, scope, name);
-      if (Elements.isUnresolved(element) && name == 'dynamic') {
-        // TODO(johnniwinther): Remove this hack when we can return more complex
-        // objects than [Element] from this method.
-        ClassElement typeClass = commonElements.typeClass;
-        element = typeClass;
-        // Set the type to be `dynamic` to mark that this is a type literal.
-        registry.setType(node, const ResolutionDynamicType());
-      }
-      element = reportLookupErrorIfAny(element, node, name);
-      if (element == null) {
-        if (!inInstanceContext) {
-          element = reportCannotResolve(node, name);
-        }
-      } else if (element.isMalformed) {
-        // Use the malformed element.
-      } else {
-        if ((element.kind.category & allowedCategory) == 0) {
-          element =
-              reportAndCreateErroneousElement(node, name, MessageKind.GENERIC,
-                  // TODO(ahe): Improve error message. Need UX input.
-                  {'text': "is not an expression $element"});
-        }
-      }
-      if (!Elements.isUnresolved(element) && element.isClass) {
-        ClassElement classElement = element;
-        classElement.ensureResolved(resolution);
-      }
-      if (element != null) {
-        registry.useElement(node, element);
-        if (element.isPrefix) {
-          return new PrefixResult(element, null);
-        } else if (element.isClass && sendIsMemberAccess) {
-          return new PrefixResult(null, element);
-        }
-        return new ElementResult(element);
-      }
-      return const NoneResult();
-    }
-  }
-
-  TypeResult visitTypeAnnotation(TypeAnnotation node) {
-    return new TypeResult(resolveTypeAnnotation(node));
-  }
-
-  bool isNamedConstructor(Send node) => node.receiver != null;
-
-  Name getRedirectingThisOrSuperConstructorName(Send node) {
-    if (isNamedConstructor(node)) {
-      String constructorName = node.selector.asIdentifier().source;
-      return new Name(constructorName, enclosingElement.library);
-    } else {
-      return const PublicName('');
-    }
-  }
-
-  FunctionElement resolveConstructorRedirection(FunctionElementX constructor) {
-    FunctionExpression node = constructor.parseNode(resolution.parsingContext);
-
-    // A synthetic constructor does not have a node.
-    if (node == null) return null;
-    if (node.initializers == null) return null;
-    Link<Node> initializers = node.initializers.nodes;
-    if (!initializers.isEmpty &&
-        Initializers.isConstructorRedirect(initializers.head)) {
-      Name name = getRedirectingThisOrSuperConstructorName(initializers.head);
-      final ClassElement classElement = constructor.enclosingClass;
-      return classElement.lookupConstructor(name.text);
-    }
-    return null;
-  }
-
-  void setupFunction(FunctionExpression node, FunctionElement function) {
-    Element enclosingElement = function.enclosingElement;
-    if (node.modifiers.isStatic && enclosingElement.kind != ElementKind.CLASS) {
-      reporter.reportErrorMessage(node, MessageKind.ILLEGAL_STATIC);
-    }
-    FunctionSignature functionSignature = function.functionSignature;
-
-    // Create the scope where the type variables are introduced, if any.
-    scope = new MethodScope(scope, function);
-    functionSignature.typeVariables
-        .forEach((ResolutionDartType type) => addToScope(type.element));
-
-    // Create the scope for the function body, and put the parameters in scope.
-    scope = new BlockScope(scope);
-    Link<Node> parameterNodes =
-        (node.parameters == null) ? const Link<Node>() : node.parameters.nodes;
-    functionSignature.forEachParameter((_element) {
-      ParameterElementX element = _element;
-      // TODO(karlklose): should be a list of [FormalElement]s, but the actual
-      // implementation uses [Element].
-      List<Element> optionals = functionSignature.optionalParameters;
-      if (!optionals.isEmpty && element == optionals.first) {
-        NodeList nodes = parameterNodes.head;
-        parameterNodes = nodes.nodes;
-      }
-      if (element.isOptional) {
-        if (element.initializer != null) {
-          ResolutionResult result = visitInConstantContext(element.initializer);
-          if (result.isConstant) {
-            element.constant = result.constant;
-          }
-        } else {
-          registry.registerConstantLiteral(
-              element.constant = new NullConstantExpression());
-        }
-      }
-      VariableDefinitions variableDefinitions = parameterNodes.head;
-      Node parameterNode = variableDefinitions.definitions.nodes.head;
-      // Field parameters (this.x) are not visible inside the constructor. The
-      // fields they reference are visible, but must be resolved independently.
-      if (element.isInitializingFormal) {
-        registry.useElement(parameterNode, element);
-      } else {
-        LocalParameterElementX parameterElement = element;
-        defineLocalVariable(parameterNode, parameterElement);
-        addToScope(parameterElement);
-      }
-      parameterNodes = parameterNodes.tail;
-    });
-    addDeferredAction(enclosingElement, () {
-      functionSignature.forEachOptionalParameter((_parameter) {
-        ParameterElementX parameter = _parameter;
-        parameter.constant =
-            resolver.constantCompiler.compileConstant(parameter);
-      });
-    });
-    registry.registerCheckedModeCheck(functionSignature.returnType);
-    functionSignature.forEachParameter((_element) {
-      ParameterElement element = _element;
-      registry.registerCheckedModeCheck(element.type);
-    });
-  }
-
-  ResolutionResult visitAssert(Assert node) {
-    // TODO(sra): We could completely ignore the assert in production mode if we
-    // didn't need it to be resolved for type checking.
-    registry.registerFeature(
-        node.hasMessage ? Feature.ASSERT_WITH_MESSAGE : Feature.ASSERT);
-    visit(node.condition);
-    visit(node.message);
-    return const NoneResult();
-  }
-
-  ResolutionResult visitCascade(Cascade node) {
-    visit(node.expression);
-    return const NoneResult();
-  }
-
-  ResolutionResult visitCascadeReceiver(CascadeReceiver node) {
-    visit(node.expression);
-    return const NoneResult();
-  }
-
-  ResolutionResult visitIn(Node node, Scope nestedScope) {
-    Scope oldScope = scope;
-    scope = nestedScope;
-    ResolutionResult result = visit(node);
-    scope = oldScope;
-    return result;
-  }
-
-  /**
-   * Introduces new default targets for break and continue
-   * before visiting the body of the loop
-   */
-  void visitLoopBodyIn(Loop loop, Node body, Scope bodyScope) {
-    JumpTarget element = getOrDefineTarget(loop);
-    statementScope.enterLoop(element);
-    visitIn(body, bodyScope);
-    statementScope.exitLoop();
-    if (!element.isTarget) {
-      registry.undefineTarget(loop);
-    }
-  }
-
-  ResolutionResult visitBlock(Block node) {
-    visitIn(node.statements, new BlockScope(scope));
-    return const NoneResult();
-  }
-
-  ResolutionResult visitDoWhile(DoWhile node) {
-    visitLoopBodyIn(node, node.body, new BlockScope(scope));
-    visit(node.condition);
-    return const NoneResult();
-  }
-
-  ResolutionResult visitEmptyStatement(EmptyStatement node) {
-    return const NoneResult();
-  }
-
-  ResolutionResult visitExpressionStatement(ExpressionStatement node) {
-    ExpressionStatement oldExpressionStatement = currentExpressionStatement;
-    currentExpressionStatement = node;
-    visit(node.expression);
-    currentExpressionStatement = oldExpressionStatement;
-    return const NoneResult();
-  }
-
-  ResolutionResult visitFor(For node) {
-    Scope blockScope = new BlockScope(scope);
-    visitIn(node.initializer, blockScope);
-    visitIn(node.condition, blockScope);
-    visitIn(node.update, blockScope);
-    visitLoopBodyIn(node, node.body, blockScope);
-    return const NoneResult();
-  }
-
-  ResolutionResult visitFunctionDeclaration(FunctionDeclaration node) {
-    assert(node.function.name != null);
-    visitFunctionExpression(node.function, inFunctionDeclaration: true);
-    return const NoneResult();
-  }
-
-  /// Process a local function declaration or an anonymous function expression.
-  ///
-  /// [inFunctionDeclaration] is `true` when the current node is the immediate
-  /// child of a function declaration.
-  ///
-  /// This is used to distinguish local function declarations from anonymous
-  /// function expressions.
-  ResolutionResult visitFunctionExpression(FunctionExpression node,
-      {bool inFunctionDeclaration: false}) {
-    bool doAddToScope = inFunctionDeclaration;
-    if (!inFunctionDeclaration && node.name != null) {
-      reporter.reportErrorMessage(node.name,
-          MessageKind.NAMED_FUNCTION_EXPRESSION, {'name': node.name});
-    }
-    String name;
-    if (node.name == null) {
-      name = "";
-    } else {
-      name = node.name.asIdentifier().source;
-    }
-    LocalFunctionElementX function = new LocalFunctionElementX(
-        name, node, ElementKind.FUNCTION, Modifiers.EMPTY, enclosingElement);
-    ResolverTask.processAsyncMarker(resolution, function, registry);
-    function.functionSignature = SignatureResolver.analyze(
-        resolution,
-        scope,
-        const FunctionTypeParameterScope(),
-        node.typeVariables,
-        node.parameters,
-        node.returnType,
-        function,
-        registry,
-        createRealParameters: true,
-        isFunctionExpression: !inFunctionDeclaration);
-    checkLocalDefinitionName(node, function);
-    registry.defineFunction(node, function);
-    if (doAddToScope) {
-      addToScope(function);
-    }
-    Scope oldScope = scope; // The scope is modified by [setupFunction].
-    setupFunction(node, function);
-
-    Element previousEnclosingElement = enclosingElement;
-    enclosingElement = function;
-    // Run the body in a fresh statement scope.
-    StatementScope oldStatementScope = statementScope;
-    statementScope = new StatementScope();
-    visit(node.body);
-    statementScope = oldStatementScope;
-
-    scope = oldScope;
-    enclosingElement = previousEnclosingElement;
-
-    registry.registerStaticUse(new StaticUse.closure(function));
-    return const NoneResult();
-  }
-
-  ResolutionResult visitIf(If node) {
-    doInPromotionScope(node.condition.expression, () => visit(node.condition));
-    doInPromotionScope(
-        node.thenPart, () => visitIn(node.thenPart, new BlockScope(scope)));
-    visitIn(node.elsePart, new BlockScope(scope));
-    return const NoneResult();
-  }
-
-  static Selector computeSendSelector(
-      Send node, LibraryElement library, Element element) {
-    // First determine if this is part of an assignment.
-    bool isSet = node.asSendSet() != null;
-
-    if (node.isIndex) {
-      return isSet ? new Selector.indexSet() : new Selector.index();
-    }
-
-    if (node.isOperator) {
-      String source = node.selector.asOperator().source;
-      String string = source;
-      if (identical(string, '!') ||
-          identical(string, '&&') ||
-          identical(string, '||') ||
-          identical(string, 'is') ||
-          identical(string, 'as') ||
-          identical(string, '?') ||
-          identical(string, '??')) {
-        return null;
-      }
-      String op = source;
-      if (!isUserDefinableOperator(source)) {
-        op = Elements.mapToUserOperatorOrNull(source);
-      }
-      if (op == null) {
-        // Unsupported operator. An error has been reported during parsing.
-        return new Selector.call(new Name(source, library),
-            new CallStructure.unnamed(node.argumentsNode.slowLength()));
-      }
-      return node.arguments.isEmpty
-          ? new Selector.unaryOperator(op)
-          : new Selector.binaryOperator(op);
-    }
-
-    Identifier identifier = node.selector.asIdentifier();
-    if (node.isPropertyAccess) {
-      assert(!isSet);
-      return new Selector.getter(new Name(identifier.source, library));
-    } else if (isSet) {
-      return new Selector.setter(
-          new Name(identifier.source, library, isSetter: true));
-    }
-
-    // Compute the arity and the list of named arguments.
-    int arity = 0;
-    List<String> named = <String>[];
-    for (Link<Node> link = node.argumentsNode.nodes;
-        !link.isEmpty;
-        link = link.tail) {
-      Expression argument = link.head;
-      NamedArgument namedArgument = argument.asNamedArgument();
-      if (namedArgument != null) {
-        named.add(namedArgument.name.source);
-      }
-      arity++;
-    }
-
-    if (element != null && element.isConstructor) {
-      return new Selector.callConstructor(
-          new Name(element.name, library), arity, named);
-    }
-
-    // If we're invoking a closure, we do not have an identifier.
-    return (identifier == null)
-        ? new Selector.callClosure(arity, named)
-        : new Selector.call(new Name(identifier.source, library),
-            new CallStructure(arity, named));
-  }
-
-  Selector resolveSelector(Send node, Element element) {
-    LibraryElement library = enclosingElement.library;
-    Selector selector = computeSendSelector(node, library, element);
-    if (selector != null) registry.setSelector(node, selector);
-    return selector;
-  }
-
-  ArgumentsResult resolveArguments(NodeList list) {
-    if (list == null) return null;
-    bool isValidAsConstant = true;
-    List<ResolutionResult> argumentResults = <ResolutionResult>[];
-    bool oldSendIsMemberAccess = sendIsMemberAccess;
-    sendIsMemberAccess = false;
-    Map<String, Node> seenNamedArguments = new Map<String, Node>();
-    int argumentCount = 0;
-    List<String> namedArguments = <String>[];
-    for (Link<Node> link = list.nodes; !link.isEmpty; link = link.tail) {
-      Expression argument = link.head;
-      ResolutionResult result = visit(argument);
-      if (!result.isConstant) {
-        isValidAsConstant = false;
-      }
-      argumentResults.add(result);
-
-      NamedArgument namedArgument = argument.asNamedArgument();
-      if (namedArgument != null) {
-        String source = namedArgument.name.source;
-        namedArguments.add(source);
-        if (seenNamedArguments.containsKey(source)) {
-          reportDuplicateDefinition(
-              source, argument, seenNamedArguments[source]);
-          isValidAsConstant = false;
-        } else {
-          seenNamedArguments[source] = namedArgument;
-        }
-      } else if (!seenNamedArguments.isEmpty) {
-        reporter.reportErrorMessage(
-            argument, MessageKind.INVALID_ARGUMENT_AFTER_NAMED);
-        isValidAsConstant = false;
-      }
-      argumentCount++;
-    }
-    sendIsMemberAccess = oldSendIsMemberAccess;
-    return new ArgumentsResult(
-        new CallStructure(argumentCount, namedArguments), argumentResults,
-        isValidAsConstant: isValidAsConstant);
-  }
-
-  /// Check that access to `super` is currently allowed. Returns an
-  /// [AccessSemantics] in case of an error, `null` otherwise.
-  AccessSemantics checkSuperAccess(Send node) {
-    if (!inInstanceContext) {
-      ErroneousElement error = reportAndCreateErroneousElement(
-          node, 'super', MessageKind.NO_SUPER_IN_STATIC, {},
-          isError: true);
-      registry.registerFeature(Feature.COMPILE_TIME_ERROR);
-      return new StaticAccess.invalid(error);
-    }
-    if (node.isConditional) {
-      // `super?.foo` is not allowed.
-      ErroneousElement error = reportAndCreateErroneousElement(
-          node, 'super', MessageKind.INVALID_USE_OF_SUPER, {},
-          isError: true);
-      registry.registerFeature(Feature.COMPILE_TIME_ERROR);
-      return new StaticAccess.invalid(error);
-    }
-    if (currentClass.supertype == null) {
-      // This is just to guard against internal errors, so no need
-      // for a real error message.
-      ErroneousElement error = reportAndCreateErroneousElement(node, 'super',
-          MessageKind.GENERIC, {'text': "Object has no superclass"},
-          isError: true);
-      registry.registerFeature(Feature.COMPILE_TIME_ERROR);
-      return new StaticAccess.invalid(error);
-    }
-    registry.registerSuperUse(reporter.spanFromSpannable(node));
-    return null;
-  }
-
-  /// Check that access to `this` is currently allowed. Returns an
-  /// [AccessSemantics] in case of an error, `null` otherwise.
-  AccessSemantics checkThisAccess(Send node) {
-    if (!inInstanceContext) {
-      ErroneousElement error = reportAndCreateErroneousElement(
-          node, 'this', MessageKind.NO_THIS_AVAILABLE, const {},
-          isError: true);
-      registry.registerFeature(Feature.COMPILE_TIME_ERROR);
-      return new StaticAccess.invalid(error);
-    }
-    return null;
-  }
-
-  /// Compute the [AccessSemantics] corresponding to a super access of [target].
-  AccessSemantics computeSuperAccessSemantics(Spannable node, Element target) {
-    if (target.isMalformed) {
-      return new StaticAccess.unresolvedSuper(target);
-    } else if (target.isGetter) {
-      return new StaticAccess.superGetter(target);
-    } else if (target.isSetter) {
-      return new StaticAccess.superSetter(target);
-    } else if (target.isField) {
-      if (target.isFinal) {
-        return new StaticAccess.superFinalField(target);
-      } else {
-        return new StaticAccess.superField(target);
-      }
-    } else {
-      assert(target.isFunction,
-          failedAt(node, "Unexpected super target '$target'."));
-      return new StaticAccess.superMethod(target);
-    }
-  }
-
-  /// Compute the [AccessSemantics] corresponding to a compound super access
-  /// reading from [getter] and writing to [setter].
-  AccessSemantics computeCompoundSuperAccessSemantics(
-      Spannable node, Element getter, Element setter,
-      {bool isIndex: false}) {
-    if (getter.isMalformed) {
-      if (setter.isMalformed) {
-        return new StaticAccess.unresolvedSuper(getter);
-      } else if (setter.isFunction) {
-        assert(setter.name == '[]=',
-            failedAt(node, "Unexpected super setter '$setter'."));
-        return new CompoundAccessSemantics(
-            CompoundAccessKind.UNRESOLVED_SUPER_GETTER, getter, setter);
-      } else {
-        assert(setter.isSetter,
-            failedAt(node, "Unexpected super setter '$setter'."));
-        return new CompoundAccessSemantics(
-            CompoundAccessKind.UNRESOLVED_SUPER_GETTER, getter, setter);
-      }
-    } else if (getter.isField) {
-      if (setter.isMalformed) {
-        assert(
-            getter.isFinal,
-            failedAt(node,
-                "Unexpected super setter '$setter' for getter '$getter."));
-        return new StaticAccess.superFinalField(getter);
-      } else if (setter.isField) {
-        if (getter == setter) {
-          return new StaticAccess.superField(getter);
-        } else {
-          return new CompoundAccessSemantics(
-              CompoundAccessKind.SUPER_FIELD_FIELD, getter, setter);
-        }
-      } else {
-        // Either the field is accessible directly, or a setter shadows the
-        // setter access. If there was another instance member it would shadow
-        // the field.
-        assert(setter.isSetter,
-            failedAt(node, "Unexpected super setter '$setter'."));
-        return new CompoundAccessSemantics(
-            CompoundAccessKind.SUPER_FIELD_SETTER, getter, setter);
-      }
-    } else if (getter.isGetter) {
-      if (setter.isMalformed) {
-        return new CompoundAccessSemantics(
-            CompoundAccessKind.UNRESOLVED_SUPER_SETTER, getter, setter);
-      } else if (setter.isField) {
-        return new CompoundAccessSemantics(
-            CompoundAccessKind.SUPER_GETTER_FIELD, getter, setter);
-      } else {
-        assert(setter.isSetter,
-            failedAt(node, "Unexpected super setter '$setter'."));
-        return new CompoundAccessSemantics(
-            CompoundAccessKind.SUPER_GETTER_SETTER, getter, setter);
-      }
-    } else {
-      assert(getter.isFunction,
-          failedAt(node, "Unexpected super getter '$getter'."));
-      if (setter.isMalformed) {
-        if (isIndex) {
-          return new CompoundAccessSemantics(
-              CompoundAccessKind.UNRESOLVED_SUPER_SETTER, getter, setter);
-        } else {
-          return new StaticAccess.superMethod(getter);
-        }
-      } else if (setter.isFunction) {
-        assert(setter.name == '[]=',
-            failedAt(node, "Unexpected super setter '$setter'."));
-        assert(getter.name == '[]',
-            failedAt(node, "Unexpected super getter '$getter'."));
-        return new CompoundAccessSemantics(
-            CompoundAccessKind.SUPER_GETTER_SETTER, getter, setter);
-      } else {
-        assert(setter.isSetter,
-            failedAt(node, "Unexpected super setter '$setter'."));
-        return new CompoundAccessSemantics(
-            CompoundAccessKind.SUPER_METHOD_SETTER, getter, setter);
-      }
-    }
-  }
-
-  /// Compute the [AccessSemantics] corresponding to a local access of [target].
-  AccessSemantics computeLocalAccessSemantics(
-      Spannable node, LocalElement target) {
-    if (target.isRegularParameter) {
-      if (target.isFinal || target.isConst) {
-        return new StaticAccess.finalParameter(target);
-      } else {
-        return new StaticAccess.parameter(target);
-      }
-    } else if (target.isInitializingFormal) {
-      return new StaticAccess.finalParameter(target);
-    } else if (target.isVariable) {
-      if (target.isFinal || target.isConst) {
-        return new StaticAccess.finalLocalVariable(target);
-      } else {
-        return new StaticAccess.localVariable(target);
-      }
-    } else {
-      assert(target.isFunction,
-          failedAt(node, "Unexpected local target '$target'."));
-      return new StaticAccess.localFunction(target);
-    }
-  }
-
-  /// Compute the [AccessSemantics] corresponding to a static or toplevel access
-  /// of [target].
-  AccessSemantics computeStaticOrTopLevelAccessSemantics(
-      Spannable node, Element target) {
-    target = target.declaration;
-    if (target.isMalformed) {
-      // This handles elements with parser errors.
-      return new StaticAccess.unresolved(target);
-    }
-    if (target.isStatic) {
-      if (target.isGetter) {
-        return new StaticAccess.staticGetter(target);
-      } else if (target.isSetter) {
-        return new StaticAccess.staticSetter(target);
-      } else if (target.isField) {
-        if (target.isFinal || target.isConst) {
-          return new StaticAccess.finalStaticField(target);
-        } else {
-          return new StaticAccess.staticField(target);
-        }
-      } else {
-        assert(target.isFunction,
-            failedAt(node, "Unexpected static target '$target'."));
-        return new StaticAccess.staticMethod(target);
-      }
-    } else {
-      assert(target.isTopLevel,
-          failedAt(node, "Unexpected statically resolved target '$target'."));
-      if (target.isGetter) {
-        return new StaticAccess.topLevelGetter(target);
-      } else if (target.isSetter) {
-        return new StaticAccess.topLevelSetter(target);
-      } else if (target.isField) {
-        if (target.isFinal) {
-          return new StaticAccess.finalTopLevelField(target);
-        } else {
-          return new StaticAccess.topLevelField(target);
-        }
-      } else {
-        assert(target.isFunction,
-            failedAt(node, "Unexpected top level target '$target'."));
-        return new StaticAccess.topLevelMethod(target);
-      }
-    }
-  }
-
-  /// Compute the [AccessSemantics] for accessing the name of [selector] on the
-  /// super class.
-  ///
-  /// If no matching super member is found and error is reported and
-  /// `noSuchMethod` on `super` is registered. Furthermore, if [alternateName]
-  /// is provided, the [AccessSemantics] corresponding to the alternate name is
-  /// returned. For instance, the access of a super setter for an unresolved
-  /// getter:
-  ///
-  ///     class Super {
-  ///       set name(_) {}
-  ///     }
-  ///     class Sub extends Super {
-  ///       foo => super.name; // Access to the setter.
-  ///     }
-  ///
-  AccessSemantics computeSuperAccessSemanticsForSelector(
-      Spannable node, Selector selector,
-      {Name alternateName}) {
-    Name name = selector.memberName;
-    // TODO(johnniwinther): Ensure correct behavior if currentClass is a
-    // patch.
-    Element target = currentClass.lookupSuperByName(name);
-    // [target] may be null which means invoking noSuchMethod on super.
-    if (target == null) {
-      if (alternateName != null) {
-        target = currentClass.lookupSuperByName(alternateName);
-      }
-      Element error;
-      if (selector.isSetter) {
-        error = reportAndCreateErroneousElement(
-            node,
-            name.text,
-            MessageKind.UNDEFINED_SUPER_SETTER,
-            {'className': currentClass.name, 'memberName': name});
-      } else {
-        error = reportAndCreateErroneousElement(
-            node,
-            name.text,
-            MessageKind.NO_SUCH_SUPER_MEMBER,
-            {'className': currentClass.name, 'memberName': name});
-      }
-      if (target == null) {
-        // If a setter wasn't resolved, use the [ErroneousElement].
-        target = error;
-      }
-      // We still need to register the invocation, because we might
-      // call [:super.noSuchMethod:] which calls [JSInvocationMirror._invokeOn].
-      registry.registerDynamicUse(new DynamicUse(selector));
-      registry.registerFeature(Feature.SUPER_NO_SUCH_METHOD);
-    }
-    return computeSuperAccessSemantics(node, target);
-  }
-
-  /// Compute the [AccessSemantics] for accessing the name of [selector] on the
-  /// super class.
-  ///
-  /// If no matching super member is found and error is reported and
-  /// `noSuchMethod` on `super` is registered. Furthermore, if [alternateName]
-  /// is provided, the [AccessSemantics] corresponding to the alternate name is
-  /// returned. For instance, the access of a super setter for an unresolved
-  /// getter:
-  ///
-  ///     class Super {
-  ///       set name(_) {}
-  ///     }
-  ///     class Sub extends Super {
-  ///       foo => super.name; // Access to the setter.
-  ///     }
-  ///
-  AccessSemantics computeSuperAccessSemanticsForSelectors(
-      Spannable node, Selector getterSelector, Selector setterSelector,
-      {bool isIndex: false}) {
-    bool getterError = false;
-    bool setterError = false;
-
-    // TODO(johnniwinther): Ensure correct behavior if currentClass is a
-    // patch.
-    Element getter = currentClass.lookupSuperByName(getterSelector.memberName);
-    // [target] may be null which means invoking noSuchMethod on super.
-    if (getter == null) {
-      getter = reportAndCreateErroneousElement(
-          node,
-          getterSelector.name,
-          MessageKind.NO_SUCH_SUPER_MEMBER,
-          {'className': currentClass.name, 'memberName': getterSelector.name});
-      getterError = true;
-    }
-    Element setter = currentClass.lookupSuperByName(setterSelector.memberName);
-    // [target] may be null which means invoking noSuchMethod on super.
-    if (setter == null) {
-      setter = reportAndCreateErroneousElement(
-          node,
-          setterSelector.name,
-          MessageKind.NO_SUCH_SUPER_MEMBER,
-          {'className': currentClass.name, 'memberName': setterSelector.name});
-      setterError = true;
-    } else if (getter == setter) {
-      if (setter.isFunction) {
-        setter = reportAndCreateErroneousElement(
-            node, setterSelector.name, MessageKind.ASSIGNING_METHOD_IN_SUPER, {
-          'superclassName': setter.enclosingClass.name,
-          'name': setterSelector.name
-        });
-        setterError = true;
-      } else if (setter.isField && setter.isFinal) {
-        setter = reportAndCreateErroneousElement(node, setterSelector.name,
-            MessageKind.ASSIGNING_FINAL_FIELD_IN_SUPER, {
-          'superclassName': setter.enclosingClass.name,
-          'name': setterSelector.name
-        });
-        setterError = true;
-      }
-    }
-    if (getterError) {
-      // We still need to register the invocation, because we might
-      // call [:super.noSuchMethod:] which calls [JSInvocationMirror._invokeOn].
-      registry.registerDynamicUse(new DynamicUse(getterSelector));
-    }
-    if (setterError) {
-      // We still need to register the invocation, because we might
-      // call [:super.noSuchMethod:] which calls [JSInvocationMirror._invokeOn].
-      registry.registerDynamicUse(new DynamicUse(setterSelector));
-    }
-    if (getterError || setterError) {
-      registry.registerFeature(Feature.SUPER_NO_SUCH_METHOD);
-    }
-    return computeCompoundSuperAccessSemantics(node, getter, setter,
-        isIndex: isIndex);
-  }
-
-  /// Resolve [node] as a subexpression that is _not_ the prefix of a member
-  /// access. For instance `a` in `a + b`, as opposed to `a` in `a.b`.
-  ResolutionResult visitExpression(Node node) {
-    bool oldSendIsMemberAccess = sendIsMemberAccess;
-    sendIsMemberAccess = false;
-    ResolutionResult result = visit(node);
-    sendIsMemberAccess = oldSendIsMemberAccess;
-    return result;
-  }
-
-  /// Resolve [node] as a subexpression that _is_ the prefix of a member access.
-  /// For instance `a` in `a.b`, as opposed to `a` in `a + b`.
-  ResolutionResult visitExpressionPrefix(Node node) {
-    int oldAllowedCategory = allowedCategory;
-    bool oldSendIsMemberAccess = sendIsMemberAccess;
-    allowedCategory |= ElementCategory.PREFIX | ElementCategory.SUPER;
-    sendIsMemberAccess = true;
-    ResolutionResult result = visit(node);
-    sendIsMemberAccess = oldSendIsMemberAccess;
-    allowedCategory = oldAllowedCategory;
-    return result;
-  }
-
-  /// Handle a type test expression, like `a is T` and `a is! T`.
-  ResolutionResult handleIs(Send node) {
-    Node expression = node.receiver;
-    visitExpression(expression);
-
-    // TODO(johnniwinther): Use seen type tests to avoid registration of
-    // mutation/access to unpromoted variables.
-
-    Send notTypeNode = node.arguments.head.asSend();
-    ResolutionDartType type;
-    SendStructure sendStructure;
-    if (notTypeNode != null) {
-      // `e is! T`.
-      Node typeNode = notTypeNode.receiver;
-      type = resolveTypeAnnotation(typeNode, registerCheckedModeCheck: false);
-      sendStructure = new IsNotStructure(type);
-    } else {
-      // `e is T`.
-      Node typeNode = node.arguments.head;
-      type = resolveTypeAnnotation(typeNode, registerCheckedModeCheck: false);
-      sendStructure = new IsStructure(type);
-    }
-
-    // GENERIC_METHODS: Method type variables are not reified so we must warn
-    // about the error which will occur at runtime.
-    if (type is MethodTypeVariableType) {
-      reporter.reportWarningMessage(
-          node, MessageKind.TYPE_VARIABLE_FROM_METHOD_NOT_REIFIED);
-    }
-
-    registry.registerTypeUse(new TypeUse.isCheck(type));
-    registry.registerSendStructure(node, sendStructure);
-    return const NoneResult();
-  }
-
-  /// Handle a type cast expression, like `a as T`.
-  ResolutionResult handleAs(Send node) {
-    Node expression = node.receiver;
-    visitExpression(expression);
-
-    Node typeNode = node.arguments.head;
-    ResolutionDartType type =
-        resolveTypeAnnotation(typeNode, registerCheckedModeCheck: false);
-
-    // GENERIC_METHODS: Method type variables are not reified, so we must inform
-    // the developer about the potentially bug-inducing semantics.
-    if (type is MethodTypeVariableType) {
-      reporter.reportHintMessage(
-          node, MessageKind.TYPE_VARIABLE_FROM_METHOD_CONSIDERED_DYNAMIC);
-    }
-
-    registry.registerTypeUse(new TypeUse.asCast(type));
-    registry.registerSendStructure(node, new AsStructure(type));
-    return const NoneResult();
-  }
-
-  /// Handle the unary expression of an unresolved unary operator [text], like
-  /// the no longer supported `+a`.
-  ResolutionResult handleUnresolvedUnary(Send node, String text) {
-    Node expression = node.receiver;
-    if (node.isSuperCall) {
-      checkSuperAccess(node);
-    } else {
-      visitExpression(expression);
-    }
-
-    registry.registerSendStructure(node, const InvalidUnaryStructure());
-    return const NoneResult();
-  }
-
-  /// Handle the unary expression of a user definable unary [operator], like
-  /// `-a`, and `-super`.
-  ResolutionResult handleUserDefinableUnary(Send node, UnaryOperator operator) {
-    ResolutionResult result = const NoneResult();
-    Node expression = node.receiver;
-    Selector selector = operator.selector;
-    // TODO(23998): Remove this when all information goes through the
-    // [SendStructure].
-    registry.setSelector(node, selector);
-
-    AccessSemantics semantics;
-    if (node.isSuperCall) {
-      semantics = checkSuperAccess(node);
-      if (semantics == null) {
-        semantics = computeSuperAccessSemanticsForSelector(node, selector);
-        // TODO(johnniwinther): Add information to [AccessSemantics] about
-        // whether it is erroneous.
-        if (semantics.kind == AccessKind.SUPER_METHOD) {
-          MethodElement superMethod = semantics.element.declaration;
-          registry.registerStaticUse(
-              new StaticUse.superInvoke(superMethod, selector.callStructure));
-        }
-        // TODO(23998): Remove this when all information goes through
-        // the [SendStructure].
-        registry.useElement(node, semantics.element);
-      }
-    } else {
-      ResolutionResult expressionResult = visitExpression(expression);
-      semantics = const DynamicAccess.expression();
-      registry.registerDynamicUse(new DynamicUse(selector));
-
-      if (expressionResult.isConstant) {
-        bool isValidConstant;
-        ConstantExpression expressionConstant = expressionResult.constant;
-        ResolutionDartType knownExpressionType =
-            expressionConstant.getKnownType(commonElements);
-        switch (operator.kind) {
-          case UnaryOperatorKind.COMPLEMENT:
-            isValidConstant = knownExpressionType == commonElements.intType;
-            break;
-          case UnaryOperatorKind.NEGATE:
-            isValidConstant = knownExpressionType == commonElements.intType ||
-                knownExpressionType == commonElements.doubleType;
-            break;
-          case UnaryOperatorKind.NOT:
-            reporter.internalError(
-                node, "Unexpected user definable unary operator: $operator");
-        }
-        if (isValidConstant) {
-          // TODO(johnniwinther): Handle potentially invalid constant
-          // expressions.
-          ConstantExpression constant =
-              new UnaryConstantExpression(operator, expressionConstant);
-          registry.setConstant(node, constant);
-          result = new ConstantResult(node, constant);
-        }
-      }
-    }
-    if (semantics != null) {
-      registry.registerSendStructure(
-          node, new UnaryStructure(semantics, operator));
-    }
-    return result;
-  }
-
-  /// Handle a not expression, like `!a`.
-  ResolutionResult handleNot(Send node, UnaryOperator operator) {
-    assert(operator.kind == UnaryOperatorKind.NOT, failedAt(node));
-
-    Node expression = node.receiver;
-    ResolutionResult result = visitExpression(expression);
-    registry.registerSendStructure(node, const NotStructure());
-
-    if (result.isConstant) {
-      ConstantExpression expressionConstant = result.constant;
-      if (expressionConstant.getKnownType(commonElements) ==
-          commonElements.boolType) {
-        // TODO(johnniwinther): Handle potentially invalid constant expressions.
-        ConstantExpression constant =
-            new UnaryConstantExpression(operator, expressionConstant);
-        registry.setConstant(node, constant);
-        return new ConstantResult(node, constant);
-      }
-    }
-
-    return const NoneResult();
-  }
-
-  /// Handle a logical and expression, like `a && b`.
-  ResolutionResult handleLogicalAnd(Send node) {
-    Node left = node.receiver;
-    Node right = node.arguments.head;
-    ResolutionResult leftResult =
-        doInPromotionScope(left, () => visitExpression(left));
-    ResolutionResult rightResult =
-        doInPromotionScope(right, () => visitExpression(right));
-    registry.registerSendStructure(node, const LogicalAndStructure());
-
-    if (leftResult.isConstant && rightResult.isConstant) {
-      ConstantExpression leftConstant = leftResult.constant;
-      ConstantExpression rightConstant = rightResult.constant;
-      if (leftConstant.getKnownType(commonElements) ==
-              commonElements.boolType &&
-          rightConstant.getKnownType(commonElements) ==
-              commonElements.boolType) {
-        // TODO(johnniwinther): Handle potentially invalid constant expressions.
-        ConstantExpression constant = new BinaryConstantExpression(
-            leftConstant, BinaryOperator.LOGICAL_AND, rightConstant);
-        registry.setConstant(node, constant);
-        return new ConstantResult(node, constant);
-      }
-    }
-
-    return const NoneResult();
-  }
-
-  /// Handle a logical or expression, like `a || b`.
-  ResolutionResult handleLogicalOr(Send node) {
-    Node left = node.receiver;
-    Node right = node.arguments.head;
-    ResolutionResult leftResult = visitExpression(left);
-    ResolutionResult rightResult = visitExpression(right);
-    registry.registerSendStructure(node, const LogicalOrStructure());
-
-    if (leftResult.isConstant && rightResult.isConstant) {
-      ConstantExpression leftConstant = leftResult.constant;
-      ConstantExpression rightConstant = rightResult.constant;
-      if (leftConstant.getKnownType(commonElements) ==
-              commonElements.boolType &&
-          rightConstant.getKnownType(commonElements) ==
-              commonElements.boolType) {
-        // TODO(johnniwinther): Handle potentially invalid constant expressions.
-        ConstantExpression constant = new BinaryConstantExpression(
-            leftConstant, BinaryOperator.LOGICAL_OR, rightConstant);
-        registry.setConstant(node, constant);
-        return new ConstantResult(node, constant);
-      }
-    }
-    return const NoneResult();
-  }
-
-  /// Handle an if-null expression, like `a ?? b`.
-  ResolutionResult handleIfNull(Send node) {
-    Node left = node.receiver;
-    Node right = node.arguments.head;
-    visitExpression(left);
-    visitExpression(right);
-    registry.registerConstantLiteral(new NullConstantExpression());
-    registry.registerDynamicUse(new DynamicUse(Selectors.equals));
-    registry.registerSendStructure(node, const IfNullStructure());
-    return const NoneResult();
-  }
-
-  /// Handle the binary expression of an unresolved binary operator [text], like
-  /// the no longer supported `a === b`.
-  ResolutionResult handleUnresolvedBinary(Send node, String text) {
-    Node left = node.receiver;
-    Node right = node.arguments.head;
-    if (node.isSuperCall) {
-      checkSuperAccess(node);
-    } else {
-      visitExpression(left);
-    }
-    visitExpression(right);
-    registry.registerSendStructure(node, const InvalidBinaryStructure());
-    return const NoneResult();
-  }
-
-  /// Handle the binary expression of a user definable binary [operator], like
-  /// `a + b`, `super + b`, `a == b` and `a != b`.
-  ResolutionResult handleUserDefinableBinary(
-      Send node, BinaryOperator operator) {
-    ResolutionResult result = const NoneResult();
-    Node left = node.receiver;
-    Node right = node.arguments.head;
-    AccessSemantics semantics;
-    Selector selector;
-    if (operator.kind == BinaryOperatorKind.INDEX) {
-      selector = new Selector.index();
-    } else {
-      selector = new Selector.binaryOperator(operator.selectorName);
-    }
-    // TODO(23998): Remove this when all information goes through the
-    // [SendStructure].
-    registry.setSelector(node, selector);
-
-    if (node.isSuperCall) {
-      semantics = checkSuperAccess(node);
-      if (semantics == null) {
-        semantics = computeSuperAccessSemanticsForSelector(node, selector);
-        // TODO(johnniwinther): Add information to [AccessSemantics] about
-        // whether it is erroneous.
-        if (semantics.kind == AccessKind.SUPER_METHOD) {
-          MethodElement superMethod = semantics.element.declaration;
-          registry.registerStaticUse(
-              new StaticUse.superInvoke(superMethod, selector.callStructure));
-        }
-        // TODO(23998): Remove this when all information goes through
-        // the [SendStructure].
-        registry.useElement(node, semantics.element);
-      }
-      visitExpression(right);
-    } else {
-      ResolutionResult leftResult = visitExpression(left);
-      ResolutionResult rightResult = visitExpression(right);
-      registry.registerDynamicUse(new DynamicUse(selector));
-      semantics = const DynamicAccess.expression();
-
-      if (leftResult.isConstant && rightResult.isConstant) {
-        bool isValidConstant;
-        ConstantExpression leftConstant = leftResult.constant;
-        ConstantExpression rightConstant = rightResult.constant;
-        ResolutionDartType knownLeftType =
-            leftConstant.getKnownType(commonElements);
-        ResolutionDartType knownRightType =
-            rightConstant.getKnownType(commonElements);
-        switch (operator.kind) {
-          case BinaryOperatorKind.EQ:
-          case BinaryOperatorKind.NOT_EQ:
-            isValidConstant = (knownLeftType == commonElements.intType ||
-                    knownLeftType == commonElements.doubleType ||
-                    knownLeftType == commonElements.stringType ||
-                    knownLeftType == commonElements.boolType ||
-                    knownLeftType == commonElements.nullType) &&
-                (knownRightType == commonElements.intType ||
-                    knownRightType == commonElements.doubleType ||
-                    knownRightType == commonElements.stringType ||
-                    knownRightType == commonElements.boolType ||
-                    knownRightType == commonElements.nullType);
-            break;
-          case BinaryOperatorKind.ADD:
-            isValidConstant = (knownLeftType == commonElements.intType ||
-                    knownLeftType == commonElements.doubleType ||
-                    knownLeftType == commonElements.stringType) &&
-                (knownRightType == commonElements.intType ||
-                    knownRightType == commonElements.doubleType ||
-                    knownRightType == commonElements.stringType);
-            break;
-          case BinaryOperatorKind.SUB:
-          case BinaryOperatorKind.MUL:
-          case BinaryOperatorKind.DIV:
-          case BinaryOperatorKind.IDIV:
-          case BinaryOperatorKind.MOD:
-          case BinaryOperatorKind.GTEQ:
-          case BinaryOperatorKind.GT:
-          case BinaryOperatorKind.LTEQ:
-          case BinaryOperatorKind.LT:
-            isValidConstant = (knownLeftType == commonElements.intType ||
-                    knownLeftType == commonElements.doubleType) &&
-                (knownRightType == commonElements.intType ||
-                    knownRightType == commonElements.doubleType);
-            break;
-          case BinaryOperatorKind.SHL:
-          case BinaryOperatorKind.SHR:
-          case BinaryOperatorKind.AND:
-          case BinaryOperatorKind.OR:
-          case BinaryOperatorKind.XOR:
-            isValidConstant = knownLeftType == commonElements.intType &&
-                knownRightType == commonElements.intType;
-            break;
-          case BinaryOperatorKind.INDEX:
-            isValidConstant = false;
-            break;
-          case BinaryOperatorKind.LOGICAL_AND:
-          case BinaryOperatorKind.LOGICAL_OR:
-          case BinaryOperatorKind.IF_NULL:
-            reporter.internalError(
-                node, "Unexpected binary operator '${operator}'.");
-            break;
-        }
-        if (isValidConstant) {
-          // TODO(johnniwinther): Handle potentially invalid constant
-          // expressions.
-          ConstantExpression constant = new BinaryConstantExpression(
-              leftResult.constant, operator, rightResult.constant);
-          registry.setConstant(node, constant);
-          result = new ConstantResult(node, constant);
-        }
-      }
-    }
-
-    if (semantics != null) {
-      // TODO(johnniwinther): Support invalid super access as an
-      // [AccessSemantics].
-      SendStructure sendStructure;
-      switch (operator.kind) {
-        case BinaryOperatorKind.EQ:
-          sendStructure = new EqualsStructure(semantics);
-          break;
-        case BinaryOperatorKind.NOT_EQ:
-          sendStructure = new NotEqualsStructure(semantics);
-          break;
-        case BinaryOperatorKind.INDEX:
-          sendStructure = new IndexStructure(semantics);
-          break;
-        case BinaryOperatorKind.ADD:
-        case BinaryOperatorKind.SUB:
-        case BinaryOperatorKind.MUL:
-        case BinaryOperatorKind.DIV:
-        case BinaryOperatorKind.IDIV:
-        case BinaryOperatorKind.MOD:
-        case BinaryOperatorKind.SHL:
-        case BinaryOperatorKind.SHR:
-        case BinaryOperatorKind.GTEQ:
-        case BinaryOperatorKind.GT:
-        case BinaryOperatorKind.LTEQ:
-        case BinaryOperatorKind.LT:
-        case BinaryOperatorKind.AND:
-        case BinaryOperatorKind.OR:
-        case BinaryOperatorKind.XOR:
-          sendStructure = new BinaryStructure(semantics, operator);
-          break;
-        case BinaryOperatorKind.LOGICAL_AND:
-        case BinaryOperatorKind.LOGICAL_OR:
-        case BinaryOperatorKind.IF_NULL:
-          reporter.internalError(
-              node, "Unexpected binary operator '${operator}'.");
-          break;
-      }
-      registry.registerSendStructure(node, sendStructure);
-    }
-    return result;
-  }
-
-  /// Handle an invocation of an expression, like `(){}()` or `(foo)()`.
-  ResolutionResult handleExpressionInvoke(Send node) {
-    assert(node.isCall, failedAt(node, "Unexpected expression: $node"));
-    Node expression = node.selector;
-    visitExpression(expression);
-    CallStructure callStructure =
-        resolveArguments(node.argumentsNode).callStructure;
-    Selector selector = callStructure.callSelector;
-    // TODO(23998): Remove this when all information goes through the
-    // [SendStructure].
-    registry.setSelector(node, selector);
-    registry.registerDynamicUse(new DynamicUse(selector));
-    registry.registerSendStructure(
-        node, new InvokeStructure(const DynamicAccess.expression(), selector));
-    return const NoneResult();
-  }
-
-  /// Handle access of a property of [name] on `this`, like `this.name` and
-  /// `this.name()`, or `name` and `name()` in instance context.
-  ResolutionResult handleThisPropertyAccess(Send node, Name name) {
-    AccessSemantics semantics = new DynamicAccess.thisProperty(name);
-    return handleDynamicAccessSemantics(node, name, semantics);
-  }
-
-  /// Handle update of a property of [name] on `this`, like `this.name = b` and
-  /// `this.name++`, or `name = b` and `name++` in instance context.
-  ResolutionResult handleThisPropertyUpdate(
-      SendSet node, Name name, Element element) {
-    AccessSemantics semantics = new DynamicAccess.thisProperty(name);
-    return handleDynamicUpdateSemantics(node, name, element, semantics);
-  }
-
-  /// Handle access on `this`, like `this()` and `this` when it is parsed as a
-  /// [Send] node.
-  ResolutionResult handleThisAccess(Send node) {
-    if (node.isCall) {
-      CallStructure callStructure =
-          resolveArguments(node.argumentsNode).callStructure;
-      Selector selector = callStructure.callSelector;
-      // TODO(johnniwinther): Handle invalid this access as an
-      // [AccessSemantics].
-      AccessSemantics accessSemantics = checkThisAccess(node);
-      if (accessSemantics == null) {
-        accessSemantics = const DynamicAccess.thisAccess();
-        registry.registerDynamicUse(new DynamicUse(selector));
-      }
-      registry.registerSendStructure(
-          node, new InvokeStructure(accessSemantics, selector));
-      // TODO(23998): Remove this when all information goes through
-      // the [SendStructure].
-      registry.setSelector(node, selector);
-      return const NoneResult();
-    } else {
-      // TODO(johnniwinther): Handle get of `this` when it is a [Send] node.
-      reporter.internalError(node, "Unexpected node '$node'.");
-    }
-    return const NoneResult();
-  }
-
-  /// Handle access of a super property, like `super.foo` and `super.foo()`.
-  ResolutionResult handleSuperPropertyAccess(Send node, Name name) {
-    Element target;
-    Selector selector;
-    CallStructure callStructure;
-    if (node.isCall) {
-      callStructure = resolveArguments(node.argumentsNode).callStructure;
-      selector = new Selector.call(name, callStructure);
-    } else {
-      selector = new Selector.getter(name);
-    }
-    AccessSemantics semantics = checkSuperAccess(node);
-    if (semantics == null) {
-      semantics = computeSuperAccessSemanticsForSelector(node, selector,
-          alternateName: name.setter);
-    }
-    if (node.isCall) {
-      bool isIncompatibleInvoke = false;
-      switch (semantics.kind) {
-        case AccessKind.SUPER_METHOD:
-          MethodElement superMethod = semantics.element;
-          superMethod.computeType(resolution);
-          if (!callStructure.signatureApplies(superMethod.parameterStructure)) {
-            registry.registerFeature(Feature.THROW_NO_SUCH_METHOD);
-            registry.registerDynamicUse(new DynamicUse(selector));
-            registry.registerFeature(Feature.SUPER_NO_SUCH_METHOD);
-            isIncompatibleInvoke = true;
-          } else {
-            registry.registerStaticUse(
-                new StaticUse.superInvoke(superMethod, callStructure));
-          }
-          break;
-        case AccessKind.SUPER_FIELD:
-        case AccessKind.SUPER_FINAL_FIELD:
-        case AccessKind.SUPER_GETTER:
-          MemberElement superMember = semantics.element;
-          registry.registerStaticUse(new StaticUse.superGet(superMember));
-          selector = callStructure.callSelector;
-          registry.registerDynamicUse(new DynamicUse(selector));
-          break;
-        case AccessKind.SUPER_SETTER:
-        case AccessKind.UNRESOLVED_SUPER:
-          // NoSuchMethod registered in [computeSuperSemantics].
-          break;
-        case AccessKind.INVALID:
-          // 'super' is not allowed.
-          break;
-        default:
-          reporter.internalError(
-              node, "Unexpected super property access $semantics.");
-          break;
-      }
-      registry.registerSendStructure(
-          node,
-          isIncompatibleInvoke
-              ? new IncompatibleInvokeStructure(semantics, selector)
-              : new InvokeStructure(semantics, selector));
-    } else {
-      switch (semantics.kind) {
-        case AccessKind.SUPER_METHOD:
-          // TODO(johnniwinther): Method this should be registered as a
-          // closurization.
-          MethodElement superMethod = semantics.element;
-          registry.registerStaticUse(new StaticUse.superTearOff(superMethod));
-          break;
-        case AccessKind.SUPER_FIELD:
-        case AccessKind.SUPER_FINAL_FIELD:
-        case AccessKind.SUPER_GETTER:
-          MemberElement superMember = semantics.element;
-          registry.registerStaticUse(new StaticUse.superGet(superMember));
-          break;
-        case AccessKind.SUPER_SETTER:
-        case AccessKind.UNRESOLVED_SUPER:
-          // NoSuchMethod registered in [computeSuperSemantics].
-          break;
-        case AccessKind.INVALID:
-          // 'super' is not allowed.
-          break;
-        default:
-          reporter.internalError(
-              node, "Unexpected super property access $semantics.");
-          break;
-      }
-      registry.registerSendStructure(node, new GetStructure(semantics));
-    }
-    target = semantics.element;
-
-    // TODO(23998): Remove these when all information goes through
-    // the [SendStructure].
-    registry.useElement(node, target);
-    registry.setSelector(node, selector);
-    return const NoneResult();
-  }
-
-  /// Handle a [Send] whose selector is an [Operator], like `a && b`, `a is T`,
-  /// `a + b`, and `~a`.
-  // ignore: MISSING_RETURN
-  ResolutionResult handleOperatorSend(Send node) {
-    String operatorText = node.selector.asOperator().source;
-    if (operatorText == 'is') {
-      return handleIs(node);
-    } else if (operatorText == 'as') {
-      return handleAs(node);
-    } else if (node.arguments.isEmpty) {
-      UnaryOperator operator = UnaryOperator.parse(operatorText);
-      if (operator == null) {
-        return handleUnresolvedUnary(node, operatorText);
-      } else {
-        switch (operator.kind) {
-          case UnaryOperatorKind.NOT:
-            return handleNot(node, operator);
-          case UnaryOperatorKind.COMPLEMENT:
-          case UnaryOperatorKind.NEGATE:
-            assert(operator.isUserDefinable,
-                failedAt(node, "Unexpected unary operator '${operator}'."));
-            return handleUserDefinableUnary(node, operator);
-        }
-      }
-    } else {
-      BinaryOperator operator = BinaryOperator.parse(operatorText);
-      if (operator == null) {
-        return handleUnresolvedBinary(node, operatorText);
-      } else {
-        switch (operator.kind) {
-          case BinaryOperatorKind.LOGICAL_AND:
-            return handleLogicalAnd(node);
-          case BinaryOperatorKind.LOGICAL_OR:
-            return handleLogicalOr(node);
-          case BinaryOperatorKind.IF_NULL:
-            return handleIfNull(node);
-          case BinaryOperatorKind.EQ:
-          case BinaryOperatorKind.NOT_EQ:
-          case BinaryOperatorKind.INDEX:
-          case BinaryOperatorKind.ADD:
-          case BinaryOperatorKind.SUB:
-          case BinaryOperatorKind.MUL:
-          case BinaryOperatorKind.DIV:
-          case BinaryOperatorKind.IDIV:
-          case BinaryOperatorKind.MOD:
-          case BinaryOperatorKind.SHL:
-          case BinaryOperatorKind.SHR:
-          case BinaryOperatorKind.GTEQ:
-          case BinaryOperatorKind.GT:
-          case BinaryOperatorKind.LTEQ:
-          case BinaryOperatorKind.LT:
-          case BinaryOperatorKind.AND:
-          case BinaryOperatorKind.OR:
-          case BinaryOperatorKind.XOR:
-            return handleUserDefinableBinary(node, operator);
-        }
-      }
-    }
-  }
-
-  /// Handle qualified access to an unresolved static class member, like `a.b`
-  /// or `a.b()` where `a` is a class and `b` is unresolved.
-  ResolutionResult handleUnresolvedStaticMemberAccess(
-      Send node, Name name, ClassElement receiverClass) {
-    // TODO(johnniwinther): Share code with [handleStaticInstanceMemberAccess]
-    // and [handlePrivateStaticMemberAccess].
-    registry.registerFeature(Feature.THROW_NO_SUCH_METHOD);
-    // TODO(johnniwinther): Produce a different error if [name] is resolves to
-    // a constructor.
-
-    // TODO(johnniwinther): With the simplified [TreeElements] invariant,
-    // try to resolve injected elements if [currentClass] is in the patch
-    // library of [receiverClass].
-
-    // TODO(karlklose): this should be reported by the caller of
-    // [resolveSend] to select better warning messages for getters and
-    // setters.
-    ErroneousElement error = reportAndCreateErroneousElement(
-        node,
-        name.text,
-        MessageKind.UNDEFINED_GETTER,
-        {'className': receiverClass.name, 'memberName': name.text});
-    // TODO(johnniwinther): Add an [AccessSemantics] for unresolved static
-    // member access.
-    return handleErroneousAccess(
-        node, name, new StaticAccess.unresolved(error));
-  }
-
-  /// Handle qualified update to an unresolved static class member, like
-  /// `a.b = c` or `a.b++` where `a` is a class and `b` is unresolved.
-  ResolutionResult handleUnresolvedStaticMemberUpdate(
-      SendSet node, Name name, ClassElement receiverClass) {
-    // TODO(johnniwinther): Share code with [handleStaticInstanceMemberUpdate]
-    // and [handlePrivateStaticMemberUpdate].
-    registry.registerFeature(Feature.THROW_NO_SUCH_METHOD);
-    // TODO(johnniwinther): Produce a different error if [name] is resolves to
-    // a constructor.
-
-    // TODO(johnniwinther): With the simplified [TreeElements] invariant,
-    // try to resolve injected elements if [currentClass] is in the patch
-    // library of [receiverClass].
-
-    // TODO(johnniwinther): Produce a different error for complex update.
-    ErroneousElement error = reportAndCreateErroneousElement(
-        node,
-        name.text,
-        MessageKind.UNDEFINED_GETTER,
-        {'className': receiverClass.name, 'memberName': name.text});
-    // TODO(johnniwinther): Add an [AccessSemantics] for unresolved static
-    // member access.
-    return handleUpdate(node, name, new StaticAccess.unresolved(error));
-  }
-
-  /// Handle qualified access of an instance member, like `a.b` or `a.b()` where
-  /// `a` is a class and `b` is a non-static member.
-  ResolutionResult handleStaticInstanceMemberAccess(
-      Send node, Name name, ClassElement receiverClass, Element member) {
-    registry.registerFeature(Feature.THROW_NO_SUCH_METHOD);
-    // TODO(johnniwinther): With the simplified [TreeElements] invariant,
-    // try to resolve injected elements if [currentClass] is in the patch
-    // library of [receiverClass].
-
-    // TODO(karlklose): this should be reported by the caller of
-    // [resolveSend] to select better warning messages for getters and
-    // setters.
-    ErroneousElement error = reportAndCreateErroneousElement(
-        node,
-        name.text,
-        MessageKind.MEMBER_NOT_STATIC,
-        {'className': receiverClass.name, 'memberName': name});
-
-    // TODO(johnniwinther): Add an [AccessSemantics] for statically accessed
-    // instance members.
-    return handleErroneousAccess(
-        node, name, new StaticAccess.unresolved(error));
-  }
-
-  /// Handle qualified update of an instance member, like `a.b = c` or `a.b++`
-  /// where `a` is a class and `b` is a non-static member.
-  ResolutionResult handleStaticInstanceMemberUpdate(
-      SendSet node, Name name, ClassElement receiverClass, Element member) {
-    registry.registerFeature(Feature.THROW_NO_SUCH_METHOD);
-    // TODO(johnniwinther): With the simplified [TreeElements] invariant,
-    // try to resolve injected elements if [currentClass] is in the patch
-    // library of [receiverClass].
-
-    // TODO(johnniwinther): Produce a different error for complex update.
-    ErroneousElement error = reportAndCreateErroneousElement(
-        node,
-        name.text,
-        MessageKind.MEMBER_NOT_STATIC,
-        {'className': receiverClass.name, 'memberName': name});
-
-    // TODO(johnniwinther): Add an [AccessSemantics] for statically accessed
-    // instance members.
-    return handleUpdate(node, name, new StaticAccess.unresolved(error));
-  }
-
-  /// Handle qualified access of an inaccessible private static class member,
-  /// like `a._b` or `a._b()` where `a` is class, `_b` is static member of `a`
-  /// but `a` is not defined in the current library.
-  ResolutionResult handlePrivateStaticMemberAccess(
-      Send node, Name name, ClassElement receiverClass, Element member) {
-    registry.registerFeature(Feature.THROW_NO_SUCH_METHOD);
-    ErroneousElement error = reportAndCreateErroneousElement(
-        node,
-        name.text,
-        MessageKind.PRIVATE_ACCESS,
-        {'libraryName': member.library.name, 'name': name});
-    // TODO(johnniwinther): Add an [AccessSemantics] for unresolved static
-    // member access.
-    return handleErroneousAccess(
-        node, name, new StaticAccess.unresolved(error));
-  }
-
-  /// Handle qualified update of an inaccessible private static class member,
-  /// like `a._b = c` or `a._b++` where `a` is class, `_b` is static member of
-  /// `a` but `a` is not defined in the current library.
-  ResolutionResult handlePrivateStaticMemberUpdate(
-      SendSet node, Name name, ClassElement receiverClass, Element member) {
-    registry.registerFeature(Feature.THROW_NO_SUCH_METHOD);
-    ErroneousElement error = reportAndCreateErroneousElement(
-        node,
-        name.text,
-        MessageKind.PRIVATE_ACCESS,
-        {'libraryName': member.library.name, 'name': name});
-    // TODO(johnniwinther): Add an [AccessSemantics] for unresolved static
-    // member access.
-    return handleUpdate(node, name, new StaticAccess.unresolved(error));
-  }
-
-  /// Handle qualified access to a static member, like `a.b` or `a.b()` where
-  /// `a` is a class and `b` is a static member of `a`.
-  ResolutionResult handleStaticMemberAccess(
-      Send node, Name memberName, ClassElement receiverClass) {
-    String name = memberName.text;
-    receiverClass.ensureResolved(resolution);
-    if (node.isOperator) {
-      // When the resolved receiver is a class, we can have two cases:
-      //  1) a static send: C.foo, or
-      //  2) an operator send, where the receiver is a class literal: 'C + 1'.
-      // The following code that looks up the selector on the resolved
-      // receiver will treat the second as the invocation of a static operator
-      // if the resolved receiver is not null.
-      return const NoneResult();
-    }
-    MembersCreator.computeClassMembersByName(
-        resolution, receiverClass.declaration, name);
-    Element member = receiverClass.lookupLocalMember(name);
-    if (member == null) {
-      return handleUnresolvedStaticMemberAccess(
-          node, memberName, receiverClass);
-    } else if (member.isAmbiguous) {
-      return handleAmbiguousSend(node, memberName, member);
-    } else if (member.isInstanceMember) {
-      return handleStaticInstanceMemberAccess(
-          node, memberName, receiverClass, member);
-    } else if (memberName.isPrivate && memberName.library != member.library) {
-      return handlePrivateStaticMemberAccess(
-          node, memberName, receiverClass, member);
-    } else {
-      return handleStaticOrTopLevelAccess(node, memberName, member);
-    }
-  }
-
-  /// Handle qualified update to a static member, like `a.b = c` or `a.b++`
-  /// where `a` is a class and `b` is a static member of `a`.
-  ResolutionResult handleStaticMemberUpdate(
-      Send node, Name memberName, ClassElement receiverClass) {
-    String name = memberName.text;
-    receiverClass.ensureResolved(resolution);
-    MembersCreator.computeClassMembersByName(
-        resolution, receiverClass.declaration, name);
-    Element member = receiverClass.lookupLocalMember(name);
-    if (member == null) {
-      return handleUnresolvedStaticMemberUpdate(
-          node, memberName, receiverClass);
-    } else if (member.isAmbiguous) {
-      return handleAmbiguousUpdate(node, memberName, member);
-    } else if (member.isInstanceMember) {
-      return handleStaticInstanceMemberUpdate(
-          node, memberName, receiverClass, member);
-    } else if (memberName.isPrivate && memberName.library != member.library) {
-      return handlePrivateStaticMemberUpdate(
-          node, memberName, receiverClass, member);
-    } else {
-      return handleStaticOrTopLevelUpdate(node, memberName, member);
-    }
-  }
-
-  /// Handle access to a type literal of type variable [element]. Like `T` or
-  /// `T()` where 'T' is type variable.
-  // TODO(johnniwinther): Remove [name] when [Selector] is not required for the
-  // the [GetStructure].
-  // TODO(johnniwinther): Remove [element] when it is no longer needed for
-  // evaluating constants.
-  ResolutionResult handleTypeVariableTypeLiteralAccess(
-      Send node, Name name, TypeVariableElement element) {
-    AccessSemantics semantics;
-    if (!Elements.hasAccessToTypeVariable(enclosingElement, element)) {
-      // TODO(johnniwinther): Add another access semantics for this.
-      ErroneousElement error = reportAndCreateErroneousElement(
-          node,
-          name.text,
-          MessageKind.TYPE_VARIABLE_WITHIN_STATIC_MEMBER,
-          {'typeVariableName': name},
-          isError: true);
-      registry.registerFeature(Feature.COMPILE_TIME_ERROR);
-      semantics = new StaticAccess.invalid(error);
-      // TODO(johnniwinther): Clean up registration of elements and selectors
-      // for this case.
-    } else {
-      // GENERIC_METHODS: Method type variables are not reified so we must warn
-      // about the error which will occur at runtime.
-      if (element.type is MethodTypeVariableType) {
-        reporter.reportWarningMessage(
-            node, MessageKind.TYPE_VARIABLE_FROM_METHOD_NOT_REIFIED);
-      }
-      semantics = new StaticAccess.typeParameterTypeLiteral(element);
-    }
-
-    registry.useElement(node, element);
-    registry.registerTypeLiteral(node, element.type);
-
-    if (node.isCall) {
-      CallStructure callStructure =
-          resolveArguments(node.argumentsNode).callStructure;
-      Selector selector = callStructure.callSelector;
-      // TODO(23998): Remove this when all information goes through
-      // the [SendStructure].
-      registry.setSelector(node, selector);
-
-      registry.registerSendStructure(
-          node, new InvokeStructure(semantics, selector));
-    } else {
-      // TODO(johnniwinther): Avoid the need for a [Selector] here.
-      registry.registerSendStructure(node, new GetStructure(semantics));
-    }
-    return const NoneResult();
-  }
-
-  /// Handle access to a type literal of type variable [element]. Like `T = b`,
-  /// `T++` or `T += b` where 'T' is type variable.
-  ResolutionResult handleTypeVariableTypeLiteralUpdate(
-      SendSet node, Name name, TypeVariableElement element) {
-    AccessSemantics semantics;
-    if (!Elements.hasAccessToTypeVariable(enclosingElement, element)) {
-      // TODO(johnniwinther): Add another access semantics for this.
-      ErroneousElement error = reportAndCreateErroneousElement(
-          node,
-          name.text,
-          MessageKind.TYPE_VARIABLE_WITHIN_STATIC_MEMBER,
-          {'typeVariableName': name},
-          isError: true);
-      registry.registerFeature(Feature.COMPILE_TIME_ERROR);
-      semantics = new StaticAccess.invalid(error);
-    } else {
-      ErroneousElement error;
-      if (node.isIfNullAssignment) {
-        error = reportAndCreateErroneousElement(node.selector, name.text,
-            MessageKind.IF_NULL_ASSIGNING_TYPE, const {});
-        // TODO(23998): Remove these when all information goes through
-        // the [SendStructure].
-        registry.useElement(node.selector, element);
-      } else {
-        error = reportAndCreateErroneousElement(
-            node.selector, name.text, MessageKind.ASSIGNING_TYPE, const {});
-      }
-
-      // TODO(23998): Remove this when all information goes through
-      // the [SendStructure].
-      registry.useElement(node, error);
-      // TODO(johnniwinther): Register only on read?
-      registry.registerTypeLiteral(node, element.type);
-      registry.registerFeature(Feature.THROW_NO_SUCH_METHOD);
-      semantics = new StaticAccess.typeParameterTypeLiteral(element);
-    }
-    return handleUpdate(node, name, semantics);
-  }
-
-  /// Handle access to a constant type literal of [type].
-  // TODO(johnniwinther): Remove [name] when [Selector] is not required for the
-  // the [GetStructure].
-  // TODO(johnniwinther): Remove [element] when it is no longer needed for
-  // evaluating constants.
-  ResolutionResult handleConstantTypeLiteralAccess(
-      Send node,
-      Name name,
-      TypeDeclarationElement element,
-      ResolutionDartType type,
-      ConstantAccess semantics) {
-    registry.useElement(node, element);
-    registry.registerTypeLiteral(node, type);
-
-    if (node.isCall) {
-      CallStructure callStructure =
-          resolveArguments(node.argumentsNode).callStructure;
-      Selector selector = callStructure.callSelector;
-      // TODO(23998): Remove this when all information goes through
-      // the [SendStructure].
-      registry.setSelector(node, selector);
-
-      // The node itself is not a constant but we register the selector (the
-      // identifier that refers to the class/typedef) as a constant.
-      registry.useElement(node.selector, element);
-      analyzeConstantDeferred(node.selector, enforceConst: false);
-
-      registry.registerSendStructure(
-          node, new InvokeStructure(semantics, selector));
-      return const NoneResult();
-    } else {
-      analyzeConstantDeferred(node, enforceConst: false);
-
-      registry.setConstant(node, semantics.constant);
-      registry.registerSendStructure(node, new GetStructure(semantics));
-      return new ConstantResult(node, semantics.constant);
-    }
-  }
-
-  /// Handle access to a constant type literal of [type].
-  // TODO(johnniwinther): Remove [name] when [Selector] is not required for the
-  // the [GetStructure].
-  // TODO(johnniwinther): Remove [element] when it is no longer needed for
-  // evaluating constants.
-  ResolutionResult handleConstantTypeLiteralUpdate(
-      SendSet node,
-      Name name,
-      TypeDeclarationElement element,
-      ResolutionDartType type,
-      ConstantAccess semantics) {
-    // TODO(johnniwinther): Remove this when all constants are evaluated.
-    resolver.constantCompiler.evaluate(semantics.constant);
-
-    ErroneousElement error;
-    if (node.isIfNullAssignment) {
-      error = reportAndCreateErroneousElement(node.selector, name.text,
-          MessageKind.IF_NULL_ASSIGNING_TYPE, const {});
-      // TODO(23998): Remove these when all information goes through
-      // the [SendStructure].
-      registry.setConstant(node.selector, semantics.constant);
-      registry.useElement(node.selector, element);
-    } else {
-      error = reportAndCreateErroneousElement(
-          node.selector, name.text, MessageKind.ASSIGNING_TYPE, const {});
-    }
-
-    // TODO(23998): Remove this when all information goes through
-    // the [SendStructure].
-    registry.useElement(node, error);
-    registry.registerTypeLiteral(node, type);
-    registry.registerFeature(Feature.THROW_NO_SUCH_METHOD);
-
-    return handleUpdate(node, name, semantics);
-  }
-
-  /// Handle access to a type literal of a typedef. Like `F` or
-  /// `F()` where 'F' is typedef.
-  ResolutionResult handleTypedefTypeLiteralAccess(
-      Send node, Name name, TypedefElement typdef) {
-    typdef.ensureResolved(resolution);
-    ResolutionDartType type = typdef.rawType;
-    ConstantExpression constant = new TypeConstantExpression(type, name.text);
-    AccessSemantics semantics = new ConstantAccess.typedefTypeLiteral(constant);
-    return handleConstantTypeLiteralAccess(node, name, typdef, type, semantics);
-  }
-
-  /// Handle access to a type literal of a typedef. Like `F = b`, `F++` or
-  /// `F += b` where 'F' is typedef.
-  ResolutionResult handleTypedefTypeLiteralUpdate(
-      SendSet node, Name name, TypedefElement typdef) {
-    typdef.ensureResolved(resolution);
-    ResolutionDartType type = typdef.rawType;
-    ConstantExpression constant = new TypeConstantExpression(type, name.text);
-    AccessSemantics semantics = new ConstantAccess.typedefTypeLiteral(constant);
-    return handleConstantTypeLiteralUpdate(node, name, typdef, type, semantics);
-  }
-
-  /// Handle access to a type literal of the type 'dynamic'. Like `dynamic` or
-  /// `dynamic()`.
-  ResolutionResult handleDynamicTypeLiteralAccess(Send node) {
-    ResolutionDartType type = const ResolutionDynamicType();
-    ConstantExpression constant = new TypeConstantExpression(
-        // TODO(johnniwinther): Use [type] when evaluation of constants is done
-        // directly on the constant expressions.
-        node.isCall ? commonElements.typeType : type,
-        'dynamic');
-    AccessSemantics semantics = new ConstantAccess.dynamicTypeLiteral(constant);
-    ClassElement typeClass = commonElements.typeClass;
-    return handleConstantTypeLiteralAccess(
-        node, const PublicName('dynamic'), typeClass, type, semantics);
-  }
-
-  /// Handle update to a type literal of the type 'dynamic'. Like `dynamic++` or
-  /// `dynamic = 0`.
-  ResolutionResult handleDynamicTypeLiteralUpdate(SendSet node) {
-    ResolutionDartType type = const ResolutionDynamicType();
-    ConstantExpression constant =
-        new TypeConstantExpression(const ResolutionDynamicType(), 'dynamic');
-    AccessSemantics semantics = new ConstantAccess.dynamicTypeLiteral(constant);
-    ClassElement typeClass = commonElements.typeClass;
-    return handleConstantTypeLiteralUpdate(
-        node, const PublicName('dynamic'), typeClass, type, semantics);
-  }
-
-  /// Handle access to a type literal of a class. Like `C` or
-  /// `C()` where 'C' is class.
-  ResolutionResult handleClassTypeLiteralAccess(
-      Send node, Name name, ClassElement cls) {
-    cls.ensureResolved(resolution);
-    ResolutionDartType type = cls.rawType;
-    ConstantExpression constant = new TypeConstantExpression(type, name.text);
-    AccessSemantics semantics = new ConstantAccess.classTypeLiteral(constant);
-    return handleConstantTypeLiteralAccess(node, name, cls, type, semantics);
-  }
-
-  /// Handle access to a type literal of a class. Like `C = b`, `C++` or
-  /// `C += b` where 'C' is class.
-  ResolutionResult handleClassTypeLiteralUpdate(
-      SendSet node, Name name, ClassElement cls) {
-    cls.ensureResolved(resolution);
-    ResolutionDartType type = cls.rawType;
-    ConstantExpression constant = new TypeConstantExpression(type, name.text);
-    AccessSemantics semantics = new ConstantAccess.classTypeLiteral(constant);
-    return handleConstantTypeLiteralUpdate(node, name, cls, type, semantics);
-  }
-
-  /// Handle a [Send] that resolves to a [prefix]. Like `prefix` in
-  /// `prefix.Class` or `prefix` in `prefix()`, the latter being a compile time
-  /// error.
-  ResolutionResult handleClassSend(Send node, Name name, ClassElement cls) {
-    cls.ensureResolved(resolution);
-    if (sendIsMemberAccess) {
-      registry.useElement(node, cls);
-      return new PrefixResult(null, cls);
-    } else {
-      // `C` or `C()` where 'C' is a class.
-      return handleClassTypeLiteralAccess(node, name, cls);
-    }
-  }
-
-  /// Compute a [DeferredPrefixStructure] for [node].
-  ResolutionResult handleDeferredAccess(
-      Send node, PrefixElement prefix, ResolutionResult result) {
-    assert(
-        prefix.isDeferred, failedAt(node, "Prefix $prefix is not deferred."));
-    SendStructure sendStructure = registry.getSendStructure(node);
-    assert(
-        sendStructure != null, failedAt(node, "No SendStructure for $node."));
-    registry.registerSendStructure(
-        node, new DeferredPrefixStructure(prefix, sendStructure));
-    if (result.isConstant) {
-      ConstantExpression constant = new DeferredConstantExpression(
-          result.constant, prefix.deferredImport);
-      registry.setConstant(node, constant);
-      result = new ConstantResult(node, constant);
-    }
-    return result;
-  }
-
-  /// Handle qualified [Send] where the receiver resolves to a [prefix],
-  /// like `prefix.toplevelFunction()` or `prefix.Class.staticField` where
-  /// `prefix` is a library prefix.
-  ResolutionResult handleLibraryPrefixSend(
-      Send node, Name name, PrefixElement prefix) {
-    ResolutionResult result;
-    Element member = prefix.lookupLocalMember(name.text);
-    if (member == null) {
-      registry.registerFeature(Feature.THROW_NO_SUCH_METHOD);
-      Element error = reportAndCreateErroneousElement(
-          node,
-          name.text,
-          MessageKind.NO_SUCH_LIBRARY_MEMBER,
-          {'libraryName': prefix.name, 'memberName': name});
-      result = handleUnresolvedAccess(node, name, error);
-    } else {
-      result = handleResolvedSend(node, name, member);
-    }
-    if (result.kind == ResultKind.PREFIX) {
-      // [member] is a class prefix of a static access like `prefix.Class` of
-      // `prefix.Class.foo`. No need to call [handleDeferredAccess]; it will
-      // called on the parent `prefix.Class.foo` node.
-      result = new PrefixResult(prefix, result.element);
-    } else if (prefix.isDeferred &&
-        (member == null || !member.isDeferredLoaderGetter)) {
-      result = handleDeferredAccess(node, prefix, result);
-    }
-    return result;
-  }
-
-  /// Handle qualified [SendSet] where the receiver resolves to a [prefix],
-  /// like `prefix.toplevelField = b` or `prefix.Class.staticField++` where
-  /// `prefix` is a library prefix.
-  ResolutionResult handleLibraryPrefixSendSet(
-      SendSet node, Name name, PrefixElement prefix) {
-    ResolutionResult result;
-    Element member = prefix.lookupLocalMember(name.text);
-    if (member == null) {
-      registry.registerFeature(Feature.THROW_NO_SUCH_METHOD);
-      Element error = reportAndCreateErroneousElement(
-          node,
-          name.text,
-          MessageKind.NO_SUCH_LIBRARY_MEMBER,
-          {'libraryName': prefix.name, 'memberName': name});
-      return handleUpdate(node, name, new StaticAccess.unresolved(error));
-    } else {
-      result = handleResolvedSendSet(node, name, member);
-    }
-    if (result.kind == ResultKind.PREFIX) {
-      // [member] is a class prefix of a static access like `prefix.Class` of
-      // `prefix.Class.foo`. No need to call [handleDeferredAccess]; it will
-      // called on the parent `prefix.Class.foo` node.
-      result = new PrefixResult(prefix, result.element);
-    } else if (prefix.isDeferred &&
-        (member == null || !member.isDeferredLoaderGetter)) {
-      result = handleDeferredAccess(node, prefix, result);
-    }
-    return result;
-  }
-
-  /// Handle a [Send] that resolves to a [prefix]. Like `prefix` in
-  /// `prefix.Class` or `prefix` in `prefix()`, the latter being a compile time
-  /// error.
-  ResolutionResult handleLibraryPrefix(
-      Send node, Name name, PrefixElement prefix) {
-    if ((ElementCategory.PREFIX & allowedCategory) == 0) {
-      ErroneousElement error = reportAndCreateErroneousElement(
-          node, name.text, MessageKind.PREFIX_AS_EXPRESSION, {'prefix': name},
-          isError: true);
-      registry.registerFeature(Feature.COMPILE_TIME_ERROR);
-      return handleErroneousAccess(node, name, new StaticAccess.invalid(error));
-    }
-    if (prefix.isDeferred) {
-      // TODO(23998): Remove this when deferred access is detected
-      // through a [SendStructure].
-      registry.useElement(node.selector, prefix);
-    }
-    registry.useElement(node, prefix);
-    return new PrefixResult(prefix, null);
-  }
-
-  /// Handle qualified [Send] where the receiver resolves to an [Element], like
-  /// `a.b` where `a` is a prefix or a class.
-  ResolutionResult handlePrefixSend(
-      Send node, Name name, PrefixResult prefixResult) {
-    Element element = prefixResult.element;
-    if (element.isPrefix) {
-      if (node.isConditional) {
-        return handleLibraryPrefix(node, name, element);
-      } else {
-        return handleLibraryPrefixSend(node, name, element);
-      }
-    } else {
-      assert(element.isClass);
-      ResolutionResult result = handleStaticMemberAccess(node, name, element);
-      if (prefixResult.isDeferred) {
-        result = handleDeferredAccess(node, prefixResult.prefix, result);
-      }
-      return result;
-    }
-  }
-
-  /// Handle qualified [SendSet] where the receiver resolves to an [Element],
-  /// like `a.b = c` where `a` is a prefix or a class.
-  ResolutionResult handlePrefixSendSet(
-      SendSet node, Name name, PrefixResult prefixResult) {
-    Element element = prefixResult.element;
-    if (element.isPrefix) {
-      if (node.isConditional) {
-        return handleLibraryPrefix(node, name, element);
-      } else {
-        return handleLibraryPrefixSendSet(node, name, element);
-      }
-    } else {
-      assert(element.isClass);
-      ResolutionResult result = handleStaticMemberUpdate(node, name, element);
-      if (prefixResult.isDeferred) {
-        result = handleDeferredAccess(node, prefixResult.prefix, result);
-      }
-      return result;
-    }
-  }
-
-  /// Handle dynamic access of [semantics].
-  ResolutionResult handleDynamicAccessSemantics(
-      Send node, Name name, AccessSemantics semantics) {
-    SendStructure sendStructure;
-    Selector selector;
-    if (node.isCall) {
-      CallStructure callStructure =
-          resolveArguments(node.argumentsNode).callStructure;
-      selector = new Selector.call(name, callStructure);
-      registry.registerDynamicUse(new DynamicUse(selector));
-      sendStructure = new InvokeStructure(semantics, selector);
-    } else {
-      assert(node.isPropertyAccess, failedAt(node));
-      selector = new Selector.getter(name);
-      registry.registerDynamicUse(new DynamicUse(selector));
-      sendStructure = new GetStructure(semantics);
-    }
-    registry.registerSendStructure(node, sendStructure);
-    // TODO(23998): Remove this when all information goes through
-    // the [SendStructure].
-    registry.setSelector(node, selector);
-    return const NoneResult();
-  }
-
-  /// Handle dynamic update of [semantics].
-  ResolutionResult handleDynamicUpdateSemantics(
-      SendSet node, Name name, Element element, AccessSemantics semantics) {
-    Selector getterSelector = new Selector.getter(name);
-    Selector setterSelector = new Selector.setter(name.setter);
-    registry.registerDynamicUse(new DynamicUse(setterSelector));
-    if (node.isComplex) {
-      registry.registerDynamicUse(new DynamicUse(getterSelector));
-    }
-
-    // TODO(23998): Remove these when elements are only accessed through the
-    // send structure.
-    Element getter = element;
-    Element setter = element;
-    if (element != null && element.isAbstractField) {
-      AbstractFieldElement abstractField = element;
-      getter = abstractField.getter;
-      setter = abstractField.setter;
-    }
-    if (setter != null) {
-      registry.useElement(node, setter);
-      if (getter != null && node.isComplex) {
-        registry.useElement(node.selector, getter);
-      }
-    }
-
-    return handleUpdate(node, name, semantics);
-  }
-
-  /// Handle `this` as a qualified property, like `a.this`.
-  ResolutionResult handleQualifiedThisAccess(Send node, Name name) {
-    ErroneousElement error = reportAndCreateErroneousElement(
-        node.selector, name.text, MessageKind.THIS_PROPERTY, {},
-        isError: true);
-    registry.registerFeature(Feature.COMPILE_TIME_ERROR);
-    AccessSemantics accessSemantics = new StaticAccess.invalid(error);
-    return handleErroneousAccess(node, name, accessSemantics);
-  }
-
-  /// Handle a qualified [Send], that is where the receiver is non-null, like
-  /// `a.b`, `a.b()`, `this.a()` and `super.a()`.
-  ResolutionResult handleQualifiedSend(Send node) {
-    Identifier selector = node.selector.asIdentifier();
-    String text = selector.source;
-    Name name = new Name(text, enclosingElement.library);
-    if (text == 'this') {
-      return handleQualifiedThisAccess(node, name);
-    } else if (node.isSuperCall) {
-      return handleSuperPropertyAccess(node, name);
-    } else if (node.receiver.isThis()) {
-      AccessSemantics semantics = checkThisAccess(node);
-      if (semantics == null) {
-        return handleThisPropertyAccess(node, name);
-      } else {
-        // TODO(johnniwinther): Handle invalid this access as an
-        // [AccessSemantics].
-        return handleErroneousAccess(node, name, semantics);
-      }
-    }
-    ResolutionResult result = visitExpressionPrefix(node.receiver);
-    if (result.kind == ResultKind.PREFIX) {
-      return handlePrefixSend(node, name, result);
-    } else if (node.isConditional) {
-      registry.registerConstantLiteral(new NullConstantExpression());
-      registry.registerDynamicUse(new DynamicUse(Selectors.equals));
-      return handleDynamicAccessSemantics(
-          node, name, new DynamicAccess.ifNotNullProperty(name));
-    } else {
-      // Handle dynamic property access, like `a.b` or `a.b()` where `a` is not
-      // a prefix or class.
-      // TODO(johnniwinther): Use the `element` of [result].
-      return handleDynamicAccessSemantics(
-          node, name, new DynamicAccess.dynamicProperty(name));
-    }
-  }
-
-  /// Handle a qualified [SendSet], that is where the receiver is non-null, like
-  /// `a.b = c`, `a.b++`, and `a.b += c`.
-  ResolutionResult handleQualifiedSendSet(SendSet node) {
-    Identifier selector = node.selector.asIdentifier();
-    String text = selector.source;
-    Name name = new Name(text, enclosingElement.library);
-    if (text == 'this') {
-      return handleQualifiedThisAccess(node, name);
-    } else if (node.receiver.isThis()) {
-      AccessSemantics semantics = checkThisAccess(node);
-      if (semantics == null) {
-        return handleThisPropertyUpdate(node, name, null);
-      } else {
-        // TODO(johnniwinther): Handle invalid this access as an
-        // [AccessSemantics].
-        return handleUpdate(node, name, semantics);
-      }
-    }
-    ResolutionResult result = visitExpressionPrefix(node.receiver);
-    if (result.kind == ResultKind.PREFIX) {
-      return handlePrefixSendSet(node, name, result);
-    } else if (node.isConditional) {
-      registry.registerConstantLiteral(new NullConstantExpression());
-      registry.registerDynamicUse(new DynamicUse(Selectors.equals));
-      return handleDynamicUpdateSemantics(
-          node, name, null, new DynamicAccess.ifNotNullProperty(name));
-    } else {
-      // Handle dynamic property access, like `a.b = c`, `a.b++` or `a.b += c`
-      // where `a` is not a prefix or class.
-      // TODO(johnniwinther): Use the `element` of [result].
-      return handleDynamicUpdateSemantics(
-          node, name, null, new DynamicAccess.dynamicProperty(name));
-    }
-  }
-
-  /// Handle access unresolved access to [name] in a non-instance context.
-  ResolutionResult handleUnresolvedAccess(
-      Send node, Name name, Element element) {
-    // TODO(johnniwinther): Support unresolved top level access as an
-    // [AccessSemantics].
-    AccessSemantics semantics = new StaticAccess.unresolved(element);
-    return handleErroneousAccess(node, name, semantics);
-  }
-
-  /// Handle erroneous access of [element] of the given [semantics].
-  ResolutionResult handleErroneousAccess(
-      Send node, Name name, AccessSemantics semantics) {
-    SendStructure sendStructure;
-    Selector selector;
-    if (node.isCall) {
-      CallStructure callStructure =
-          resolveArguments(node.argumentsNode).callStructure;
-      selector = new Selector.call(name, callStructure);
-      registry.registerDynamicUse(new DynamicUse(selector));
-      sendStructure = new InvokeStructure(semantics, selector);
-    } else {
-      assert(node.isPropertyAccess, failedAt(node));
-      selector = new Selector.getter(name);
-      registry.registerDynamicUse(new DynamicUse(selector));
-      sendStructure = new GetStructure(semantics);
-    }
-    // TODO(23998): Remove this when all information goes through
-    // the [SendStructure].
-    registry.setSelector(node, selector);
-    registry.useElement(node, semantics.element);
-    registry.registerSendStructure(node, sendStructure);
-    return const NoneResult();
-  }
-
-  /// Handle access to an ambiguous element, that is, a name imported twice.
-  ResolutionResult handleAmbiguousSend(
-      Send node, Name name, AmbiguousElement element) {
-    ErroneousElement error = reportAndCreateErroneousElement(
-        node, name.text, element.messageKind, element.messageArguments,
-        infos: element.computeInfos(enclosingElement, reporter));
-    registry.registerFeature(Feature.THROW_NO_SUCH_METHOD);
-
-    // TODO(johnniwinther): Support ambiguous access as an [AccessSemantics].
-    AccessSemantics semantics = new StaticAccess.unresolved(error);
-    return handleErroneousAccess(node, name, semantics);
-  }
-
-  /// Handle update to an ambiguous element, that is, a name imported twice.
-  ResolutionResult handleAmbiguousUpdate(
-      SendSet node, Name name, AmbiguousElement element) {
-    ErroneousElement error = reportAndCreateErroneousElement(
-        node, name.text, element.messageKind, element.messageArguments,
-        infos: element.computeInfos(enclosingElement, reporter));
-    registry.registerFeature(Feature.THROW_NO_SUCH_METHOD);
-
-    // TODO(johnniwinther): Support ambiguous access as an [AccessSemantics].
-    AccessSemantics accessSemantics = new StaticAccess.unresolved(error);
-    return handleUpdate(node, name, accessSemantics);
-  }
-
-  /// Report access of an instance [member] from a non-instance context.
-  AccessSemantics reportStaticInstanceAccess(Send node, Name name) {
-    ErroneousElement error = reportAndCreateErroneousElement(
-        node, name.text, MessageKind.NO_INSTANCE_AVAILABLE, {'name': name},
-        isError: true);
-    // TODO(johnniwinther): Support static instance access as an
-    // [AccessSemantics].
-    registry.registerFeature(Feature.COMPILE_TIME_ERROR);
-    return new StaticAccess.invalid(error);
-  }
-
-  /// Handle access of a parameter, local variable or local function.
-  ResolutionResult handleLocalAccess(Send node, Name name, Element element) {
-    ResolutionResult result = const NoneResult();
-    AccessSemantics semantics = computeLocalAccessSemantics(node, element);
-    Selector selector;
-    if (node.isCall) {
-      CallStructure callStructure =
-          resolveArguments(node.argumentsNode).callStructure;
-      selector = new Selector.call(name, callStructure);
-      bool isIncompatibleInvoke = false;
-      switch (semantics.kind) {
-        case AccessKind.LOCAL_FUNCTION:
-          LocalFunctionElementX function = semantics.element;
-          function.computeType(resolution);
-          if (!callStructure.signatureApplies(function.parameterStructure)) {
-            registry.registerFeature(Feature.THROW_NO_SUCH_METHOD);
-            registry.registerDynamicUse(new DynamicUse(selector));
-            isIncompatibleInvoke = true;
-          }
-          break;
-        case AccessKind.PARAMETER:
-        case AccessKind.FINAL_PARAMETER:
-        case AccessKind.LOCAL_VARIABLE:
-        case AccessKind.FINAL_LOCAL_VARIABLE:
-          selector = callStructure.callSelector;
-          registry.registerDynamicUse(new DynamicUse(selector));
-          break;
-        default:
-          reporter.internalError(node, "Unexpected local access $semantics.");
-          break;
-      }
-      registry.registerSendStructure(
-          node,
-          isIncompatibleInvoke
-              ? new IncompatibleInvokeStructure(semantics, selector)
-              : new InvokeStructure(semantics, selector));
-    } else {
-      switch (semantics.kind) {
-        case AccessKind.LOCAL_VARIABLE:
-        case AccessKind.LOCAL_FUNCTION:
-          result = new ElementResult(element);
-          break;
-        case AccessKind.PARAMETER:
-        case AccessKind.FINAL_PARAMETER:
-          if (constantState == ConstantState.CONSTANT_INITIALIZER) {
-            ParameterElement parameter = element;
-            if (parameter.isNamed) {
-              result = new ConstantResult(
-                  node, new NamedArgumentReference(parameter.name),
-                  element: element);
-            } else {
-              result = new ConstantResult(
-                  node,
-                  new PositionalArgumentReference(parameter
-                      .functionDeclaration.parameters
-                      .indexOf(parameter)),
-                  element: element);
-            }
-          } else {
-            result = new ElementResult(element);
-          }
-          break;
-        case AccessKind.FINAL_LOCAL_VARIABLE:
-          if (element.isConst) {
-            LocalVariableElement local = element;
-            result = new ConstantResult(
-                node, new LocalVariableConstantExpression(local),
-                element: element);
-          } else {
-            result = new ElementResult(element);
-          }
-          break;
-        default:
-          reporter.internalError(node, "Unexpected local access $semantics.");
-          break;
-      }
-      selector = new Selector.getter(name);
-      registry.registerSendStructure(node, new GetStructure(semantics));
-    }
-
-    // TODO(23998): Remove these when all information goes through
-    // the [SendStructure].
-    registry.useElement(node, element);
-    registry.setSelector(node, selector);
-
-    registerPotentialAccessInClosure(node, element);
-
-    return result;
-  }
-
-  /// Handle update of a parameter, local variable or local function.
-  ResolutionResult handleLocalUpdate(Send node, Name name, Element element) {
-    AccessSemantics semantics;
-    ErroneousElement error;
-    if (element.isRegularParameter) {
-      if (element.isFinal) {
-        error = reportAndCreateErroneousElement(node.selector, name.text,
-            MessageKind.UNDEFINED_STATIC_SETTER_BUT_GETTER, {'name': name});
-        semantics = new StaticAccess.finalParameter(element);
-      } else {
-        semantics = new StaticAccess.parameter(element);
-      }
-    } else if (element.isInitializingFormal) {
-      error = reportAndCreateErroneousElement(node.selector, name.text,
-          MessageKind.UNDEFINED_STATIC_SETTER_BUT_GETTER, {'name': name});
-      semantics = new StaticAccess.finalParameter(element);
-    } else if (element.isVariable) {
-      if (element.isFinal || element.isConst) {
-        error = reportAndCreateErroneousElement(node.selector, name.text,
-            MessageKind.UNDEFINED_STATIC_SETTER_BUT_GETTER, {'name': name});
-        semantics = new StaticAccess.finalLocalVariable(element);
-      } else {
-        semantics = new StaticAccess.localVariable(element);
-      }
-    } else {
-      assert(element.isFunction, failedAt(node, "Unexpected local $element."));
-      error = reportAndCreateErroneousElement(
-          node.selector, name.text, MessageKind.ASSIGNING_METHOD, const {});
-      semantics = new StaticAccess.localFunction(element);
-    }
-    if (isPotentiallyMutableTarget(element)) {
-      registry.registerPotentialMutation(element, node);
-      if (enclosingElement != element.enclosingElement) {
-        registry.registerPotentialMutationInClosure(element, node);
-      }
-      for (Node scope in promotionScope) {
-        registry.registerPotentialMutationIn(scope, element, node);
-      }
-    }
-
-    ResolutionResult result = handleUpdate(node, name, semantics);
-    if (error != null) {
-      registry.registerFeature(Feature.THROW_NO_SUCH_METHOD);
-      // TODO(23998): Remove this when all information goes through
-      // the [SendStructure].
-      registry.useElement(node, error);
-    }
-    return result;
-  }
-
-  /// Handle access of a static or top level [element].
-  ResolutionResult handleStaticOrTopLevelAccess(
-      Send node, Name name, Element element) {
-    ResolutionResult result = const NoneResult();
-    MemberElement member;
-    if (element.isAbstractField) {
-      AbstractFieldElement abstractField = element;
-      if (abstractField.getter != null) {
-        member = abstractField.getter;
-      } else {
-        member = abstractField.setter;
-      }
-    } else {
-      member = element;
-    }
-    // TODO(johnniwinther): Needed to provoke a parsing and with it discovery
-    // of parse errors to make [element] erroneous. Fix this!
-    member.computeType(resolution);
-
-    if (resolution.commonElements.isMirrorSystemGetNameFunction(member) &&
-        !resolution.mirrorUsageAnalyzerTask.hasMirrorUsage(enclosingElement)) {
-      reporter.reportHintMessage(
-          node.selector, MessageKind.STATIC_FUNCTION_BLOAT, {
-        'class': resolution.commonElements.mirrorSystemClass.name,
-        'name': member.name
-      });
-    }
-
-    Selector selector;
-    AccessSemantics semantics =
-        computeStaticOrTopLevelAccessSemantics(node, member);
-    if (node.isCall) {
-      ArgumentsResult argumentsResult = resolveArguments(node.argumentsNode);
-      CallStructure callStructure = argumentsResult.callStructure;
-      selector = new Selector.call(name, callStructure);
-
-      bool isIncompatibleInvoke = false;
-      switch (semantics.kind) {
-        case AccessKind.STATIC_METHOD:
-        case AccessKind.TOPLEVEL_METHOD:
-          MethodElement method = semantics.element;
-          method.computeType(resolution);
-          if (!callStructure.signatureApplies(method.parameterStructure)) {
-            registry.registerFeature(Feature.THROW_NO_SUCH_METHOD);
-            registry.registerDynamicUse(new DynamicUse(selector));
-            isIncompatibleInvoke = true;
-          } else {
-            registry.registerStaticUse(
-                new StaticUse.staticInvoke(method, callStructure));
-            handleForeignCall(node, semantics.element, callStructure);
-            if (method == resolution.commonElements.identicalFunction &&
-                argumentsResult.isValidAsConstant) {
-              result = new ConstantResult(
-                  node,
-                  new IdenticalConstantExpression(
-                      argumentsResult.argumentResults[0].constant,
-                      argumentsResult.argumentResults[1].constant));
-            }
-          }
-          break;
-        case AccessKind.STATIC_FIELD:
-        case AccessKind.FINAL_STATIC_FIELD:
-        case AccessKind.STATIC_GETTER:
-        case AccessKind.TOPLEVEL_FIELD:
-        case AccessKind.FINAL_TOPLEVEL_FIELD:
-        case AccessKind.TOPLEVEL_GETTER:
-          MemberElement member = semantics.element;
-          registry.registerStaticUse(new StaticUse.staticGet(member));
-          selector = callStructure.callSelector;
-          registry.registerDynamicUse(new DynamicUse(selector));
-          break;
-        case AccessKind.STATIC_SETTER:
-        case AccessKind.TOPLEVEL_SETTER:
-        case AccessKind.UNRESOLVED:
-          registry.registerFeature(Feature.THROW_NO_SUCH_METHOD);
-          member = reportAndCreateErroneousElement(node.selector, name.text,
-              MessageKind.UNDEFINED_STATIC_GETTER_BUT_SETTER, {'name': name});
-          break;
-        default:
-          reporter.internalError(
-              node, "Unexpected statically resolved access $semantics.");
-          break;
-      }
-      registry.registerSendStructure(
-          node,
-          isIncompatibleInvoke
-              ? new IncompatibleInvokeStructure(semantics, selector)
-              : new InvokeStructure(semantics, selector));
-    } else {
-      selector = new Selector.getter(name);
-      switch (semantics.kind) {
-        case AccessKind.STATIC_METHOD:
-        case AccessKind.TOPLEVEL_METHOD:
-          MethodElement method = semantics.element;
-          registry.registerStaticUse(new StaticUse.staticTearOff(method));
-          break;
-        case AccessKind.STATIC_FIELD:
-        case AccessKind.FINAL_STATIC_FIELD:
-        case AccessKind.STATIC_GETTER:
-        case AccessKind.TOPLEVEL_FIELD:
-        case AccessKind.FINAL_TOPLEVEL_FIELD:
-        case AccessKind.TOPLEVEL_GETTER:
-          MemberElement member = semantics.element;
-          registry.registerStaticUse(new StaticUse.staticGet(member));
-          break;
-        case AccessKind.STATIC_SETTER:
-        case AccessKind.TOPLEVEL_SETTER:
-        case AccessKind.UNRESOLVED:
-          registry.registerFeature(Feature.THROW_NO_SUCH_METHOD);
-          member = reportAndCreateErroneousElement(node.selector, name.text,
-              MessageKind.UNDEFINED_STATIC_GETTER_BUT_SETTER, {'name': name});
-          break;
-        default:
-          reporter.internalError(
-              node, "Unexpected statically resolved access $semantics.");
-          break;
-      }
-      registry.registerSendStructure(node, new GetStructure(semantics));
-      if (member.isConst) {
-        FieldElement field = member;
-        result = new ConstantResult(node, new FieldConstantExpression(field),
-            element: field);
-      } else {
-        result = new ElementResult(member);
-      }
-    }
-
-    // TODO(23998): Remove these when all information goes through
-    // the [SendStructure].
-    registry.useElement(node, member);
-    registry.setSelector(node, selector);
-
-    return result;
-  }
-
-  /// Handle update of a static or top level [element].
-  ResolutionResult handleStaticOrTopLevelUpdate(
-      SendSet node, Name name, Element element) {
-    AccessSemantics semantics;
-    if (element.isAbstractField) {
-      AbstractFieldElement abstractField = element;
-      if (abstractField.setter == null) {
-        ErroneousElement error = reportAndCreateErroneousElement(
-            node.selector,
-            name.text,
-            MessageKind.UNDEFINED_STATIC_SETTER_BUT_GETTER,
-            {'name': name});
-        registry.registerFeature(Feature.THROW_NO_SUCH_METHOD);
-
-        if (node.isComplex) {
-          // `a++` or `a += b` where `a` has no setter.
-          semantics = new CompoundAccessSemantics(
-              element.isTopLevel
-                  ? CompoundAccessKind.UNRESOLVED_TOPLEVEL_SETTER
-                  : CompoundAccessKind.UNRESOLVED_STATIC_SETTER,
-              abstractField.getter,
-              error);
-        } else {
-          // `a = b` where `a` has no setter.
-          semantics = element.isTopLevel
-              ? new StaticAccess.topLevelGetter(abstractField.getter)
-              : new StaticAccess.staticGetter(abstractField.getter);
-        }
-        registry
-            .registerStaticUse(new StaticUse.staticGet(abstractField.getter));
-      } else if (node.isComplex) {
-        if (abstractField.getter == null) {
-          ErroneousElement error = reportAndCreateErroneousElement(
-              node.selector,
-              name.text,
-              MessageKind.UNDEFINED_STATIC_GETTER_BUT_SETTER,
-              {'name': name});
-          registry.registerFeature(Feature.THROW_NO_SUCH_METHOD);
-          // `a++` or `a += b` where `a` has no getter.
-          semantics = new CompoundAccessSemantics(
-              element.isTopLevel
-                  ? CompoundAccessKind.UNRESOLVED_TOPLEVEL_GETTER
-                  : CompoundAccessKind.UNRESOLVED_STATIC_GETTER,
-              error,
-              abstractField.setter);
-          registry
-              .registerStaticUse(new StaticUse.staticSet(abstractField.setter));
-        } else {
-          // `a++` or `a += b` where `a` has both a getter and a setter.
-          semantics = new CompoundAccessSemantics(
-              element.isTopLevel
-                  ? CompoundAccessKind.TOPLEVEL_GETTER_SETTER
-                  : CompoundAccessKind.STATIC_GETTER_SETTER,
-              abstractField.getter,
-              abstractField.setter);
-          registry
-              .registerStaticUse(new StaticUse.staticGet(abstractField.getter));
-          registry
-              .registerStaticUse(new StaticUse.staticSet(abstractField.setter));
-        }
-      } else {
-        // `a = b` where `a` has a setter.
-        semantics = element.isTopLevel
-            ? new StaticAccess.topLevelSetter(abstractField.setter)
-            : new StaticAccess.staticSetter(abstractField.setter);
-        registry
-            .registerStaticUse(new StaticUse.staticSet(abstractField.setter));
-      }
-    } else {
-      MemberElement member = element;
-      // TODO(johnniwinther): Needed to provoke a parsing and with it discovery
-      // of parse errors to make [element] erroneous. Fix this!
-      member.computeType(resolution);
-      if (member.isMalformed) {
-        // [member] has parse errors.
-        semantics = new StaticAccess.unresolved(member);
-      } else if (member.isFunction) {
-        // `a = b`, `a++` or `a += b` where `a` is a function.
-        MethodElement method = member;
-        reportAndCreateErroneousElement(
-            node.selector, name.text, MessageKind.ASSIGNING_METHOD, const {});
-        registry.registerFeature(Feature.THROW_NO_SUCH_METHOD);
-        if (node.isComplex) {
-          // `a++` or `a += b` where `a` is a function.
-          registry.registerStaticUse(new StaticUse.staticTearOff(method));
-        }
-        semantics = member.isTopLevel
-            ? new StaticAccess.topLevelMethod(method)
-            : new StaticAccess.staticMethod(method);
-      } else {
-        // `a = b`, `a++` or `a += b` where `a` is a field.
-        assert(member.isField, failedAt(node, "Unexpected element: $member."));
-        if (node.isComplex) {
-          // `a++` or `a += b` where `a` is a field.
-          registry.registerStaticUse(new StaticUse.staticGet(member));
-        }
-        if (member.isFinal || member.isConst) {
-          reportAndCreateErroneousElement(node.selector, name.text,
-              MessageKind.UNDEFINED_STATIC_SETTER_BUT_GETTER, {'name': name});
-          registry.registerFeature(Feature.THROW_NO_SUCH_METHOD);
-          semantics = member.isTopLevel
-              ? new StaticAccess.finalTopLevelField(member)
-              : new StaticAccess.finalStaticField(member);
-        } else {
-          registry.registerStaticUse(new StaticUse.staticSet(member));
-          semantics = member.isTopLevel
-              ? new StaticAccess.topLevelField(member)
-              : new StaticAccess.staticField(member);
-        }
-      }
-    }
-    return handleUpdate(node, name, semantics);
-  }
-
-  /// Handle access to resolved [element].
-  ResolutionResult handleResolvedSend(Send node, Name name, Element element) {
-    if (element.isAmbiguous) {
-      return handleAmbiguousSend(node, name, element);
-    }
-    if (element.isMalformed) {
-      // This handles elements with parser errors.
-      assert(element is! ErroneousElement,
-          failedAt(node, "Unexpected erroneous element $element."));
-      return handleErroneousAccess(
-          node, name, new StaticAccess.unresolved(element));
-    }
-    if (element.isInstanceMember) {
-      if (inInstanceContext) {
-        // TODO(johnniwinther): Maybe use the found [element].
-        return handleThisPropertyAccess(node, name);
-      } else {
-        return handleErroneousAccess(
-            node, name, reportStaticInstanceAccess(node, name));
-      }
-    }
-    if (element.isClass) {
-      // `C`, `C()`, or 'C.b` where 'C' is a class.
-      return handleClassSend(node, name, element);
-    } else if (element.isTypedef) {
-      // `F` or `F()` where 'F' is a typedef.
-      return handleTypedefTypeLiteralAccess(node, name, element);
-    } else if (element.isTypeVariable) {
-      return handleTypeVariableTypeLiteralAccess(node, name, element);
-    } else if (element.isPrefix) {
-      return handleLibraryPrefix(node, name, element);
-    } else if (element.isLocal) {
-      return handleLocalAccess(node, name, element);
-    } else if (element.isStatic || element.isTopLevel) {
-      return handleStaticOrTopLevelAccess(node, name, element);
-    }
-    return reporter.internalError(node, "Unexpected resolved send: $element");
-  }
-
-  /// Handle update to resolved [element].
-  ResolutionResult handleResolvedSendSet(
-      SendSet node, Name name, Element element) {
-    if (element.isAmbiguous) {
-      return handleAmbiguousUpdate(node, name, element);
-    }
-    if (element.isMalformed) {
-      // This handles elements with parser errors..
-      assert(element is! ErroneousElement,
-          failedAt(node, "Unexpected erroneous element $element."));
-      return handleUpdate(node, name, new StaticAccess.unresolved(element));
-    }
-    if (element.isInstanceMember) {
-      if (inInstanceContext) {
-        return handleThisPropertyUpdate(node, name, element);
-      } else {
-        return handleUpdate(node, name, reportStaticInstanceAccess(node, name));
-      }
-    }
-    if (element.isClass) {
-      // `C = b`, `C++`, or 'C += b` where 'C' is a class.
-      return handleClassTypeLiteralUpdate(node, name, element);
-    } else if (element.isTypedef) {
-      // `C = b`, `C++`, or 'C += b` where 'F' is a typedef.
-      return handleTypedefTypeLiteralUpdate(node, name, element);
-    } else if (element.isTypeVariable) {
-      // `T = b`, `T++`, or 'T += b` where 'T' is a type variable.
-      return handleTypeVariableTypeLiteralUpdate(node, name, element);
-    } else if (element.isPrefix) {
-      // `p = b` where `p` is a prefix.
-      ErroneousElement error = reportAndCreateErroneousElement(
-          node, name.text, MessageKind.PREFIX_AS_EXPRESSION, {'prefix': name},
-          isError: true);
-      registry.registerFeature(Feature.COMPILE_TIME_ERROR);
-      return handleUpdate(node, name, new StaticAccess.invalid(error));
-    } else if (element.isLocal) {
-      return handleLocalUpdate(node, name, element);
-    } else if (element.isStatic || element.isTopLevel) {
-      return handleStaticOrTopLevelUpdate(node, name, element);
-    }
-    return reporter.internalError(node, "Unexpected resolved send: $element");
-  }
-
-  /// Handle an unqualified [Send], that is where the `node.receiver` is null,
-  /// like `a`, `a()`, `this()`, `assert()`, and `(){}()`.
-  ResolutionResult handleUnqualifiedSend(Send node) {
-    Identifier selector = node.selector.asIdentifier();
-    if (selector == null) {
-      // `(){}()` and `(foo)()`.
-      return handleExpressionInvoke(node);
-    }
-    String text = selector.source;
-    if (text == 'this') {
-      // `this()`.
-      return handleThisAccess(node);
-    }
-    // `name` or `name()`
-    Name name = new Name(text, enclosingElement.library);
-    Element element = lookupInScope(reporter, node, scope, text);
-    if (element == null) {
-      if (text == 'dynamic') {
-        // `dynamic` or `dynamic()` where 'dynamic' is not declared in the
-        // current scope.
-        return handleDynamicTypeLiteralAccess(node);
-      } else if (inInstanceContext) {
-        // Implicitly `this.name`.
-        return handleThisPropertyAccess(node, name);
-      } else {
-        // Create [ErroneousElement] for unresolved access.
-        ErroneousElement error = reportCannotResolve(node, text);
-        return handleUnresolvedAccess(node, name, error);
-      }
-    } else {
-      return handleResolvedSend(node, name, element);
-    }
-  }
-
-  /// Handle an unqualified [SendSet], that is where the `node.receiver` is
-  /// null, like `a = b`, `a++`, and `a += b`.
-  ResolutionResult handleUnqualifiedSendSet(SendSet node) {
-    Identifier selector = node.selector.asIdentifier();
-    String text = selector.source;
-    Name name = new Name(text, enclosingElement.library);
-    Element element = lookupInScope(reporter, node, scope, text);
-    if (element == null) {
-      if (text == 'dynamic') {
-        // `dynamic = b`, `dynamic++`, or `dynamic += b` where 'dynamic' is not
-        // declared in the current scope.
-        return handleDynamicTypeLiteralUpdate(node);
-      } else if (inInstanceContext) {
-        // Left-hand side is implicitly `this.name`.
-        return handleThisPropertyUpdate(node, name, null);
-      } else {
-        // Create [ErroneousElement] for unresolved access.
-        ErroneousElement error = reportCannotResolve(node, text);
-        return handleUpdate(node, name, new StaticAccess.unresolved(error));
-      }
-    } else {
-      return handleResolvedSendSet(node, name, element);
-    }
-  }
-
-  ResolutionResult visitSend(Send node) {
-    // Resolve type arguments to ensure that these are well-formed types.
-    if (node.typeArgumentsNode != null) {
-      for (TypeAnnotation type in node.typeArgumentsNode.nodes) {
-        resolveTypeAnnotation(type, registerCheckedModeCheck: false);
-      }
-    }
-    if (node.isOperator) {
-      // `a && b`, `a + b`, `-a`, or `a is T`.
-      return handleOperatorSend(node);
-    } else if (node.receiver != null) {
-      // `a.b`.
-      return handleQualifiedSend(node);
-    } else {
-      // `a`.
-      return handleUnqualifiedSend(node);
-    }
-  }
-
-  /// Register read access of [target] inside a closure.
-  void registerPotentialAccessInClosure(Send node, Element target) {
-    if (isPotentiallyMutableTarget(target)) {
-      if (enclosingElement != target.enclosingElement) {
-        for (Node scope in promotionScope) {
-          registry.setAccessedByClosureIn(scope, target, node);
-        }
-      }
-    }
-  }
-
-  // TODO(johnniwinther): Move this to the backend resolution callbacks.
-  void handleForeignCall(
-      Send node, Element target, CallStructure callStructure) {
-    if (target != null && resolution.target.isForeign(target)) {
-      registry.registerForeignCall(node, target, callStructure, this);
-    }
-  }
-
-  /// Callback for native enqueuer to parse a type.  Returns [:null:] on error.
-  ResolutionDartType resolveTypeFromString(Node node, String typeName) {
-    Element element = lookupInScope(reporter, node, scope, typeName);
-    if (element == null) return null;
-    if (element is! ClassElement) return null;
-    ClassElement cls = element;
-    cls.ensureResolved(resolution);
-    cls.computeType(resolution);
-    return cls.rawType;
-  }
-
-  /// Handle index operations like `a[b] = c`, `a[b] += c`, and `a[b]++`.
-  ResolutionResult handleIndexSendSet(SendSet node) {
-    String operatorText = node.assignmentOperator.source;
-    Node receiver = node.receiver;
-    Node index = node.arguments.head;
-    visitExpression(receiver);
-    visitExpression(index);
-    AccessSemantics semantics = const DynamicAccess.expression();
-    if (node.isPrefix || node.isPostfix) {
-      // `a[b]++` or `++a[b]`.
-      IncDecOperator operator = IncDecOperator.parse(operatorText);
-      Selector getterSelector = new Selector.index();
-      Selector setterSelector = new Selector.indexSet();
-      Selector operatorSelector =
-          new Selector.binaryOperator(operator.selectorName);
-
-      // TODO(23998): Remove these when selectors are only accessed
-      // through the send structure.
-      registry.setGetterSelectorInComplexSendSet(node, getterSelector);
-      registry.setSelector(node, setterSelector);
-      registry.setOperatorSelectorInComplexSendSet(node, operatorSelector);
-
-      registry.registerDynamicUse(new DynamicUse(getterSelector));
-      registry.registerDynamicUse(new DynamicUse(setterSelector));
-      registry.registerDynamicUse(new DynamicUse(operatorSelector));
-
-      SendStructure sendStructure = node.isPrefix
-          ? new IndexPrefixStructure(semantics, operator)
-          : new IndexPostfixStructure(semantics, operator);
-      registry.registerSendStructure(node, sendStructure);
-      return const NoneResult();
-    } else {
-      Node rhs = node.arguments.tail.head;
-      visitExpression(rhs);
-
-      AssignmentOperator operator = AssignmentOperator.parse(operatorText);
-      if (operator.kind == AssignmentOperatorKind.ASSIGN) {
-        // `a[b] = c`.
-        Selector setterSelector = new Selector.indexSet();
-
-        // TODO(23998): Remove this when selectors are only accessed
-        // through the send structure.
-        registry.setSelector(node, setterSelector);
-        registry.registerDynamicUse(new DynamicUse(setterSelector));
-
-        SendStructure sendStructure = new IndexSetStructure(semantics);
-        registry.registerSendStructure(node, sendStructure);
-        return const NoneResult();
-      } else {
-        // `a[b] += c`.
-        Selector getterSelector = new Selector.index();
-        Selector setterSelector = new Selector.indexSet();
-        Selector operatorSelector =
-            new Selector.binaryOperator(operator.selectorName);
-
-        // TODO(23998): Remove these when selectors are only accessed
-        // through the send structure.
-        registry.setGetterSelectorInComplexSendSet(node, getterSelector);
-        registry.setSelector(node, setterSelector);
-        registry.setOperatorSelectorInComplexSendSet(node, operatorSelector);
-
-        registry.registerDynamicUse(new DynamicUse(getterSelector));
-        registry.registerDynamicUse(new DynamicUse(setterSelector));
-        registry.registerDynamicUse(new DynamicUse(operatorSelector));
-
-        SendStructure sendStructure;
-        if (operator.kind == AssignmentOperatorKind.IF_NULL) {
-          sendStructure = new IndexSetIfNullStructure(semantics);
-        } else {
-          sendStructure = new CompoundIndexSetStructure(semantics, operator);
-        }
-        registry.registerSendStructure(node, sendStructure);
-        return const NoneResult();
-      }
-    }
-  }
-
-  /// Handle super index operations like `super[a] = b`, `super[a] += b`, and
-  /// `super[a]++`.
-  // TODO(johnniwinther): Share code with [handleIndexSendSet].
-  ResolutionResult handleSuperIndexSendSet(SendSet node) {
-    String operatorText = node.assignmentOperator.source;
-    Node index = node.arguments.head;
-    visitExpression(index);
-
-    AccessSemantics semantics = checkSuperAccess(node);
-    if (node.isPrefix || node.isPostfix) {
-      // `super[a]++` or `++super[a]`.
-      IncDecOperator operator = IncDecOperator.parse(operatorText);
-      Selector getterSelector = new Selector.index();
-      Selector setterSelector = new Selector.indexSet();
-      Selector operatorSelector =
-          new Selector.binaryOperator(operator.selectorName);
-
-      // TODO(23998): Remove these when selectors are only accessed
-      // through the send structure.
-      registry.setGetterSelectorInComplexSendSet(node, getterSelector);
-      registry.setSelector(node, setterSelector);
-      registry.setOperatorSelectorInComplexSendSet(node, operatorSelector);
-
-      if (semantics == null) {
-        semantics = computeSuperAccessSemanticsForSelectors(
-            node, getterSelector, setterSelector,
-            isIndex: true);
-
-        if (!semantics.getter.isError) {
-          MethodElement getter = semantics.getter;
-          registry.registerStaticUse(
-              new StaticUse.superInvoke(getter, getterSelector.callStructure));
-        }
-        if (!semantics.setter.isError) {
-          MethodElement setter = semantics.setter;
-          registry.registerStaticUse(
-              new StaticUse.superInvoke(setter, setterSelector.callStructure));
-        }
-
-        // TODO(23998): Remove these when elements are only accessed
-        // through the send structure.
-        registry.useElement(node, semantics.setter);
-        registry.useElement(node.selector, semantics.getter);
-      }
-      registry.registerDynamicUse(new DynamicUse(operatorSelector));
-
-      SendStructure sendStructure = node.isPrefix
-          ? new IndexPrefixStructure(semantics, operator)
-          : new IndexPostfixStructure(semantics, operator);
-      registry.registerSendStructure(node, sendStructure);
-      return const NoneResult();
-    } else {
-      Node rhs = node.arguments.tail.head;
-      visitExpression(rhs);
-
-      AssignmentOperator operator = AssignmentOperator.parse(operatorText);
-      if (operator.kind == AssignmentOperatorKind.ASSIGN) {
-        // `super[a] = b`.
-        Selector setterSelector = new Selector.indexSet();
-        if (semantics == null) {
-          semantics =
-              computeSuperAccessSemanticsForSelector(node, setterSelector);
-
-          // TODO(23998): Remove these when elements are only accessed
-          // through the send structure.
-          registry.useElement(node, semantics.setter);
-        }
-
-        // TODO(23998): Remove this when selectors are only accessed
-        // through the send structure.
-        registry.setSelector(node, setterSelector);
-        if (!semantics.setter.isError) {
-          MethodElement setter = semantics.setter;
-          registry.registerStaticUse(
-              new StaticUse.superInvoke(setter, setterSelector.callStructure));
-        }
-
-        SendStructure sendStructure = new IndexSetStructure(semantics);
-        registry.registerSendStructure(node, sendStructure);
-        return const NoneResult();
-      } else {
-        // `super[a] += b`.
-        Selector getterSelector = new Selector.index();
-        Selector setterSelector = new Selector.indexSet();
-        Selector operatorSelector =
-            new Selector.binaryOperator(operator.selectorName);
-        if (semantics == null) {
-          semantics = computeSuperAccessSemanticsForSelectors(
-              node, getterSelector, setterSelector,
-              isIndex: true);
-
-          if (!semantics.getter.isError) {
-            MethodElement getter = semantics.getter;
-            registry.registerStaticUse(new StaticUse.superInvoke(
-                getter, getterSelector.callStructure));
-          }
-          if (!semantics.setter.isError) {
-            MethodElement setter = semantics.setter;
-            registry.registerStaticUse(new StaticUse.superInvoke(
-                setter, setterSelector.callStructure));
-          }
-
-          // TODO(23998): Remove these when elements are only accessed
-          // through the send structure.
-          registry.useElement(node, semantics.setter);
-          registry.useElement(node.selector, semantics.getter);
-        }
-
-        // TODO(23998): Remove these when selectors are only accessed
-        // through the send structure.
-        registry.setGetterSelectorInComplexSendSet(node, getterSelector);
-        registry.setSelector(node, setterSelector);
-        registry.setOperatorSelectorInComplexSendSet(node, operatorSelector);
-
-        registry.registerDynamicUse(new DynamicUse(operatorSelector));
-
-        SendStructure sendStructure;
-        if (operator.kind == AssignmentOperatorKind.IF_NULL) {
-          sendStructure = new IndexSetIfNullStructure(semantics);
-        } else {
-          sendStructure = new CompoundIndexSetStructure(semantics, operator);
-        }
-        registry.registerSendStructure(node, sendStructure);
-        return const NoneResult();
-      }
-    }
-  }
-
-  /// Handle super index operations like `super.a = b`, `super.a += b`, and
-  /// `super.a++`.
-  // TODO(johnniwinther): Share code with [handleSuperIndexSendSet].
-  ResolutionResult handleSuperSendSet(SendSet node) {
-    Identifier selector = node.selector.asIdentifier();
-    String text = selector.source;
-    Name name = new Name(text, enclosingElement.library);
-    String operatorText = node.assignmentOperator.source;
-    Selector getterSelector = new Selector.getter(name);
-    Selector setterSelector = new Selector.setter(name);
-
-    void registerStaticUses(AccessSemantics semantics) {
-      switch (semantics.kind) {
-        case AccessKind.SUPER_METHOD:
-          MethodElement method = semantics.element;
-          registry.registerStaticUse(new StaticUse.superTearOff(method));
-          break;
-        case AccessKind.SUPER_GETTER:
-          MethodElement getter = semantics.getter;
-          registry.registerStaticUse(new StaticUse.superGet(getter));
-          break;
-        case AccessKind.SUPER_SETTER:
-          MethodElement setter = semantics.setter;
-          registry.registerStaticUse(new StaticUse.superSetterSet(setter));
-          break;
-        case AccessKind.SUPER_FIELD:
-          FieldElement field = semantics.element;
-          registry.registerStaticUse(new StaticUse.superGet(field));
-          registry.registerStaticUse(new StaticUse.superFieldSet(field));
-          break;
-        case AccessKind.SUPER_FINAL_FIELD:
-          FieldElement field = semantics.element;
-          registry.registerStaticUse(new StaticUse.superGet(field));
-          break;
-        case AccessKind.COMPOUND:
-          CompoundAccessSemantics compoundSemantics = semantics;
-          switch (compoundSemantics.compoundAccessKind) {
-            case CompoundAccessKind.SUPER_GETTER_FIELD:
-            case CompoundAccessKind.SUPER_FIELD_FIELD:
-              MemberElement getter = semantics.getter;
-              FieldElement setter = semantics.setter;
-              registry.registerStaticUse(new StaticUse.superGet(getter));
-              registry.registerStaticUse(new StaticUse.superFieldSet(setter));
-              break;
-            case CompoundAccessKind.SUPER_FIELD_SETTER:
-            case CompoundAccessKind.SUPER_GETTER_SETTER:
-              MemberElement getter = semantics.getter;
-              MethodElement setter = semantics.setter;
-              registry.registerStaticUse(new StaticUse.superGet(getter));
-              registry.registerStaticUse(new StaticUse.superSetterSet(setter));
-              break;
-            case CompoundAccessKind.SUPER_METHOD_SETTER:
-              MethodElement setter = semantics.setter;
-              registry.registerStaticUse(new StaticUse.superSetterSet(setter));
-              break;
-            case CompoundAccessKind.UNRESOLVED_SUPER_GETTER:
-              MethodElement setter = semantics.setter;
-              registry.registerStaticUse(new StaticUse.superSetterSet(setter));
-              break;
-            case CompoundAccessKind.UNRESOLVED_SUPER_SETTER:
-              MethodElement getter = semantics.getter;
-              registry.registerStaticUse(new StaticUse.superGet(getter));
-              break;
-            default:
-              break;
-          }
-          break;
-        default:
-          break;
-      }
-    }
-
-    AccessSemantics semantics = checkSuperAccess(node);
-    if (node.isPrefix || node.isPostfix) {
-      // `super.a++` or `++super.a`.
-      if (semantics == null) {
-        semantics = computeSuperAccessSemanticsForSelectors(
-            node, getterSelector, setterSelector);
-        registerStaticUses(semantics);
-      }
-      return handleUpdate(node, name, semantics);
-    } else {
-      AssignmentOperator operator = AssignmentOperator.parse(operatorText);
-      if (operator.kind == AssignmentOperatorKind.ASSIGN) {
-        // `super.a = b`.
-        if (semantics == null) {
-          semantics = computeSuperAccessSemanticsForSelector(
-              node, setterSelector,
-              alternateName: name);
-          switch (semantics.kind) {
-            case AccessKind.SUPER_FINAL_FIELD:
-              reporter.reportWarningMessage(
-                  node, MessageKind.ASSIGNING_FINAL_FIELD_IN_SUPER, {
-                'name': name,
-                'superclassName': semantics.setter.enclosingClass.name
-              });
-              // TODO(johnniwinther): This shouldn't be needed.
-              registry.registerDynamicUse(new DynamicUse(setterSelector));
-              registry.registerFeature(Feature.SUPER_NO_SUCH_METHOD);
-              break;
-            case AccessKind.SUPER_METHOD:
-              reporter.reportWarningMessage(
-                  node, MessageKind.ASSIGNING_METHOD_IN_SUPER, {
-                'name': name,
-                'superclassName': semantics.setter.enclosingClass.name
-              });
-              // TODO(johnniwinther): This shouldn't be needed.
-              registry.registerDynamicUse(new DynamicUse(setterSelector));
-              registry.registerFeature(Feature.SUPER_NO_SUCH_METHOD);
-              break;
-            case AccessKind.SUPER_FIELD:
-              FieldElement field = semantics.setter;
-              registry.registerStaticUse(new StaticUse.superFieldSet(field));
-              break;
-            case AccessKind.SUPER_SETTER:
-              MethodElement setter = semantics.setter;
-              registry.registerStaticUse(new StaticUse.superSetterSet(setter));
-              break;
-            default:
-              break;
-          }
-        }
-        return handleUpdate(node, name, semantics);
-      } else {
-        // `super.a += b`.
-        if (semantics == null) {
-          semantics = computeSuperAccessSemanticsForSelectors(
-              node, getterSelector, setterSelector);
-          registerStaticUses(semantics);
-        }
-        return handleUpdate(node, name, semantics);
-      }
-    }
-  }
-
-  /// Handle update of an entity defined by [semantics]. For instance `a = b`,
-  /// `a++` or `a += b` where [semantics] describe `a`.
-  ResolutionResult handleUpdate(
-      SendSet node, Name name, AccessSemantics semantics) {
-    String operatorText = node.assignmentOperator.source;
-    Selector getterSelector = new Selector.getter(name);
-    Selector setterSelector = new Selector.setter(name);
-    if (node.isPrefix || node.isPostfix) {
-      // `e++` or `++e`.
-      IncDecOperator operator = IncDecOperator.parse(operatorText);
-      Selector operatorSelector =
-          new Selector.binaryOperator(operator.selectorName);
-
-      // TODO(23998): Remove these when selectors are only accessed
-      // through the send structure.
-      registry.setGetterSelectorInComplexSendSet(node, getterSelector);
-      registry.setSelector(node, setterSelector);
-      registry.setOperatorSelectorInComplexSendSet(node, operatorSelector);
-
-      // TODO(23998): Remove these when elements are only accessed
-      // through the send structure.
-      registry.useElement(node, semantics.setter);
-      registry.useElement(node.selector, semantics.getter);
-
-      registry.registerDynamicUse(new DynamicUse(operatorSelector));
-
-      SendStructure sendStructure = node.isPrefix
-          ? new PrefixStructure(semantics, operator)
-          : new PostfixStructure(semantics, operator);
-      registry.registerSendStructure(node, sendStructure);
-      registry.registerConstantLiteral(new IntConstantExpression(1));
-    } else {
-      Node rhs = node.arguments.head;
-      visitExpression(rhs);
-
-      AssignmentOperator operator = AssignmentOperator.parse(operatorText);
-      if (operator.kind == AssignmentOperatorKind.ASSIGN) {
-        // `e1 = e2`.
-
-        // TODO(23998): Remove these when elements are only accessed
-        // through the send structure.
-        registry.useElement(node, semantics.setter);
-
-        // TODO(23998): Remove this when selectors are only accessed
-        // through the send structure.
-        registry.setSelector(node, setterSelector);
-
-        SendStructure sendStructure = new SetStructure(semantics);
-        registry.registerSendStructure(node, sendStructure);
-      } else {
-        // `e1 += e2`.
-        Selector operatorSelector =
-            new Selector.binaryOperator(operator.selectorName);
-
-        // TODO(23998): Remove these when elements are only accessed
-        // through the send structure.
-        registry.useElement(node, semantics.setter);
-        registry.useElement(node.selector, semantics.getter);
-
-        // TODO(23998): Remove these when selectors are only accessed
-        // through the send structure.
-        registry.setGetterSelectorInComplexSendSet(node, getterSelector);
-        registry.setSelector(node, setterSelector);
-        registry.setOperatorSelectorInComplexSendSet(node, operatorSelector);
-
-        SendStructure sendStructure;
-        if (operator.kind == AssignmentOperatorKind.IF_NULL) {
-          registry.registerConstantLiteral(new NullConstantExpression());
-          registry.registerDynamicUse(new DynamicUse(Selectors.equals));
-          sendStructure = new SetIfNullStructure(semantics);
-        } else {
-          registry.registerDynamicUse(new DynamicUse(operatorSelector));
-          sendStructure = new CompoundStructure(semantics, operator);
-        }
-        registry.registerSendStructure(node, sendStructure);
-      }
-    }
-    return new ResolutionResult.forElement(semantics.setter);
-  }
-
-  ResolutionResult visitSendSet(SendSet node) {
-    if (node.isIndex) {
-      // `a[b] = c`
-      if (node.isSuperCall) {
-        // `super[b] = c`
-        return handleSuperIndexSendSet(node);
-      } else {
-        return handleIndexSendSet(node);
-      }
-    } else if (node.isSuperCall) {
-      // `super.a = c`
-      return handleSuperSendSet(node);
-    } else if (node.receiver == null) {
-      // `a = c`
-      return handleUnqualifiedSendSet(node);
-    } else {
-      // `a.b = c`
-      return handleQualifiedSendSet(node);
-    }
-  }
-
-  ConstantResult visitLiteralInt(LiteralInt node) {
-    ConstantExpression constant = new IntConstantExpression(node.value);
-    registry.registerConstantLiteral(constant);
-    registry.setConstant(node, constant);
-    return new ConstantResult(node, constant);
-  }
-
-  ConstantResult visitLiteralDouble(LiteralDouble node) {
-    ConstantExpression constant = new DoubleConstantExpression(node.value);
-    registry.registerConstantLiteral(constant);
-    registry.setConstant(node, constant);
-    return new ConstantResult(node, constant);
-  }
-
-  ConstantResult visitLiteralBool(LiteralBool node) {
-    ConstantExpression constant = new BoolConstantExpression(node.value);
-    registry.registerConstantLiteral(constant);
-    registry.setConstant(node, constant);
-    return new ConstantResult(node, constant);
-  }
-
-  ResolutionResult visitLiteralString(LiteralString node) {
-    if (node.dartString != null) {
-      // [dartString] might be null on parser errors.
-      ConstantExpression constant =
-          new StringConstantExpression(node.dartString.slowToString());
-      registry.registerConstantLiteral(constant);
-      registry.setConstant(node, constant);
-      return new ConstantResult(node, constant);
-    }
-    return const NoneResult();
-  }
-
-  ConstantResult visitLiteralNull(LiteralNull node) {
-    ConstantExpression constant = new NullConstantExpression();
-    registry.registerConstantLiteral(constant);
-    registry.setConstant(node, constant);
-    return new ConstantResult(node, constant);
-  }
-
-  ConstantResult visitLiteralSymbol(LiteralSymbol node) {
-    String name = node.slowNameString;
-    // TODO(johnniwinther): Use [registerConstantLiteral] instead.
-    registry.registerConstSymbol(name);
-    if (!validateSymbol(node, name, reportError: false)) {
-      reporter.reportErrorMessage(
-          node, MessageKind.UNSUPPORTED_LITERAL_SYMBOL, {'value': name});
-    }
-    analyzeConstantDeferred(node);
-    ConstantExpression constant = new SymbolConstantExpression(name);
-    registry.setConstant(node, constant);
-    return new ConstantResult(node, constant);
-  }
-
-  ResolutionResult visitStringJuxtaposition(StringJuxtaposition node) {
-    registry.registerFeature(Feature.STRING_JUXTAPOSITION);
-    ResolutionResult first = visit(node.first);
-    ResolutionResult second = visit(node.second);
-    if (first.isConstant && second.isConstant) {
-      ConstantExpression constant = new ConcatenateConstantExpression(
-          <ConstantExpression>[first.constant, second.constant]);
-      registry.setConstant(node, constant);
-      return new ConstantResult(node, constant);
-    }
-    return const NoneResult();
-  }
-
-  ResolutionResult visitNodeList(NodeList node) {
-    for (Link<Node> link = node.nodes; !link.isEmpty; link = link.tail) {
-      visit(link.head);
-    }
-    return const NoneResult();
-  }
-
-  ResolutionResult visitRethrow(Rethrow node) {
-    if (!inCatchBlock && node.throwToken.stringValue == 'rethrow') {
-      reporter.reportErrorMessage(node, MessageKind.RETHROW_OUTSIDE_CATCH);
-    }
-    return const NoneResult();
-  }
-
-  ResolutionResult visitReturn(Return node) {
-    Node expression = node.expression;
-    if (expression != null) {
-      if (enclosingElement.isGenerativeConstructor) {
-        // It is a compile-time error if a return statement of the form
-        // `return e;` appears in a generative constructor.  (Dart Language
-        // Specification 13.12.)
-        reporter.reportErrorMessage(
-            expression, MessageKind.RETURN_IN_GENERATIVE_CONSTRUCTOR);
-      } else if (!node.isArrowBody && currentAsyncMarker.isYielding) {
-        reporter.reportErrorMessage(node, MessageKind.RETURN_IN_GENERATOR,
-            {'modifier': currentAsyncMarker});
-      }
-    }
-    visit(node.expression);
-    return const NoneResult();
-  }
-
-  ResolutionResult visitYield(Yield node) {
-    if (!resolution.target.supportsAsyncAwait) {
-      reporter.reportErrorMessage(reporter.spanFromToken(node.yieldToken),
-          MessageKind.ASYNC_AWAIT_NOT_SUPPORTED);
-    } else {
-      if (!currentAsyncMarker.isYielding) {
-        reporter.reportErrorMessage(node, MessageKind.INVALID_YIELD);
-      }
-      ClassElement cls;
-      if (currentAsyncMarker.isAsync) {
-        cls = commonElements.streamClass;
-      } else {
-        cls = commonElements.iterableClass;
-      }
-      cls.ensureResolved(resolution);
-    }
-    visit(node.expression);
-    return const NoneResult();
-  }
-
-  ResolutionResult visitRedirectingFactoryBody(RedirectingFactoryBody node) {
-    if (!enclosingElement.isFactoryConstructor) {
-      reporter.reportErrorMessage(
-          node, MessageKind.FACTORY_REDIRECTION_IN_NON_FACTORY);
-      reporter.reportHintMessage(
-          enclosingElement, MessageKind.MISSING_FACTORY_KEYWORD);
-    }
-
-    ConstructorElementX constructor = enclosingElement;
-    bool isConstConstructor = constructor.isConst;
-    bool isValidAsConstant = isConstConstructor;
-    ConstructorResult result =
-        resolveRedirectingFactory(node, inConstContext: isConstConstructor);
-    ConstructorElement redirectionTarget = result.element;
-    constructor.setImmediateRedirectionTarget(
-        redirectionTarget, result.isDeferred ? result.prefix : null);
-
-    registry.setRedirectingTargetConstructor(node, redirectionTarget);
-    switch (result.kind) {
-      case ConstructorResultKind.GENERATIVE:
-      case ConstructorResultKind.FACTORY:
-        // Register a post process to check for cycles in the redirection chain
-        // and set the actual generative constructor at the end of the chain.
-        addDeferredAction(constructor, () {
-          resolver.resolveRedirectionChain(constructor, node);
-        });
-        break;
-      case ConstructorResultKind.ABSTRACT:
-      case ConstructorResultKind.INVALID_TYPE:
-      case ConstructorResultKind.UNRESOLVED_CONSTRUCTOR:
-      case ConstructorResultKind.NON_CONSTANT:
-        isValidAsConstant = false;
-        constructor.setEffectiveTarget(result.element, result.type,
-            isMalformed: true);
-        break;
-    }
-    if (Elements.isUnresolved(redirectionTarget)) {
-      registry.registerFeature(Feature.THROW_NO_SUCH_METHOD);
-      return const NoneResult();
-    } else {
-      if (isConstConstructor && !redirectionTarget.isConst) {
-        reporter.reportErrorMessage(node, MessageKind.CONSTRUCTOR_IS_NOT_CONST);
-        isValidAsConstant = false;
-      }
-      if (redirectionTarget == constructor) {
-        reporter.reportErrorMessage(
-            node, MessageKind.CYCLIC_REDIRECTING_FACTORY);
-        // TODO(johnniwinther): Create constant constructor for this case and
-        // let evaluation detect the cyclicity.
-        isValidAsConstant = false;
-      }
-    }
-
-    // Check that the target constructor is type compatible with the
-    // redirecting constructor.
-    ClassElement targetClass = redirectionTarget.enclosingClass;
-    ResolutionInterfaceType type = registry.getType(node);
-    ResolutionFunctionType targetConstructorType = redirectionTarget
-        .computeType(resolution)
-        .subst(type.typeArguments, targetClass.typeVariables);
-    ResolutionFunctionType constructorType =
-        constructor.computeType(resolution);
-    bool isSubtype =
-        resolution.types.isSubtype(targetConstructorType, constructorType);
-    if (!isSubtype) {
-      reporter.reportWarningMessage(node, MessageKind.NOT_ASSIGNABLE,
-          {'fromType': targetConstructorType, 'toType': constructorType});
-      // TODO(johnniwinther): Handle this (potentially) erroneous case.
-      isValidAsConstant = false;
-    }
-    if (type.typeArguments.any((ResolutionDartType type) => !type.isDynamic)) {
-      registry.registerFeature(Feature.TYPE_VARIABLE_BOUNDS_CHECK);
-    }
-
-    redirectionTarget.computeType(resolution);
-    FunctionSignature targetSignature = redirectionTarget.functionSignature;
-    constructor.computeType(resolution);
-    FunctionSignature constructorSignature = constructor.functionSignature;
-    if (!targetSignature.isCompatibleWith(constructorSignature)) {
-      assert(!isSubtype);
-      registry.registerFeature(Feature.THROW_NO_SUCH_METHOD);
-      isValidAsConstant = false;
-    }
-
-    registry.registerStaticUse(new StaticUse.constructorRedirect(
-        redirectionTarget,
-        redirectionTarget.enclosingClass.thisType
-            .subst(type.typeArguments, targetClass.typeVariables)));
-    if (resolution.commonElements.isSymbolConstructor(constructor)) {
-      registry.registerFeature(Feature.SYMBOL_CONSTRUCTOR);
-    }
-    if (isValidAsConstant) {
-      List<String> names = <String>[];
-      List<ConstantExpression> arguments = <ConstantExpression>[];
-      int index = 0;
-      constructorSignature.forEachParameter((_parameter) {
-        ParameterElement parameter = _parameter;
-        if (parameter.isNamed) {
-          String name = parameter.name;
-          names.add(name);
-          arguments.add(new NamedArgumentReference(name));
-        } else {
-          arguments.add(new PositionalArgumentReference(index));
-        }
-        index++;
-      });
-      CallStructure callStructure =
-          new CallStructure(constructorSignature.parameterCount, names);
-      constructor.constantConstructor =
-          new RedirectingFactoryConstantConstructor(
-              new ConstructedConstantExpression(
-                  type, redirectionTarget, callStructure, arguments));
-    }
-    return const NoneResult();
-  }
-
-  ResolutionResult visitThrow(Throw node) {
-    registry.registerFeature(Feature.THROW_EXPRESSION);
-    visit(node.expression);
-    return const NoneResult();
-  }
-
-  ResolutionResult visitAwait(Await node) {
-    if (!resolution.target.supportsAsyncAwait) {
-      reporter.reportErrorMessage(reporter.spanFromToken(node.awaitToken),
-          MessageKind.ASYNC_AWAIT_NOT_SUPPORTED);
-    } else {
-      if (!currentAsyncMarker.isAsync) {
-        reporter.reportErrorMessage(node, MessageKind.INVALID_AWAIT);
-      }
-      ClassElement futureClass = commonElements.futureClass;
-      futureClass.ensureResolved(resolution);
-    }
-    visit(node.expression);
-    return const NoneResult();
-  }
-
-  ResolutionResult visitVariableDefinitions(VariableDefinitions node) {
-    ResolutionDartType type;
-    if (node.type != null) {
-      type = resolveTypeAnnotation(node.type);
-    } else {
-      type = const ResolutionDynamicType();
-    }
-    VariableList variables = new VariableList.node(node, type);
-    VariableDefinitionsVisitor visitor =
-        new VariableDefinitionsVisitor(resolution, node, this, variables);
-
-    Modifiers modifiers = node.modifiers;
-    void reportExtraModifier(String modifier) {
-      Node modifierNode;
-      for (Link<Node> nodes = modifiers.nodes.nodes;
-          !nodes.isEmpty;
-          nodes = nodes.tail) {
-        if (modifier == nodes.head.asIdentifier().source) {
-          modifierNode = nodes.head;
-          break;
-        }
-      }
-      assert(modifierNode != null);
-      reporter.reportErrorMessage(modifierNode, MessageKind.EXTRANEOUS_MODIFIER,
-          {'modifier': modifier});
-    }
-
-    if (modifiers.isFinal && (modifiers.isConst || modifiers.isVar)) {
-      reportExtraModifier('final');
-    }
-    if (modifiers.isVar && (modifiers.isConst || node.type != null)) {
-      reportExtraModifier('var');
-    }
-    if (enclosingElement.isFunction || enclosingElement.isConstructor) {
-      if (modifiers.isAbstract) {
-        reportExtraModifier('abstract');
-      }
-      if (modifiers.isStatic) {
-        reportExtraModifier('static');
-      }
-    }
-    if (node.metadata != null) {
-      variables.metadataInternal =
-          resolver.resolveMetadata(enclosingElement, node);
-    }
-    visitor.visit(node.definitions);
-    return const NoneResult();
-  }
-
-  ResolutionResult visitWhile(While node) {
-    visit(node.condition);
-    visitLoopBodyIn(node, node.body, new BlockScope(scope));
-    return const NoneResult();
-  }
-
-  ResolutionResult visitParenthesizedExpression(ParenthesizedExpression node) {
-    bool oldSendIsMemberAccess = sendIsMemberAccess;
-    sendIsMemberAccess = false;
-    var oldCategory = allowedCategory;
-    allowedCategory = ElementCategory.VARIABLE |
-        ElementCategory.FUNCTION |
-        ElementCategory.IMPLIES_TYPE;
-    ResolutionResult result = visit(node.expression);
-    allowedCategory = oldCategory;
-    sendIsMemberAccess = oldSendIsMemberAccess;
-    if (result.kind == ResultKind.CONSTANT) {
-      return result;
-    }
-    return const NoneResult();
-  }
-
-  ResolutionResult visitNewExpression(NewExpression node) {
-    ConstructorResult result = resolveConstructor(node);
-    ConstructorElement constructor = result.element;
-    if (resolution.commonElements.isSymbolConstructor(constructor)) {
-      registry.registerFeature(Feature.SYMBOL_CONSTRUCTOR);
-    }
-    ArgumentsResult argumentsResult;
-    if (node.isConst) {
-      argumentsResult =
-          inConstantContext(() => resolveArguments(node.send.argumentsNode));
-    } else {
-      if (!node.isConst && constructor.isFromEnvironmentConstructor) {
-        // TODO(sigmund): consider turning this into a compile-time-error.
-        reporter.reportHintMessage(
-            node,
-            MessageKind.FROM_ENVIRONMENT_MUST_BE_CONST,
-            {'className': constructor.enclosingClass.name});
-        registry.registerFeature(Feature.THROW_UNSUPPORTED_ERROR);
-      }
-      argumentsResult = resolveArguments(node.send.argumentsNode);
-    }
-    // TODO(johnniwinther): Avoid the need for a [Selector].
-    Selector selector = resolveSelector(node.send, constructor);
-    CallStructure callStructure = selector.callStructure;
-    registry.useElement(node.send, constructor);
-
-    ResolutionDartType type = result.type;
-    ConstructorAccessKind kind;
-    bool isInvalid = false;
-    switch (result.kind) {
-      case ConstructorResultKind.GENERATIVE:
-        // Ensure that the signature of [constructor] has been computed.
-        constructor.computeType(resolution);
-        if (!callStructure.signatureApplies(constructor.parameterStructure)) {
-          isInvalid = true;
-          kind = ConstructorAccessKind.INCOMPATIBLE;
-          registry.registerFeature(Feature.THROW_NO_SUCH_METHOD);
-        } else {
-          kind = ConstructorAccessKind.GENERATIVE;
-        }
-        break;
-      case ConstructorResultKind.FACTORY:
-        // Ensure that the signature of [constructor] has been computed.
-        constructor.computeType(resolution);
-        if (!callStructure.signatureApplies(constructor.parameterStructure)) {
-          // The effective target might still be valid(!) so the is not an
-          // invalid case in itself. For instance
-          //
-          //    class A {
-          //       factory A() = A.a;
-          //       A.a(a);
-          //    }
-          //    m() => new A(0); // This creates a warning but works at runtime.
-          //
-          registry.registerFeature(Feature.THROW_NO_SUCH_METHOD);
-        }
-        kind = ConstructorAccessKind.FACTORY;
-        break;
-      case ConstructorResultKind.ABSTRACT:
-        isInvalid = true;
-        kind = ConstructorAccessKind.ABSTRACT;
-        break;
-      case ConstructorResultKind.INVALID_TYPE:
-        isInvalid = true;
-        kind = ConstructorAccessKind.UNRESOLVED_TYPE;
-        break;
-      case ConstructorResultKind.UNRESOLVED_CONSTRUCTOR:
-        // TODO(johnniwinther): Unify codepaths to only have one return.
-        ResolutionInterfaceType interfaceType = type;
-        registry.registerNewStructure(
-            node,
-            new NewInvokeStructure(
-                new ConstructorAccessSemantics(
-                    ConstructorAccessKind.UNRESOLVED_CONSTRUCTOR,
-                    constructor,
-                    interfaceType),
-                selector));
-        return new ResolutionResult.forElement(constructor);
-      case ConstructorResultKind.NON_CONSTANT:
-        ResolutionInterfaceType interfaceType = type;
-        registry.registerNewStructure(
-            node,
-            new NewInvokeStructure(
-                new ConstructorAccessSemantics(
-                    ConstructorAccessKind.NON_CONSTANT_CONSTRUCTOR,
-                    constructor,
-                    interfaceType),
-                selector));
-        return new ResolutionResult.forElement(constructor);
-    }
-
-    if (!isInvalid) {
-      // [constructor] might be the implementation element
-      // and only declaration elements may be registered.
-      // TODO(johniwinther): Avoid registration of `type` in face of redirecting
-      // factory constructors.
-      ResolutionInterfaceType interfaceType = type;
-      ConstructorElement declaration = constructor.declaration;
-      registry.registerStaticUse(node.isConst
-          ? new StaticUse.constConstructorInvoke(
-              declaration, callStructure, interfaceType)
-          : new StaticUse.typedConstructorInvoke(
-              constructor, callStructure, interfaceType));
-      if (interfaceType.typeArguments
-          .any((ResolutionDartType type) => !type.isDynamic)) {
-        registry.registerFeature(Feature.TYPE_VARIABLE_BOUNDS_CHECK);
-      }
-    }
-
-    ResolutionResult resolutionResult = const NoneResult();
-    if (node.isConst) {
-      bool isValidAsConstant = !isInvalid && constructor.isConst;
-
-      CommonElements commonElements = resolution.commonElements;
-      if (commonElements.isSymbolConstructor(constructor)) {
-        Node argumentNode = node.send.arguments.head;
-        ConstantExpression constant = resolver.constantCompiler
-            .compileNode(argumentNode, registry.mapping);
-        ConstantValue name = resolution.constants.getConstantValue(constant);
-        if (!name.isString) {
-          ResolutionDartType type = name.getType(commonElements);
-          reporter.reportErrorMessage(
-              argumentNode, MessageKind.STRING_EXPECTED, {'type': type});
-        } else {
-          StringConstantValue stringConstant = name;
-          String nameString = stringConstant.stringValue;
-          if (validateSymbol(argumentNode, nameString)) {
-            registry.registerConstSymbol(nameString);
-          }
-        }
-      } else if (commonElements.isMirrorsUsedConstructor(constructor)) {
-        resolution.mirrorUsageAnalyzerTask.validate(node, registry.mapping);
-      }
-
-      analyzeConstantDeferred(node);
-
-      if (type.containsTypeVariables) {
-        reporter.reportErrorMessage(
-            node.send.selector, MessageKind.TYPE_VARIABLE_IN_CONSTANT);
-        isValidAsConstant = false;
-        isInvalid = true;
-      }
-
-      if (result.isDeferred) {
-        isValidAsConstant = false;
-      }
-
-      // Callback hook for when the compile-time constant evaluator has
-      // analyzed the constant.
-      // TODO(johnniwinther): Remove this when all constants are computed
-      // in resolution.
-      Function onAnalyzed;
-      if (isValidAsConstant &&
-          argumentsResult.isValidAsConstant &&
-          // TODO(johnniwinther): Remove this when all constants are computed
-          // in resolution.
-          !constructor.isFromEnvironmentConstructor) {
-        ResolutionInterfaceType interfaceType = type;
-        CallStructure callStructure = argumentsResult.callStructure;
-        List<ConstantExpression> arguments = argumentsResult.constantArguments;
-
-        ConstructedConstantExpression constant =
-            new ConstructedConstantExpression(
-                interfaceType, constructor, callStructure, arguments);
-        registry.registerNewStructure(node,
-            new ConstInvokeStructure(ConstantInvokeKind.CONSTRUCTED, constant));
-        resolutionResult = new ConstantResult(node, constant);
-      } else if (isInvalid) {
-        // Known to be non-constant.
-        kind == ConstructorAccessKind.NON_CONSTANT_CONSTRUCTOR;
-        registry.registerNewStructure(
-            node,
-            new NewInvokeStructure(
-                new ConstructorAccessSemantics(kind, constructor, type),
-                selector));
-      } else {
-        // Might be valid but we don't know for sure. The compile-time constant
-        // evaluator will compute the actual constant as a deferred action.
-        LateConstInvokeStructure structure =
-            new LateConstInvokeStructure(registry.mapping);
-        // TODO(johnniwinther): Avoid registering the
-        // [LateConstInvokeStructure]; it might not be necessary.
-        registry.registerNewStructure(node, structure);
-        onAnalyzed = () {
-          registry.registerNewStructure(node, structure.resolve(node));
-        };
-      }
-
-      analyzeConstantDeferred(node, onAnalyzed: onAnalyzed);
-    } else {
-      // Not constant.
-      if (resolution.commonElements.isSymbolConstructor(constructor) &&
-          !resolution.mirrorUsageAnalyzerTask
-              .hasMirrorUsage(enclosingElement)) {
-        reporter.reportHintMessage(
-            reporter.spanFromToken(node.newToken),
-            MessageKind.NON_CONST_BLOAT,
-            {'name': commonElements.symbolClass.name});
-      }
-      registry.registerNewStructure(
-          node,
-          new NewInvokeStructure(
-              new ConstructorAccessSemantics(kind, constructor, type),
-              selector));
-    }
-
-    return resolutionResult;
-  }
-
-  void checkConstMapKeysDontOverrideEquals(
-      Spannable spannable, MapConstantValue map) {
-    for (ConstantValue key in map.keys) {
-      if (!key.isObject) continue;
-      ObjectConstantValue objectConstant = key;
-      ResolutionInterfaceType keyType = objectConstant.type;
-      ClassElement cls = keyType.element;
-      if (cls == commonElements.stringClass) continue;
-      Element equals = cls.lookupMember('==');
-      if (equals.enclosingClass != commonElements.objectClass) {
-        reporter.reportErrorMessage(spannable,
-            MessageKind.CONST_MAP_KEY_OVERRIDES_EQUALS, {'type': keyType});
-      }
-    }
-  }
-
-  void analyzeConstant(Node node, {enforceConst: true}) {
-    ConstantExpression constant = resolver.constantCompiler
-        .compileNode(node, registry.mapping, enforceConst: enforceConst);
-
-    if (constant == null) {
-      assert(reporter.hasReportedError, failedAt(node));
-      return;
-    }
-
-    ConstantValue value = resolution.constants.getConstantValue(constant);
-    if (value.isMap) {
-      checkConstMapKeysDontOverrideEquals(node, value);
-    }
-  }
-
-  void analyzeConstantDeferred(Node node,
-      {bool enforceConst: true, void onAnalyzed()}) {
-    addDeferredAction(enclosingElement, () {
-      analyzeConstant(node, enforceConst: enforceConst);
-      if (onAnalyzed != null) {
-        onAnalyzed();
-      }
-    });
-  }
-
-  bool validateSymbol(Node node, String name, {bool reportError: true}) {
-    if (name.isEmpty) return true;
-    if (name.startsWith('_')) {
-      if (reportError) {
-        reporter.reportErrorMessage(
-            node, MessageKind.PRIVATE_IDENTIFIER, {'value': name});
-      }
-      return false;
-    }
-    if (!symbolValidationPattern.hasMatch(name)) {
-      if (reportError) {
-        reporter.reportErrorMessage(
-            node, MessageKind.INVALID_SYMBOL, {'value': name});
-      }
-      return false;
-    }
-    return true;
-  }
-
-  /**
-   * Try to resolve the constructor that is referred to by [node].
-   * Note: this function may return an ErroneousFunctionElement instead of
-   * [:null:], if there is no corresponding constructor, class or library.
-   */
-  ConstructorResult resolveConstructor(NewExpression node) {
-    return node.accept(new ConstructorResolver(resolution, this,
-        inConstContext: node.isConst));
-  }
-
-  ConstructorResult resolveRedirectingFactory(RedirectingFactoryBody node,
-      {bool inConstContext: false}) {
-    return node.accept(new ConstructorResolver(resolution, this,
-        inConstContext: inConstContext));
-  }
-
-  ResolutionDartType resolveTypeAnnotation(TypeAnnotation node,
-      {FunctionTypeParameterScope functionTypeParameters:
-          const FunctionTypeParameterScope(),
-      bool malformedIsError: false,
-      bool deferredIsMalformed: true,
-      bool registerCheckedModeCheck: true}) {
-    ResolutionDartType type = typeResolver.resolveTypeAnnotation(
-        this, node, functionTypeParameters,
-        malformedIsError: malformedIsError,
-        deferredIsMalformed: deferredIsMalformed);
-    if (registerCheckedModeCheck) {
-      registry.registerCheckedModeCheck(type);
-    }
-    return type;
-  }
-
-  ResolutionResult visitLiteralList(LiteralList node) {
-    bool isValidAsConstant = true;
-    sendIsMemberAccess = false;
-
-    NodeList arguments = node.typeArguments;
-    ResolutionDartType typeArgument;
-    if (arguments != null) {
-      Link<Node> nodes = arguments.nodes;
-      if (nodes.isEmpty) {
-        // The syntax [: <>[] :] is not allowed.
-        reporter.reportErrorMessage(
-            arguments, MessageKind.MISSING_TYPE_ARGUMENT);
-        isValidAsConstant = false;
-      } else {
-        typeArgument = resolveTypeAnnotation(nodes.head);
-        for (nodes = nodes.tail; !nodes.isEmpty; nodes = nodes.tail) {
-          reporter.reportWarningMessage(
-              nodes.head, MessageKind.ADDITIONAL_TYPE_ARGUMENT);
-          resolveTypeAnnotation(nodes.head);
-        }
-      }
-    }
-    ResolutionInterfaceType listType;
-    if (typeArgument != null) {
-      if (node.isConst && typeArgument.containsTypeVariables) {
-        reporter.reportErrorMessage(
-            arguments.nodes.head, MessageKind.TYPE_VARIABLE_IN_CONSTANT);
-        isValidAsConstant = false;
-      }
-      listType = commonElements.listType(typeArgument);
-    } else {
-      listType = commonElements.listType();
-    }
-    registry.registerLiteralList(node, listType,
-        isConstant: node.isConst, isEmpty: node.elements.isEmpty);
-    if (node.isConst) {
-      List<ConstantExpression> constantExpressions = <ConstantExpression>[];
-      inConstantContext(() {
-        for (Node element in node.elements) {
-          ResolutionResult elementResult = visit(element);
-          if (isValidAsConstant && elementResult.isConstant) {
-            constantExpressions.add(elementResult.constant);
-          } else {
-            isValidAsConstant = false;
-          }
-        }
-      });
-      analyzeConstantDeferred(node);
-      sendIsMemberAccess = false;
-      if (isValidAsConstant) {
-        ConstantExpression constant =
-            new ListConstantExpression(listType, constantExpressions);
-        registry.setConstant(node, constant);
-        return new ConstantResult(node, constant);
-      }
-    } else {
-      visit(node.elements);
-      sendIsMemberAccess = false;
-    }
-    return const NoneResult();
-  }
-
-  ResolutionResult visitConditional(Conditional node) {
-    ResolutionResult conditionResult =
-        doInPromotionScope(node.condition, () => visit(node.condition));
-    ResolutionResult thenResult = doInPromotionScope(
-        node.thenExpression, () => visit(node.thenExpression));
-    ResolutionResult elseResult = visit(node.elseExpression);
-    if (conditionResult.isConstant &&
-        thenResult.isConstant &&
-        elseResult.isConstant) {
-      ConstantExpression constant = new ConditionalConstantExpression(
-          conditionResult.constant, thenResult.constant, elseResult.constant);
-      registry.setConstant(node, constant);
-      return new ConstantResult(node, constant);
-    }
-    return const NoneResult();
-  }
-
-  ResolutionResult visitStringInterpolation(StringInterpolation node) {
-    // TODO(johnniwinther): This should be a consequence of the registration
-    // of [registerStringInterpolation].
-    registry.registerFeature(Feature.STRING_INTERPOLATION);
-
-    bool isValidAsConstant = true;
-    List<ConstantExpression> parts = <ConstantExpression>[];
-
-    void resolvePart(Node subnode) {
-      ResolutionResult result = visit(subnode);
-      if (isValidAsConstant && result.isConstant) {
-        parts.add(result.constant);
-      } else {
-        isValidAsConstant = false;
-      }
-    }
-
-    resolvePart(node.string);
-    for (StringInterpolationPart part in node.parts) {
-      resolvePart(part.expression);
-      resolvePart(part.string);
-    }
-
-    if (isValidAsConstant) {
-      ConstantExpression constant = new ConcatenateConstantExpression(parts);
-      registry.setConstant(node, constant);
-      return new ConstantResult(node, constant);
-    }
-    return const NoneResult();
-  }
-
-  ResolutionResult visitBreakStatement(BreakStatement node) {
-    JumpTargetX target;
-    if (node.target == null) {
-      target = statementScope.currentBreakTarget();
-      if (target == null) {
-        reporter.reportErrorMessage(node, MessageKind.NO_BREAK_TARGET);
-        return const NoneResult();
-      }
-      target.isBreakTarget = true;
-    } else {
-      String labelName = node.target.source;
-      LabelDefinitionX label = statementScope.lookupLabel(labelName);
-      if (label == null) {
-        reporter.reportErrorMessage(
-            node.target, MessageKind.UNBOUND_LABEL, {'labelName': labelName});
-        return const NoneResult();
-      }
-      target = label.target;
-      if (!target.statement.isValidBreakTarget()) {
-        reporter.reportErrorMessage(node.target, MessageKind.INVALID_BREAK);
-        return const NoneResult();
-      }
-      label.setBreakTarget();
-      registry.useLabel(node, label);
-    }
-    registry.registerTargetOf(node, target);
-    return const NoneResult();
-  }
-
-  ResolutionResult visitContinueStatement(ContinueStatement node) {
-    JumpTargetX target;
-    if (node.target == null) {
-      target = statementScope.currentContinueTarget();
-      if (target == null) {
-        reporter.reportErrorMessage(node, MessageKind.NO_CONTINUE_TARGET);
-        return const NoneResult();
-      }
-      target.isContinueTarget = true;
-    } else {
-      String labelName = node.target.source;
-      LabelDefinitionX label = statementScope.lookupLabel(labelName);
-      if (label == null) {
-        reporter.reportErrorMessage(
-            node.target, MessageKind.UNBOUND_LABEL, {'labelName': labelName});
-        return const NoneResult();
-      }
-      target = label.target;
-      if (!target.statement.isValidContinueTarget()) {
-        reporter.reportErrorMessage(node.target, MessageKind.INVALID_CONTINUE);
-      }
-      label.setContinueTarget();
-      registry.useLabel(node, label);
-    }
-    registry.registerTargetOf(node, target);
-    return const NoneResult();
-  }
-
-  ResolutionResult visitAsyncForIn(AsyncForIn node) {
-    if (!resolution.target.supportsAsyncAwait) {
-      reporter.reportErrorMessage(reporter.spanFromToken(node.awaitToken),
-          MessageKind.ASYNC_AWAIT_NOT_SUPPORTED);
-    } else {
-      if (!currentAsyncMarker.isAsync) {
-        reporter.reportErrorMessage(reporter.spanFromToken(node.awaitToken),
-            MessageKind.INVALID_AWAIT_FOR_IN);
-      }
-      registry.registerFeature(Feature.ASYNC_FOR_IN);
-      registry.registerDynamicUse(new DynamicUse(Selectors.cancel));
-      registry.registerDynamicUse(new DynamicUse(Selectors.current));
-      registry.registerDynamicUse(new DynamicUse(Selectors.moveNext));
-    }
-    visit(node.expression);
-
-    Scope blockScope = new BlockScope(scope);
-    visitForInDeclaredIdentifierIn(node.declaredIdentifier, node, blockScope);
-    visitLoopBodyIn(node, node.body, blockScope);
-    return const NoneResult();
-  }
-
-  ResolutionResult visitSyncForIn(SyncForIn node) {
-    registry.registerFeature(Feature.SYNC_FOR_IN);
-    registry.registerDynamicUse(new DynamicUse(Selectors.iterator));
-    registry.registerDynamicUse(new DynamicUse(Selectors.current));
-    registry.registerDynamicUse(new DynamicUse(Selectors.moveNext));
-
-    visit(node.expression);
-
-    Scope blockScope = new BlockScope(scope);
-    visitForInDeclaredIdentifierIn(node.declaredIdentifier, node, blockScope);
-    visitLoopBodyIn(node, node.body, blockScope);
-    return const NoneResult();
-  }
-
-  void visitForInDeclaredIdentifierIn(
-      Node declaration, ForIn node, Scope blockScope) {
-    LibraryElement library = enclosingElement.library;
-
-    bool oldAllowFinalWithoutInitializer = inLoopVariable;
-    inLoopVariable = true;
-    visitIn(declaration, blockScope);
-    inLoopVariable = oldAllowFinalWithoutInitializer;
-
-    Send send = declaration.asSend();
-    VariableDefinitions variableDefinitions =
-        declaration.asVariableDefinitions();
-    Element loopVariable;
-    Selector loopVariableSelector;
-    if (send != null) {
-      loopVariable = registry.getDefinition(send);
-      Identifier identifier = send.selector.asIdentifier();
-      if (identifier == null) {
-        reporter.reportErrorMessage(send.selector, MessageKind.INVALID_FOR_IN);
-      } else {
-        loopVariableSelector =
-            new Selector.setter(new Name(identifier.source, library));
-      }
-      if (send.receiver != null) {
-        reporter.reportErrorMessage(send.receiver, MessageKind.INVALID_FOR_IN);
-      }
-    } else if (variableDefinitions != null) {
-      Link<Node> nodes = variableDefinitions.definitions.nodes;
-      if (!nodes.tail.isEmpty) {
-        reporter.reportErrorMessage(
-            nodes.tail.head, MessageKind.INVALID_FOR_IN);
-      }
-      Node first = nodes.head;
-      Identifier identifier = first.asIdentifier();
-      if (identifier == null) {
-        reporter.reportErrorMessage(first, MessageKind.INVALID_FOR_IN);
-      } else {
-        loopVariableSelector =
-            new Selector.setter(new Name(identifier.source, library));
-        loopVariable = registry.getDefinition(identifier);
-      }
-    } else {
-      reporter.reportErrorMessage(declaration, MessageKind.INVALID_FOR_IN);
-    }
-    if (loopVariableSelector != null) {
-      registry.setSelector(declaration, loopVariableSelector);
-      if (loopVariable == null || loopVariable.isInstanceMember) {
-        registry.registerDynamicUse(new DynamicUse(loopVariableSelector));
-      } else if (loopVariable.isStatic || loopVariable.isTopLevel) {
-        MemberElement member = loopVariable.declaration;
-        registry.registerStaticUse(new StaticUse.staticSet(member));
-      }
-    } else {
-      // The selector may only be null if we reported an error.
-      assert(reporter.hasReportedError, failedAt(declaration));
-    }
-    if (loopVariable != null) {
-      // loopVariable may be null if it could not be resolved.
-      registry.setForInVariable(node, loopVariable);
-    }
-  }
-
-  visitLabel(Label node) {
-    // Labels are handled by their containing statements/cases.
-  }
-
-  ResolutionResult visitLabeledStatement(LabeledStatement node) {
-    Statement body = node.statement;
-    JumpTarget targetElement = getOrDefineTarget(body);
-    Map<String, LabelDefinitionX> labelElements = <String, LabelDefinitionX>{};
-    for (Label label in node.labels) {
-      String labelName = label.labelName;
-      if (labelElements.containsKey(labelName)) continue;
-      LabelDefinition element = targetElement.addLabel(label, labelName);
-      labelElements[labelName] = element;
-    }
-    statementScope.enterLabelScope(labelElements);
-    visit(node.statement);
-    statementScope.exitLabelScope();
-    labelElements.forEach((String labelName, LabelDefinitionX element) {
-      if (element.isTarget) {
-        registry.defineLabel(element.label, element);
-      } else {
-        reporter.reportWarningMessage(
-            element.label, MessageKind.UNUSED_LABEL, {'labelName': labelName});
-      }
-    });
-    if (!targetElement.isTarget) {
-      registry.undefineTarget(body);
-    }
-    return const NoneResult();
-  }
-
-  ResolutionResult visitLiteralMap(LiteralMap node) {
-    bool isValidAsConstant = true;
-    sendIsMemberAccess = false;
-
-    NodeList arguments = node.typeArguments;
-    ResolutionDartType keyTypeArgument;
-    ResolutionDartType valueTypeArgument;
-    if (arguments != null) {
-      Link<Node> nodes = arguments.nodes;
-      if (nodes.isEmpty) {
-        // The syntax [: <>{} :] is not allowed.
-        reporter.reportErrorMessage(
-            arguments, MessageKind.MISSING_TYPE_ARGUMENT);
-        isValidAsConstant = false;
-      } else {
-        keyTypeArgument = resolveTypeAnnotation(nodes.head);
-        nodes = nodes.tail;
-        if (nodes.isEmpty) {
-          reporter.reportWarningMessage(
-              arguments, MessageKind.MISSING_TYPE_ARGUMENT);
-        } else {
-          valueTypeArgument = resolveTypeAnnotation(nodes.head);
-          for (nodes = nodes.tail; !nodes.isEmpty; nodes = nodes.tail) {
-            reporter.reportWarningMessage(
-                nodes.head, MessageKind.ADDITIONAL_TYPE_ARGUMENT);
-            resolveTypeAnnotation(nodes.head);
-          }
-        }
-      }
-    }
-    ResolutionInterfaceType mapType;
-    if (valueTypeArgument != null) {
-      mapType = commonElements.mapType(keyTypeArgument, valueTypeArgument);
-    } else {
-      mapType = commonElements.mapType();
-    }
-    if (node.isConst && mapType.containsTypeVariables) {
-      reporter.reportErrorMessage(
-          arguments, MessageKind.TYPE_VARIABLE_IN_CONSTANT);
-      isValidAsConstant = false;
-    }
-    registry.registerMapLiteral(node, mapType,
-        isConstant: node.isConst, isEmpty: node.entries.isEmpty);
-
-    if (node.isConst) {
-      List<ConstantExpression> keyExpressions = <ConstantExpression>[];
-      List<ConstantExpression> valueExpressions = <ConstantExpression>[];
-      inConstantContext(() {
-        for (LiteralMapEntry entry in node.entries) {
-          ResolutionResult keyResult = visit(entry.key);
-          ResolutionResult valueResult = visit(entry.value);
-          if (isValidAsConstant &&
-              keyResult.isConstant &&
-              valueResult.isConstant) {
-            keyExpressions.add(keyResult.constant);
-            valueExpressions.add(valueResult.constant);
-          } else {
-            isValidAsConstant = false;
-          }
-        }
-      });
-      analyzeConstantDeferred(node);
-      sendIsMemberAccess = false;
-      if (isValidAsConstant) {
-        ConstantExpression constant = new MapConstantExpression(
-            mapType, keyExpressions, valueExpressions);
-        registry.setConstant(node, constant);
-        return new ConstantResult(node, constant);
-      }
-    } else {
-      node.visitChildren(this);
-      sendIsMemberAccess = false;
-    }
-    return const NoneResult();
-  }
-
-  ResolutionResult visitLiteralMapEntry(LiteralMapEntry node) {
-    node.visitChildren(this);
-    return const NoneResult();
-  }
-
-  ResolutionResult visitNamedArgument(NamedArgument node) {
-    return visit(node.expression);
-  }
-
-  ResolutionInterfaceType typeOfConstant(ConstantValue constant) {
-    if (constant.isInt) return commonElements.intType;
-    if (constant.isBool) return commonElements.boolType;
-    if (constant.isDouble) return commonElements.doubleType;
-    if (constant.isString) return commonElements.stringType;
-    if (constant.isNull) return commonElements.nullType;
-    if (constant.isFunction) return commonElements.functionType;
-    assert(constant.isObject);
-    ObjectConstantValue objectConstant = constant;
-    ResolutionInterfaceType type = objectConstant.type;
-    return type;
-  }
-
-  bool overridesEquals(ResolutionDartType type) {
-    ClassElement cls = type.element;
-    Element equals = cls.lookupMember('==');
-    return equals.enclosingClass != commonElements.objectClass;
-  }
-
-  void checkCaseExpressions(SwitchStatement node) {
-    CaseMatch firstCase = null;
-    ResolutionDartType firstCaseType = null;
-    DiagnosticMessage error;
-    List<DiagnosticMessage> infos = <DiagnosticMessage>[];
-
-    for (Link<Node> cases = node.cases.nodes;
-        !cases.isEmpty;
-        cases = cases.tail) {
-      SwitchCase switchCase = cases.head;
-
-      for (Node labelOrCase in switchCase.labelsAndCases) {
-        CaseMatch caseMatch = labelOrCase.asCaseMatch();
-        if (caseMatch == null) continue;
-
-        // Analyze the constant.
-        ConstantExpression constant =
-            registry.getConstant(caseMatch.expression);
-        assert(
-            constant != null, failedAt(node, 'No constant computed for $node'));
-
-        ConstantValue value = resolution.constants.getConstantValue(constant);
-        ResolutionDartType caseType =
-            value.getType(commonElements); //typeOfConstant(value);
-
-        if (firstCaseType == null) {
-          firstCase = caseMatch;
-          firstCaseType = caseType;
-
-          // We only report the bad type on the first class element. All others
-          // get a "type differs" error.
-          if (caseType == commonElements.doubleType) {
-            reporter.reportErrorMessage(
-                node,
-                MessageKind.SWITCH_CASE_VALUE_OVERRIDES_EQUALS,
-                {'type': "double"});
-          } else if (caseType == commonElements.functionType) {
-            reporter.reportErrorMessage(
-                node, MessageKind.SWITCH_CASE_FORBIDDEN, {'type': "Function"});
-          } else if (value.isObject && overridesEquals(caseType)) {
-            reporter.reportErrorMessage(
-                firstCase.expression,
-                MessageKind.SWITCH_CASE_VALUE_OVERRIDES_EQUALS,
-                {'type': caseType});
-          }
-        } else {
-          if (caseType != firstCaseType) {
-            if (error == null) {
-              error = reporter.createMessage(
-                  node,
-                  MessageKind.SWITCH_CASE_TYPES_NOT_EQUAL,
-                  {'type': firstCaseType});
-              infos.add(reporter.createMessage(
-                  firstCase.expression,
-                  MessageKind.SWITCH_CASE_TYPES_NOT_EQUAL_CASE,
-                  {'type': firstCaseType}));
-            }
-            infos.add(reporter.createMessage(
-                caseMatch.expression,
-                MessageKind.SWITCH_CASE_TYPES_NOT_EQUAL_CASE,
-                {'type': caseType}));
-          }
-        }
-      }
-    }
-    if (error != null) {
-      reporter.reportError(error, infos);
-    }
-  }
-
-  ResolutionResult visitSwitchStatement(SwitchStatement node) {
-    node.expression.accept(this);
-
-    JumpTarget breakElement = getOrDefineTarget(node);
-    Map<String, LabelDefinitionX> continueLabels = <String, LabelDefinitionX>{};
-    Set<SwitchCase> switchCasesWithContinues = new Set<SwitchCase>();
-    Link<Node> cases = node.cases.nodes;
-    while (!cases.isEmpty) {
-      SwitchCase switchCase = cases.head;
-      for (Node labelOrCase in switchCase.labelsAndCases) {
-        CaseMatch caseMatch = labelOrCase.asCaseMatch();
-        if (caseMatch != null) {
-          analyzeConstantDeferred(caseMatch.expression);
-          continue;
-        }
-        Label label = labelOrCase;
-        String labelName = label.labelName;
-
-        LabelDefinitionX existingElement = continueLabels[labelName];
-        if (existingElement != null) {
-          // It's an error if the same label occurs twice in the same switch.
-          reporter.reportError(
-              reporter.createMessage(
-                  label, MessageKind.DUPLICATE_LABEL, {'labelName': labelName}),
-              <DiagnosticMessage>[
-                reporter.createMessage(existingElement.label,
-                    MessageKind.EXISTING_LABEL, {'labelName': labelName}),
-              ]);
-        } else {
-          // It's only a warning if it shadows another label.
-          existingElement = statementScope.lookupLabel(labelName);
-          if (existingElement != null) {
-            reporter.reportWarning(
-                reporter.createMessage(label, MessageKind.DUPLICATE_LABEL,
-                    {'labelName': labelName}),
-                <DiagnosticMessage>[
-                  reporter.createMessage(existingElement.label,
-                      MessageKind.EXISTING_LABEL, {'labelName': labelName}),
-                ]);
-          }
-        }
-
-        JumpTarget targetElement = getOrDefineTarget(switchCase);
-        LabelDefinition labelElement = targetElement.addLabel(label, labelName);
-        registry.defineLabel(label, labelElement);
-        continueLabels[labelName] = labelElement;
-      }
-      cases = cases.tail;
-      // Test that only the last case, if any, is a default case.
-      if (switchCase.defaultKeyword != null && !cases.isEmpty) {
-        reporter.reportErrorMessage(
-            switchCase, MessageKind.INVALID_CASE_DEFAULT);
-      }
-      if (cases.isNotEmpty && switchCase.statements.isNotEmpty) {
-        Node last = switchCase.statements.last;
-        if (last.asReturn() == null &&
-            last.asBreakStatement() == null &&
-            last.asContinueStatement() == null &&
-            (last.asExpressionStatement() == null ||
-                last.asExpressionStatement().expression.asThrow() == null)) {
-          registry.registerFeature(Feature.FALL_THROUGH_ERROR);
-        }
-      }
-    }
-
-    addDeferredAction(enclosingElement, () {
-      checkCaseExpressions(node);
-    });
-
-    statementScope.enterSwitch(breakElement, continueLabels);
-    node.cases.accept(this);
-    statementScope.exitSwitch();
-
-    continueLabels.forEach((String key, LabelDefinition label) {
-      if (label.isContinueTarget) {
-        JumpTarget targetElement = label.target;
-        SwitchCase switchCase = targetElement.statement;
-        switchCasesWithContinues.add(switchCase);
-      }
-    });
-
-    // Clean-up unused labels.
-    continueLabels.forEach((String key, LabelDefinitionX label) {
-      if (!label.isContinueTarget) {
-        JumpTarget targetElement = label.target;
-        SwitchCase switchCase = targetElement.statement;
-        if (!switchCasesWithContinues.contains(switchCase)) {
-          registry.undefineTarget(switchCase);
-        }
-        registry.undefineLabel(label.label);
-      }
-    });
-    // TODO(15575): We should warn if we can detect a fall through
-    // error.
-    return const NoneResult();
-  }
-
-  ResolutionResult visitSwitchCase(SwitchCase node) {
-    node.labelsAndCases.accept(this);
-    visitIn(node.statements, new BlockScope(scope));
-    return const NoneResult();
-  }
-
-  ResolutionResult visitCaseMatch(CaseMatch node) {
-    visit(node.expression);
-    return const NoneResult();
-  }
-
-  ResolutionResult visitTryStatement(TryStatement node) {
-    // TODO(karlklose): also track the information about mutated variables,
-    // catch, and finally-block.
-    registry.registerTryStatement();
-
-    visit(node.tryBlock);
-    if (node.catchBlocks.isEmpty && node.finallyBlock == null) {
-      reporter.reportErrorMessage(
-          reporter.spanFromToken(node.getEndToken().next),
-          MessageKind.NO_CATCH_NOR_FINALLY);
-    }
-    visit(node.catchBlocks);
-    visit(node.finallyBlock);
-    return const NoneResult();
-  }
-
-  ResolutionResult visitCatchBlock(CatchBlock node) {
-    registry.registerFeature(Feature.CATCH_STATEMENT);
-    // Check that if catch part is present, then
-    // it has one or two formal parameters.
-    VariableDefinitions exceptionDefinition;
-    VariableDefinitions stackTraceDefinition;
-    if (node.formals != null) {
-      Link<Node> formalsToProcess = node.formals.nodes;
-      if (formalsToProcess.isEmpty) {
-        reporter.reportErrorMessage(node, MessageKind.EMPTY_CATCH_DECLARATION);
-      } else {
-        exceptionDefinition = formalsToProcess.head.asVariableDefinitions();
-        formalsToProcess = formalsToProcess.tail;
-        if (!formalsToProcess.isEmpty) {
-          stackTraceDefinition = formalsToProcess.head.asVariableDefinitions();
-          formalsToProcess = formalsToProcess.tail;
-          if (!formalsToProcess.isEmpty) {
-            for (Node extra in formalsToProcess) {
-              reporter.reportErrorMessage(
-                  extra, MessageKind.EXTRA_CATCH_DECLARATION);
-            }
-          }
-          registry.registerFeature(Feature.STACK_TRACE_IN_CATCH);
-        }
-      }
-
-      // Check that the formals aren't optional and that they have no
-      // modifiers or type.
-      for (Link<Node> link = node.formals.nodes;
-          !link.isEmpty;
-          link = link.tail) {
-        // If the formal parameter is a node list, it means that it is a
-        // sequence of optional parameters.
-        NodeList nodeList = link.head.asNodeList();
-        if (nodeList != null) {
-          reporter.reportErrorMessage(
-              nodeList, MessageKind.OPTIONAL_PARAMETER_IN_CATCH);
-        } else {
-          VariableDefinitions declaration = link.head;
-
-          for (Node modifier in declaration.modifiers.nodes) {
-            reporter.reportErrorMessage(
-                modifier, MessageKind.PARAMETER_WITH_MODIFIER_IN_CATCH);
-          }
-          TypeAnnotation type = declaration.type;
-          if (type != null) {
-            reporter.reportErrorMessage(
-                type, MessageKind.PARAMETER_WITH_TYPE_IN_CATCH);
-          }
-        }
-      }
-    }
-
-    Scope blockScope = new BlockScope(scope);
-    inCatchParameters = true;
-    visitIn(node.formals, blockScope);
-    inCatchParameters = false;
-    var oldInCatchBlock = inCatchBlock;
-    inCatchBlock = true;
-    visitIn(node.block, blockScope);
-    inCatchBlock = oldInCatchBlock;
-
-    if (node.type != null) {
-      ResolutionDartType exceptionType =
-          resolveTypeAnnotation(node.type, registerCheckedModeCheck: false);
-      if (exceptionDefinition != null) {
-        Node exceptionVariable = exceptionDefinition.definitions.nodes.head;
-        VariableElementX exceptionElement =
-            registry.getDefinition(exceptionVariable);
-        exceptionElement.variables.type = exceptionType;
-      }
-      registry.registerTypeUse(new TypeUse.catchType(exceptionType));
-    }
-    if (stackTraceDefinition != null) {
-      Node stackTraceVariable = stackTraceDefinition.definitions.nodes.head;
-      VariableElementX stackTraceElement =
-          registry.getDefinition(stackTraceVariable);
-      ResolutionInterfaceType stackTraceType = commonElements.stackTraceType;
-      stackTraceElement.variables.type = stackTraceType;
-    }
-    return const NoneResult();
-  }
-}
-
-/// Looks up [name] in [scope] and unwraps the result.
-Element lookupInScope(
-    DiagnosticReporter reporter, Node node, Scope scope, String name) {
-  return Elements.unwrap(scope.lookup(name), reporter, node);
-}
diff --git a/pkg/compiler/lib/src/resolution/no_such_method_resolver.dart b/pkg/compiler/lib/src/resolution/no_such_method_resolver.dart
deleted file mode 100644
index 5e4955f..0000000
--- a/pkg/compiler/lib/src/resolution/no_such_method_resolver.dart
+++ /dev/null
@@ -1,92 +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 '../common/names.dart' show Identifiers, Names;
-import '../elements/elements.dart';
-import '../js_backend/no_such_method_registry.dart';
-import '../tree/tree.dart';
-
-/// AST-based implementation of [NoSuchMethodResolver].
-class ResolutionNoSuchMethodResolver implements NoSuchMethodResolver {
-  bool hasForwardingSyntax(MethodElement element) {
-    // At this point we know that this is signature-compatible with
-    // Object.noSuchMethod, but it may have more than one argument as long as
-    // it only has one required argument.
-    if (!element.hasResolvedAst) {
-      // TODO(johnniwinther): Why do we see unresolved elements here?
-      return false;
-    }
-    ResolvedAst resolvedAst = element.resolvedAst;
-    if (resolvedAst.kind != ResolvedAstKind.PARSED) {
-      return false;
-    }
-    String param = element.parameters.first.name;
-    Statement body = resolvedAst.body;
-    Expression expr;
-    if (body is Return && body.isArrowBody) {
-      expr = body.expression;
-    } else if (body is Block &&
-        !body.statements.isEmpty &&
-        body.statements.nodes.tail.isEmpty) {
-      Statement stmt = body.statements.nodes.head;
-      if (stmt is Return && stmt.hasExpression) {
-        expr = stmt.expression;
-      }
-    }
-    if (expr is Send && expr.isTypeCast) {
-      Send sendExpr = expr;
-      var typeAnnotation = sendExpr.typeAnnotationFromIsCheckOrCast;
-      var typeName = typeAnnotation.asNominalTypeAnnotation()?.typeName;
-      if (typeName is Identifier && typeName.source == "dynamic") {
-        expr = sendExpr.receiver;
-      }
-    }
-    if (expr is Send &&
-        expr.isSuperCall &&
-        expr.selector is Identifier &&
-        (expr.selector as Identifier).source == Identifiers.noSuchMethod_) {
-      var arg = expr.arguments.head;
-      if (expr.arguments.tail.isEmpty &&
-          arg is Send &&
-          arg.argumentsNode == null &&
-          arg.receiver == null &&
-          arg.selector is Identifier) {
-        Identifier selector = arg.selector;
-        if (selector.source == param) {
-          return true;
-        }
-      }
-    }
-    return false;
-  }
-
-  bool hasThrowingSyntax(MethodElement element) {
-    if (!element.hasResolvedAst) {
-      // TODO(johnniwinther): Why do we see unresolved elements here?
-      return false;
-    }
-    ResolvedAst resolvedAst = element.resolvedAst;
-    if (resolvedAst.kind != ResolvedAstKind.PARSED) {
-      return false;
-    }
-    Statement body = resolvedAst.body;
-    if (body is Return && body.isArrowBody) {
-      if (body.expression is Throw) {
-        return true;
-      }
-    } else if (body is Block &&
-        !body.statements.isEmpty &&
-        body.statements.nodes.tail.isEmpty) {
-      if (body.statements.nodes.head is ExpressionStatement) {
-        ExpressionStatement stmt = body.statements.nodes.head;
-        return stmt.expression is Throw;
-      }
-    }
-    return false;
-  }
-
-  MethodElement getSuperNoSuchMethod(MethodElement method) {
-    return method.enclosingClass.lookupSuperByName(Names.noSuchMethod_);
-  }
-}
diff --git a/pkg/compiler/lib/src/resolution/registry.dart b/pkg/compiler/lib/src/resolution/registry.dart
index 2094ecf..2d713f1 100644
--- a/pkg/compiler/lib/src/resolution/registry.dart
+++ b/pkg/compiler/lib/src/resolution/registry.dart
@@ -4,29 +4,16 @@
 
 library dart2js.resolution.registry;
 
-import '../common.dart';
-import '../common/backend_api.dart' show ForeignResolver, NativeRegistry;
-import '../common/resolution.dart' show ResolutionImpact, Target;
+import '../common/resolution.dart' show ResolutionImpact;
 import '../constants/expressions.dart';
-import '../diagnostics/source_span.dart';
-import '../elements/elements.dart';
 import '../elements/entities.dart' show ClassEntity;
-import '../elements/jumps.dart';
-import '../elements/resolution_types.dart';
-import '../tree/tree.dart';
-import '../universe/call_structure.dart' show CallStructure;
 import '../universe/feature.dart';
-import '../universe/selector.dart' show Selector;
-import '../universe/use.dart' show DynamicUse, StaticUse, TypeUse;
 import '../universe/world_impact.dart' show WorldImpact, WorldImpactBuilderImpl;
 import '../util/enumset.dart' show EnumSet;
 import '../util/util.dart' show Setlet;
-import 'members.dart' show ResolverVisitor;
-import 'send_structure.dart';
-import 'tree_elements.dart' show TreeElementMapping;
 
 class ResolutionWorldImpactBuilder extends WorldImpactBuilderImpl
-    implements NativeRegistry, ResolutionImpact {
+    implements ResolutionImpact {
   final String name;
   EnumSet<Feature> _features;
   Setlet<MapLiteralUse> _mapLiterals;
@@ -171,295 +158,3 @@
     return sb.toString();
   }
 }
-
-/// [ResolutionRegistry] collects all resolution information. It stores node
-/// related information in a [TreeElements] mapping and registers calls with
-/// [Backend], [World] and [Enqueuer].
-// TODO(johnniwinther): Split this into an interface and implementation class.
-class ResolutionRegistry {
-  final Target target;
-  final TreeElementMapping mapping;
-  final ResolutionWorldImpactBuilder impactBuilder;
-
-  ResolutionRegistry(this.target, TreeElementMapping mapping)
-      : this.mapping = mapping,
-        this.impactBuilder = new ResolutionWorldImpactBuilder(
-            mapping.analyzedElement.toString());
-
-  bool get isForResolution => true;
-
-  String toString() => 'ResolutionRegistry for ${mapping.analyzedElement}';
-
-  //////////////////////////////////////////////////////////////////////////////
-  //  Node-to-Element mapping functionality.
-  //////////////////////////////////////////////////////////////////////////////
-
-  /// Register [node] as the declaration of [element].
-  void defineFunction(FunctionExpression node, FunctionElement element) {
-    // TODO(sigurdm): Remove when not needed by the dart2dart backend.
-    if (node.name != null) {
-      mapping[node.name] = element;
-    }
-    mapping[node] = element;
-  }
-
-  /// Register [node] as a reference to [element].
-  Element useElement(Node node, Element element) {
-    if (element == null) return null;
-    return mapping[node] = element;
-  }
-
-  /// Register [node] as the declaration of [element].
-  void defineElement(Node node, Element element) {
-    mapping[node] = element;
-  }
-
-  /// Returns the [Element] defined by [node].
-  Element getDefinition(Node node) {
-    return mapping[node];
-  }
-
-  /// Sets the loop variable of the for-in [node] to be [element].
-  void setForInVariable(ForIn node, Element element) {
-    mapping[node] = element;
-  }
-
-  /// Sets the target constructor [node] to be [element].
-  void setRedirectingTargetConstructor(
-      RedirectingFactoryBody node, ConstructorElement element) {
-    useElement(node, element);
-  }
-
-  //////////////////////////////////////////////////////////////////////////////
-  //  Node-to-Selector mapping functionality.
-  //////////////////////////////////////////////////////////////////////////////
-
-  void setSelector(Node node, Selector selector) {
-    mapping.setSelector(node, selector);
-  }
-
-  void setGetterSelectorInComplexSendSet(SendSet node, Selector selector) {
-    mapping.setGetterSelectorInComplexSendSet(node, selector);
-  }
-
-  void setOperatorSelectorInComplexSendSet(SendSet node, Selector selector) {
-    mapping.setOperatorSelectorInComplexSendSet(node, selector);
-  }
-
-  //////////////////////////////////////////////////////////////////////////////
-  //  Node-to-Type mapping functionality.
-  //////////////////////////////////////////////////////////////////////////////
-
-  ResolutionDartType useType(Node annotation, ResolutionDartType type) {
-    if (type != null) {
-      mapping.setType(annotation, type);
-    }
-    return type;
-  }
-
-  void setType(Node node, ResolutionDartType type) =>
-      mapping.setType(node, type);
-
-  ResolutionDartType getType(Node node) => mapping.getType(node);
-
-  //////////////////////////////////////////////////////////////////////////////
-  //  Node-to-Constant mapping functionality.
-  //////////////////////////////////////////////////////////////////////////////
-
-  ConstantExpression getConstant(Node node) => mapping.getConstant(node);
-
-  void setConstant(Node node, ConstantExpression constant) {
-    mapping.setConstant(node, constant);
-  }
-
-  //////////////////////////////////////////////////////////////////////////////
-  //  Target/Label functionality.
-  //////////////////////////////////////////////////////////////////////////////
-
-  /// Register [node] to be the declaration of [label].
-  void defineLabel(Label node, LabelDefinition label) {
-    mapping.defineLabel(node, label);
-  }
-
-  /// Undefine the label of [node].
-  /// This is used to cleanup and detect unused labels.
-  void undefineLabel(Label node) {
-    mapping.undefineLabel(node);
-  }
-
-  /// Register the target of [node] as reference to [label].
-  void useLabel(GotoStatement node, LabelDefinition label) {
-    mapping.registerTargetLabel(node, label);
-  }
-
-  /// Register [node] to be the declaration of [target].
-  void defineTarget(Node node, JumpTarget target) {
-    assert(node is Statement || node is SwitchCase,
-        failedAt(node, "Only statements and switch cases can define targets."));
-    mapping.defineTarget(node, target);
-  }
-
-  /// Returns the [JumpTarget] defined by [node].
-  JumpTarget getTargetDefinition(Node node) {
-    assert(node is Statement || node is SwitchCase,
-        failedAt(node, "Only statements and switch cases can define targets."));
-    return mapping.getTargetDefinition(node);
-  }
-
-  /// Undefine the target of [node]. This is used to cleanup unused targets.
-  void undefineTarget(Node node) {
-    assert(node is Statement || node is SwitchCase,
-        failedAt(node, "Only statements and switch cases can define targets."));
-    mapping.undefineTarget(node);
-  }
-
-  /// Register the target of [node] to be [target].
-  void registerTargetOf(GotoStatement node, JumpTarget target) {
-    mapping.registerTargetOf(node, target);
-  }
-
-  //////////////////////////////////////////////////////////////////////////////
-  //  Potential access registration.
-  //////////////////////////////////////////////////////////////////////////////
-
-  void setAccessedByClosureIn(
-      Node contextNode, VariableElement element, Node accessNode) {
-    mapping.setAccessedByClosureIn(contextNode, element, accessNode);
-  }
-
-  void registerPotentialMutation(VariableElement element, Node mutationNode) {
-    mapping.registerPotentialMutation(element, mutationNode);
-  }
-
-  void registerPotentialMutationInClosure(
-      VariableElement element, Node mutationNode) {
-    mapping.registerPotentialMutationInClosure(element, mutationNode);
-  }
-
-  void registerPotentialMutationIn(
-      Node contextNode, VariableElement element, Node mutationNode) {
-    mapping.registerPotentialMutationIn(contextNode, element, mutationNode);
-  }
-
-  //////////////////////////////////////////////////////////////////////////////
-  //  Various Backend/Enqueuer/World registration.
-  //////////////////////////////////////////////////////////////////////////////
-
-  void registerStaticUse(StaticUse staticUse) {
-    impactBuilder.registerStaticUse(staticUse);
-  }
-
-  /// Register the use of a type.
-  void registerTypeUse(TypeUse typeUse) {
-    impactBuilder.registerTypeUse(typeUse);
-  }
-
-  /// Register checked mode check of [type] if it isn't `dynamic`.
-  void registerCheckedModeCheck(ResolutionDartType type) {
-    if (!type.isDynamic) {
-      impactBuilder.registerTypeUse(new TypeUse.checkedModeCheck(type));
-    }
-  }
-
-  void registerSuperUse(SourceSpan span) {
-    mapping.addSuperUse(span);
-  }
-
-  void registerTypeLiteral(Send node, ResolutionDartType type) {
-    mapping.setType(node, type);
-    impactBuilder.registerTypeUse(new TypeUse.typeLiteral(type));
-  }
-
-  void registerLiteralList(Node node, ResolutionInterfaceType type,
-      {bool isConstant, bool isEmpty}) {
-    setType(node, type);
-    impactBuilder.registerListLiteral(
-        new ListLiteralUse(type, isConstant: isConstant, isEmpty: isEmpty));
-  }
-
-  void registerMapLiteral(Node node, ResolutionInterfaceType type,
-      {bool isConstant, bool isEmpty}) {
-    setType(node, type);
-    impactBuilder.registerMapLiteral(
-        new MapLiteralUse(type, isConstant: isConstant, isEmpty: isEmpty));
-  }
-
-  void registerForeignCall(Node node, Element element,
-      CallStructure callStructure, ResolverVisitor visitor) {
-    var nativeData = target.resolveForeignCall(node, element, callStructure,
-        new ForeignResolutionResolver(visitor, this));
-    if (nativeData != null) {
-      // Split impact from resolution result.
-      mapping.registerNativeData(node, nativeData);
-      impactBuilder.registerNativeData(nativeData);
-    }
-  }
-
-  void registerDynamicUse(DynamicUse dynamicUse) {
-    impactBuilder.registerDynamicUse(dynamicUse);
-  }
-
-  void registerFeature(Feature feature) {
-    impactBuilder.registerFeature(feature);
-  }
-
-  void registerConstSymbol(String name) {
-    impactBuilder.registerConstSymbolName(name);
-  }
-
-  void registerConstantLiteral(ConstantExpression constant) {
-    impactBuilder.registerConstantLiteral(constant);
-  }
-
-  ClassElement defaultSuperclass(ClassElement element) {
-    return target.defaultSuperclass(element);
-  }
-
-  void registerInstantiation(ResolutionInterfaceType type) {
-    impactBuilder.registerTypeUse(new TypeUse.instantiation(type));
-  }
-
-  void registerSendStructure(Send node, SendStructure sendStructure) {
-    mapping.setSendStructure(node, sendStructure);
-  }
-
-  void registerNewStructure(NewExpression node, NewStructure newStructure) {
-    mapping.setNewStructure(node, newStructure);
-  }
-
-  // TODO(johnniwinther): Remove this when [SendStructure]s are part of the
-  // [ResolutionResult].
-  SendStructure getSendStructure(Send node) {
-    return mapping.getSendStructure(node);
-  }
-
-  void registerTryStatement() {
-    mapping.containsTryStatement = true;
-  }
-
-  void registerSeenClass(ClassEntity seenClass) {
-    impactBuilder.registerSeenClass(seenClass);
-  }
-}
-
-class ForeignResolutionResolver implements ForeignResolver {
-  final ResolverVisitor visitor;
-  final ResolutionRegistry registry;
-
-  ForeignResolutionResolver(this.visitor, this.registry);
-
-  @override
-  ConstantExpression getConstant(Node node) {
-    return registry.getConstant(node);
-  }
-
-  @override
-  void registerInstantiatedType(ResolutionInterfaceType type) {
-    registry.registerInstantiation(type);
-  }
-
-  @override
-  ResolutionDartType resolveTypeFromString(Node node, String typeName) {
-    return visitor.resolveTypeFromString(node, typeName);
-  }
-}
diff --git a/pkg/compiler/lib/src/resolution/resolution.dart b/pkg/compiler/lib/src/resolution/resolution.dart
deleted file mode 100644
index ed4c280..0000000
--- a/pkg/compiler/lib/src/resolution/resolution.dart
+++ /dev/null
@@ -1,1192 +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.
-
-library dart2js.resolution;
-
-import 'dart:collection' show Queue;
-
-import '../common.dart';
-import '../common/names.dart' show Identifiers;
-import '../common/resolution.dart'
-    show ParsingContext, Resolution, ResolutionImpact, Target;
-import '../common/tasks.dart' show CompilerTask, Measurer;
-import '../compile_time_constants.dart' show ConstantCompiler;
-import '../constants/expressions.dart'
-    show
-        ConstantExpression,
-        ConstantExpressionKind,
-        ConstructedConstantExpression,
-        ErroneousConstantExpression;
-import '../constants/values.dart' show ConstantValue;
-import '../common_elements.dart' show CommonElements;
-import '../elements/resolution_types.dart';
-import '../elements/elements.dart';
-import '../elements/entities.dart' show AsyncMarker;
-import '../elements/modelx.dart'
-    show
-        BaseClassElementX,
-        BaseFunctionElementX,
-        ConstructorElementX,
-        FieldElementX,
-        FunctionElementX,
-        GetterElementX,
-        MetadataAnnotationX,
-        MixinApplicationElementX,
-        ParameterMetadataAnnotation,
-        SetterElementX,
-        TypedefElementX;
-import '../enqueue.dart';
-import '../options.dart';
-import 'package:front_end/src/fasta/scanner.dart'
-    show
-        isBinaryOperator,
-        isMinusOperator,
-        isTernaryOperator,
-        isUnaryOperator,
-        isUserDefinableOperator;
-import '../tree/tree.dart';
-import '../universe/call_structure.dart' show CallStructure;
-import '../universe/feature.dart' show Feature;
-import '../universe/use.dart' show StaticUse;
-import '../universe/world_impact.dart' show WorldImpact;
-import '../util/util.dart' show Link, Setlet;
-import '../world.dart';
-import 'class_hierarchy.dart';
-import 'class_members.dart' show MembersCreator;
-import 'constructors.dart';
-import 'members.dart';
-import 'registry.dart';
-import 'resolution_result.dart';
-import 'signatures.dart';
-import 'tree_elements.dart';
-import 'typedefs.dart';
-import 'type_resolver.dart' show FunctionTypeParameterScope;
-
-class ResolverTask extends CompilerTask {
-  final ConstantCompiler constantCompiler;
-  final Resolution resolution;
-
-  ResolverTask(this.resolution, this.constantCompiler, Measurer measurer)
-      : super(measurer);
-
-  String get name => 'Resolver';
-
-  DiagnosticReporter get reporter => resolution.reporter;
-  Target get target => resolution.target;
-  CommonElements get commonElements => resolution.commonElements;
-  ParsingContext get parsingContext => resolution.parsingContext;
-  CompilerOptions get options => resolution.options;
-  ResolutionEnqueuer get enqueuer => resolution.enqueuer;
-  OpenWorld get world => enqueuer.worldBuilder;
-
-  ResolutionImpact resolve(Element element) {
-    return measure(() {
-      if (Elements.isMalformed(element)) {
-        // TODO(johnniwinther): Add a predicate for this.
-        assert(
-            element is! ErroneousElement,
-            failedAt(
-                element, "Element $element expected to have parse errors."));
-        _ensureTreeElements(element);
-        return const ResolutionImpact();
-      }
-
-      WorldImpact processMetadata([WorldImpact result]) {
-        for (MetadataAnnotation metadata in element.implementation.metadata) {
-          metadata.ensureResolved(resolution);
-        }
-        return result;
-      }
-
-      if (element.isConstructor ||
-          element.isFunction ||
-          element.isGetter ||
-          element.isSetter) {
-        return processMetadata(resolveMethodElement(element));
-      }
-
-      if (element.isField) {
-        return processMetadata(resolveField(element));
-      }
-      if (element.isClass) {
-        ClassElement cls = element;
-        cls.ensureResolved(resolution);
-        return processMetadata(const ResolutionImpact());
-      } else if (element.isTypedef) {
-        TypedefElement typdef = element;
-        return processMetadata(resolveTypedef(typdef));
-      }
-
-      reporter.internalError(element, "resolve($element) not implemented.");
-    });
-  }
-
-  void resolveRedirectingConstructor(InitializerResolver resolver, Node node,
-      FunctionElement constructor, FunctionElement redirection) {
-    assert(
-        constructor.isImplementation,
-        failedAt(
-            node,
-            'Redirecting constructors must be resolved on implementation '
-            'elements.'));
-    Setlet<FunctionElement> seen = new Setlet<FunctionElement>();
-    seen.add(constructor);
-    while (redirection != null) {
-      // Ensure that we follow redirections through implementation elements.
-      redirection = redirection.implementation;
-      if (redirection.isError) {
-        break;
-      }
-      if (seen.contains(redirection)) {
-        reporter.reportErrorMessage(
-            node, MessageKind.REDIRECTING_CONSTRUCTOR_CYCLE);
-        return;
-      }
-      seen.add(redirection);
-      redirection = resolver.visitor.resolveConstructorRedirection(redirection);
-    }
-  }
-
-  static void processAsyncMarker(Resolution resolution,
-      BaseFunctionElementX element, ResolutionRegistry registry) {
-    DiagnosticReporter reporter = resolution.reporter;
-    CommonElements commonElements = resolution.commonElements;
-    FunctionExpression functionExpression = element.node;
-    AsyncModifier asyncModifier = functionExpression.asyncModifier;
-    if (asyncModifier != null) {
-      if (!resolution.target.supportsAsyncAwait) {
-        reporter.reportErrorMessage(functionExpression.asyncModifier,
-            MessageKind.ASYNC_AWAIT_NOT_SUPPORTED);
-      } else {
-        if (asyncModifier.isAsynchronous) {
-          element.asyncMarker = asyncModifier.isYielding
-              ? AsyncMarker.ASYNC_STAR
-              : AsyncMarker.ASYNC;
-        } else {
-          element.asyncMarker = AsyncMarker.SYNC_STAR;
-        }
-        if (element.isAbstract) {
-          reporter.reportErrorMessage(
-              asyncModifier,
-              MessageKind.ASYNC_MODIFIER_ON_ABSTRACT_METHOD,
-              {'modifier': element.asyncMarker});
-        } else if (element.isConstructor) {
-          reporter.reportErrorMessage(
-              asyncModifier,
-              MessageKind.ASYNC_MODIFIER_ON_CONSTRUCTOR,
-              {'modifier': element.asyncMarker});
-        } else {
-          if (element.isSetter) {
-            reporter.reportErrorMessage(
-                asyncModifier,
-                MessageKind.ASYNC_MODIFIER_ON_SETTER,
-                {'modifier': element.asyncMarker});
-          }
-          if (functionExpression.body.asReturn() != null &&
-              element.asyncMarker.isYielding) {
-            reporter.reportErrorMessage(
-                asyncModifier,
-                MessageKind.YIELDING_MODIFIER_ON_ARROW_BODY,
-                {'modifier': element.asyncMarker});
-          }
-        }
-        ClassElement cls;
-        switch (element.asyncMarker) {
-          case AsyncMarker.ASYNC:
-            registry.registerFeature(Feature.ASYNC);
-            cls = commonElements.futureClass;
-            break;
-          case AsyncMarker.ASYNC_STAR:
-            registry.registerFeature(Feature.ASYNC_STAR);
-            cls = commonElements.streamClass;
-            break;
-          case AsyncMarker.SYNC_STAR:
-            registry.registerFeature(Feature.SYNC_STAR);
-            cls = commonElements.iterableClass;
-            break;
-        }
-        cls?.ensureResolved(resolution);
-      }
-    }
-  }
-
-  bool _isNativeClassOrExtendsNativeClass(ClassElement classElement) {
-    assert(classElement != null);
-    while (classElement != null) {
-      if (target.isNativeClass(classElement)) return true;
-      classElement = classElement.superclass;
-    }
-    return false;
-  }
-
-  WorldImpact resolveMethodElementImplementation(
-      FunctionElementX element, FunctionExpression tree) {
-    return reporter.withCurrentElement(element, () {
-      if (element.isMarkedExternal && tree.hasBody) {
-        reporter.reportErrorMessage(element, MessageKind.EXTERNAL_WITH_BODY,
-            {'functionName': element.name});
-      }
-      if (element.isConstructor) {
-        if (tree.returnType != null) {
-          reporter.reportErrorMessage(
-              tree, MessageKind.CONSTRUCTOR_WITH_RETURN_TYPE);
-        }
-        if (tree.hasBody && element.isConst) {
-          if (element.isGenerativeConstructor) {
-            reporter.reportErrorMessage(
-                tree, MessageKind.CONST_CONSTRUCTOR_WITH_BODY);
-          } else if (!tree.isRedirectingFactory) {
-            reporter.reportErrorMessage(tree, MessageKind.CONST_FACTORY);
-          }
-        }
-      }
-
-      ResolverVisitor visitor = visitorFor(element);
-      ResolutionRegistry registry = visitor.registry;
-      registry.defineFunction(tree, element);
-      visitor.setupFunction(tree, element); // Modifies the scope.
-      processAsyncMarker(resolution, element, registry);
-
-      if (element.isGenerativeConstructor) {
-        // Even if there is no initializer list we still have to do the
-        // resolution in case there is an implicit super constructor call.
-        InitializerResolver resolver =
-            new InitializerResolver(visitor, element, tree);
-        FunctionElement redirection = resolver.resolveInitializers();
-        if (redirection != null) {
-          resolveRedirectingConstructor(resolver, tree, element, redirection);
-        }
-      } else if (tree.initializers != null) {
-        reporter.reportErrorMessage(
-            tree, MessageKind.FUNCTION_WITH_INITIALIZER);
-      }
-
-      if (!options.analyzeSignaturesOnly || tree.isRedirectingFactory) {
-        // We need to analyze the redirecting factory bodies to ensure that
-        // we can analyze compile-time constants.
-        visitor.visit(tree.body);
-      }
-
-      // Get the resolution tree and check that the resolved
-      // function doesn't use 'super' if it is mixed into another
-      // class. This is the part of the 'super' mixin check that
-      // happens when a function is resolved after the mixin
-      // application has been performed.
-      TreeElements resolutionTree = registry.mapping;
-      ClassElement enclosingClass = element.enclosingClass;
-      if (enclosingClass != null) {
-        // TODO(johnniwinther): Find another way to obtain mixin uses.
-        ClassElement mixin = enclosingClass;
-        for (MixinApplicationElement mixinApplication
-            in world.allMixinUsesOf(enclosingClass)) {
-          checkMixinSuperUses(resolutionTree, mixinApplication, mixin);
-        }
-      }
-
-      // TODO(9631): support noSuchMethod on native classes.
-      if (element.isFunction &&
-          element.isInstanceMember &&
-          element.name == Identifiers.noSuchMethod_ &&
-          _isNativeClassOrExtendsNativeClass(enclosingClass)) {
-        reporter.reportErrorMessage(tree, MessageKind.NO_SUCH_METHOD_IN_NATIVE);
-      }
-
-      resolution.target.resolveNativeMember(element, registry.impactBuilder);
-
-      return registry.impactBuilder;
-    });
-  }
-
-  /// Returns `true` if [element] has been processed by the resolution enqueuer.
-  bool _hasBeenProcessed(MemberElement element) {
-    assert(element == element.analyzableElement.declaration,
-        failedAt(element, "Unexpected element $element"));
-    return enqueuer.processedEntities.contains(element);
-  }
-
-  WorldImpact resolveMethodElement(FunctionElementX element) {
-    assert(element.isDeclaration, failedAt(element));
-    return reporter.withCurrentElement(element, () {
-      if (_hasBeenProcessed(element)) {
-        // TODO(karlklose): Remove the check for [isConstructor]. [elememts]
-        // should never be non-null, not even for constructors.
-        assert(
-            element.isConstructor,
-            failedAt(element,
-                'Non-constructor element $element has already been analyzed.'));
-        return const ResolutionImpact();
-      }
-      if (element.isSynthesized) {
-        if (element.isGenerativeConstructor) {
-          ResolutionRegistry registry =
-              new ResolutionRegistry(this.target, _ensureTreeElements(element));
-          ConstructorElement constructor = element.asFunctionElement();
-          ConstructorElement target = constructor.definingConstructor;
-          // Ensure the signature of the synthesized element is
-          // resolved. This is the only place where the resolver is
-          // seeing this element.
-          ResolutionFunctionType type = element.computeType(resolution);
-          if (!target.isMalformed) {
-            registry.registerStaticUse(new StaticUse.superConstructorInvoke(
-                // TODO(johnniwinther): Provide the right call structure for
-                // forwarding constructors.
-                target,
-                CallStructure.NO_ARGS));
-          }
-          // TODO(johnniwinther): Remove this substitution when synthesized
-          // constructors handle type variables correctly.
-          type = type.substByContext(
-              constructor.enclosingClass.asInstanceOf(target.enclosingClass));
-          type.parameterTypes.forEach(registry.registerCheckedModeCheck);
-          type.optionalParameterTypes
-              .forEach(registry.registerCheckedModeCheck);
-          type.namedParameterTypes.forEach(registry.registerCheckedModeCheck);
-          return registry.impactBuilder;
-        } else {
-          assert(element.isDeferredLoaderGetter || element.isMalformed);
-          _ensureTreeElements(element);
-          return const ResolutionImpact();
-        }
-      } else {
-        element.parseNode(resolution.parsingContext);
-        element.computeType(resolution);
-        FunctionElementX implementation = element;
-        if (element.isMarkedExternal) {
-          implementation = target.resolveExternalFunction(element);
-        }
-        return resolveMethodElementImplementation(
-            implementation, implementation.node);
-      }
-    });
-  }
-
-  /// Creates a [ResolverVisitor] for resolving an AST in context of [element].
-  /// If [useEnclosingScope] is `true` then the initial scope of the visitor
-  /// does not include inner scope of [element].
-  ///
-  /// This method should only be used by this library (or tests of
-  /// this library).
-  ResolverVisitor visitorFor(Element element, {bool useEnclosingScope: false}) {
-    return new ResolverVisitor(resolution, element,
-        new ResolutionRegistry(target, _ensureTreeElements(element)),
-        useEnclosingScope: useEnclosingScope);
-  }
-
-  WorldImpact resolveField(FieldElementX element) {
-    return reporter.withCurrentElement(element, () {
-      VariableDefinitions tree = element.parseNode(parsingContext);
-      if (element.modifiers.isStatic && element.isTopLevel) {
-        reporter.reportErrorMessage(element.modifiers.getStatic(),
-            MessageKind.TOP_LEVEL_VARIABLE_DECLARED_STATIC);
-      }
-      ResolverVisitor visitor = visitorFor(element);
-      ResolutionRegistry registry = visitor.registry;
-      // TODO(johnniwinther): Maybe remove this when placeholderCollector
-      // migrates to the backend ast.
-      registry.defineElement(element.definition, element);
-      // TODO(johnniwinther): Share the resolved type between all variables
-      // declared in the same declaration.
-      if (tree.type != null) {
-        ResolutionDartType type = visitor.resolveTypeAnnotation(tree.type);
-        assert(
-            element.variables.type == null ||
-                // Crude check but we have no equivalence relation that
-                // equates malformed types, like matching creations of type
-                // `Foo<Unresolved>`.
-                element.variables.type.toString() == type.toString(),
-            failedAt(
-                element,
-                "Unexpected type computed for $element. "
-                "Was ${element.variables.type}, computed $type."));
-        element.variables.type = type;
-      } else if (element.variables.type == null) {
-        // Only assign the dynamic type if the element has no known type. This
-        // happens for enum fields where the type is known but is not in the
-        // synthesized AST.
-        element.variables.type = const ResolutionDynamicType();
-      } else {
-        registry.registerCheckedModeCheck(element.variables.type);
-      }
-
-      Expression initializer = element.initializer;
-      Modifiers modifiers = element.modifiers;
-      if (initializer != null) {
-        // TODO(johnniwinther): Avoid analyzing initializers if
-        // [Compiler.analyzeSignaturesOnly] is set.
-        ResolutionResult result = visitor.visit(initializer);
-        if (result.isConstant) {
-          element.constant = result.constant;
-        }
-      } else if (modifiers.isConst) {
-        reporter.reportErrorMessage(
-            element, MessageKind.CONST_WITHOUT_INITIALIZER);
-      } else if (modifiers.isFinal && !element.isInstanceMember) {
-        reporter.reportErrorMessage(
-            element, MessageKind.FINAL_WITHOUT_INITIALIZER);
-      } else {
-        registry.registerFeature(Feature.FIELD_WITHOUT_INITIALIZER);
-      }
-
-      if (Elements.isStaticOrTopLevelField(element)) {
-        visitor.addDeferredAction(element, () {
-          if (element.modifiers.isConst) {
-            element.constant = constantCompiler.compileConstant(element);
-          } else {
-            element.constant = constantCompiler.compileVariable(element);
-          }
-        });
-        if (initializer != null) {
-          if (!element.modifiers.isConst &&
-              initializer.asLiteralNull() == null) {
-            // TODO(johnniwinther): Determine the const-ness eagerly to avoid
-            // unnecessary registrations.
-            registry.registerFeature(Feature.LAZY_FIELD);
-          }
-        }
-      }
-
-      // Perform various checks as side effect of "computing" the type.
-      element.computeType(resolution);
-
-      resolution.target.resolveNativeMember(element, registry.impactBuilder);
-
-      return registry.impactBuilder;
-    });
-  }
-
-  ResolutionDartType resolveTypeAnnotation(
-      Element element, TypeAnnotation annotation) {
-    ResolutionDartType type = _resolveReturnType(element, annotation);
-    if (type.isVoid) {
-      reporter.reportErrorMessage(annotation, MessageKind.VOID_NOT_ALLOWED);
-    }
-    return type;
-  }
-
-  ResolutionDartType _resolveReturnType(
-      Element element, TypeAnnotation annotation) {
-    if (annotation == null) return const ResolutionDynamicType();
-    ResolutionDartType result =
-        visitorFor(element).resolveTypeAnnotation(annotation);
-    assert(result != null,
-        failedAt(annotation, "No type computed for $annotation."));
-    if (result == null) {
-      // TODO(karklose): warning.
-      return const ResolutionDynamicType();
-    }
-    return result;
-  }
-
-  void resolveRedirectionChain(ConstructorElement constructor, Spannable node) {
-    ConstructorElement target = constructor;
-    ResolutionDartType targetType;
-    List<ConstructorElement> seen = new List<ConstructorElement>();
-    bool isMalformed = false;
-    // Follow the chain of redirections and check for cycles.
-    while (target.isRedirectingFactory) {
-      if (target.hasEffectiveTarget) {
-        // We found a constructor that already has been processed.
-        // TODO(johnniwinther): Should `effectiveTargetType` be part of the
-        // interface?
-        targetType =
-            target.computeEffectiveTargetType(target.enclosingClass.thisType);
-        assert(
-            targetType != null,
-            failedAt(target,
-                'Redirection target type has not been computed for $target'));
-        target = target.effectiveTarget;
-        break;
-      }
-
-      Element nextTarget = target.immediateRedirectionTarget;
-
-      if (seen.contains(nextTarget)) {
-        reporter.reportErrorMessage(
-            node, MessageKind.CYCLIC_REDIRECTING_FACTORY);
-        targetType = target.enclosingClass.thisType;
-        isMalformed = true;
-        break;
-      }
-      seen.add(target);
-      target = nextTarget;
-    }
-
-    if (target.isGenerativeConstructor && target.enclosingClass.isAbstract) {
-      isMalformed = true;
-    }
-    if (target.isMalformed) {
-      isMalformed = true;
-    }
-
-    if (targetType == null) {
-      assert(!target.isRedirectingFactory);
-      targetType = target.enclosingClass.thisType;
-    }
-
-    // [target] is now the actual target of the redirections.  Run through
-    // the constructors again and set their [redirectionTarget], so that we
-    // do not have to run the loop for these constructors again. Furthermore,
-    // compute [redirectionTargetType] for each factory by computing the
-    // substitution of the target type with respect to the factory type.
-    while (!seen.isEmpty) {
-      ConstructorElementX factory = seen.removeLast();
-      ResolvedAst resolvedAst = factory.resolvedAst;
-      assert(
-          resolvedAst != null, failedAt(node, 'No ResolvedAst for $factory.'));
-      RedirectingFactoryBody redirectionNode = resolvedAst.body;
-      ResolutionDartType factoryType =
-          resolvedAst.elements.getType(redirectionNode);
-      if (!factoryType.isDynamic) {
-        targetType = targetType.substByContext(factoryType);
-      }
-      factory.setEffectiveTarget(target, targetType, isMalformed: isMalformed);
-    }
-  }
-
-  /**
-   * Load and resolve the supertypes of [cls].
-   *
-   * Warning: do not call this method directly. It should only be
-   * called by [resolveClass] and [ClassSupertypeResolver].
-   */
-  void loadSupertypes(BaseClassElementX cls, Spannable from) {
-    measure(() {
-      if (cls.supertypeLoadState == STATE_DONE) return;
-      if (cls.supertypeLoadState == STATE_STARTED) {
-        reporter.reportErrorMessage(
-            from, MessageKind.CYCLIC_CLASS_HIERARCHY, {'className': cls.name});
-        cls.supertypeLoadState = STATE_DONE;
-        cls.hasIncompleteHierarchy = true;
-        ClassElement objectClass = commonElements.objectClass;
-        cls.allSupertypesAndSelf = objectClass.allSupertypesAndSelf
-            .extendClass(cls.computeType(resolution));
-        cls.supertype = cls.allSupertypes.head;
-        assert(cls.supertype != null,
-            failedAt(from, 'Missing supertype on cyclic class $cls.'));
-        cls.interfaces = const Link<ResolutionDartType>();
-        return;
-      }
-      cls.supertypeLoadState = STATE_STARTED;
-      reporter.withCurrentElement(cls, () {
-        // TODO(ahe): Cache the node in cls.
-        cls
-            .parseNode(parsingContext)
-            .accept(new ClassSupertypeResolver(resolution, cls));
-        if (cls.supertypeLoadState != STATE_DONE) {
-          cls.supertypeLoadState = STATE_DONE;
-        }
-      });
-    });
-  }
-
-  // TODO(johnniwinther): Remove this queue when resolution has been split into
-  // syntax and semantic resolution.
-  /// Whether or not we are currently resolving a type declaration.
-  ///
-  /// When we are resolving a type declaration, we want to avoid resolving
-  /// other type declarations that are encountered through type annotations
-  /// until after we finish resolving the current declaration.
-  bool isResolvingTypeDeclaration = false;
-
-  bool isPostProcessingTypeDeclaration = false;
-
-  /// Classes found in type annotations while resolving a type declaration.
-  ///
-  /// These are stored here so that they may be resolved after the original
-  /// type annotation.
-  Queue<ClassElement> pendingClassesToBeResolved = new Queue<ClassElement>();
-
-  /// Classes to be post-processed after the type declaration is resolved.
-  Queue<ClassElement> pendingClassesToBePostProcessed =
-      new Queue<ClassElement>();
-
-  /// Resolve [element] using [resolveTypeDeclaration].
-  ///
-  /// This method ensures that class declarations encountered through type
-  /// annotations during the resolution of [element] are resolved after
-  /// [element] has been resolved.
-  // TODO(johnniwinther): Encapsulate this functionality in a
-  // 'TypeDeclarationResolver'.
-  _resolveTypeDeclaration(
-      TypeDeclarationElement element, resolveTypeDeclaration()) {
-    return reporter.withCurrentElement(element, () {
-      return measure(() {
-        bool previouslyResolvingTypeDeclaration = isResolvingTypeDeclaration;
-        isResolvingTypeDeclaration = true;
-        var result = resolveTypeDeclaration();
-        isResolvingTypeDeclaration = previouslyResolvingTypeDeclaration;
-        if (!isResolvingTypeDeclaration) {
-          do {
-            while (pendingClassesToBeResolved.isNotEmpty) {
-              pendingClassesToBeResolved
-                  .removeFirst()
-                  .ensureResolved(resolution);
-            }
-            if (!isPostProcessingTypeDeclaration) {
-              isPostProcessingTypeDeclaration = true;
-              while (pendingClassesToBePostProcessed.isNotEmpty) {
-                _postProcessClassElement(
-                    pendingClassesToBePostProcessed.removeFirst());
-              }
-              isPostProcessingTypeDeclaration = false;
-            }
-          } while (pendingClassesToBeResolved.isNotEmpty);
-          assert(pendingClassesToBeResolved.isEmpty);
-          assert(pendingClassesToBePostProcessed.isEmpty ||
-              isPostProcessingTypeDeclaration);
-        }
-        return result;
-      });
-    });
-  }
-
-  /**
-   * Resolve the class [element].
-   *
-   * Before calling this method, [element] was constructed by the
-   * scanner and most fields are null or empty. This method fills in
-   * these fields and also ensure that the supertypes of [element] are
-   * resolved.
-   *
-   * Warning: Do not call this method directly. Instead use
-   * [:element.ensureResolved(resolution):].
-   */
-  TreeElements resolveClass(BaseClassElementX element) {
-    return _resolveTypeDeclaration(element, () {
-      // TODO(johnniwinther): Store the mapping in the resolution enqueuer.
-      ResolutionRegistry registry = new ResolutionRegistry(
-          resolution.target, _ensureTreeElements(element));
-      resolveClassInternal(element, registry);
-      return element.treeElements;
-    });
-  }
-
-  void ensureClassWillBeResolvedInternal(ClassElement element) {
-    if (!isResolvingTypeDeclaration) {
-      element.ensureResolved(resolution);
-    } else {
-      pendingClassesToBeResolved.add(element);
-    }
-  }
-
-  void resolveClassInternal(
-      BaseClassElementX element, ResolutionRegistry registry) {
-    if (!element.isPatch) {
-      reporter.withCurrentElement(
-          element,
-          () => measure(() {
-                assert(element.resolutionState == STATE_NOT_STARTED);
-                element.resolutionState = STATE_STARTED;
-                Node tree = element.parseNode(parsingContext);
-                loadSupertypes(element, tree);
-
-                ClassResolverVisitor visitor =
-                    new ClassResolverVisitor(resolution, element, registry);
-                visitor.visit(tree);
-                element.resolutionState = STATE_DONE;
-                pendingClassesToBePostProcessed.add(element);
-              }));
-      if (element.isPatched) {
-        // Ensure handling patch after origin.
-        element.patch.ensureResolved(resolution);
-      }
-    } else {
-      // Handle patch classes:
-      element.resolutionState = STATE_STARTED;
-      // Ensure handling origin before patch.
-      element.origin.ensureResolved(resolution);
-      // Ensure that the type is computed.
-      element.computeType(resolution);
-      // Copy class hierarchy from origin.
-      element.supertype = element.origin.supertype;
-      element.interfaces = element.origin.interfaces;
-      element.allSupertypesAndSelf = element.origin.allSupertypesAndSelf;
-      // Stepwise assignment to ensure invariant.
-      element.supertypeLoadState = STATE_STARTED;
-      element.supertypeLoadState = STATE_DONE;
-      element.resolutionState = STATE_DONE;
-      // TODO(johnniwinther): Check matching type variables and
-      // empty extends/implements clauses.
-    }
-  }
-
-  void _postProcessClassElement(BaseClassElementX element) {
-    for (MetadataAnnotation metadata in element.implementation.metadata) {
-      metadata.ensureResolved(resolution);
-      ConstantValue value =
-          resolution.constants.getConstantValue(metadata.constant);
-      if (!element.isProxy && resolution.isProxyConstant(value)) {
-        element.isProxy = true;
-      }
-    }
-
-    // Force resolution of metadata on non-instance members since they may be
-    // inspected by the backend while emitting. Metadata on instance members is
-    // handled as a result of processing instantiated class members in the
-    // enqueuer.
-    // TODO(ahe): Avoid this eager resolution.
-    element.forEachMember((_, Element member) {
-      if (!member.isInstanceMember) {
-        reporter.withCurrentElement(member, () {
-          for (MetadataAnnotation metadata in member.implementation.metadata) {
-            metadata.ensureResolved(resolution);
-          }
-        });
-      }
-    });
-
-    computeClassMember(element, Identifiers.call);
-  }
-
-  void computeClassMembers(ClassElement element) {
-    MembersCreator.computeAllClassMembers(resolution, element);
-  }
-
-  void computeClassMember(ClassElement element, String name) {
-    MembersCreator.computeClassMembersByName(resolution, element, name);
-  }
-
-  void checkClass(ClassElement element) {
-    computeClassMembers(element);
-    if (element.isMixinApplication) {
-      checkMixinApplication(element);
-    } else {
-      checkClassMembers(element);
-    }
-  }
-
-  void checkMixinApplication(MixinApplicationElementX mixinApplication) {
-    Modifiers modifiers = mixinApplication.modifiers;
-    int illegalFlags = modifiers.flags & ~Modifiers.FLAG_ABSTRACT;
-    if (illegalFlags != 0) {
-      Modifiers illegalModifiers = new Modifiers.withFlags(null, illegalFlags);
-      reporter.reportErrorMessage(
-          modifiers,
-          MessageKind.ILLEGAL_MIXIN_APPLICATION_MODIFIERS,
-          {'modifiers': illegalModifiers});
-    }
-
-    // In case of cyclic mixin applications, the mixin chain will have
-    // been cut. If so, we have already reported the error to the
-    // user so we just return from here.
-    ClassElement mixin = mixinApplication.mixin;
-    if (mixin == null) return;
-
-    // Check that we're not trying to use Object as a mixin.
-    if (mixin.superclass == null) {
-      reporter.reportErrorMessage(
-          mixinApplication, MessageKind.ILLEGAL_MIXIN_OBJECT);
-      // Avoid reporting additional errors for the Object class.
-      return;
-    }
-
-    if (mixin.isEnumClass) {
-      // Mixing in an enum has already caused a compile-time error.
-      return;
-    }
-
-    // Check that the mixed in class has Object as its superclass.
-    if (!mixin.superclass.isObject) {
-      reporter.reportErrorMessage(mixin, MessageKind.ILLEGAL_MIXIN_SUPERCLASS);
-    }
-
-    // Check that the mixed in class doesn't have any constructors and
-    // make sure we aren't mixing in methods that use 'super'.
-    mixin.forEachLocalMember((_member) {
-      AstElement member = _member;
-      if (member.isGenerativeConstructor && !member.isSynthesized) {
-        reporter.reportErrorMessage(
-            member, MessageKind.ILLEGAL_MIXIN_CONSTRUCTOR);
-      } else {
-        // Get the resolution tree and check that the resolved member
-        // doesn't use 'super'. This is the part of the 'super' mixin
-        // check that happens when a function is resolved before the
-        // mixin application has been performed.
-        // TODO(johnniwinther): Obtain the [TreeElements] for [member]
-        // differently.
-        if (_hasBeenProcessed(member)) {
-          if (member.resolvedAst.kind == ResolvedAstKind.PARSED) {
-            checkMixinSuperUses(
-                member.resolvedAst.elements, mixinApplication, mixin);
-          }
-        }
-      }
-    });
-  }
-
-  void checkMixinSuperUses(TreeElements elements,
-      MixinApplicationElement mixinApplication, ClassElement mixin) {
-    // TODO(johnniwinther): Avoid the use of [TreeElements] here.
-    Iterable<SourceSpan> superUses = elements.superUses;
-    if (superUses.isEmpty) return;
-    DiagnosticMessage error = reporter.createMessage(mixinApplication,
-        MessageKind.ILLEGAL_MIXIN_WITH_SUPER, {'className': mixin.name});
-    // Show the user the problematic uses of 'super' in the mixin.
-    List<DiagnosticMessage> infos = <DiagnosticMessage>[];
-    for (SourceSpan use in superUses) {
-      infos.add(
-          reporter.createMessage(use, MessageKind.ILLEGAL_MIXIN_SUPER_USE));
-    }
-    reporter.reportError(error, infos);
-  }
-
-  void checkClassMembers(ClassElement cls) {
-    assert(cls.isDeclaration, failedAt(cls));
-    if (cls.isObject) return;
-    // TODO(johnniwinther): Should this be done on the implementation element as
-    // well?
-    List<Element> constConstructors = <Element>[];
-    List<Element> nonFinalInstanceFields = <Element>[];
-    cls.forEachMember((holder, dynamic member) {
-      reporter.withCurrentElement(member, () {
-        // Perform various checks as side effect of "computing" the type.
-        member.computeType(resolution);
-
-        // Check modifiers.
-        // ignore: UNDEFINED_GETTER
-        if (member.isFunction && member.modifiers.isFinal) {
-          reporter.reportErrorMessage(
-              member, MessageKind.ILLEGAL_FINAL_METHOD_MODIFIER);
-        }
-        if (member.isConstructor) {
-          // ignore: UNDEFINED_GETTER
-          final mismatchedFlagsBits = member.modifiers.flags &
-              (Modifiers.FLAG_STATIC | Modifiers.FLAG_ABSTRACT);
-          if (mismatchedFlagsBits != 0) {
-            final mismatchedFlags =
-                new Modifiers.withFlags(null, mismatchedFlagsBits);
-            reporter.reportErrorMessage(
-                member,
-                MessageKind.ILLEGAL_CONSTRUCTOR_MODIFIERS,
-                {'modifiers': mismatchedFlags});
-          }
-          // ignore: UNDEFINED_GETTER
-          if (member.modifiers.isConst) {
-            constConstructors.add(member);
-          }
-        }
-        if (member.isField) {
-          // ignore: UNDEFINED_GETTER
-          if (member.modifiers.isConst && !member.modifiers.isStatic) {
-            reporter.reportErrorMessage(
-                member, MessageKind.ILLEGAL_CONST_FIELD_MODIFIER);
-          }
-          // ignore: UNDEFINED_GETTER
-          if (!member.modifiers.isStatic && !member.modifiers.isFinal) {
-            nonFinalInstanceFields.add(member);
-          }
-        }
-        checkAbstractField(member);
-        checkUserDefinableOperator(member);
-      });
-    });
-    if (!constConstructors.isEmpty && !nonFinalInstanceFields.isEmpty) {
-      Spannable span =
-          constConstructors.length > 1 ? cls : constConstructors[0];
-      DiagnosticMessage error = reporter.createMessage(
-          span,
-          MessageKind.CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS,
-          {'className': cls.name});
-      List<DiagnosticMessage> infos = <DiagnosticMessage>[];
-      if (constConstructors.length > 1) {
-        for (Element constructor in constConstructors) {
-          infos.add(reporter.createMessage(constructor,
-              MessageKind.CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS_CONSTRUCTOR));
-        }
-      }
-      for (Element field in nonFinalInstanceFields) {
-        infos.add(reporter.createMessage(
-            field, MessageKind.CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS_FIELD));
-      }
-      reporter.reportError(error, infos);
-    }
-  }
-
-  void checkAbstractField(Element member) {
-    // Only check for getters. The test can only fail if there is both a setter
-    // and a getter with the same name, and we only need to check each abstract
-    // field once, so we just ignore setters.
-    if (!member.isGetter) return;
-
-    // Find the associated abstract field.
-    ClassElement classElement = member.enclosingClass;
-    Element lookupElement = classElement.lookupLocalMember(member.name);
-    if (lookupElement == null) {
-      reporter.internalError(member, "No abstract field for accessor");
-    } else if (!lookupElement.isAbstractField) {
-      if (lookupElement.isMalformed || lookupElement.isAmbiguous) return;
-      reporter.internalError(
-          member, "Inaccessible abstract field for accessor");
-    }
-    AbstractFieldElement field = lookupElement;
-
-    GetterElementX getter = field.getter;
-    if (getter == null) return;
-    SetterElementX setter = field.setter;
-    if (setter == null) return;
-    int getterFlags = getter.modifiers.flags | Modifiers.FLAG_ABSTRACT;
-    int setterFlags = setter.modifiers.flags | Modifiers.FLAG_ABSTRACT;
-    if (getterFlags != setterFlags) {
-      final mismatchedFlags =
-          new Modifiers.withFlags(null, getterFlags ^ setterFlags);
-      reporter.reportWarningMessage(field.getter, MessageKind.GETTER_MISMATCH,
-          {'modifiers': mismatchedFlags});
-      reporter.reportWarningMessage(field.setter, MessageKind.SETTER_MISMATCH,
-          {'modifiers': mismatchedFlags});
-    }
-  }
-
-  void checkUserDefinableOperator(Element member) {
-    FunctionElement function = member.asFunctionElement();
-    if (function == null) return;
-    String value = member.name;
-    if (value == null) return;
-    if (!(isUserDefinableOperator(value) || identical(value, 'unary-'))) return;
-
-    bool isMinus = false;
-    int requiredParameterCount;
-    MessageKind messageKind;
-    if (identical(value, 'unary-')) {
-      isMinus = true;
-      messageKind = MessageKind.MINUS_OPERATOR_BAD_ARITY;
-      requiredParameterCount = 0;
-    } else if (isMinusOperator(value)) {
-      isMinus = true;
-      messageKind = MessageKind.MINUS_OPERATOR_BAD_ARITY;
-      requiredParameterCount = 1;
-    } else if (isUnaryOperator(value)) {
-      messageKind = MessageKind.UNARY_OPERATOR_BAD_ARITY;
-      requiredParameterCount = 0;
-    } else if (isBinaryOperator(value)) {
-      messageKind = MessageKind.BINARY_OPERATOR_BAD_ARITY;
-      requiredParameterCount = 1;
-      if (identical(value, '==')) checkOverrideHashCode(member);
-    } else if (isTernaryOperator(value)) {
-      messageKind = MessageKind.TERNARY_OPERATOR_BAD_ARITY;
-      requiredParameterCount = 2;
-    } else {
-      reporter.internalError(
-          function, 'Unexpected user defined operator $value');
-    }
-    checkArity(function, requiredParameterCount, messageKind, isMinus);
-  }
-
-  void checkOverrideHashCode(FunctionElement operatorEquals) {
-    if (operatorEquals.isAbstract) return;
-    ClassElement cls = operatorEquals.enclosingClass;
-    Element hashCodeImplementation = cls.lookupLocalMember('hashCode');
-    if (hashCodeImplementation != null) return;
-    reporter.reportHintMessage(operatorEquals,
-        MessageKind.OVERRIDE_EQUALS_NOT_HASH_CODE, {'class': cls.name});
-  }
-
-  void checkArity(FunctionElement function, int requiredParameterCount,
-      MessageKind messageKind, bool isMinus) {
-    FunctionExpression node = function.node;
-    FunctionSignature signature = function.functionSignature;
-    if (signature.requiredParameterCount != requiredParameterCount) {
-      Node errorNode = node;
-      if (node.parameters != null) {
-        if (isMinus ||
-            signature.requiredParameterCount < requiredParameterCount) {
-          // If there are too few parameters, point to the whole parameter list.
-          // For instance
-          //
-          //     int operator +() {}
-          //                   ^^
-          //
-          //     int operator []=(value) {}
-          //                     ^^^^^^^
-          //
-          // For operator -, always point the whole parameter list, like
-          //
-          //     int operator -(a, b) {}
-          //                   ^^^^^^
-          //
-          // instead of
-          //
-          //     int operator -(a, b) {}
-          //                       ^
-          //
-          // since the correction might not be to remove 'b' but instead to
-          // remove 'a, b'.
-          errorNode = node.parameters;
-        } else {
-          errorNode = node.parameters.nodes.skip(requiredParameterCount).head;
-        }
-      }
-      reporter.reportErrorMessage(
-          errorNode, messageKind, {'operatorName': function.name});
-    }
-    if (signature.optionalParameterCount != 0) {
-      Node errorNode =
-          node.parameters.nodes.skip(signature.requiredParameterCount).head;
-      if (signature.optionalParametersAreNamed) {
-        reporter.reportErrorMessage(
-            errorNode,
-            MessageKind.OPERATOR_NAMED_PARAMETERS,
-            {'operatorName': function.name});
-      } else {
-        reporter.reportErrorMessage(
-            errorNode,
-            MessageKind.OPERATOR_OPTIONAL_PARAMETERS,
-            {'operatorName': function.name});
-      }
-    }
-  }
-
-  reportErrorWithContext(Element errorneousElement, MessageKind errorMessage,
-      Element contextElement, MessageKind contextMessage) {
-    reporter.reportError(
-        reporter.createMessage(errorneousElement, errorMessage, {
-          'memberName': contextElement.name,
-          'className': contextElement.enclosingClass.name
-        }),
-        <DiagnosticMessage>[
-          reporter.createMessage(contextElement, contextMessage),
-        ]);
-  }
-
-  FunctionSignature resolveSignature(FunctionElementX element) {
-    MessageKind defaultValuesError = null;
-    if (element.isFactoryConstructor) {
-      FunctionExpression body = element.parseNode(parsingContext);
-      if (body.isRedirectingFactory) {
-        defaultValuesError = MessageKind.REDIRECTING_FACTORY_WITH_DEFAULT;
-      }
-    }
-    return reporter.withCurrentElement(element, () {
-      FunctionExpression node = element.parseNode(parsingContext);
-      return measure(() => SignatureResolver.analyze(
-          resolution,
-          element.enclosingElement.buildScope(),
-          const FunctionTypeParameterScope(),
-          node.typeVariables,
-          node.parameters,
-          node.returnType,
-          element,
-          new ResolutionRegistry(
-              resolution.target, _ensureTreeElements(element)),
-          defaultValuesError: defaultValuesError,
-          createRealParameters: true));
-    });
-  }
-
-  WorldImpact resolveTypedef(TypedefElementX element) {
-    if (element.isResolved) return const ResolutionImpact();
-    world.registerTypedef(element);
-    return _resolveTypeDeclaration(element, () {
-      ResolutionRegistry registry = new ResolutionRegistry(
-          resolution.target, _ensureTreeElements(element));
-      return reporter.withCurrentElement(element, () {
-        return measure(() {
-          assert(element.resolutionState == STATE_NOT_STARTED);
-          element.resolutionState = STATE_STARTED;
-          Typedef node = element.parseNode(parsingContext);
-          TypedefResolverVisitor visitor =
-              new TypedefResolverVisitor(resolution, element, registry);
-          visitor.visit(node);
-          element.resolutionState = STATE_DONE;
-          return registry.impactBuilder;
-        });
-      });
-    });
-  }
-
-  void resolveMetadataAnnotation(MetadataAnnotationX annotation) {
-    reporter.withCurrentElement(
-        annotation.annotatedElement,
-        () => measure(() {
-              assert(annotation.resolutionState == STATE_NOT_STARTED);
-              annotation.resolutionState = STATE_STARTED;
-
-              Node node = annotation.parseNode(parsingContext);
-              Element annotatedElement = annotation.annotatedElement;
-              AnalyzableElement context = annotatedElement.analyzableElement;
-              ClassElement classElement = annotatedElement.enclosingClass;
-              if (classElement != null) {
-                // The annotation is resolved in the scope of [classElement].
-                classElement.ensureResolved(resolution);
-              }
-              assert(
-                  context != null,
-                  failedAt(
-                      node,
-                      "No context found for metadata annotation "
-                      "on $annotatedElement."));
-              ResolverVisitor visitor =
-                  visitorFor(context, useEnclosingScope: true);
-              ResolutionRegistry registry = visitor.registry;
-              node.accept(visitor);
-              // TODO(johnniwinther): Avoid passing the [TreeElements] to
-              // [compileMetadata].
-              ConstantExpression constant = constantCompiler.compileMetadata(
-                  annotation, node, registry.mapping);
-              switch (constant.kind) {
-                case ConstantExpressionKind.CONSTRUCTED:
-                  ConstructedConstantExpression constructedConstant = constant;
-                  ResolutionInterfaceType type = constructedConstant.type;
-                  if (type.isGeneric && !type.isRaw) {
-                    // Const constructor calls cannot have type arguments.
-                    // TODO(24312): Remove this.
-                    reporter.reportErrorMessage(
-                        node, MessageKind.INVALID_METADATA_GENERIC);
-                    constant = new ErroneousConstantExpression();
-                  }
-                  break;
-                case ConstantExpressionKind.FIELD:
-                case ConstantExpressionKind.ERRONEOUS:
-                  break;
-                default:
-                  reporter.reportErrorMessage(
-                      node, MessageKind.INVALID_METADATA);
-                  constant = new ErroneousConstantExpression();
-                  break;
-              }
-              annotation.constant = constant;
-
-              constantCompiler.evaluate(annotation.constant);
-              // TODO(johnniwinther): Register the relation between the
-              // annotation and the annotated element instead. This will allow
-              // the backend to retrieve the backend constant and only register
-              // metadata on the elements for which it is needed. (Issue 17732).
-              annotation.resolutionState = STATE_DONE;
-            }));
-  }
-
-  List<MetadataAnnotation> resolveMetadata(
-      Element element, VariableDefinitions node) {
-    List<MetadataAnnotation> metadata = <MetadataAnnotation>[];
-    for (Metadata annotation in node.metadata.nodes) {
-      ParameterMetadataAnnotation metadataAnnotation =
-          new ParameterMetadataAnnotation(annotation);
-      metadataAnnotation.annotatedElement = element;
-      metadata.add(metadataAnnotation.ensureResolved(resolution));
-    }
-    return metadata;
-  }
-}
-
-TreeElements _ensureTreeElements(AnalyzableElementX element) {
-  if (element._treeElements == null) {
-    element._treeElements = new TreeElementMapping(element);
-  }
-  return element._treeElements;
-}
-
-abstract class AnalyzableElementX implements AnalyzableElement {
-  TreeElements _treeElements;
-
-  bool get hasTreeElements => _treeElements != null;
-
-  TreeElements get treeElements {
-    assert(_treeElements != null,
-        failedAt(this, "TreeElements have not been computed for $this."));
-    return _treeElements;
-  }
-
-  void reuseElement() {
-    _treeElements = null;
-  }
-}
diff --git a/pkg/compiler/lib/src/resolution/resolution_common.dart b/pkg/compiler/lib/src/resolution/resolution_common.dart
deleted file mode 100644
index 4428cd3..0000000
--- a/pkg/compiler/lib/src/resolution/resolution_common.dart
+++ /dev/null
@@ -1,103 +0,0 @@
-// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library dart2js.resolution.common;
-
-import '../common.dart';
-import '../common/resolution.dart' show Resolution;
-import '../elements/elements.dart';
-import '../elements/entities.dart' show AsyncMarker;
-import '../enqueue.dart' show DeferredAction;
-import '../tree/tree.dart';
-import 'registry.dart' show ResolutionRegistry;
-import 'scope.dart' show Scope;
-import 'type_resolver.dart' show TypeResolver;
-
-class CommonResolverVisitor<R> extends Visitor<R> {
-  final Resolution resolution;
-
-  CommonResolverVisitor(this.resolution);
-
-  DiagnosticReporter get reporter => resolution.reporter;
-
-  R visitNode(Node node) {
-    return reporter.internalError(
-        node, 'internal error: Unhandled node: ${node.getObjectDescription()}');
-  }
-
-  R visitEmptyStatement(EmptyStatement node) => null;
-
-  /** Convenience method for visiting nodes that may be null. */
-  R visit(Node node) => (node == null) ? null : node.accept(this);
-
-  void addDeferredAction(Element element, void action()) {
-    resolution.enqueuer.addDeferredAction(new DeferredAction(element, action));
-  }
-}
-
-/**
- * Common supertype for resolver visitors that record resolutions in a
- * [ResolutionRegistry].
- */
-abstract class MappingVisitor<T> extends CommonResolverVisitor<T> {
-  final ResolutionRegistry registry;
-  final TypeResolver typeResolver;
-
-  /// The current enclosing element for the visited AST nodes.
-  Element get enclosingElement;
-
-  /// The current scope of the visitor.
-  Scope get scope;
-
-  MappingVisitor(Resolution resolution, this.registry)
-      : typeResolver = new TypeResolver(resolution),
-        super(resolution);
-
-  AsyncMarker get currentAsyncMarker => AsyncMarker.SYNC;
-
-  /// Add [element] to the current scope and check for duplicate definitions.
-  void addToScope(Element element) {
-    if (element is FormalElement && element.isUnnamed) {
-      // No duplicate names possible.
-      return;
-    }
-    Element existing = scope.add(element);
-    if (existing != element) {
-      reportDuplicateDefinition(element.name, element, existing);
-    }
-  }
-
-  void checkLocalDefinitionName(Node node, Element element) {
-    if (currentAsyncMarker != AsyncMarker.SYNC) {
-      if (element.name == 'yield' ||
-          element.name == 'async' ||
-          element.name == 'await') {
-        reporter.reportErrorMessage(
-            node,
-            MessageKind.ASYNC_KEYWORD_AS_IDENTIFIER,
-            {'keyword': element.name, 'modifier': currentAsyncMarker});
-      }
-    }
-  }
-
-  /// Register [node] as the definition of [element].
-  void defineLocalVariable(Node node, LocalVariableElement element) {
-    if (element == null) {
-      throw reporter.internalError(node, 'element is null');
-    }
-    checkLocalDefinitionName(node, element);
-    registry.defineElement(node, element);
-  }
-
-  void reportDuplicateDefinition(
-      String name, Spannable definition, Spannable existing) {
-    reporter.reportError(
-        reporter.createMessage(
-            definition, MessageKind.DUPLICATE_DEFINITION, {'name': name}),
-        <DiagnosticMessage>[
-          reporter.createMessage(
-              existing, MessageKind.EXISTING_DEFINITION, {'name': name}),
-        ]);
-  }
-}
diff --git a/pkg/compiler/lib/src/resolution/resolution_result.dart b/pkg/compiler/lib/src/resolution/resolution_result.dart
deleted file mode 100644
index fd7576f..0000000
--- a/pkg/compiler/lib/src/resolution/resolution_result.dart
+++ /dev/null
@@ -1,135 +0,0 @@
-// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library dart2js.resolution.result;
-
-import '../constants/expressions.dart';
-import '../elements/resolution_types.dart';
-import '../elements/elements.dart';
-import '../tree/tree.dart';
-import '../universe/call_structure.dart' show CallStructure;
-
-enum ResultKind {
-  NONE,
-  ELEMENT,
-  TYPE,
-  ASSERT,
-  CONSTANT,
-  PREFIX,
-}
-
-/// The result of resolving a node.
-abstract class ResolutionResult {
-  const ResolutionResult();
-
-  // TODO(johnniwinther): Remove this factory constructor when `null` is never
-  // passed as an element result.
-  factory ResolutionResult.forElement(Element element) {
-    return element != null ? new ElementResult(element) : const NoneResult();
-  }
-
-  ResultKind get kind;
-  Node get node => null;
-  Element get element => null;
-  ResolutionDartType get type => null;
-  ConstantExpression get constant => null;
-  bool get isConstant => false;
-}
-
-/// The prefix of top level or member access, like `prefix.member`,
-/// `prefix.Class.member` or `Class.member`.
-class PrefixResult extends ResolutionResult {
-  final PrefixElement prefix;
-  final ClassElement cls;
-
-  PrefixResult(this.prefix, this.cls);
-
-  Element get element => cls != null ? cls : prefix;
-
-  bool get isDeferred => prefix != null && prefix.isDeferred;
-
-  ResultKind get kind => ResultKind.PREFIX;
-
-  String toString() => 'PrefixResult($prefix,$cls)';
-}
-
-/// The result for the resolution of a node that points to an [Element].
-class ElementResult extends ResolutionResult {
-  final Element element;
-
-  ResultKind get kind => ResultKind.ELEMENT;
-
-  ElementResult(this.element) {
-    assert(element != null);
-  }
-
-  String toString() => 'ElementResult($element)';
-}
-
-/// The result for the resolution of a node that points to an
-/// [ResolutionDartType].
-class TypeResult extends ResolutionResult {
-  final ResolutionDartType type;
-
-  TypeResult(this.type) {
-    assert(type != null);
-  }
-
-  ResultKind get kind => ResultKind.TYPE;
-
-  Element get element => type.element;
-
-  String toString() => 'TypeResult($type)';
-}
-
-/// The result for resolving a constant expression.
-class ConstantResult extends ResolutionResult {
-  final Node node;
-  final ConstantExpression constant;
-  final Element element;
-
-  /// Creates a result for the [constant] expression. [node] is provided for
-  /// error reporting on the constant and [element] is provided if the
-  /// expression additionally serves an [Element] like [ElementResult].
-  ConstantResult(this.node, this.constant, {this.element});
-
-  bool get isConstant => true;
-
-  ResultKind get kind => ResultKind.CONSTANT;
-
-  String toString() => 'ConstantResult(${constant.toDartText()})';
-}
-
-class NoneResult extends ResolutionResult {
-  const NoneResult();
-
-  ResultKind get kind => ResultKind.NONE;
-
-  String toString() => 'NoneResult()';
-}
-
-/// The result of resolving a list of arguments.
-class ArgumentsResult {
-  /// The call structure of the arguments.
-  final CallStructure callStructure;
-
-  /// The resolutions results for each argument.
-  final List<ResolutionResult> argumentResults;
-
-  /// `true` if the arguments are valid as arguments to a constructed constant
-  /// expression.
-  final bool isValidAsConstant;
-
-  ArgumentsResult(this.callStructure, this.argumentResults,
-      {this.isValidAsConstant});
-
-  /// Returns the list of [ConstantExpression]s for each of the arguments. If
-  /// [isValidAsConstant] is `false`, `null` is returned.
-  List<ConstantExpression> get constantArguments {
-    if (!isValidAsConstant) return null;
-    return argumentResults.map((ResolutionResult result) {
-      return result.constant;
-    }).toList();
-  }
-}
diff --git a/pkg/compiler/lib/src/resolution/resolution_strategy.dart b/pkg/compiler/lib/src/resolution/resolution_strategy.dart
deleted file mode 100644
index 0b51c6f..0000000
--- a/pkg/compiler/lib/src/resolution/resolution_strategy.dart
+++ /dev/null
@@ -1,1069 +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 dart2js.resolution_strategy;
-
-import 'package:front_end/src/fasta/scanner.dart' show Token;
-
-import '../../compiler_new.dart' as api;
-import '../common.dart';
-import '../common/backend_api.dart';
-import '../common/names.dart';
-import '../common/resolution.dart';
-import '../common/tasks.dart';
-import '../common/work.dart';
-import '../common_elements.dart';
-import '../compiler.dart';
-import '../constants/expressions.dart' show ConstantExpression;
-import '../constants/values.dart';
-import '../deferred_load.dart' show DeferredLoadTask;
-import '../elements/elements.dart';
-import '../elements/entities.dart';
-import '../elements/modelx.dart';
-import '../elements/resolution_types.dart';
-import '../elements/types.dart';
-import '../enqueue.dart';
-import '../environment.dart';
-import '../frontend_strategy.dart';
-import '../js_backend/backend.dart';
-import '../js_backend/backend_usage.dart';
-import '../js_backend/interceptor_data.dart';
-import '../js_backend/mirrors_analysis.dart';
-import '../js_backend/mirrors_data.dart';
-import '../js_backend/native_data.dart';
-import '../js_backend/no_such_method_registry.dart';
-import '../js_backend/runtime_types.dart';
-import '../library_loader.dart';
-import '../native/enqueue.dart' show NativeResolutionEnqueuer;
-import '../native/resolver.dart';
-import '../patch_parser.dart';
-import '../resolved_uri_translator.dart';
-import '../tree/tree.dart' show Node;
-import '../universe/call_structure.dart';
-import '../universe/class_hierarchy_builder.dart';
-import '../universe/use.dart';
-import '../universe/world_builder.dart';
-import '../universe/world_impact.dart';
-
-import 'deferred_load.dart';
-import 'no_such_method_resolver.dart';
-
-/// [FrontendStrategy] that loads '.dart' files and creates a resolved element
-/// model using the resolver.
-class ResolutionFrontEndStrategy extends FrontendStrategyBase
-    with ComputeSpannableMixin {
-  final Compiler _compiler;
-  final _CompilerElementEnvironment _elementEnvironment;
-  final CommonElements commonElements;
-  RuntimeTypesNeedBuilder _runtimeTypesNeedBuilder;
-
-  AnnotationProcessor _annotationProcessor;
-
-  factory ResolutionFrontEndStrategy(Compiler compiler) {
-    ElementEnvironment elementEnvironment =
-        new _CompilerElementEnvironment(compiler);
-    CommonElements commonElements = new CommonElements(elementEnvironment);
-    return new ResolutionFrontEndStrategy.internal(
-        compiler, elementEnvironment, commonElements);
-  }
-
-  ResolutionFrontEndStrategy.internal(
-      this._compiler, this._elementEnvironment, this.commonElements);
-
-  ElementEnvironment get elementEnvironment => _elementEnvironment;
-
-  DartTypes get dartTypes => _compiler.resolution.types;
-
-  LibraryLoaderTask createLibraryLoader(
-      ResolvedUriTranslator uriTranslator,
-      ScriptLoader scriptLoader,
-      api.CompilerInput compilerInput,
-      ElementScanner scriptScanner,
-      PatchResolverFunction patchResolverFunc,
-      PatchParserTask patchParser,
-      Environment environment,
-      DiagnosticReporter reporter,
-      Measurer measurer) {
-    return new ResolutionLibraryLoaderTask(
-        uriTranslator,
-        scriptLoader,
-        scriptScanner,
-        patchResolverFunc,
-        patchParser,
-        environment,
-        reporter,
-        measurer);
-  }
-
-  AnnotationProcessor get annotationProcesser => _annotationProcessor ??=
-      new _ElementAnnotationProcessor(_compiler, nativeBasicDataBuilder);
-
-  DeferredLoadTask createDeferredLoadTask(Compiler compiler) =>
-      new AstDeferredLoadTask(_compiler);
-
-  @override
-  NativeClassFinder createNativeClassFinder(NativeBasicData nativeBasicData) {
-    return new ResolutionNativeClassFinder(
-        _compiler.resolution,
-        _compiler.reporter,
-        elementEnvironment,
-        commonElements,
-        nativeBasicData);
-  }
-
-  NoSuchMethodResolver createNoSuchMethodResolver() =>
-      new ResolutionNoSuchMethodResolver();
-
-  MirrorsDataBuilder createMirrorsDataBuilder() {
-    return new ResolutionMirrorsData(
-        _compiler, elementEnvironment, commonElements);
-  }
-
-  MirrorsResolutionAnalysis createMirrorsResolutionAnalysis(
-          JavaScriptBackend backend) =>
-      new MirrorsResolutionAnalysisImpl(backend, _compiler.resolution);
-
-  RuntimeTypesNeedBuilder createRuntimeTypesNeedBuilder() {
-    return _runtimeTypesNeedBuilder ??= _compiler.options.disableRtiOptimization
-        ? const TrivialRuntimeTypesNeedBuilder()
-        : new ResolutionRuntimeTypesNeedBuilderImpl(
-            elementEnvironment, dartTypes);
-  }
-
-  RuntimeTypesNeedBuilder get runtimeTypesNeedBuilderForTesting =>
-      _runtimeTypesNeedBuilder;
-
-  ResolutionWorldBuilder createResolutionWorldBuilder(
-      NativeBasicData nativeBasicData,
-      NativeDataBuilder nativeDataBuilder,
-      InterceptorDataBuilder interceptorDataBuilder,
-      BackendUsageBuilder backendUsageBuilder,
-      RuntimeTypesNeedBuilder rtiNeedBuilder,
-      NativeResolutionEnqueuer nativeResolutionEnqueuer,
-      NoSuchMethodRegistry noSuchMethodRegistry,
-      SelectorConstraintsStrategy selectorConstraintsStrategy,
-      ClassHierarchyBuilder classHierarchyBuilder,
-      ClassQueries classQueries) {
-    return new ElementResolutionWorldBuilder(
-        _compiler.backend,
-        _compiler.resolution,
-        nativeBasicData,
-        nativeDataBuilder,
-        interceptorDataBuilder,
-        backendUsageBuilder,
-        rtiNeedBuilder,
-        nativeResolutionEnqueuer,
-        noSuchMethodRegistry,
-        selectorConstraintsStrategy,
-        classHierarchyBuilder,
-        classQueries);
-  }
-
-  WorkItemBuilder createResolutionWorkItemBuilder(
-      NativeBasicData nativeBasicData,
-      NativeDataBuilder nativeDataBuilder,
-      ImpactTransformer impactTransformer,
-      Map<Entity, WorldImpact> impactCache) {
-    return new ResolutionWorkItemBuilder(_compiler.resolution);
-  }
-
-  ClassQueries createClassQueries() {
-    return new ElementClassQueries(commonElements);
-  }
-
-  FunctionEntity computeMain(
-      covariant LibraryElement mainApp, WorldImpactBuilder impactBuilder) {
-    _elementEnvironment._mainLibrary = mainApp;
-    if (mainApp == null) return null;
-    MethodElement mainFunction;
-    Element main = mainApp.findExported(Identifiers.main);
-    ErroneousElement errorElement = null;
-    if (main == null) {
-      if (_compiler.options.analyzeOnly) {
-        if (!_compiler.analyzeAll) {
-          errorElement = new ErroneousElementX(MessageKind.CONSIDER_ANALYZE_ALL,
-              {'main': Identifiers.main}, Identifiers.main, mainApp);
-        }
-      } else {
-        // Compilation requires a main method.
-        errorElement = new ErroneousElementX(MessageKind.MISSING_MAIN,
-            {'main': Identifiers.main}, Identifiers.main, mainApp);
-      }
-      mainFunction = commonElements.missingMain;
-    } else if (main.isError && main.isSynthesized) {
-      if (main is ErroneousElement) {
-        errorElement = main;
-      } else {
-        _compiler.reporter
-            .internalError(main, 'Problem with ${Identifiers.main}.');
-      }
-      mainFunction = commonElements.badMain;
-    } else if (!main.isFunction) {
-      errorElement = new ErroneousElementX(MessageKind.MAIN_NOT_A_FUNCTION,
-          {'main': Identifiers.main}, Identifiers.main, main);
-      mainFunction = commonElements.badMain;
-    } else {
-      mainFunction = main;
-      mainFunction.computeType(_compiler.resolution);
-      FunctionSignature parameters = mainFunction.functionSignature;
-      if (parameters.requiredParameterCount > 2) {
-        int index = 0;
-        parameters.orderedForEachParameter((Element parameter) {
-          if (index++ < 2) return;
-          errorElement = new ErroneousElementX(
-              MessageKind.MAIN_WITH_EXTRA_PARAMETER,
-              {'main': Identifiers.main},
-              Identifiers.main,
-              parameter);
-          // Don't warn about main not being used:
-          impactBuilder.registerStaticUse(
-              new StaticUse.staticInvoke(mainFunction, CallStructure.NO_ARGS));
-
-          mainFunction = commonElements.mainHasTooManyParameters;
-        });
-      }
-    }
-    if (mainFunction == null) {
-      if (errorElement == null &&
-          !_compiler.options.analyzeOnly &&
-          !_compiler.analyzeAll) {
-        _compiler.reporter
-            .internalError(mainApp, "Problem with '${Identifiers.main}'.");
-      } else {
-        mainFunction = errorElement;
-      }
-    }
-    if (errorElement != null &&
-        errorElement.isSynthesized &&
-        !mainApp.isSynthesized) {
-      _compiler.reporter.reportWarningMessage(errorElement,
-          errorElement.messageKind, errorElement.messageArguments);
-    }
-    MethodElement mainMethod;
-    if (mainFunction != null && !mainFunction.isMalformed) {
-      mainFunction.computeType(_compiler.resolution);
-      mainMethod = mainFunction;
-    }
-    _elementEnvironment._mainFunction = mainMethod;
-    return mainMethod;
-  }
-}
-
-class ComputeSpannableMixin {
-  SourceSpan spanFromToken(Element currentElement, Token token) =>
-      _spanFromTokens(currentElement, token, token);
-
-  SourceSpan _spanFromTokens(Element currentElement, Token begin, Token end,
-      [Uri uri]) {
-    if (begin == null || end == null) {
-      // TODO(ahe): We can almost always do better. Often it is only
-      // end that is null. Otherwise, we probably know the current
-      // URI.
-      throw 'Cannot find tokens to produce error message.';
-    }
-    if (uri == null && currentElement != null) {
-      if (currentElement is! Element) {
-        throw 'Can only find tokens from an Element.';
-      }
-      Element element = currentElement;
-      uri = element.compilationUnit.script.resourceUri;
-      String message;
-      assert(() {
-        bool sameToken(Token token, Token sought) {
-          if (token == sought) return true;
-          if (token.stringValue == '[') {
-            // `[` is converted to `[]` in the parser when needed.
-            return sought.stringValue == '[]' &&
-                token.charOffset <= sought.charOffset &&
-                sought.charOffset < token.charEnd;
-          }
-          if (token.stringValue == '>>') {
-            // `>>` is converted to `>` in the parser when needed.
-            return sought.stringValue == '>' &&
-                token.charOffset <= sought.charOffset &&
-                sought.charOffset < token.charEnd;
-          }
-          return false;
-        }
-
-        /// Check that [begin] and [end] can be found between [from] and [to].
-        validateToken(Token from, Token to) {
-          if (from == null || to == null) return true;
-          bool foundBegin = false;
-          bool foundEnd = false;
-          Token token = from;
-          while (true) {
-            if (sameToken(token, begin)) {
-              foundBegin = true;
-            }
-            if (sameToken(token, end)) {
-              foundEnd = true;
-            }
-            if (foundBegin && foundEnd) {
-              return true;
-            }
-            if (token == to || token == token.next || token.next == null) {
-              break;
-            }
-            token = token.next;
-          }
-
-          // Create a good message for when the tokens were not found.
-          StringBuffer sb = new StringBuffer();
-          sb.write('Invalid current element: $element. ');
-          sb.write('Looking for ');
-          sb.write('[${begin} (${begin.hashCode}),');
-          sb.write('${end} (${end.hashCode})] in');
-
-          token = from;
-          while (true) {
-            sb.write('\n ${token} (${token.hashCode})');
-            if (token == to || token == token.next || token.next == null) {
-              break;
-            }
-            token = token.next;
-          }
-          message = sb.toString();
-          return false;
-        }
-
-        if (element.enclosingClass != null &&
-            element.enclosingClass.isEnumClass) {
-          // Enums ASTs are synthesized (and give messed up messages).
-          return true;
-        }
-
-        if (element is AstElement) {
-          AstElement astElement = element;
-          if (astElement.hasNode) {
-            Token from = astElement.node.getBeginToken();
-            Token to = astElement.node.getEndToken();
-            if (astElement.metadata.isNotEmpty) {
-              if (!astElement.metadata.first.hasNode) {
-                // We might try to report an error while parsing the metadata
-                // itself.
-                return true;
-              }
-              from = astElement.metadata.first.node.getBeginToken();
-            }
-            return validateToken(from, to);
-          }
-        }
-        return true;
-      }(), failedAt(currentElement, message));
-    }
-    return new SourceSpan.fromTokens(uri, begin, end);
-  }
-
-  SourceSpan _spanFromNode(Element currentElement, Node node) {
-    return _spanFromTokens(
-        currentElement, node.getBeginToken(), node.getPrefixEndToken());
-  }
-
-  SourceSpan _spanFromElement(Element currentElement, Element element) {
-    if (element != null && element.sourcePosition != null) {
-      return element.sourcePosition;
-    }
-    while (element != null && element.isSynthesized) {
-      element = element.enclosingElement;
-    }
-    if (element != null &&
-        element.sourcePosition == null &&
-        !element.isLibrary &&
-        !element.isCompilationUnit) {
-      // Sometimes, the backend fakes up elements that have no
-      // position. So we use the enclosing element instead. It is
-      // not a good error location, but cancel really is "internal
-      // error" or "not implemented yet", so the vicinity is good
-      // enough for now.
-      element = element.enclosingElement;
-      // TODO(ahe): I plan to overhaul this infrastructure anyways.
-    }
-    if (element == null) {
-      element = currentElement;
-    }
-    if (element == null) {
-      return null;
-    }
-
-    if (element.sourcePosition != null) {
-      return element.sourcePosition;
-    }
-    Token position = element.position;
-    Uri uri = element.compilationUnit.script.resourceUri;
-    return (position == null)
-        ? new SourceSpan(uri, 0, 0)
-        : _spanFromTokens(currentElement, position, position, uri);
-  }
-
-  SourceSpan spanFromSpannable(Spannable spannable, Entity currentElement) {
-    if (spannable is Node) {
-      return _spanFromNode(currentElement, spannable);
-    } else if (spannable is Element) {
-      return _spanFromElement(currentElement, spannable);
-    } else if (spannable is MetadataAnnotation) {
-      return spannable.sourcePosition;
-    } else if (spannable is LocalVariable) {
-      return spanFromSpannable(spannable.executableContext, currentElement);
-    }
-    return null;
-  }
-}
-
-/// An element environment base on a [Compiler].
-class _CompilerElementEnvironment extends ElementEnvironment {
-  final Compiler _compiler;
-
-  LibraryEntity _mainLibrary;
-  FunctionEntity _mainFunction;
-
-  _CompilerElementEnvironment(this._compiler);
-
-  LibraryProvider get _libraryProvider => _compiler.libraryLoader;
-  Resolution get _resolution => _compiler.resolution;
-
-  ResolutionDynamicType get dynamicType => const ResolutionDynamicType();
-
-  @override
-  LibraryEntity get mainLibrary => _mainLibrary;
-
-  @override
-  FunctionEntity get mainFunction => _mainFunction;
-
-  @override
-  Iterable<LibraryEntity> get libraries => _compiler.libraryLoader.libraries;
-
-  @override
-  String getLibraryName(covariant LibraryElement library) =>
-      library.libraryName;
-
-  @override
-  ResolutionInterfaceType getThisType(covariant ClassElement cls) {
-    cls.ensureResolved(_resolution);
-    return cls.thisType;
-  }
-
-  @override
-  ResolutionInterfaceType getRawType(covariant ClassElement cls) {
-    cls.ensureResolved(_resolution);
-    return cls.rawType;
-  }
-
-  @override
-  bool isGenericClass(ClassEntity cls) {
-    return getThisType(cls).typeArguments.isNotEmpty;
-  }
-
-  @override
-  bool isMixinApplication(covariant ClassElement cls) {
-    return cls.isMixinApplication;
-  }
-
-  @override
-  bool isUnnamedMixinApplication(covariant ClassElement cls) {
-    return cls.isUnnamedMixinApplication;
-  }
-
-  @override
-  ClassEntity getEffectiveMixinClass(covariant ClassElement cls) {
-    if (!cls.isMixinApplication) return null;
-    do {
-      MixinApplicationElement mixinApplication = cls;
-      cls = mixinApplication.mixin;
-    } while (cls.isMixinApplication);
-    return cls;
-  }
-
-  @override
-  ResolutionDartType getTypeVariableBound(
-      covariant TypeVariableElement typeVariable) {
-    return typeVariable.bound;
-  }
-
-  @override
-  ResolutionInterfaceType createInterfaceType(covariant ClassElement cls,
-      covariant List<ResolutionDartType> typeArguments) {
-    cls.ensureResolved(_resolution);
-    return cls.thisType.createInstantiation(typeArguments);
-  }
-
-  @override
-  MemberElement lookupLocalClassMember(covariant ClassElement cls, String name,
-      {bool setter: false, bool required: false}) {
-    cls.ensureResolved(_resolution);
-    Element member = cls.implementation.lookupLocalMember(name);
-    if (member != null && member.isAbstractField) {
-      AbstractFieldElement abstractField = member;
-      if (setter) {
-        member = abstractField.setter;
-      } else {
-        member = abstractField.getter;
-      }
-      if (member == null && required) {
-        failedAt(
-            cls,
-            "The class '${cls.name}' does not contain required "
-            "${setter ? 'setter' : 'getter'}: '$name'.");
-      }
-    }
-    if (member == null && required) {
-      throw new SpannableAssertionFailure(
-          cls,
-          "The class '${cls.name}' does not "
-          "contain required member: '$name'.");
-    }
-    return member?.declaration;
-  }
-
-  @override
-  ConstructorElement lookupConstructor(covariant ClassElement cls, String name,
-      {bool required: false}) {
-    cls.ensureResolved(_resolution);
-    ConstructorElement constructor = cls.implementation.lookupConstructor(name);
-    // TODO(johnniwinther): Skip redirecting factories.
-    if (constructor == null && required) {
-      throw new SpannableAssertionFailure(
-          cls,
-          "The class '${cls.name}' does not contain "
-          "required constructor: '$name'.");
-    }
-    return constructor?.declaration;
-  }
-
-  @override
-  void forEachLocalClassMember(
-      covariant ClassElement cls, void f(MemberElement member)) {
-    cls.ensureResolved(_resolution);
-
-    void handleMember(_member) {
-      MemberElement member = _member;
-      if (member.isSynthesized) return;
-      if (member.isMalformed) return;
-      if (member.isConstructor) return;
-      if (!member.isDeclaration) return;
-      f(member);
-    }
-
-    cls.forEachLocalMember(handleMember);
-    if (cls.isPatched) {
-      cls.implementation.forEachLocalMember(handleMember);
-    }
-  }
-
-  @override
-  void forEachInjectedClassMember(
-      covariant ClassElement cls, void f(MemberElement member)) {}
-
-  @override
-  void forEachClassMember(covariant ClassElement cls,
-      void f(ClassElement declarer, MemberElement member)) {
-    cls.ensureResolved(_resolution);
-    cls.forEachMember((ClassElement declarer, _member) {
-      MemberElement member = _member;
-      if (member.isSynthesized) return;
-      if (member.isMalformed) return;
-      if (member.isConstructor) return;
-      f(declarer, member);
-    }, includeSuperAndInjectedMembers: true);
-  }
-
-  @override
-  void forEachConstructor(
-      covariant ClassElement cls, void f(ConstructorEntity constructor),
-      {bool ensureResolved: true}) {
-    if (ensureResolved) cls.ensureResolved(_resolution);
-    for (ConstructorElement constructor in cls.implementation.constructors) {
-      if (ensureResolved) _resolution.ensureResolved(constructor.declaration);
-      if (constructor.isRedirectingFactory) continue;
-      f(constructor);
-    }
-  }
-
-  @override
-  void forEachConstructorBody(
-      covariant ClassElement cls, void f(ConstructorBodyEntity constructor)) {
-    cls.forEachConstructorBody(f);
-  }
-
-  @override
-  void forEachNestedClosure(
-      covariant MemberElement member, void f(FunctionEntity closure)) {
-    for (var closure in member.nestedClosures) {
-      f(closure);
-    }
-  }
-
-  @override
-  ClassEntity getSuperClass(covariant ClassElement cls,
-      {bool skipUnnamedMixinApplications: false}) {
-    cls.ensureResolved(_resolution);
-    ClassElement superclass = cls.superclass;
-    if (skipUnnamedMixinApplications) {
-      while (superclass != null && superclass.isUnnamedMixinApplication) {
-        superclass = superclass.superclass;
-      }
-    }
-    return superclass;
-  }
-
-  @override
-  void forEachSupertype(
-      covariant ClassElement cls, void f(ResolutionInterfaceType supertype)) {
-    cls.allSupertypes.forEach((InterfaceType supertype) => f(supertype));
-  }
-
-  @override
-  void forEachMixin(covariant ClassElement cls, void f(ClassElement mixin)) {
-    for (; cls != null; cls = cls.superclass) {
-      if (cls.isMixinApplication) {
-        MixinApplicationElement mixinApplication = cls;
-        f(mixinApplication.mixin);
-      }
-    }
-  }
-
-  @override
-  MemberElement lookupLibraryMember(
-      covariant LibraryElement library, String name,
-      {bool setter: false, bool required: false}) {
-    Element member = library.implementation.findLocal(name);
-    if (member != null && member.isAbstractField) {
-      AbstractFieldElement abstractField = member;
-      if (setter) {
-        member = abstractField.setter;
-      } else {
-        member = abstractField.getter;
-      }
-      if (member == null && required) {
-        failedAt(
-            library,
-            "The library '${library.canonicalUri}' does not contain required "
-            "${setter ? 'setter' : 'getter'}: '$name'.");
-      }
-    }
-    if (member is! MemberElement) {
-      member = null;
-    }
-    if (member == null && required) {
-      failedAt(
-          library,
-          "The library '${library.canonicalUri}' does not "
-          "contain required member: '$name'.");
-    }
-    return member?.declaration;
-  }
-
-  @override
-  void forEachLibraryMember(
-      covariant LibraryElement library, void f(MemberEntity member)) {
-    library.implementation.forEachLocalMember((Element element) {
-      if (!element.isClass && !element.isTypedef) {
-        MemberElement member = element;
-        f(member);
-      }
-    });
-  }
-
-  @override
-  ClassElement lookupClass(covariant LibraryElement library, String name,
-      {bool required: false}) {
-    Element cls = library.implementation.findLocal(name);
-    if (cls is! ClassElement) {
-      cls = null;
-    }
-    if (cls == null && required) {
-      failedAt(
-          library,
-          "The library '${library.libraryName}' does not "
-          "contain required class: '$name'.");
-    }
-    return cls?.declaration;
-  }
-
-  @override
-  void forEachClass(covariant LibraryElement library, void f(ClassEntity cls)) {
-    library.implementation.forEachLocalMember((dynamic member) {
-      if (member.isClass) {
-        ClassElement cls = member;
-        f(cls);
-      }
-    });
-  }
-
-  @override
-  LibraryElement lookupLibrary(Uri uri, {bool required: false}) {
-    LibraryElement library = _libraryProvider.lookupLibrary(uri);
-    // If the script of the library is synthesized, the library does not exist
-    // and we do not try to load the helpers.
-    //
-    // This could for example happen if dart:async is disabled, then loading it
-    // should not try to find the given element.
-    if (library != null && library.isSynthesized) {
-      return null;
-    }
-    if (library == null && required) {
-      failedAt(NO_LOCATION_SPANNABLE, "The library '${uri}' was not found.");
-    }
-    return library;
-  }
-
-  @override
-  bool isDeferredLoadLibraryGetter(covariant MemberElement member) {
-    return member.isDeferredLoaderGetter;
-  }
-
-  @override
-  ResolutionFunctionType getFunctionType(covariant MethodElement method) {
-    if (method is ConstructorBodyElement) {
-      return method.constructor.type;
-    }
-    method.computeType(_resolution);
-    ResolutionFunctionType type = method.type;
-    if (method.isConstructor) {
-      ConstructorElement constructor = method;
-      if (constructor.definingConstructor != null) {
-        // The type of a defining constructor doesn't use the right type
-        // variables. Substitute the type variable of the defining class by the
-        // type variables of the enclosing class.
-        ClassElement definingClass =
-            constructor.definingConstructor.enclosingClass;
-        type = type.substByContext(
-            method.enclosingClass.thisType.asInstanceOf(definingClass));
-      }
-    }
-    return type;
-  }
-
-  @override
-  List<TypeVariableType> getFunctionTypeVariables(FunctionEntity function) {
-    return const <TypeVariableType>[];
-  }
-
-  @override
-  DartType getFunctionAsyncOrSyncStarElementType(FunctionEntity function) {
-    return dynamicType;
-  }
-
-  @override
-  DartType getAsyncOrSyncStarElementType(AsyncMarker marker, DartType type) {
-    return dynamicType;
-  }
-
-  @override
-  DartType getFieldType(covariant FieldElement field) {
-    field.computeType(_resolution);
-    return field.type;
-  }
-
-  @override
-  ResolutionFunctionType getLocalFunctionType(
-      covariant LocalFunctionElement function) {
-    return function.type;
-  }
-
-  @override
-  ConstantExpression getFieldConstant(covariant FieldElement field) {
-    return field.constant;
-  }
-
-  @override
-  ResolutionDartType getUnaliasedType(covariant ResolutionDartType type) {
-    type.computeUnaliased(_resolution);
-    return type.unaliased;
-  }
-
-  @override
-  Iterable<ConstantValue> getMemberMetadata(covariant MemberElement element,
-      {bool includeParameterMetadata: false}) {
-    List<ConstantValue> values = <ConstantValue>[];
-    values.addAll(_getMetadataOf(element));
-    if (includeParameterMetadata) {
-      if (element.isFunction || element.isConstructor || element.isSetter) {
-        MethodElement function = element.implementation;
-        function.functionSignature.forEachParameter(
-            (parameter) => values.addAll(_getMetadataOf(parameter)));
-      }
-    }
-    return values;
-  }
-
-  @override
-  Iterable<ConstantValue> getLibraryMetadata(covariant LibraryElement element) {
-    return _getMetadataOf(element);
-  }
-
-  @override
-  Iterable<ImportEntity> getImports(covariant LibraryElement library) {
-    return library.imports;
-  }
-
-  @override
-  Iterable<ConstantValue> getClassMetadata(covariant ClassElement element) {
-    return _getMetadataOf(element);
-  }
-
-  @override
-  Iterable<ConstantValue> getTypedefMetadata(covariant TypedefElement element) {
-    return _getMetadataOf(element);
-  }
-
-  Iterable<ConstantValue> _getMetadataOf(Element element) {
-    List<ConstantValue> constants = <ConstantValue>[];
-    _compiler.reporter.withCurrentElement(element, () {
-      for (MetadataAnnotation metadata in element.implementation.metadata) {
-        metadata.ensureResolved(_compiler.resolution);
-        assert(metadata.constant != null,
-            failedAt(metadata, "Unevaluated metadata constant."));
-        constants.add(
-            _compiler.backend.constants.getConstantValue(metadata.constant));
-      }
-    });
-    return constants;
-  }
-
-  @override
-  ResolutionFunctionType getFunctionTypeOfTypedef(
-      covariant TypedefElement typedef) {
-    var result = typedef.alias;
-    if (result.isMalformed) return null;
-    return result;
-  }
-
-  @override
-  ResolutionTypedefType getTypedefTypeOfTypedef(
-          covariant TypedefElement typedef) =>
-      typedef.thisType;
-
-  @override
-  bool isEnumClass(covariant ClassElement cls) => cls.isEnumClass;
-}
-
-/// AST-based logic for processing annotations. These annotations are processed
-/// very early in the compilation pipeline, typically this is before resolution
-/// is complete. Because of that this processor does a lightweight parse of the
-/// annotation (which is restricted to a limited subset of the annotation
-/// syntax), and, once resolution completes, it validates that the parsed
-/// annotations correspond to the correct element.
-class _ElementAnnotationProcessor implements AnnotationProcessor {
-  final Compiler _compiler;
-  final NativeBasicDataBuilder _nativeBasicDataBuilder;
-
-  _ElementAnnotationProcessor(this._compiler, this._nativeBasicDataBuilder);
-
-  CommonElements get _commonElements => _compiler.resolution.commonElements;
-
-  /// Check whether [cls] has a `@Native(...)` annotation, and if so, set its
-  /// native name from the annotation.
-  void extractNativeAnnotations(covariant LibraryElement library) {
-    library.forEachLocalMember((Element element) {
-      if (element.isClass) {
-        EagerAnnotationHandler.checkAnnotation(_compiler, element,
-            new NativeAnnotationHandler(_nativeBasicDataBuilder));
-      }
-    });
-  }
-
-  void extractJsInteropAnnotations(covariant LibraryElement library) {
-    bool checkJsInteropAnnotation(Element element) {
-      return EagerAnnotationHandler.checkAnnotation(
-          _compiler, element, const JsInteropAnnotationHandler());
-    }
-
-    if (checkJsInteropAnnotation(library)) {
-      _nativeBasicDataBuilder.markAsJsInteropLibrary(library);
-    }
-    library.forEachLocalMember((Element element) {
-      if (element.isClass) {
-        ClassElement cls = element;
-        if (checkJsInteropAnnotation(element)) {
-          _nativeBasicDataBuilder.markAsJsInteropClass(cls);
-        }
-      }
-    });
-  }
-
-  void processJsInteropAnnotations(
-      NativeBasicData nativeBasicData, NativeDataBuilder nativeDataBuilder) {
-    if (_commonElements.jsAnnotationClass == null) return;
-
-    ClassElement cls = _commonElements.jsAnnotationClass;
-    FieldElement nameField = cls.lookupMember('name');
-
-    /// Resolves the metadata of [element] and returns the name of the `JS(...)`
-    /// annotation for js interop, if found.
-    String processJsInteropAnnotation(Element element) {
-      for (MetadataAnnotation annotation in element.implementation.metadata) {
-        // TODO(johnniwinther): Avoid processing unresolved elements.
-        if (annotation.constant == null) continue;
-        ConstantValue constant =
-            _compiler.constants.getConstantValue(annotation.constant);
-        if (constant == null || constant is! ConstructedConstantValue) continue;
-        ConstructedConstantValue constructedConstant = constant;
-        if (constructedConstant.type.element ==
-            _commonElements.jsAnnotationClass) {
-          ConstantValue value = constructedConstant.fields[nameField];
-          String name;
-          if (value.isString) {
-            StringConstantValue stringValue = value;
-            name = stringValue.stringValue;
-          } else {
-            // TODO(jacobr): report a warning if the value is not a String.
-            name = '';
-          }
-          return name;
-        }
-      }
-      return null;
-    }
-
-    void checkFunctionParameters(MethodElement fn) {
-      if (fn.hasFunctionSignature &&
-          fn.functionSignature.optionalParametersAreNamed) {
-        _compiler.reporter.reportErrorMessage(
-            fn,
-            MessageKind.JS_INTEROP_METHOD_WITH_NAMED_ARGUMENTS,
-            {'method': fn.name});
-      }
-    }
-
-    bool hasAnonymousAnnotation(Element element) {
-      if (_commonElements.jsAnonymousClass == null) return false;
-      return element.metadata.any((MetadataAnnotation annotation) {
-        ConstantValue constant =
-            _compiler.constants.getConstantValue(annotation.constant);
-        if (constant == null || constant is! ConstructedConstantValue)
-          return false;
-        ConstructedConstantValue constructedConstant = constant;
-        return constructedConstant.type.element ==
-            _commonElements.jsAnonymousClass;
-      });
-    }
-
-    void processJsInteropAnnotationsInLibrary(LibraryElement library) {
-      String libraryName = processJsInteropAnnotation(library);
-      if (libraryName != null) {
-        nativeDataBuilder.setJsInteropLibraryName(library, libraryName);
-      }
-      library.implementation.forEachLocalMember((Element element) {
-        if (element is MemberElement) {
-          String memberName = processJsInteropAnnotation(element);
-          if (memberName != null) {
-            nativeDataBuilder.setJsInteropMemberName(element, memberName);
-            if (element is MethodElement) {
-              checkFunctionParameters(element);
-            }
-          }
-        }
-
-        if (!element.isClass) return;
-
-        ClassElement classElement = element;
-        String className = processJsInteropAnnotation(classElement);
-        if (className != null) {
-          nativeDataBuilder.setJsInteropClassName(classElement, className);
-        }
-        if (!nativeBasicData.isJsInteropClass(classElement)) return;
-
-        bool isAnonymous = hasAnonymousAnnotation(classElement);
-        if (isAnonymous) {
-          nativeDataBuilder.markJsInteropClassAsAnonymous(classElement);
-        }
-
-        // Skip classes that are completely unreachable. This should only happen
-        // when all of jsinterop types are unreachable from main.
-        if (!_compiler.resolutionWorldBuilder.isImplemented(classElement)) {
-          return;
-        }
-
-        if (!classElement
-            .implementsInterface(_commonElements.jsJavaScriptObjectClass)) {
-          _compiler.reporter.reportErrorMessage(classElement,
-              MessageKind.JS_INTEROP_CLASS_CANNOT_EXTEND_DART_CLASS, {
-            'cls': classElement.name,
-            'superclass': classElement.superclass.name
-          });
-        }
-
-        classElement.forEachMember((ClassElement classElement, _member) {
-          MemberElement member = _member;
-          String memberName = processJsInteropAnnotation(member);
-          if (memberName != null) {
-            nativeDataBuilder.setJsInteropMemberName(member, memberName);
-          }
-
-          if (!member.isSynthesized &&
-              nativeBasicData.isJsInteropClass(classElement) &&
-              member is MethodElement) {
-            MethodElement fn = member;
-            if (!fn.isExternal &&
-                !fn.isAbstract &&
-                !fn.isConstructor &&
-                !fn.isStatic) {
-              _compiler.reporter.reportErrorMessage(
-                  fn,
-                  MessageKind.JS_INTEROP_CLASS_NON_EXTERNAL_MEMBER,
-                  {'cls': classElement.name, 'member': member.name});
-            }
-
-            if (fn.isFactoryConstructor && isAnonymous) {
-              if (fn.functionSignature.requiredParameterCount > 0 ||
-                  fn.functionSignature.hasOptionalParameters &&
-                      !fn.functionSignature.optionalParametersAreNamed) {
-                _compiler.reporter.reportErrorMessage(
-                    fn,
-                    MessageKind
-                        .JS_OBJECT_LITERAL_CONSTRUCTOR_WITH_POSITIONAL_ARGUMENTS,
-                    {'cls': classElement.name});
-              }
-            } else {
-              checkFunctionParameters(fn);
-            }
-          }
-        });
-      });
-    }
-
-    _compiler.libraryLoader.libraries
-        .forEach((LibraryEntity l) => processJsInteropAnnotationsInLibrary(l));
-  }
-}
-
-/// Builder that creates work item necessary for the resolution of a
-/// [MemberElement].
-class ResolutionWorkItemBuilder extends WorkItemBuilder {
-  final Resolution _resolution;
-
-  ResolutionWorkItemBuilder(this._resolution);
-
-  @override
-  WorkItem createWorkItem(MemberElement element) {
-    assert(element.isDeclaration, failedAt(element));
-    if (element.isMalformed) return null;
-
-    assert(element is AnalyzableElement,
-        failedAt(element, 'Element $element is not analyzable.'));
-    return _resolution.createWorkItem(element);
-  }
-}
-
-class ResolutionMirrorsData extends MirrorsDataImpl {
-  ResolutionMirrorsData(Compiler compiler,
-      ElementEnvironment elementEnvironment, CommonElements commonElements)
-      : super(compiler, elementEnvironment, commonElements);
-
-  @override
-  bool isClassInjected(covariant ClassElement cls) => cls.isInjected;
-
-  @override
-  bool isClassResolved(covariant ClassElement cls) => cls.isResolved;
-
-  @override
-  void forEachConstructor(
-      covariant ClassElement cls, void f(ConstructorEntity constructor)) {
-    cls.constructors.forEach((Element _constructor) {
-      ConstructorElement constructor = _constructor;
-      f(constructor);
-    });
-  }
-}
diff --git a/pkg/compiler/lib/src/resolution/scope.dart b/pkg/compiler/lib/src/resolution/scope.dart
deleted file mode 100644
index a047968..0000000
--- a/pkg/compiler/lib/src/resolution/scope.dart
+++ /dev/null
@@ -1,230 +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.
-
-library dart2js.resolution.scope;
-
-import '../elements/resolution_types.dart';
-import '../elements/elements.dart';
-
-abstract class Scope {
-  /**
-   * If an [Element] named `element.name` has already been added to this
-   * [Scope], return that element and make no changes. If no such element has
-   * been added, add the given [element] to this [Scope], and return [element].
-   * Note that this operation is only allowed on mutable scopes such as
-   * [MethodScope] and [BlockScope].
-   */
-  Element add(Element element);
-
-  /**
-   * Looks up the [Element] for [name] in this scope.
-   */
-  Element lookup(String name);
-
-  static Scope buildEnclosingScope(Element element) {
-    return element.enclosingElement != null
-        ? element.enclosingElement.buildScope()
-        : element.buildScope();
-  }
-}
-
-abstract class NestedScope extends Scope {
-  final Scope parent;
-
-  NestedScope(this.parent);
-
-  Element lookup(String name) {
-    Element result = localLookup(name);
-    if (result != null) return result;
-    return parent.lookup(name);
-  }
-
-  Element localLookup(String name);
-}
-
-class VariableDefinitionScope extends NestedScope {
-  final String variableName;
-  bool variableReferencedInInitializer = false;
-
-  VariableDefinitionScope(Scope parent, this.variableName) : super(parent);
-
-  Element localLookup(String name) {
-    if (name == variableName) {
-      variableReferencedInInitializer = true;
-    }
-    return null;
-  }
-
-  Element add(Element newElement) {
-    throw "Cannot add element to VariableDefinitionScope";
-  }
-}
-
-/// [TypeVariablesScope] defines the outer scope in a context where some type
-/// variables are declared and the entities in the enclosing scope are
-/// available, but where locally declared and inherited members are not
-/// available.
-abstract class TypeVariablesScope extends NestedScope {
-  List<ResolutionDartType> get typeVariables;
-
-  TypeVariablesScope(Scope parent) : super(parent) {
-    assert(parent != null);
-  }
-
-  Element add(Element newElement) {
-    throw "Cannot add element to TypeDeclarationScope";
-  }
-
-  Element lookupTypeVariable(String name) {
-    for (ResolutionTypeVariableType type in typeVariables) {
-      if (type.name == name) {
-        return type.element;
-      }
-    }
-    return null;
-  }
-
-  Element localLookup(String name) => lookupTypeVariable(name);
-}
-
-/**
- * [TypeDeclarationScope] defines the outer scope of a type declaration in
- * which the declared type variables and the entities in the enclosing scope are
- * available but where declared and inherited members are not available. This
- * scope is used for class declarations during resolution of the class hierarchy
- * and when resolving typedef signatures. In other cases [ClassScope] is used.
- */
-class TypeDeclarationScope extends TypeVariablesScope {
-  final GenericElement element;
-
-  @override
-  List<ResolutionDartType> get typeVariables => element.typeVariables;
-
-  TypeDeclarationScope(Scope parent, this.element) : super(parent);
-
-  String toString() => 'TypeDeclarationScope($element)';
-}
-
-abstract class MutableScope extends NestedScope {
-  final Map<String, Element> elements;
-
-  MutableScope(Scope parent)
-      : this.elements = new Map<String, Element>(),
-        super(parent) {
-    assert(parent != null);
-  }
-
-  Element add(Element newElement) {
-    if (elements.containsKey(newElement.name)) {
-      return elements[newElement.name];
-    }
-    elements[newElement.name] = newElement;
-    return newElement;
-  }
-
-  Element localLookup(String name) => elements[name];
-}
-
-/**
- * [ExtensionScope] enables the creation of an extended version of an
- * existing [NestedScope], received during construction and stored in
- * [extendee]. An [ExtensionScope] will treat an added `element` as conflicting
- * if an element `e` where `e.name == element.name` exists among the elements
- * added to this [ExtensionScope], or among the ones added to [extendee]
- * (according to `extendee.localLookup`). In this sense, it represents the
- * union of the bindings stored locally in [elements] and the bindings in
- * [extendee], not a new scope which is nested inside [extendee].
- *
- * Note that it is required that no bindings are added to [extendee] during the
- * lifetime of this [ExtensionScope]: That would enable duplicates to be
- * introduced into the extended scope consisting of [this] plus [extendee]
- * without detection.
- */
-class ExtensionScope extends Scope {
-  final NestedScope extendee;
-  final Map<String, Element> elements;
-
-  ExtensionScope(this.extendee) : this.elements = new Map<String, Element>() {
-    assert(extendee != null);
-  }
-
-  Element lookup(String name) {
-    Element result = elements[name];
-    if (result != null) return result;
-    return extendee.lookup(name);
-  }
-
-  Element add(Element newElement) {
-    if (elements.containsKey(newElement.name)) {
-      return elements[newElement.name];
-    }
-    Element existing = extendee.localLookup(newElement.name);
-    if (existing != null) return existing;
-    elements[newElement.name] = newElement;
-    return newElement;
-  }
-}
-
-class MethodScope extends MutableScope {
-  final Element element;
-
-  MethodScope(Scope parent, this.element) : super(parent);
-
-  String toString() => 'MethodScope($element${elements.keys.toList()})';
-}
-
-class BlockScope extends MutableScope {
-  BlockScope(Scope parent) : super(parent);
-
-  String toString() => 'BlockScope(${elements.keys.toList()})';
-}
-
-/**
- * [ClassScope] defines the inner scope of a class/interface declaration in
- * which declared members, declared type variables, entities in the enclosing
- * scope and inherited members are available, in the given order.
- */
-class ClassScope extends TypeDeclarationScope {
-  ClassElement get element => super.element;
-
-  ClassScope(Scope parentScope, ClassElement element)
-      : super(parentScope, element) {
-    assert(parent != null);
-  }
-
-  Element localLookup(String name) {
-    Element result = element.lookupLocalMember(name);
-    if (result != null) return result;
-    return super.localLookup(name);
-  }
-
-  Element lookup(String name) {
-    Element result = localLookup(name);
-    if (result != null) return result;
-    result = parent.lookup(name);
-    if (result != null) return result;
-    return element.lookupSuperMember(name);
-  }
-
-  Element add(Element newElement) {
-    throw "Cannot add an element in a class scope";
-  }
-
-  String toString() => 'ClassScope($element)';
-}
-
-class LibraryScope implements Scope {
-  final LibraryElement library;
-
-  LibraryScope(LibraryElement this.library);
-
-  Element localLookup(String name) => library.find(name);
-  Element lookup(String name) => localLookup(name);
-
-  Element add(Element newElement) {
-    throw "Cannot add an element to a library scope";
-  }
-
-  String toString() => 'LibraryScope($library)';
-}
diff --git a/pkg/compiler/lib/src/resolution/secret_tree_element.dart b/pkg/compiler/lib/src/resolution/secret_tree_element.dart
deleted file mode 100644
index 9b118a6..0000000
--- a/pkg/compiler/lib/src/resolution/secret_tree_element.dart
+++ /dev/null
@@ -1,12 +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.
-
-library dart2js.resolution.secret_tree_element;
-
-// The code in this library was moved to ../tree/nodes.dart to satisfy extra
-// restrictions on overriding private members.
-//
-// [See issue for more details](https://github.com/dart-lang/sdk/issues/28809).
-
-export '../tree/nodes.dart' show getTreeElement, setTreeElement;
diff --git a/pkg/compiler/lib/src/resolution/semantic_visitor.dart b/pkg/compiler/lib/src/resolution/semantic_visitor.dart
deleted file mode 100644
index f917349..0000000
--- a/pkg/compiler/lib/src/resolution/semantic_visitor.dart
+++ /dev/null
@@ -1,4725 +0,0 @@
-// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library dart2js.semantics_visitor;
-
-import '../common.dart';
-import '../constants/expressions.dart';
-import '../elements/elements.dart';
-import '../elements/names.dart';
-import '../elements/operators.dart';
-import '../elements/resolution_types.dart';
-import '../tree/tree.dart';
-import '../universe/call_structure.dart' show CallStructure;
-import '../universe/selector.dart' show Selector;
-import 'send_resolver.dart';
-import 'send_structure.dart';
-import 'tree_elements.dart';
-
-part 'semantic_visitor_mixins.dart';
-
-/// Mixin that couples a [SendResolverMixin] to a [SemanticSendVisitor] in a
-/// [Visitor].
-abstract class SemanticSendResolvedMixin<R, A> implements Visitor<R> {
-  TreeElements get elements;
-
-  internalError(Spannable spannable, String message);
-
-  SemanticSendVisitor<R, A> get sendVisitor;
-
-  @override
-  R visitIdentifier(Identifier node) {
-    // TODO(johnniwinther): Support argument.
-    A arg = null;
-    if (node.isThis()) {
-      // TODO(johnniwinther): Parse `this` as a [Send] whose selector is `this`
-      // to normalize with `this(...)`.
-      return sendVisitor.visitThisGet(node, arg);
-    }
-    return null;
-  }
-
-  @override
-  R visitSend(Send node) {
-    // TODO(johnniwinther): Support argument.
-    A arg = null;
-
-    SendStructure structure = elements.getSendStructure(node);
-    if (structure == null) {
-      return internalError(node, 'No structure for $node');
-    } else {
-      return structure.dispatch(sendVisitor, node, arg);
-    }
-  }
-
-  @override
-  R visitSendSet(SendSet node) {
-    return visitSend(node);
-  }
-
-  @override
-  R visitNewExpression(NewExpression node) {
-    // TODO(johnniwinther): Support argument.
-    A arg = null;
-
-    NewStructure structure = elements.getNewStructure(node);
-    if (structure == null) {
-      return internalError(node, 'No structure for $node');
-    } else {
-      return structure.dispatch(sendVisitor, node, arg);
-    }
-  }
-}
-
-/// Mixin that couples a [DeclarationResolverMixin] to a
-/// [SemanticDeclarationVisitor] in a [Visitor].
-abstract class SemanticDeclarationResolvedMixin<R, A>
-    implements Visitor<R>, DeclarationResolverMixin {
-  SemanticDeclarationVisitor<R, A> get declVisitor;
-
-  @override
-  R visitFunctionExpression(FunctionExpression node) {
-    // TODO(johnniwinther): Support argument.
-    A arg = null;
-
-    DeclStructure structure = computeFunctionStructure(node);
-    if (structure == null) {
-      return internalError(node, 'No structure for $node');
-    } else {
-      return structure.dispatch(declVisitor, node, arg);
-    }
-  }
-
-  visitInitializers(FunctionExpression function, A arg) {
-    InitializersStructure initializers = computeInitializersStructure(function);
-    for (InitializerStructure structure in initializers.initializers) {
-      structure.dispatch(declVisitor, arg);
-    }
-  }
-
-  visitParameters(NodeList parameters, A arg) {
-    List<ParameterStructure> structures =
-        computeParameterStructures(parameters);
-    for (ParameterStructure structure in structures) {
-      structure.dispatch(declVisitor, arg);
-    }
-  }
-
-  @override
-  R visitVariableDefinitions(VariableDefinitions definitions) {
-    // TODO(johnniwinther): Support argument.
-    A arg = null;
-
-    computeVariableStructures(definitions,
-        (Node node, VariableStructure structure) {
-      if (structure == null) {
-        return internalError(node, 'No structure for $node');
-      } else {
-        return structure.dispatch(declVisitor, node, arg);
-      }
-    });
-    return null;
-  }
-}
-
-abstract class SemanticVisitor<R, A> extends Visitor<R>
-    with
-        SemanticSendResolvedMixin<R, A>,
-        SemanticDeclarationResolvedMixin<R, A>,
-        DeclarationResolverMixin {
-  TreeElements elements;
-
-  SemanticVisitor(this.elements);
-}
-
-// TODO(johnniwinther): Add visits for [visitLocalConstantGet],
-// [visitLocalConstantInvoke], [visitStaticConstantGet], etc.
-abstract class SemanticSendVisitor<R, A> {
-  R apply(Node node, A arg);
-
-  /// Read of the [parameter].
-  ///
-  /// For instance:
-  ///
-  ///     m(parameter) => parameter;
-  ///
-  R visitParameterGet(Send node, ParameterElement parameter, A arg);
-
-  /// Assignment of [rhs] to the [parameter].
-  ///
-  /// For instance:
-  ///
-  ///     m(parameter) {
-  ///       parameter = rhs;
-  ///     }
-  ///
-  R visitParameterSet(
-      SendSet node, ParameterElement parameter, Node rhs, A arg);
-
-  /// Assignment of [rhs] to the final [parameter].
-  ///
-  /// For instance:
-  ///
-  ///     m(final parameter) {
-  ///       parameter = rhs;
-  ///     }
-  ///
-  R visitFinalParameterSet(
-      SendSet node, ParameterElement parameter, Node rhs, A arg);
-
-  /// Invocation of the [parameter] with [arguments].
-  ///
-  /// For instance:
-  ///
-  ///     m(parameter) {
-  ///       parameter(null, 42);
-  ///     }
-  ///
-  R visitParameterInvoke(Send node, ParameterElement parameter,
-      NodeList arguments, CallStructure callStructure, A arg);
-
-  /// Read of the local [variable].
-  ///
-  /// For instance:
-  ///
-  ///     m() {
-  ///       var variable;
-  ///       return variable;
-  ///     }
-  ///
-  R visitLocalVariableGet(Send node, LocalVariableElement variable, A arg);
-
-  /// Assignment of [rhs] to the local [variable].
-  ///
-  /// For instance:
-  ///
-  ///     m() {
-  ///       var variable;
-  ///       variable = rhs;
-  ///     }
-  ///
-  R visitLocalVariableSet(
-      SendSet node, LocalVariableElement variable, Node rhs, A arg);
-
-  /// Assignment of [rhs] to the final local [variable].
-  ///
-  /// For instance:
-  ///
-  ///     m() {
-  ///       final variable = null;
-  ///       variable = rhs;
-  ///     }
-  ///
-  R visitFinalLocalVariableSet(
-      SendSet node, LocalVariableElement variable, Node rhs, A arg);
-
-  /// Invocation of the local variable [variable] with [arguments].
-  ///
-  /// For instance:
-  ///
-  ///     m() {
-  ///       var variable;
-  ///       variable(null, 42);
-  ///     }
-  ///
-  R visitLocalVariableInvoke(Send node, LocalVariableElement variable,
-      NodeList arguments, CallStructure callStructure, A arg);
-
-  /// Closurization of the local [function].
-  ///
-  /// For instance:
-  ///
-  ///     m() {
-  ///       o(a, b) {}
-  ///       return o;
-  ///     }
-  ///
-  R visitLocalFunctionGet(Send node, LocalFunctionElement function, A arg);
-
-  /// Assignment of [rhs] to the local [function].
-  ///
-  /// For instance:
-  ///
-  ///     m() {
-  ///       o(a, b) {}
-  ///       o = rhs;
-  ///     }
-  ///
-  R visitLocalFunctionSet(
-      SendSet node, LocalFunctionElement function, Node rhs, A arg);
-
-  /// Invocation of the local [function] with [arguments].
-  ///
-  /// For instance:
-  ///
-  ///     m() {
-  ///       o(a, b) {}
-  ///       return o(null, 42);
-  ///     }
-  ///
-  R visitLocalFunctionInvoke(Send node, LocalFunctionElement function,
-      NodeList arguments, CallStructure callStructure, A arg);
-
-  /// Invocation of the local [function] with incompatible [arguments].
-  ///
-  /// For instance:
-  ///
-  ///     m() {
-  ///       o(a) {}
-  ///       return o(null, 42);
-  ///     }
-  ///
-  R visitLocalFunctionIncompatibleInvoke(
-      Send node,
-      LocalFunctionElement function,
-      NodeList arguments,
-      CallStructure callStructure,
-      A arg);
-
-  /// Getter call on [receiver] of the property defined by [selector].
-  ///
-  /// For instance:
-  ///
-  ///     m(receiver) => receiver.foo;
-  ///
-  R visitDynamicPropertyGet(Send node, Node receiver, Name name, A arg);
-
-  /// Conditional (if not null) getter call on [receiver] of the property
-  /// defined by [selector].
-  ///
-  /// For instance:
-  ///
-  ///     m(receiver) => receiver?.foo;
-  ///
-  R visitIfNotNullDynamicPropertyGet(
-      Send node, Node receiver, Name name, A arg);
-
-  /// Setter call on [receiver] with argument [rhs] of the property defined by
-  /// [selector].
-  ///
-  /// For instance:
-  ///
-  ///     m(receiver) {
-  ///       receiver.foo = rhs;
-  ///     }
-  ///
-  R visitDynamicPropertySet(
-      SendSet node, Node receiver, Name name, Node rhs, A arg);
-
-  /// Conditional (if not null) setter call on [receiver] with argument [rhs] of
-  /// the property defined by [selector].
-  ///
-  /// For instance:
-  ///
-  ///     m(receiver) {
-  ///       receiver?.foo = rhs;
-  ///     }
-  ///
-  R visitIfNotNullDynamicPropertySet(
-      SendSet node, Node receiver, Name name, Node rhs, A arg);
-
-  /// Invocation of the property defined by [selector] on [receiver] with
-  /// [arguments].
-  ///
-  /// For instance:
-  ///
-  ///     m(receiver) {
-  ///       receiver.foo(null, 42);
-  ///     }
-  ///
-  R visitDynamicPropertyInvoke(
-      Send node, Node receiver, NodeList arguments, Selector selector, A arg);
-
-  /// Conditional invocation of the property defined by [selector] on [receiver]
-  /// with [arguments], if [receiver] is not null.
-  ///
-  /// For instance:
-  ///
-  ///     m(receiver) {
-  ///       receiver?.foo(null, 42);
-  ///     }
-  ///
-  R visitIfNotNullDynamicPropertyInvoke(
-      Send node, Node receiver, NodeList arguments, Selector selector, A arg);
-
-  /// Getter call on `this` of the property defined by [selector].
-  ///
-  /// For instance:
-  ///
-  ///     class C {
-  ///       m() => this.foo;
-  ///     }
-  ///
-  /// or
-  ///
-  ///     class C {
-  ///       m() => foo;
-  ///     }
-  ///
-  R visitThisPropertyGet(Send node, Name name, A arg);
-
-  /// Setter call on `this` with argument [rhs] of the property defined by
-  /// [selector].
-  ///
-  /// For instance:
-  ///
-  ///     class C {
-  ///       m() { this.foo = rhs; }
-  ///     }
-  ///
-  /// or
-  ///
-  ///     class C {
-  ///       m() { foo = rhs; }
-  ///     }
-  ///
-  R visitThisPropertySet(SendSet node, Name name, Node rhs, A arg);
-
-  /// Invocation of the property defined by [selector] on `this` with
-  /// [arguments].
-  ///
-  /// For instance:
-  ///
-  ///     class C {
-  ///       m() { this.foo(null, 42); }
-  ///     }
-  ///
-  /// or
-  ///
-  ///     class C {
-  ///       m() { foo(null, 42); }
-  ///     }
-  ///
-  ///
-  R visitThisPropertyInvoke(
-      Send node, NodeList arguments, Selector selector, A arg);
-
-  /// Read of `this`.
-  ///
-  /// For instance:
-  ///
-  ///     class C {
-  ///       m() => this;
-  ///     }
-  ///
-  R visitThisGet(Identifier node, A arg);
-
-  /// Invocation of `this` with [arguments].
-  ///
-  /// For instance:
-  ///
-  ///     class C {
-  ///       m() => this(null, 42);
-  ///     }
-  ///
-  R visitThisInvoke(
-      Send node, NodeList arguments, CallStructure callStructure, A arg);
-
-  /// Read of the super [field].
-  ///
-  /// For instance:
-  ///
-  ///     class B {
-  ///       var foo;
-  ///     }
-  ///     class C extends B {
-  ///        m() => super.foo;
-  ///     }
-  ///
-  R visitSuperFieldGet(Send node, FieldElement field, A arg);
-
-  /// Assignment of [rhs] to the super [field].
-  ///
-  /// For instance:
-  ///
-  ///     class B {
-  ///       var foo;
-  ///     }
-  ///     class C extends B {
-  ///        m() { super.foo = rhs; }
-  ///     }
-  ///
-  R visitSuperFieldSet(SendSet node, FieldElement field, Node rhs, A arg);
-
-  /// Assignment of [rhs] to the final static [field].
-  ///
-  /// For instance:
-  ///
-  ///     class B {
-  ///       final foo = null;
-  ///     }
-  ///     class C extends B {
-  ///        m() { super.foo = rhs; }
-  ///     }
-  ///
-  R visitFinalSuperFieldSet(SendSet node, FieldElement field, Node rhs, A arg);
-
-  /// Invocation of the super [field] with [arguments].
-  ///
-  /// For instance:
-  ///
-  ///     class B {
-  ///       var foo;
-  ///     }
-  ///     class C extends B {
-  ///        m() { super.foo(null, 42); }
-  ///     }
-  ///
-  R visitSuperFieldInvoke(Send node, FieldElement field, NodeList arguments,
-      CallStructure callStructure, A arg);
-
-  /// Closurization of the super [method].
-  ///
-  /// For instance:
-  ///
-  ///     class B {
-  ///       foo(a, b) {}
-  ///     }
-  ///     class C extends B {
-  ///        m() => super.foo;
-  ///     }
-  ///
-  R visitSuperMethodGet(Send node, MethodElement method, A arg);
-
-  /// Invocation of the super [method] with [arguments].
-  ///
-  /// For instance:
-  ///
-  ///     class B {
-  ///       foo(a, b) {}
-  ///     }
-  ///     class C extends B {
-  ///        m() { super.foo(null, 42); }
-  ///     }
-  ///
-  R visitSuperMethodInvoke(Send node, MethodElement method, NodeList arguments,
-      CallStructure callStructure, A arg);
-
-  /// Invocation of the super [method] with incompatible [arguments].
-  ///
-  /// For instance:
-  ///
-  ///     class B {
-  ///       foo(a, b) {}
-  ///     }
-  ///     class C extends B {
-  ///        m() { super.foo(null); } // One argument missing.
-  ///     }
-  ///
-  R visitSuperMethodIncompatibleInvoke(Send node, MethodElement method,
-      NodeList arguments, CallStructure callStructure, A arg);
-
-  /// Assignment of [rhs] to the super [method].
-  ///
-  /// For instance:
-  ///
-  ///     class B {
-  ///       foo(a, b) {}
-  ///     }
-  ///     class C extends B {
-  ///        m() { super.foo = rhs; }
-  ///     }
-  ///
-  R visitSuperMethodSet(SendSet node, MethodElement method, Node rhs, A arg);
-
-  /// Getter call to the super [getter].
-  ///
-  /// For instance:
-  ///
-  ///     class B {
-  ///       get foo => null;
-  ///     }
-  ///     class C extends B {
-  ///        m() => super.foo;
-  ///     }
-  ///
-  R visitSuperGetterGet(Send node, GetterElement getter, A arg);
-
-  /// Getter call the super [setter].
-  ///
-  /// For instance:
-  ///
-  ///     class B {
-  ///       set foo(_) {}
-  ///     }
-  ///     class C extends B {
-  ///        m() => super.foo;
-  ///     }
-  ///
-  R visitSuperSetterGet(Send node, SetterElement setter, A arg);
-
-  /// Setter call to the super [setter].
-  ///
-  /// For instance:
-  ///
-  ///     class B {
-  ///       set foo(_) {}
-  ///     }
-  ///     class C extends B {
-  ///        m() { super.foo = rhs; }
-  ///     }
-  ///
-  R visitSuperSetterSet(SendSet node, SetterElement setter, Node rhs, A arg);
-
-  /// Assignment of [rhs] to the super [getter].
-  ///
-  /// For instance:
-  ///
-  ///     class B {
-  ///       get foo => null;
-  ///     }
-  ///     class C extends B {
-  ///        m() { super.foo = rhs; }
-  ///     }
-  ///
-  R visitSuperGetterSet(SendSet node, GetterElement getter, Node rhs, A arg);
-
-  /// Invocation of the super [getter] with [arguments].
-  ///
-  /// For instance:
-  ///
-  ///     class B {
-  ///       get foo => null;
-  ///     }
-  ///     class C extends B {
-  ///        m() { super.foo(null, 42; }
-  ///     }
-  ///
-  R visitSuperGetterInvoke(Send node, GetterElement getter, NodeList arguments,
-      CallStructure callStructure, A arg);
-
-  /// Invocation of the super [setter] with [arguments].
-  ///
-  /// For instance:
-  ///
-  ///     class B {
-  ///       set foo(_) {}
-  ///     }
-  ///     class C extends B {
-  ///        m() { super.foo(null, 42; }
-  ///     }
-  ///
-  R visitSuperSetterInvoke(Send node, SetterElement setter, NodeList arguments,
-      CallStructure callStructure, A arg);
-
-  /// Invocation of a [expression] with [arguments].
-  ///
-  /// For instance:
-  ///
-  ///     m() => (a, b){}(null, 42);
-  ///
-  R visitExpressionInvoke(Send node, Node expression, NodeList arguments,
-      CallStructure callStructure, A arg);
-
-  /// Read of the static [field].
-  ///
-  /// For instance:
-  ///
-  ///     class C {
-  ///       static var foo;
-  ///     }
-  ///     m() => C.foo;
-  ///
-  R visitStaticFieldGet(Send node, FieldElement field, A arg);
-
-  /// Assignment of [rhs] to the static [field].
-  ///
-  /// For instance:
-  ///
-  ///     class C {
-  ///       static var foo;
-  ///     }
-  ///     m() { C.foo = rhs; }
-  ///
-  R visitStaticFieldSet(SendSet node, FieldElement field, Node rhs, A arg);
-
-  /// Assignment of [rhs] to the final static [field].
-  ///
-  /// For instance:
-  ///
-  ///     class C {
-  ///       static final foo;
-  ///     }
-  ///     m() { C.foo = rhs; }
-  ///
-  R visitFinalStaticFieldSet(SendSet node, FieldElement field, Node rhs, A arg);
-
-  /// Invocation of the static [field] with [arguments].
-  ///
-  /// For instance:
-  ///
-  ///     class C {
-  ///       static var foo;
-  ///     }
-  ///     m() { C.foo(null, 42); }
-  ///
-  R visitStaticFieldInvoke(Send node, FieldElement field, NodeList arguments,
-      CallStructure callStructure, A arg);
-
-  /// Closurization of the static [function].
-  ///
-  /// For instance:
-  ///
-  ///     class C {
-  ///       static foo(a, b) {}
-  ///     }
-  ///     m() => C.foo;
-  ///
-  R visitStaticFunctionGet(Send node, MethodElement function, A arg);
-
-  /// Invocation of the static [function] with [arguments].
-  ///
-  /// For instance:
-  ///
-  ///     class C {
-  ///       static foo(a, b) {}
-  ///     }
-  ///     m() { C.foo(null, 42); }
-  ///
-  R visitStaticFunctionInvoke(Send node, MethodElement function,
-      NodeList arguments, CallStructure callStructure, A arg);
-
-  /// Invocation of the static [function] with incompatible [arguments].
-  ///
-  /// For instance:
-  ///
-  ///     class C {
-  ///       static foo(a, b) {}
-  ///     }
-  ///     m() { C.foo(null); }
-  ///
-  R visitStaticFunctionIncompatibleInvoke(Send node, MethodElement function,
-      NodeList arguments, CallStructure callStructure, A arg);
-
-  /// Assignment of [rhs] to the static [function].
-  ///
-  /// For instance:
-  ///
-  ///     class C {
-  ///       static foo(a, b) {}
-  ///     }
-  ///     m() { C.foo = rhs; }
-  ///
-  R visitStaticFunctionSet(
-      SendSet node, MethodElement function, Node rhs, A arg);
-
-  /// Getter call to the static [getter].
-  ///
-  /// For instance:
-  ///
-  ///     class C {
-  ///       static get foo => null;
-  ///     }
-  ///     m() => C.foo;
-  ///
-  R visitStaticGetterGet(Send node, GetterElement getter, A arg);
-
-  /// Getter call the static [setter].
-  ///
-  /// For instance:
-  ///
-  ///     class C {
-  ///       static set foo(_) {}
-  ///     }
-  ///     m() => C.foo;
-  ///
-  R visitStaticSetterGet(Send node, SetterElement setter, A arg);
-
-  /// Setter call to the static [setter].
-  ///
-  /// For instance:
-  ///
-  ///     class C {
-  ///       static set foo(_) {}
-  ///     }
-  ///     m() { C.foo = rhs; }
-  ///
-  R visitStaticSetterSet(SendSet node, SetterElement setter, Node rhs, A arg);
-
-  /// Assignment of [rhs] to the static [getter].
-  ///
-  /// For instance:
-  ///
-  ///     class C {
-  ///       static get foo => null;
-  ///     }
-  ///     m() { C.foo = rhs; }
-  ///
-  R visitStaticGetterSet(SendSet node, GetterElement getter, Node rhs, A arg);
-
-  /// Invocation of the static [getter] with [arguments].
-  ///
-  /// For instance:
-  ///
-  ///     class C {
-  ///       static get foo => null;
-  ///     }
-  ///     m() { C.foo(null, 42; }
-  ///
-  R visitStaticGetterInvoke(Send node, GetterElement getter, NodeList arguments,
-      CallStructure callStructure, A arg);
-
-  /// Invocation of the static [setter] with [arguments].
-  ///
-  /// For instance:
-  ///
-  ///     class C {
-  ///       static set foo(_) {}
-  ///     }
-  ///     m() { C.foo(null, 42; }
-  ///
-  R visitStaticSetterInvoke(Send node, SetterElement setter, NodeList arguments,
-      CallStructure callStructure, A arg);
-
-  /// Read of the top level [field].
-  ///
-  /// For instance:
-  ///
-  ///     var foo;
-  ///     m() => foo;
-  ///
-  R visitTopLevelFieldGet(Send node, FieldElement field, A arg);
-
-  /// Assignment of [rhs] to the top level [field].
-  ///
-  /// For instance:
-  ///
-  ///     var foo;
-  ///     m() { foo = rhs; }
-  ///
-  R visitTopLevelFieldSet(SendSet node, FieldElement field, Node rhs, A arg);
-
-  /// Assignment of [rhs] to the final top level [field].
-  ///
-  /// For instance:
-  ///
-  ///     final foo = null;
-  ///     m() { foo = rhs; }
-  ///
-  R visitFinalTopLevelFieldSet(
-      SendSet node, FieldElement field, Node rhs, A arg);
-
-  /// Invocation of the top level [field] with [arguments].
-  ///
-  /// For instance:
-  ///
-  ///     var foo;
-  ///     m() { foo(null, 42); }
-  ///
-  R visitTopLevelFieldInvoke(Send node, FieldElement field, NodeList arguments,
-      CallStructure callStructure, A arg);
-
-  /// Closurization of the top level [function].
-  ///
-  /// For instance:
-  ///
-  ///     foo(a, b) {};
-  ///     m() => foo;
-  ///
-  R visitTopLevelFunctionGet(Send node, MethodElement function, A arg);
-
-  /// Invocation of the top level [function] with [arguments].
-  ///
-  /// For instance:
-  ///
-  ///     foo(a, b) {};
-  ///     m() { foo(null, 42); }
-  ///
-  R visitTopLevelFunctionInvoke(Send node, MethodElement function,
-      NodeList arguments, CallStructure callStructure, A arg);
-
-  /// Invocation of the top level [function] with incompatible [arguments].
-  ///
-  /// For instance:
-  ///
-  ///     class C {
-  ///       static foo(a, b) {}
-  ///     }
-  ///     m() { C.foo(null); }
-  ///
-  R visitTopLevelFunctionIncompatibleInvoke(Send node, MethodElement function,
-      NodeList arguments, CallStructure callStructure, A arg);
-
-  /// Assignment of [rhs] to the top level [function].
-  ///
-  /// For instance:
-  ///
-  ///     foo(a, b) {};
-  ///     m() { foo = rhs; }
-  ///
-  R visitTopLevelFunctionSet(
-      SendSet node, MethodElement function, Node rhs, A arg);
-
-  /// Getter call to the top level [getter].
-  ///
-  /// For instance:
-  ///
-  ///     get foo => null;
-  ///     m() => foo;
-  ///
-  R visitTopLevelGetterGet(Send node, GetterElement getter, A arg);
-
-  /// Getter call the top level [setter].
-  ///
-  /// For instance:
-  ///
-  ///     set foo(_) {}
-  ///     m() => foo;
-  ///
-  R visitTopLevelSetterGet(Send node, SetterElement setter, A arg);
-
-  /// Setter call to the top level [setter].
-  ///
-  /// For instance:
-  ///
-  ///     set foo(_) {}
-  ///     m() { foo = rhs; }
-  ///
-  R visitTopLevelSetterSet(SendSet node, SetterElement setter, Node rhs, A arg);
-
-  /// Assignment of [rhs] to the top level [getter].
-  ///
-  /// For instance:
-  ///
-  ///     get foo => null;
-  ///     m() { foo = rhs; }
-  ///
-  R visitTopLevelGetterSet(SendSet node, GetterElement getter, Node rhs, A arg);
-
-  /// Invocation of the top level [getter] with [arguments].
-  ///
-  /// For instance:
-  ///
-  ///     get foo => null;
-  ///     m() { foo(null, 42); }
-  ///
-  R visitTopLevelGetterInvoke(Send node, GetterElement getter,
-      NodeList arguments, CallStructure callStructure, A arg);
-
-  /// Invocation of the top level [setter] with [arguments].
-  ///
-  /// For instance:
-  ///
-  ///     set foo(_) {};
-  ///     m() { foo(null, 42); }
-  ///
-  R visitTopLevelSetterInvoke(Send node, SetterElement setter,
-      NodeList arguments, CallStructure callStructure, A arg);
-
-  /// Read of the type literal for class [element].
-  ///
-  /// For instance:
-  ///
-  ///     class C {}
-  ///     m() => C;
-  ///
-  R visitClassTypeLiteralGet(Send node, ConstantExpression constant, A arg);
-
-  /// Invocation of the type literal for class [element] with [arguments].
-  ///
-  /// For instance:
-  ///
-  ///     class C {}
-  ///     m() => C(null, 42);
-  ///
-  R visitClassTypeLiteralInvoke(Send node, ConstantExpression constant,
-      NodeList arguments, CallStructure callStructure, A arg);
-
-  /// Assignment of [rhs] to the type literal for class [element].
-  ///
-  /// For instance:
-  ///
-  ///     class C {}
-  ///     m() { C = rhs; }
-  ///
-  R visitClassTypeLiteralSet(
-      SendSet node, TypeConstantExpression constant, Node rhs, A arg);
-
-  /// Read of the type literal for typedef [element].
-  ///
-  /// For instance:
-  ///
-  ///     typedef F();
-  ///     m() => F;
-  ///
-  R visitTypedefTypeLiteralGet(Send node, ConstantExpression constant, A arg);
-
-  /// Invocation of the type literal for typedef [element] with [arguments].
-  ///
-  /// For instance:
-  ///
-  ///     typedef F();
-  ///     m() => F(null, 42);
-  ///
-  R visitTypedefTypeLiteralInvoke(Send node, ConstantExpression constant,
-      NodeList arguments, CallStructure callStructure, A arg);
-
-  /// Assignment of [rhs] to the type literal for typedef [element].
-  ///
-  /// For instance:
-  ///
-  ///     typedef F();
-  ///     m() { F = rhs; }
-  ///
-  R visitTypedefTypeLiteralSet(
-      SendSet node, TypeConstantExpression constant, Node rhs, A arg);
-
-  /// Read of the type literal for type variable [element].
-  ///
-  /// For instance:
-  ///
-  ///     class C<T> {
-  ///       m() => T;
-  ///     }
-  ///
-  R visitTypeVariableTypeLiteralGet(
-      Send node, TypeVariableElement element, A arg);
-
-  /// Invocation of the type literal for type variable [element] with
-  /// [arguments].
-  ///
-  /// For instance:
-  ///
-  ///     class C<T> {
-  ///       m() { T(null, 42); }
-  ///     }
-  ///
-  R visitTypeVariableTypeLiteralInvoke(Send node, TypeVariableElement element,
-      NodeList arguments, CallStructure callStructure, A arg);
-
-  /// Assignment of [rhs] to the type literal for type variable [element].
-  ///
-  /// For instance:
-  ///
-  ///     class C<T> {
-  ///       m() { T = rhs; }
-  ///     }
-  ///
-  R visitTypeVariableTypeLiteralSet(
-      SendSet node, TypeVariableElement element, Node rhs, A arg);
-
-  /// Read of the type literal for `dynamic`.
-  ///
-  /// For instance:
-  ///
-  ///     m() => dynamic;
-  ///
-  R visitDynamicTypeLiteralGet(Send node, ConstantExpression constant, A arg);
-
-  /// Invocation of the type literal for `dynamic` with [arguments].
-  ///
-  /// For instance:
-  ///
-  ///     m() { dynamic(null, 42); }
-  ///
-  R visitDynamicTypeLiteralInvoke(Send node, ConstantExpression constant,
-      NodeList arguments, CallStructure callStructure, A arg);
-
-  /// Assignment of [rhs] to the type literal for `dynamic`.
-  ///
-  /// For instance:
-  ///
-  ///     m() { dynamic = rhs; }
-  ///
-  R visitDynamicTypeLiteralSet(
-      SendSet node, TypeConstantExpression constant, Node rhs, A arg);
-
-  /// Binary expression `left operator right` where [operator] is a user
-  /// definable operator. Binary expressions using operator `==` are handled
-  /// by [visitEquals] and index operations `a[b]` are handled by [visitIndex].
-  ///
-  /// For instance:
-  ///
-  ///     add(a, b) => a + b;
-  ///     sub(a, b) => a - b;
-  ///     mul(a, b) => a * b;
-  ///
-  R visitBinary(
-      Send node, Node left, BinaryOperator operator, Node right, A arg);
-
-  /// Binary expression `super operator argument` where [operator] is a user
-  /// definable operator implemented on a superclass by [function]. Binary
-  /// expressions using operator `==` are handled by [visitSuperEquals].
-  ///
-  /// For instance:
-  ///
-  ///     class B {
-  ///       operator +(_) => null;
-  ///     }
-  ///     class C extends B {
-  ///       m(a) => super + a;
-  ///     }
-  ///
-  R visitSuperBinary(Send node, MethodElement function, BinaryOperator operator,
-      Node argument, A arg);
-
-  /// Binary operation on the unresolved super [element].
-  ///
-  /// For instance:
-  ///
-  ///     class B {
-  ///     }
-  ///     class C extends B {
-  ///       m() => super + 42;
-  ///     }
-  ///
-  R visitUnresolvedSuperBinary(Send node, Element element,
-      BinaryOperator operator, Node argument, A arg);
-
-  /// Index expression `receiver[index]`.
-  ///
-  /// For instance:
-  ///
-  ///     lookup(a, b) => a[b];
-  ///
-  R visitIndex(Send node, Node receiver, Node index, A arg);
-
-  /// Prefix operation on an index expression `operator receiver[index]` where
-  /// the operation is defined by [operator].
-  ///
-  /// For instance:
-  ///
-  ///     lookup(a, b) => --a[b];
-  ///
-  R visitIndexPrefix(
-      Send node, Node receiver, Node index, IncDecOperator operator, A arg);
-
-  /// Postfix operation on an index expression `receiver[index] operator` where
-  /// the operation is defined by [operator].
-  ///
-  /// For instance:
-  ///
-  ///     lookup(a, b) => a[b]++;
-  ///
-  R visitIndexPostfix(
-      Send node, Node receiver, Node index, IncDecOperator operator, A arg);
-
-  /// Index expression `super[index]` where 'operator []' is implemented on a
-  /// superclass by [function].
-  ///
-  /// For instance:
-  ///
-  ///     class B {
-  ///       operator [](_) => null;
-  ///     }
-  ///     class C extends B {
-  ///       m(a) => super[a];
-  ///     }
-  ///
-  R visitSuperIndex(Send node, MethodElement function, Node index, A arg);
-
-  /// Index expression `super[index]` where 'operator []' is unresolved.
-  ///
-  /// For instance:
-  ///
-  ///     class B {}
-  ///     class C extends B {
-  ///       m(a) => super[a];
-  ///     }
-  ///
-  R visitUnresolvedSuperIndex(Send node, Element element, Node index, A arg);
-
-  /// Prefix operation on an index expression `operator super[index]` where
-  /// 'operator []' is implemented on a superclass by [indexFunction] and
-  /// 'operator []=' is implemented on by [indexSetFunction] and the operation
-  /// is defined by [operator].
-  ///
-  /// For instance:
-  ///
-  ///     class B {
-  ///       operator [](_) => null;
-  ///       operator []=(a, b) {}
-  ///     }
-  ///     class C extends B {
-  ///       m(a) => --super[a];
-  ///     }
-  ///
-  R visitSuperIndexPrefix(
-      Send node,
-      MethodElement indexFunction,
-      MethodElement indexSetFunction,
-      Node index,
-      IncDecOperator operator,
-      A arg);
-
-  /// Postfix operation on an index expression `super[index] operator` where
-  /// 'operator []' is implemented on a superclass by [indexFunction] and
-  /// 'operator []=' is implemented on by [indexSetFunction] and the operation
-  /// is defined by [operator].
-  ///
-  /// For instance:
-  ///
-  ///     class B {
-  ///       operator [](_) => null;
-  ///       operator []=(a, b) {}
-  ///     }
-  ///     class C extends B {
-  ///       m(a) => super[a]++;
-  ///     }
-  ///
-  R visitSuperIndexPostfix(
-      Send node,
-      MethodElement indexFunction,
-      MethodElement indexSetFunction,
-      Node index,
-      IncDecOperator operator,
-      A arg);
-
-  /// Prefix operation on an index expression `operator super[index]` where
-  /// 'operator []' is unresolved, 'operator []=' is defined by [setter], and
-  /// the operation is defined by [operator].
-  ///
-  /// For instance:
-  ///
-  ///     class B {
-  ///       operator []=(a, b) {}
-  ///     }
-  ///     class C extends B {
-  ///       m(a) => --super[a];
-  ///     }
-  ///
-  R visitUnresolvedSuperGetterIndexPrefix(SendSet node, Element element,
-      MethodElement setter, Node index, IncDecOperator operator, A arg);
-
-  /// Postfix operation on an index expression `super[index] operator` where
-  /// 'operator []' is unresolved, 'operator []=' is defined by [setter], and
-  /// the operation is defined by [operator].
-  ///
-  /// For instance:
-  ///
-  ///     class B {
-  ///       operator []=(a, b) {}
-  ///     }
-  ///     class C extends B {
-  ///       m(a) => super[a]++;
-  ///     }
-  ///
-  R visitUnresolvedSuperGetterIndexPostfix(SendSet node, Element element,
-      MethodElement setter, Node index, IncDecOperator operator, A arg);
-
-  /// Prefix operation on an index expression `operator super[index]` where
-  /// 'operator []' is implemented on a superclass by [indexFunction] and
-  /// 'operator []=' is unresolved and the operation is defined by [operator].
-  ///
-  /// For instance:
-  ///
-  ///     class B {
-  ///       operator [](_) => 42;
-  ///     }
-  ///     class C extends B {
-  ///       m(a) => --super[a];
-  ///     }
-  ///
-  R visitUnresolvedSuperSetterIndexPrefix(
-      SendSet node,
-      MethodElement indexFunction,
-      Element element,
-      Node index,
-      IncDecOperator operator,
-      A arg);
-
-  /// Postfix operation on an index expression `super[index] operator` where
-  /// 'operator []' is implemented on a superclass by [indexFunction] and
-  /// 'operator []=' is unresolved and the operation is defined by [operator].
-  ///
-  /// For instance:
-  ///
-  ///     class B {
-  ///       operator [](_) => 42;
-  ///     }
-  ///     class C extends B {
-  ///       m(a) => super[a]++;
-  ///     }
-  ///
-  R visitUnresolvedSuperSetterIndexPostfix(
-      SendSet node,
-      MethodElement indexFunction,
-      Element element,
-      Node index,
-      IncDecOperator operator,
-      A arg);
-
-  /// Prefix operation on an index expression `super[index] operator` where
-  /// both 'operator []' and 'operator []=' are unresolved and the operation is
-  /// defined by [operator].
-  ///
-  /// For instance:
-  ///
-  ///     class B {
-  ///       operator [](_) => 42;
-  ///     }
-  ///     class C extends B {
-  ///       m(a) => super[a]++;
-  ///     }
-  ///
-  R visitUnresolvedSuperIndexPrefix(
-      Send node, Element element, Node index, IncDecOperator operator, A arg);
-
-  /// Postfix operation on an index expression `super[index] operator` where
-  /// both 'operator []' and 'operator []=' are unresolved and the operation is
-  /// defined by [operator].
-  ///
-  /// For instance:
-  ///
-  ///     class B {
-  ///       operator [](_) => 42;
-  ///     }
-  ///     class C extends B {
-  ///       m(a) => super[a]++;
-  ///     }
-  ///
-  R visitUnresolvedSuperIndexPostfix(
-      Send node, Element element, Node index, IncDecOperator operator, A arg);
-
-  /// Binary expression `left == right`.
-  ///
-  /// For instance:
-  ///
-  ///     neq(a, b) => a != b;
-  ///
-  R visitNotEquals(Send node, Node left, Node right, A arg);
-
-  /// Binary expression `super != argument` where `==` is implemented on a
-  /// superclass by [function].
-  ///
-  /// For instance:
-  ///
-  ///     class B {
-  ///       operator +(_) => null;
-  ///     }
-  ///     class C extends B {
-  ///       m(a) => super + a;
-  ///     }
-  ///
-  R visitSuperNotEquals(
-      Send node, MethodElement function, Node argument, A arg);
-
-  /// Binary expression `left == right`.
-  ///
-  /// For instance:
-  ///
-  ///     eq(a, b) => a == b;
-  ///
-  R visitEquals(Send node, Node left, Node right, A arg);
-
-  /// Binary expression `super == argument` where `==` is implemented on a
-  /// superclass by [function].
-  ///
-  /// For instance:
-  ///
-  ///     class B {
-  ///       operator ==(_) => null;
-  ///     }
-  ///     class C extends B {
-  ///       m(a) => super == a;
-  ///     }
-  ///
-  R visitSuperEquals(Send node, MethodElement function, Node argument, A arg);
-
-  /// Unary expression `operator expression` where [operator] is a user
-  /// definable operator.
-  ///
-  /// For instance:
-  ///
-  ///     neg(a, b) => -a;
-  ///     comp(a, b) => ~a;
-  ///
-  R visitUnary(Send node, UnaryOperator operator, Node expression, A arg);
-
-  /// Unary expression `operator super` where [operator] is a user definable
-  /// operator implemented on a superclass by [function].
-  ///
-  /// For instance:
-  ///
-  ///     class B {
-  ///       operator -() => null;
-  ///     }
-  ///     class C extends B {
-  ///       m(a) => -super;
-  ///     }
-  ///
-  R visitSuperUnary(
-      Send node, UnaryOperator operator, MethodElement function, A arg);
-
-  /// Unary operation on the unresolved super [element].
-  ///
-  /// For instance:
-  ///
-  ///     class B {
-  ///     }
-  ///     class C extends B {
-  ///       m() => -super;
-  ///     }
-  ///
-  R visitUnresolvedSuperUnary(
-      Send node, UnaryOperator operator, Element element, A arg);
-
-  /// Unary expression `!expression`.
-  ///
-  /// For instance:
-  ///
-  ///     not(a) => !a;
-  ///
-  R visitNot(Send node, Node expression, A arg);
-
-  /// Index set expression `receiver[index] = rhs`.
-  ///
-  /// For instance:
-  ///
-  ///     m(receiver, index, rhs) => receiver[index] = rhs;
-  ///
-  R visitIndexSet(SendSet node, Node receiver, Node index, Node rhs, A arg);
-
-  /// Index set expression `super[index] = rhs` where `operator []=` is defined
-  /// on a superclass by [function].
-  ///
-  /// For instance:
-  ///
-  ///     class B {
-  ///       operator []=(a, b) {}
-  ///     }
-  ///     class C extends B {
-  ///       m(a, b) => super[a] = b;
-  ///     }
-  ///
-  R visitSuperIndexSet(
-      SendSet node, FunctionElement function, Node index, Node rhs, A arg);
-
-  /// Index set expression `super[index] = rhs` where `operator []=` is
-  /// undefined.
-  ///
-  /// For instance:
-  ///
-  ///     class B {
-  ///     }
-  ///     class C extends B {
-  ///       m() => super[1] = 42;
-  ///     }
-  ///
-  R visitUnresolvedSuperIndexSet(
-      SendSet node, ErroneousElement element, Node index, Node rhs, A arg);
-
-  /// If-null, ??, expression with operands [left] and [right].
-  ///
-  /// For instance:
-  ///
-  ///     m() => left ?? right;
-  ///
-  R visitIfNull(Send node, Node left, Node right, A arg);
-
-  /// Logical and, &&, expression with operands [left] and [right].
-  ///
-  /// For instance:
-  ///
-  ///     m() => left && right;
-  ///
-  R visitLogicalAnd(Send node, Node left, Node right, A arg);
-
-  /// Logical or, ||, expression with operands [left] and [right].
-  ///
-  /// For instance:
-  ///
-  ///     m() => left || right;
-  ///
-  R visitLogicalOr(Send node, Node left, Node right, A arg);
-
-  /// Is test of [expression] against [type].
-  ///
-  /// For instance:
-  ///
-  ///     class C {}
-  ///     m() => expression is C;
-  ///
-  R visitIs(Send node, Node expression, ResolutionDartType type, A arg);
-
-  /// Is not test of [expression] against [type].
-  ///
-  /// For instance:
-  ///
-  ///     class C {}
-  ///     m() => expression is! C;
-  ///
-  R visitIsNot(Send node, Node expression, ResolutionDartType type, A arg);
-
-  /// As cast of [expression] to [type].
-  ///
-  /// For instance:
-  ///
-  ///     class C {}
-  ///     m() => expression as C;
-  ///
-  R visitAs(Send node, Node expression, ResolutionDartType type, A arg);
-
-  /// Compound assignment expression of [rhs] with [operator] of the property on
-  /// [receiver] whose getter and setter are defined by [getterSelector] and
-  /// [setterSelector], respectively.
-  ///
-  /// For instance:
-  ///
-  ///     m(receiver, rhs) => receiver.foo += rhs;
-  ///
-  R visitDynamicPropertyCompound(Send node, Node receiver, Name name,
-      AssignmentOperator operator, Node rhs, A arg);
-
-  /// Compound assignment expression of [rhs] with [operator] of the property on
-  /// a possibly null [receiver] whose getter and setter are defined by
-  /// [getterSelector] and [setterSelector], respectively.
-  ///
-  /// For instance:
-  ///
-  ///     m(receiver, rhs) => receiver?.foo += rhs;
-  ///
-  R visitIfNotNullDynamicPropertyCompound(Send node, Node receiver, Name name,
-      AssignmentOperator operator, Node rhs, A arg);
-
-  /// Compound assignment expression of [rhs] with [operator] of the property on
-  /// `this` whose getter and setter are defined by [getterSelector] and
-  /// [setterSelector], respectively.
-  ///
-  /// For instance:
-  ///
-  ///     class C {
-  ///       m(rhs) => this.foo += rhs;
-  ///     }
-  ///
-  /// or
-  ///
-  ///     class C {
-  ///       m(rhs) => foo += rhs;
-  ///     }
-  ///
-  R visitThisPropertyCompound(
-      Send node, Name name, AssignmentOperator operator, Node rhs, A arg);
-
-  /// Compound assignment expression of [rhs] with [operator] on a [parameter].
-  ///
-  /// For instance:
-  ///
-  ///     m(parameter, rhs) => parameter += rhs;
-  ///
-  R visitParameterCompound(Send node, ParameterElement parameter,
-      AssignmentOperator operator, Node rhs, A arg);
-
-  /// Compound assignment expression of [rhs] with [operator] on a final
-  /// [parameter].
-  ///
-  /// For instance:
-  ///
-  ///     m(final parameter, rhs) => parameter += rhs;
-  ///
-  R visitFinalParameterCompound(Send node, ParameterElement parameter,
-      AssignmentOperator operator, Node rhs, A arg);
-
-  /// Compound assignment expression of [rhs] with [operator] on a local
-  /// [variable].
-  ///
-  /// For instance:
-  ///
-  ///     m(rhs) {
-  ///       var variable;
-  ///       variable += rhs;
-  ///     }
-  ///
-  R visitLocalVariableCompound(Send node, LocalVariableElement variable,
-      AssignmentOperator operator, Node rhs, A arg);
-
-  /// Compound assignment expression of [rhs] with [operator] on a final local
-  /// [variable].
-  ///
-  /// For instance:
-  ///
-  ///     m(rhs) {
-  ///       final variable = 0;
-  ///       variable += rhs;
-  ///     }
-  ///
-  R visitFinalLocalVariableCompound(Send node, LocalVariableElement variable,
-      AssignmentOperator operator, Node rhs, A arg);
-
-  /// Compound assignment expression of [rhs] with [operator] on a local
-  /// [function].
-  ///
-  /// For instance:
-  ///
-  ///     m(rhs) {
-  ///       function() {}
-  ///       function += rhs;
-  ///     }
-  ///
-  R visitLocalFunctionCompound(Send node, LocalFunctionElement function,
-      AssignmentOperator operator, Node rhs, A arg);
-
-  /// Compound assignment expression of [rhs] with [operator] on a static
-  /// [field].
-  ///
-  /// For instance:
-  ///
-  ///     class C {
-  ///       static var field;
-  ///       m(rhs) => field += rhs;
-  ///     }
-  ///
-  R visitStaticFieldCompound(Send node, FieldElement field,
-      AssignmentOperator operator, Node rhs, A arg);
-
-  /// Compound assignment expression of [rhs] with [operator] on a final static
-  /// [field].
-  ///
-  /// For instance:
-  ///
-  ///     class C {
-  ///       static final field = 0;
-  ///       m(rhs) => field += rhs;
-  ///     }
-  ///
-  R visitFinalStaticFieldCompound(Send node, FieldElement field,
-      AssignmentOperator operator, Node rhs, A arg);
-
-  /// Compound assignment expression of [rhs] with [operator] reading from a
-  /// static [getter] and writing to a static [setter].
-  ///
-  /// For instance:
-  ///
-  ///     class C {
-  ///       static get o => 0;
-  ///       static set o(_) {}
-  ///       m(rhs) => o += rhs;
-  ///     }
-  ///
-  R visitStaticGetterSetterCompound(Send node, GetterElement getter,
-      SetterElement setter, AssignmentOperator operator, Node rhs, A arg);
-
-  /// Compound assignment expression of [rhs] with [operator] reading from a
-  /// static [method], that is, closurizing [method], and writing to a static
-  /// [setter].
-  ///
-  /// For instance:
-  ///
-  ///     class C {
-  ///       static o() {}
-  ///       static set o(_) {}
-  ///       m(rhs) => o += rhs;
-  ///     }
-  ///
-  R visitStaticMethodSetterCompound(Send node, MethodElement method,
-      SetterElement setter, AssignmentOperator operator, Node rhs, A arg);
-
-  /// Compound assignment expression of [rhs] with [operator] on a top level
-  /// [field].
-  ///
-  /// For instance:
-  ///
-  ///     var field;
-  ///     m(rhs) => field += rhs;
-  ///
-  R visitTopLevelFieldCompound(Send node, FieldElement field,
-      AssignmentOperator operator, Node rhs, A arg);
-
-  /// Compound assignment expression of [rhs] with [operator] on a final top
-  /// level [field].
-  ///
-  /// For instance:
-  ///
-  ///     final field = 0;
-  ///     m(rhs) => field += rhs;
-  ///
-  R visitFinalTopLevelFieldCompound(Send node, FieldElement field,
-      AssignmentOperator operator, Node rhs, A arg);
-
-  /// Compound assignment expression of [rhs] with [operator] reading from a
-  /// top level [getter] and writing to a top level [setter].
-  ///
-  /// For instance:
-  ///
-  ///     get o => 0;
-  ///     set o(_) {}
-  ///     m(rhs) => o += rhs;
-  ///
-  R visitTopLevelGetterSetterCompound(Send node, GetterElement getter,
-      SetterElement setter, AssignmentOperator operator, Node rhs, A arg);
-
-  /// Compound assignment expression of [rhs] with [operator] reading from a
-  /// top level [method], that is, closurizing [method], and writing to a top
-  /// level [setter].
-  ///
-  /// For instance:
-  ///
-  ///     o() {}
-  ///     set o(_) {}
-  ///     m(rhs) => o += rhs;
-  ///
-  R visitTopLevelMethodSetterCompound(Send node, FunctionElement method,
-      SetterElement setter, AssignmentOperator operator, Node rhs, A arg);
-
-  /// Compound assignment expression of [rhs] with [operator] reading from a
-  /// top level [method], that is, closurizing [method], and writing to an
-  /// unresolved setter.
-  ///
-  /// For instance:
-  ///
-  ///     o() {}
-  ///     m(rhs) => o += rhs;
-  ///
-  R visitTopLevelMethodCompound(Send node, MethodElement method,
-      AssignmentOperator operator, Node rhs, A arg);
-
-  /// Compound assignment expression of [rhs] with [operator] on a super
-  /// [field].
-  ///
-  /// For instance:
-  ///
-  ///     class B {
-  ///       var field;
-  ///     }
-  ///     class C extends B {
-  ///       m(rhs) => super.field += rhs;
-  ///     }
-  ///
-  R visitSuperFieldCompound(Send node, FieldElement field,
-      AssignmentOperator operator, Node rhs, A arg);
-
-  /// Compound assignment expression of [rhs] with [operator] on a final super
-  /// [field].
-  ///
-  /// For instance:
-  ///
-  ///     class B {
-  ///       final field = 42;
-  ///     }
-  ///     class C extends B {
-  ///       m(rhs) => super.field += rhs;
-  ///     }
-  ///
-  R visitFinalSuperFieldCompound(Send node, FieldElement field,
-      AssignmentOperator operator, Node rhs, A arg);
-
-  /// If-null assignment expression of [rhs] to the [name] property on
-  /// [receiver]. That is, [rhs] is only evaluated and assigned, if the value
-  /// of [name] on [receiver] is `null`.
-  ///
-  /// For instance:
-  ///
-  ///     m(receiver, rhs) => receiver.foo ??= rhs;
-  ///
-  R visitDynamicPropertySetIfNull(
-      Send node, Node receiver, Name name, Node rhs, A arg);
-
-  /// If-null assignment expression of [rhs] to the [name] property on
-  /// [receiver] if not null. That is, [rhs] is only evaluated and assigned,
-  /// if the value of [receiver] is _not_ `null` and the value of [name] on
-  /// [receiver] is `null`.
-  ///
-  /// For instance:
-  ///
-  ///     m(receiver, rhs) => receiver?.foo ??= rhs;
-  ///
-  R visitIfNotNullDynamicPropertySetIfNull(
-      Send node, Node receiver, Name name, Node rhs, A arg);
-
-  /// If-null assignment expression of [rhs] to the [name] property on `this`.
-  /// That is, [rhs] is only evaluated and assigned, if the value of [name] on
-  /// `this` is `null`.
-  ///
-  /// For instance:
-  ///
-  ///     class C {
-  ///       m(rhs) => this.foo ??= rhs;
-  ///     }
-  ///
-  /// or
-  ///
-  ///     class C {
-  ///       m(rhs) => foo ??= rhs;
-  ///     }
-  ///
-  R visitThisPropertySetIfNull(Send node, Name name, Node rhs, A arg);
-
-  /// If-null assignment expression of [rhs] to [parameter]. That is, [rhs] is
-  /// only evaluated and assigned, if the value of the [parameter] is `null`.
-  ///
-  /// For instance:
-  ///
-  ///     m(parameter, rhs) => parameter ??= rhs;
-  ///
-  R visitParameterSetIfNull(
-      Send node, ParameterElement parameter, Node rhs, A arg);
-
-  /// If-null assignment expression of [rhs] to the final [parameter]. That is,
-  /// [rhs] is only evaluated and assigned, if the value of the [parameter] is
-  /// `null`.
-  ///
-  /// For instance:
-  ///
-  ///     m(final parameter, rhs) => parameter ??= rhs;
-  ///
-  R visitFinalParameterSetIfNull(
-      Send node, ParameterElement parameter, Node rhs, A arg);
-
-  /// If-null assignment expression of [rhs] to the local [variable]. That is,
-  /// [rhs] is only evaluated and assigned, if the value of the [variable] is
-  /// `null`.
-  ///
-  /// For instance:
-  ///
-  ///     m(rhs) {
-  ///       var variable;
-  ///       variable ??= rhs;
-  ///     }
-  ///
-  R visitLocalVariableSetIfNull(
-      Send node, LocalVariableElement variable, Node rhs, A arg);
-
-  /// If-null assignment expression of [rhs] to the final local [variable]. That
-  /// is, [rhs] is only evaluated and assigned, if the value of the [variable]
-  /// is `null`.
-  ///
-  /// For instance:
-  ///
-  ///     m(rhs) {
-  ///       final variable = 0;
-  ///       variable ??= rhs;
-  ///     }
-  ///
-  R visitFinalLocalVariableSetIfNull(
-      Send node, LocalVariableElement variable, Node rhs, A arg);
-
-  /// If-null assignment expression of [rhs] to the local [function]. That is,
-  /// [rhs] is only evaluated and assigned, if the value of the [function] is
-  /// `null`. The behavior is thus equivalent to a closurization of [function].
-  ///
-  /// For instance:
-  ///
-  ///     m(rhs) {
-  ///       function() {}
-  ///       function ??= rhs;
-  ///     }
-  ///
-  R visitLocalFunctionSetIfNull(
-      Send node, LocalFunctionElement function, Node rhs, A arg);
-
-  /// If-null assignment expression of [rhs] to the static [field]. That is,
-  /// [rhs] is only evaluated and assigned, if the value of the [field] is
-  /// `null`.
-  ///
-  /// For instance:
-  ///
-  ///     class C {
-  ///       static var field;
-  ///       m(rhs) => field ??= rhs;
-  ///     }
-  ///
-  R visitStaticFieldSetIfNull(Send node, FieldElement field, Node rhs, A arg);
-
-  /// If-null assignment expression of [rhs] to the final static [field]. That
-  /// is, [rhs] is only evaluated and assigned, if the value of the [field] is
-  /// `null`.
-  ///
-  /// For instance:
-  ///
-  ///     class C {
-  ///       static final field = 0;
-  ///       m(rhs) => field ??= rhs;
-  ///     }
-  ///
-  R visitFinalStaticFieldSetIfNull(
-      Send node, FieldElement field, Node rhs, A arg);
-
-  /// If-null assignment expression of [rhs] to the static property defined by
-  /// [getter] and [setter]. That is, [rhs] is only evaluated and assigned to
-  /// the [setter], if the value of the [getter] is `null`.
-  ///
-  /// For instance:
-  ///
-  ///     class C {
-  ///       static get o => 0;
-  ///       static set o(_) {}
-  ///       m(rhs) => o ??= rhs;
-  ///     }
-  ///
-  R visitStaticGetterSetterSetIfNull(
-      Send node, GetterElement getter, SetterElement setter, Node rhs, A arg);
-
-  /// If-null assignment expression of [rhs] to the static property defined by
-  /// [method] and [setter]. That is, [rhs] is only evaluated and assigned to
-  /// the [setter], if the value of the [method] is `null`. The behavior is thus
-  /// equivalent to a closurization of [method].
-  ///
-  /// For instance:
-  ///
-  ///     class C {
-  ///       static o() {}
-  ///       static set o(_) {}
-  ///       m(rhs) => o ??= rhs;
-  ///     }
-  ///
-  R visitStaticMethodSetterSetIfNull(
-      Send node, MethodElement method, SetterElement setter, Node rhs, A arg);
-
-  /// If-null assignment expression of [rhs] to the static [method]. That is,
-  /// [rhs] is only evaluated and assigned, if the value of the [method] is
-  /// `null`. The behavior is thus equivalent to a closurization of [method].
-  ///
-  /// For instance:
-  ///
-  ///     o() {}
-  ///     m(rhs) => o ??= rhs;
-  ///
-  R visitStaticMethodSetIfNull(
-      Send node, FunctionElement method, Node rhs, A arg);
-
-  /// If-null assignment expression of [rhs] to the top level [field]. That is,
-  /// [rhs] is only evaluated and assigned, if the value of the [field] is
-  /// `null`.
-  ///
-  /// For instance:
-  ///
-  ///     var field;
-  ///     m(rhs) => field ??= rhs;
-  ///
-  R visitTopLevelFieldSetIfNull(Send node, FieldElement field, Node rhs, A arg);
-
-  /// If-null assignment expression of [rhs] to the final top level [field].
-  /// That is, [rhs] is only evaluated and assigned, if the value of the [field]
-  /// is `null`.
-  ///
-  /// For instance:
-  ///
-  ///     final field = 0;
-  ///     m(rhs) => field ??= rhs;
-  ///
-  R visitFinalTopLevelFieldSetIfNull(
-      Send node, FieldElement field, Node rhs, A arg);
-
-  /// If-null assignment expression of [rhs] to the top level property defined
-  /// by [getter] and [setter]. That is, [rhs] is only evaluated and assigned to
-  /// the [setter], if the value of the [getter] is `null`.
-  ///
-  /// For instance:
-  ///
-  ///     get o => 0;
-  ///     set o(_) {}
-  ///     m(rhs) => o ??= rhs;
-  ///
-  R visitTopLevelGetterSetterSetIfNull(
-      Send node, GetterElement getter, SetterElement setter, Node rhs, A arg);
-
-  /// If-null assignment expression of [rhs] to the top level property defined
-  /// by [method] and [setter]. That is, [rhs] is only evaluated and assigned to
-  /// the [setter], if the value of the [method] is `null`. The behavior is thus
-  /// equivalent to a closurization of [method].
-  ///
-  /// For instance:
-  ///
-  ///     o() {}
-  ///     set o(_) {}
-  ///     m(rhs) => o ??= rhs;
-  ///
-  R visitTopLevelMethodSetterSetIfNull(
-      Send node, FunctionElement method, SetterElement setter, Node rhs, A arg);
-
-  /// If-null assignment expression of [rhs] to the top level [method]. That is,
-  /// [rhs] is only evaluated and assigned, if the value of the [method] is
-  /// `null`. The behavior is thus equivalent to a closurization of [method].
-  ///
-  /// For instance:
-  ///
-  ///     o() {}
-  ///     m(rhs) => o ??= rhs;
-  ///
-  R visitTopLevelMethodSetIfNull(
-      Send node, FunctionElement method, Node rhs, A arg);
-
-  /// If-null assignment expression of [rhs] to the super [field]. That is,
-  /// [rhs] is only evaluated and assigned, if the value of the [field] is
-  /// `null`.
-  ///
-  /// For instance:
-  ///
-  ///     class B {
-  ///       var field;
-  ///     }
-  ///     class C extends B {
-  ///       m(rhs) => super.field ??= rhs;
-  ///     }
-  ///
-  R visitSuperFieldSetIfNull(Send node, FieldElement field, Node rhs, A arg);
-
-  /// If-null assignment expression of [rhs] to the final super [field]. That
-  /// is, [rhs] is only evaluated and assigned, if the value of the [field] is
-  /// `null`.
-  ///
-  /// For instance:
-  ///
-  ///     class B {
-  ///       final field = 42;
-  ///     }
-  ///     class C extends B {
-  ///       m(rhs) => super.field ??= rhs;
-  ///     }
-  ///
-  R visitFinalSuperFieldSetIfNull(
-      Send node, FieldElement field, Node rhs, A arg);
-
-  /// If-null assignment expression of [rhs] to the super property defined
-  /// by [readField] and [writtenField]. That is, [rhs] is only evaluated and
-  /// assigned to the [writtenField], if the value of the [readField] is `null`.
-  ///
-  /// For instance:
-  ///
-  ///     class A {
-  ///       var field;
-  ///     }
-  ///     class B extends A {
-  ///       final field;
-  ///     }
-  ///     class C extends B {
-  ///       m() => super.field ??= rhs;
-  ///     }
-  ///
-  R visitSuperFieldFieldSetIfNull(Send node, FieldElement readField,
-      FieldElement writtenField, Node rhs, A arg);
-
-  /// If-null assignment expression of [rhs] to the super property defined
-  /// by [getter] and [setter]. That is, [rhs] is only evaluated and assigned to
-  /// the [setter], if the value of the [getter] is `null`.
-  ///
-  /// For instance:
-  ///
-  ///     class B {
-  ///       get o => 0;
-  ///       set o(_) {}
-  ///     }
-  ///     class C extends B {
-  ///       m(rhs) => super.o ??= rhs;
-  ///     }
-  ///
-  R visitSuperGetterSetterSetIfNull(
-      Send node, GetterElement getter, SetterElement setter, Node rhs, A arg);
-
-  /// If-null assignment expression of [rhs] to the super property defined
-  /// by [method] and [setter]. That is, [rhs] is only evaluated and assigned to
-  /// the [setter], if the value of the [method] is `null`. The behavior is thus
-  /// equivalent to a closurization of [method].
-  ///
-  /// For instance:
-  ///
-  ///     class B {
-  ///       o() {}
-  ///       set o(_) {}
-  ///     }
-  ///     class C extends B {
-  ///       m(rhs) => super.o ??= rhs;
-  ///     }
-  ///
-  R visitSuperMethodSetterSetIfNull(
-      Send node, FunctionElement method, SetterElement setter, Node rhs, A arg);
-
-  /// If-null assignment expression of [rhs] to the super [method].
-  /// That is, [rhs] is only evaluated and assigned, if the value of
-  /// the [method] is `null`. The behavior is thus equivalent to a closurization
-  /// of [method].
-  ///
-  /// For instance:
-  ///
-  ///     class B {
-  ///       o() {}
-  ///     }
-  ///     class C extends B {
-  ///       m(rhs) => super.o ??= rhs;
-  ///     }
-  ///
-  R visitSuperMethodSetIfNull(
-      Send node, FunctionElement method, Node rhs, A arg);
-
-  /// If-null assignment expression of [rhs] to the super property defined
-  /// by [setter] with no corresponding getter. That is, [rhs] is only evaluated
-  /// and assigned to the [setter], if the value of the unresolved getter is
-  /// `null`. The behavior is thus equivalent to a no such method error.
-  ///
-  /// For instance:
-  ///
-  ///     class B {
-  ///       set o(_) {}
-  ///     }
-  ///     class C extends B {
-  ///       m(rhs) => super.o ??= rhs;
-  ///     }
-  ///
-  R visitUnresolvedSuperGetterSetIfNull(
-      Send node, Element element, SetterElement setter, Node rhs, A arg);
-
-  /// If-null assignment expression of [rhs] to the super property defined
-  /// by [getter] with no corresponding setter. That is, [rhs] is only evaluated
-  /// and assigned to the unresolved setter, if the value of the [getter] is
-  /// `null`.
-  ///
-  /// For instance:
-  ///
-  ///     class B {
-  ///       get o => 42;
-  ///     }
-  ///     class C extends B {
-  ///       m(rhs) => super.o ??= rhs;
-  ///     }
-  ///
-  R visitUnresolvedSuperSetterSetIfNull(
-      Send node, GetterElement getter, Element element, Node rhs, A arg);
-
-  /// If-null assignment expression of [rhs] to the top level property defined
-  /// by [field] and [setter]. That is, [rhs] is only evaluated and assigned to
-  /// the [setter], if the value of the [field] is `null`.
-  ///
-  /// For instance:
-  ///
-  ///     class A {
-  ///       var o;
-  ///     }
-  ///     class B extends A {
-  ///       set o(_) {}
-  ///     }
-  ///     class C extends B {
-  ///       m(rhs) => super.o ??= rhs;
-  ///     }
-  ///
-  R visitSuperFieldSetterSetIfNull(
-      Send node, FieldElement field, SetterElement setter, Node rhs, A arg);
-
-  /// If-null assignment expression of [rhs] to the top level property defined
-  /// by [getter] and [field]. That is, [rhs] is only evaluated and assigned to
-  /// the [field], if the value of the [getter] is `null`.
-  ///
-  /// For instance:
-  ///
-  ///     class A {
-  ///       var o;
-  ///     }
-  ///     class B extends A {
-  ///       get o => 0;
-  ///     }
-  ///     class C extends B {
-  ///       m(rhs) => super.o ??= rhs;
-  ///     }
-  ///
-  R visitSuperGetterFieldSetIfNull(
-      Send node, GetterElement getter, FieldElement field, Node rhs, A arg);
-
-  /// If-null assignment expression of [rhs] to an unresolved super property.
-  /// That is, [rhs] is only evaluated and assigned, if the value of the
-  /// unresolved property is `null`. The behavior is thus equivalent to a no
-  /// such method error.
-  ///
-  /// For instance:
-  ///
-  ///     class B {
-  ///     }
-  ///     class C extends B {
-  ///       m(rhs) => super.unresolved ??= rhs;
-  ///     }
-  ///
-  R visitUnresolvedSuperSetIfNull(Send node, Element element, Node rhs, A arg);
-
-  /// If-null assignment expression of [rhs] to the static property defined
-  /// by [setter] with no corresponding getter. That is, [rhs] is only evaluated
-  /// and assigned to the [setter], if the value of the unresolved
-  /// getter is `null`. The behavior is thus equivalent to a no such method
-  /// error.
-  ///
-  /// For instance:
-  ///
-  ///     class C {
-  ///       set foo(_) {}
-  ///     }
-  ///     m1() => C.foo ??= 42;
-  ///
-  R visitUnresolvedStaticGetterSetIfNull(
-      Send node, Element element, SetterElement setter, Node rhs, A arg);
-
-  /// If-null assignment expression of [rhs] to the top level property defined
-  /// by [setter] with no corresponding getter. That is, [rhs] is only evaluated
-  /// and assigned to the [setter], if the value of the unresolved getter is
-  /// `null`. The behavior is thus equivalent to a no such method error.
-  ///
-  /// For instance:
-  ///
-  ///     set foo(_) {}
-  ///     m1() => foo ??= 42;
-  ///
-  R visitUnresolvedTopLevelGetterSetIfNull(
-      Send node, Element element, SetterElement setter, Node rhs, A arg);
-
-  /// If-null assignment expression of [rhs] to the static property defined
-  /// by [getter] with no corresponding setter. That is, [rhs] is only evaluated
-  /// and assigned to the unresolved setter, if the value of the [getter] is
-  /// `null`.
-  ///
-  /// For instance:
-  ///
-  ///     class C {
-  ///       get foo => 42;
-  ///     }
-  ///     m1() => C.foo ??= 42;
-  ///
-  R visitUnresolvedStaticSetterSetIfNull(
-      Send node, GetterElement getter, Element element, Node rhs, A arg);
-
-  /// If-null assignment expression of [rhs] to the top level property defined
-  /// by [getter] with no corresponding setter. That is, [rhs] is only evaluated
-  /// and assigned to the unresolved setter, if the value of the [getter] is
-  /// `null`.
-  ///
-  /// For instance:
-  ///
-  ///     get foo => 42;
-  ///     m1() => foo ??= 42;
-  ///
-  R visitUnresolvedTopLevelSetterSetIfNull(
-      Send node, GetterElement getter, Element element, Node rhs, A arg);
-
-  /// If-null assignment expression of [rhs] to an unresolved property.
-  /// That is, [rhs] is only evaluated and assigned, if the value of the
-  /// unresolved property is `null`. The behavior is thus equivalent to a no
-  /// such method error.
-  ///
-  /// For instance:
-  ///
-  ///     class C {}
-  ///     m1() => unresolved ??= 42;
-  ///     m2() => C.unresolved ??= 42;
-  ///
-  // TODO(johnniwinther): Split the cases in which a prefix is resolved.
-  R visitUnresolvedSetIfNull(Send node, Element element, Node rhs, A arg);
-
-  /// If-null assignment expression of [rhs] to an invalid expression.
-  ///
-  /// For instance:
-  ///
-  ///     import 'foo.dart' as p;
-  ///
-  ///     m() => p ??= 42;
-  ///
-  R errorInvalidSetIfNull(Send node, ErroneousElement error, Node rhs, A arg);
-
-  /// If-null assignment expression of [rhs] to the class type literal
-  /// [constant]. That is, [rhs] is only evaluated and assigned, if the value
-  /// is of the [constant] is `null`. The behavior is thus equivalent to a type
-  /// literal access.
-  ///
-  /// For instance:
-  ///
-  ///     class C {}
-  ///     m(rhs) => C ??= rhs;
-  ///
-  R visitClassTypeLiteralSetIfNull(
-      Send node, ConstantExpression constant, Node rhs, A arg);
-
-  /// If-null assignment expression of [rhs] to the typedef type literal
-  /// [constant]. That is, [rhs] is only evaluated and assigned, if the value
-  /// is of the [constant] is `null`. The behavior is thus equivalent to a type
-  /// literal access.
-  ///
-  /// For instance:
-  ///
-  ///     typedef F();
-  ///     m(rhs) => F ??= rhs;
-  ///
-  R visitTypedefTypeLiteralSetIfNull(
-      Send node, ConstantExpression constant, Node rhs, A arg);
-
-  /// If-null assignment expression of [rhs] to the type literal for the type
-  /// variable [element]. That is, [rhs] is only evaluated and assigned, if
-  /// the value is of the [element] is `null`. The behavior is thus equivalent
-  /// to a type literal access.
-  ///
-  /// For instance:
-  ///
-  ///     class C<T> {
-  ///       m(rhs) => T ??= rhs;
-  ///     }
-  ///
-  R visitTypeVariableTypeLiteralSetIfNull(
-      Send node, TypeVariableElement element, Node rhs, A arg);
-
-  /// If-null assignment expression of [rhs] to the dynamic type literal
-  /// [constant]. That is, [rhs] is only evaluated and assigned, if the value
-  /// is of the [constant] is `null`. The behavior is thus equivalent to a type
-  /// literal access.
-  ///
-  /// For instance:
-  ///
-  ///     m(rhs) => dynamic ??= rhs;
-  ///
-  R visitDynamicTypeLiteralSetIfNull(
-      Send node, ConstantExpression constant, Node rhs, A arg);
-
-  /// Prefix expression with [operator] on a final super [field].
-  ///
-  /// For instance:
-  ///
-  ///     class B {
-  ///       final field = 42;
-  ///     }
-  ///     class C extends B {
-  ///       m(rhs) => ++super.field;
-  ///     }
-  ///
-  R visitFinalSuperFieldPrefix(
-      Send node, FieldElement field, IncDecOperator operator, A arg);
-
-  /// Prefix expression with [operator] on an unresolved super property.
-  ///
-  /// For instance:
-  ///
-  ///     class B {
-  ///     }
-  ///     class C extends B {
-  ///       m(rhs) => ++super.unresolved;
-  ///     }
-  ///
-  R visitUnresolvedSuperPrefix(
-      SendSet node, Element element, IncDecOperator operator, A arg);
-
-  /// Postfix expression with [operator] on an unresolved super property.
-  ///
-  /// For instance:
-  ///
-  ///     class B {
-  ///     }
-  ///     class C extends B {
-  ///       m(rhs) => super.unresolved++;
-  ///     }
-  ///
-  R visitUnresolvedSuperPostfix(
-      SendSet node, Element element, IncDecOperator operator, A arg);
-
-  /// Compound assignment expression of [rhs] with [operator] on an unresolved
-  /// super property.
-  ///
-  /// For instance:
-  ///
-  ///     class B {
-  ///     }
-  ///     class C extends B {
-  ///       m(rhs) => super.unresolved += rhs;
-  ///     }
-  ///
-  R visitUnresolvedSuperCompound(
-      Send node, Element element, AssignmentOperator operator, Node rhs, A arg);
-
-  /// Postfix expression with [operator] on a final super [field].
-  ///
-  /// For instance:
-  ///
-  ///     class B {
-  ///       final field = 42;
-  ///     }
-  ///     class C extends B {
-  ///       m(rhs) => super.field++;
-  ///     }
-  ///
-  R visitFinalSuperFieldPostfix(
-      Send node, FieldElement field, IncDecOperator operator, A arg);
-
-  /// Compound assignment expression of [rhs] with [operator] reading from the
-  /// super field [readField] and writing to the different super field
-  /// [writtenField].
-  ///
-  /// For instance:
-  ///
-  ///     class A {
-  ///       var field;
-  ///     }
-  ///     class B extends A {
-  ///       final field;
-  ///     }
-  ///     class C extends B {
-  ///       m() => super.field += rhs;
-  ///     }
-  ///
-  R visitSuperFieldFieldCompound(Send node, FieldElement readField,
-      FieldElement writtenField, AssignmentOperator operator, Node rhs, A arg);
-
-  /// Compound assignment expression of [rhs] with [operator] reading from a
-  /// super [getter] and writing to a super [setter].
-  ///
-  /// For instance:
-  ///
-  ///     class B {
-  ///       get o => 0;
-  ///       set o(_) {}
-  ///     }
-  ///     class C extends B {
-  ///       m(rhs) => super.o += rhs;
-  ///     }
-  ///
-  R visitSuperGetterSetterCompound(Send node, GetterElement getter,
-      SetterElement setter, AssignmentOperator operator, Node rhs, A arg);
-
-  /// Compound assignment expression of [rhs] with [operator] reading from a
-  /// super [method], that is, closurizing [method], and writing to a super
-  /// [setter].
-  ///
-  /// For instance:
-  ///
-  ///     class B {
-  ///       o() {}
-  ///       set o(_) {}
-  ///     }
-  ///     class C extends B {
-  ///       m(rhs) => super.o += rhs;
-  ///     }
-  ///
-  R visitSuperMethodSetterCompound(Send node, FunctionElement method,
-      SetterElement setter, AssignmentOperator operator, Node rhs, A arg);
-
-  /// Compound assignment expression of [rhs] with [operator] reading the
-  /// closurized super [method] and trying to invoke the non-existing setter.
-  ///
-  /// For instance:
-  ///
-  ///     class B {
-  ///       o() {}
-  ///     }
-  ///     class C extends B {
-  ///       m(rhs) => super.o += rhs;
-  ///     }
-  ///
-  R visitSuperMethodCompound(Send node, MethodElement method,
-      AssignmentOperator operator, Node rhs, A arg);
-
-  /// Compound assignment expression of [rhs] with [operator] reading from the
-  /// non-existing super getter and writing to a super [setter].
-  ///
-  /// For instance:
-  ///
-  ///     class B {
-  ///       set o(_) {}
-  ///     }
-  ///     class C extends B {
-  ///       m(rhs) => super.o += rhs;
-  ///     }
-  ///
-  R visitUnresolvedSuperGetterCompound(SendSet node, Element element,
-      SetterElement setter, AssignmentOperator operator, Node rhs, A arg);
-
-  /// Compound assignment expression of [rhs] with [operator] reading from a
-  /// super [getter] and writing to the non-existing super setter.
-  ///
-  /// For instance:
-  ///
-  ///     class B {
-  ///       get o => 42;
-  ///     }
-  ///     class C extends B {
-  ///       m(rhs) => super.o += rhs;
-  ///     }
-  ///
-  R visitUnresolvedSuperSetterCompound(Send node, GetterElement getter,
-      Element element, AssignmentOperator operator, Node rhs, A arg);
-
-  /// Compound assignment expression of [rhs] with [operator] reading from a
-  /// super [field] and writing to a super [setter].
-  ///
-  /// For instance:
-  ///
-  ///     class A {
-  ///       var o;
-  ///     }
-  ///     class B extends A {
-  ///       set o(_) {}
-  ///     }
-  ///     class C extends B {
-  ///       m(rhs) => super.o += rhs;
-  ///     }
-  ///
-  R visitSuperFieldSetterCompound(Send node, FieldElement field,
-      SetterElement setter, AssignmentOperator operator, Node rhs, A arg);
-
-  /// Compound assignment expression of [rhs] with [operator] reading from a
-  /// super [getter] and writing to a super [field].
-  ///
-  /// For instance:
-  ///
-  ///     class A {
-  ///       var o;
-  ///     }
-  ///     class B extends A {
-  ///       get o => 0;
-  ///     }
-  ///     class C extends B {
-  ///       m(rhs) => super.o += rhs;
-  ///     }
-  ///
-  R visitSuperGetterFieldCompound(Send node, GetterElement getter,
-      FieldElement field, AssignmentOperator operator, Node rhs, A arg);
-
-  /// Compound assignment expression of [rhs] with [operator] on a type literal
-  /// for class [element].
-  ///
-  /// For instance:
-  ///
-  ///     class C {}
-  ///     m(rhs) => C += rhs;
-  ///
-  R visitClassTypeLiteralCompound(Send node, ConstantExpression constant,
-      AssignmentOperator operator, Node rhs, A arg);
-
-  /// Compound assignment expression of [rhs] with [operator] on a type literal
-  /// for typedef [element].
-  ///
-  /// For instance:
-  ///
-  ///     typedef F();
-  ///     m(rhs) => F += rhs;
-  ///
-  R visitTypedefTypeLiteralCompound(Send node, ConstantExpression constant,
-      AssignmentOperator operator, Node rhs, A arg);
-
-  /// Compound assignment expression of [rhs] with [operator] on a type literal
-  /// for type variable [element].
-  ///
-  /// For instance:
-  ///
-  ///     class C<T> {
-  ///       m(rhs) => T += rhs;
-  ///     }
-  ///
-  R visitTypeVariableTypeLiteralCompound(Send node, TypeVariableElement element,
-      AssignmentOperator operator, Node rhs, A arg);
-
-  /// Compound assignment expression of [rhs] with [operator] on the type
-  /// literal for `dynamic`.
-  ///
-  /// For instance:
-  ///
-  ///     m(rhs) => dynamic += rhs;
-  ///
-  R visitDynamicTypeLiteralCompound(Send node, ConstantExpression constant,
-      AssignmentOperator operator, Node rhs, A arg);
-
-  /// Compound index assignment of [rhs] with [operator] to [index] on the
-  /// index operators of [receiver].
-  ///
-  /// For instance:
-  ///
-  ///     m(receiver, index, rhs) => receiver[index] += rhs;
-  ///
-  R visitCompoundIndexSet(SendSet node, Node receiver, Node index,
-      AssignmentOperator operator, Node rhs, A arg);
-
-  /// Compound index assignment of [rhs] with [operator] to [index] on the index
-  /// operators of a super class defined by [getter] and [setter].
-  ///
-  /// For instance:
-  ///
-  ///     class B {
-  ///       operator [](index) {}
-  ///       operator [](index, value) {}
-  ///     }
-  ///     class C extends B {
-  ///       m(index, rhs) => super[index] += rhs;
-  ///     }
-  ///
-  R visitSuperCompoundIndexSet(
-      SendSet node,
-      MethodElement getter,
-      MethodElement setter,
-      Node index,
-      AssignmentOperator operator,
-      Node rhs,
-      A arg);
-
-  /// Compound index assignment of [rhs] with [operator] to [index] on a super
-  /// class where the index getter is undefined and the index setter is defined
-  /// by [setter].
-  ///
-  /// For instance:
-  ///
-  ///     class B {
-  ///     }
-  ///     class C extends B {
-  ///       m() => super[1] += 42;
-  ///     }
-  ///
-  R visitUnresolvedSuperGetterCompoundIndexSet(
-      SendSet node,
-      Element element,
-      MethodElement setter,
-      Node index,
-      AssignmentOperator operator,
-      Node rhs,
-      A arg);
-
-  /// Compound index assignment of [rhs] with [operator] to [index] on a super
-  /// class where the index getter is defined by [getter] but the index setter
-  /// is undefined.
-  ///
-  /// For instance:
-  ///
-  ///     class B {
-  ///       operator [](index) => 42;
-  ///     }
-  ///     class C extends B {
-  ///       m() => super[1] += 42;
-  ///     }
-  ///
-  R visitUnresolvedSuperSetterCompoundIndexSet(
-      SendSet node,
-      MethodElement getter,
-      Element element,
-      Node index,
-      AssignmentOperator operator,
-      Node rhs,
-      A arg);
-
-  /// Compound index assignment of [rhs] with [operator] to [index] on a super
-  /// class where the index getter and setter are undefined.
-  ///
-  /// For instance:
-  ///
-  ///     class B {
-  ///     }
-  ///     class C extends B {
-  ///       m() => super[1] += 42;
-  ///     }
-  ///
-  R visitUnresolvedSuperCompoundIndexSet(SendSet node, Element element,
-      Node index, AssignmentOperator operator, Node rhs, A arg);
-
-  /// If-null assignment expression of [rhs] to [index] on the index operators
-  /// of [receiver].
-  ///
-  /// For instance:
-  ///
-  ///     m(receiver, index, rhs) => receiver[index] ??= rhs;
-  ///
-  R visitIndexSetIfNull(
-      SendSet node, Node receiver, Node index, Node rhs, A arg);
-
-  /// If-null assignment expression of [rhs] to [index] on the index operators
-  /// of a super class defined by [getter] and [setter].
-  ///
-  /// For instance:
-  ///
-  ///     class B {
-  ///       operator [](index) {}
-  ///       operator [](index, value) {}
-  ///     }
-  ///     class C extends B {
-  ///       m(index, rhs) => super[index] ??= rhs;
-  ///     }
-  ///
-  R visitSuperIndexSetIfNull(SendSet node, MethodElement getter,
-      MethodElement setter, Node index, Node rhs, A arg);
-
-  /// If-null assignment expression of [rhs] to [index] on a super class where
-  /// the index getter is undefined and the index setter is defined by [setter].
-  ///
-  /// For instance:
-  ///
-  ///     class B {
-  ///       operator [](index, value) {}
-  ///     }
-  ///     class C extends B {
-  ///       m() => super[1] ??= 42;
-  ///     }
-  ///
-  R visitUnresolvedSuperGetterIndexSetIfNull(SendSet node, Element element,
-      MethodElement setter, Node index, Node rhs, A arg);
-
-  /// If-null assignment expression of [rhs] to [index] on a super class where
-  /// the index getter is defined by [getter] but the index setter is undefined.
-  ///
-  /// For instance:
-  ///
-  ///     class B {
-  ///       operator [](index) => 42;
-  ///     }
-  ///     class C extends B {
-  ///       m() => super[1] ??= 42;
-  ///     }
-  ///
-  R visitUnresolvedSuperSetterIndexSetIfNull(SendSet node, MethodElement getter,
-      Element element, Node index, Node rhs, A arg);
-
-  /// If-null assignment expression of [rhs] to [index] on a super class where
-  /// the index getter and setter are undefined.
-  ///
-  /// For instance:
-  ///
-  ///     class B {
-  ///     }
-  ///     class C extends B {
-  ///       m() => super[1] ??= 42;
-  ///     }
-  ///
-  R visitUnresolvedSuperIndexSetIfNull(
-      Send node, Element element, Node index, Node rhs, A arg);
-
-  /// Prefix expression with [operator] of the property on [receiver] whose
-  /// getter and setter are defined by [getterSelector] and [setterSelector],
-  /// respectively.
-  ///
-  /// For instance:
-  ///
-  ///     m(receiver) => ++receiver.foo;
-  ///
-  R visitDynamicPropertyPrefix(
-      Send node, Node receiver, Name name, IncDecOperator operator, A arg);
-
-  /// Prefix expression with [operator] of the property on a possibly null
-  /// [receiver] whose getter and setter are defined by [getterSelector] and
-  /// [setterSelector], respectively.
-  ///
-  /// For instance:
-  ///
-  ///     m(receiver) => ++receiver?.foo;
-  ///
-  R visitIfNotNullDynamicPropertyPrefix(
-      Send node, Node receiver, Name name, IncDecOperator operator, A arg);
-
-  /// Prefix expression with [operator] on a [parameter].
-  ///
-  /// For instance:
-  ///
-  ///     m(parameter) => ++parameter;
-  ///
-  R visitParameterPrefix(
-      Send node, ParameterElement parameter, IncDecOperator operator, A arg);
-
-  /// Prefix expression with [operator] on a final [parameter].
-  ///
-  /// For instance:
-  ///
-  ///     m(final parameter) => ++parameter;
-  ///
-  R visitFinalParameterPrefix(
-      Send node, ParameterElement parameter, IncDecOperator operator, A arg);
-
-  /// Prefix expression with [operator] on a local [variable].
-  ///
-  /// For instance:
-  ///
-  ///     m() {
-  ///       var variable;
-  ///       ++variable;
-  ///     }
-  ///
-  R visitLocalVariablePrefix(
-      Send node, LocalVariableElement variable, IncDecOperator operator, A arg);
-
-  /// Prefix expression with [operator] on a final local [variable].
-  ///
-  /// For instance:
-  ///
-  ///     m() {
-  ///       final variable;
-  ///       ++variable;
-  ///     }
-  ///
-  R visitFinalLocalVariablePrefix(
-      Send node, LocalVariableElement variable, IncDecOperator operator, A arg);
-
-  /// Prefix expression with [operator] on a local [function].
-  ///
-  /// For instance:
-  ///
-  ///     m() {
-  ///       function() {}
-  ///       ++function;
-  ///     }
-  ///
-  R visitLocalFunctionPrefix(
-      Send node, LocalFunctionElement function, IncDecOperator operator, A arg);
-
-  /// Prefix expression with [operator] of the property on `this` whose getter
-  /// and setter are defined by [getterSelector] and [setterSelector],
-  /// respectively.
-  ///
-  /// For instance:
-  ///
-  ///     class C {
-  ///       m() => ++foo;
-  ///     }
-  ///
-  /// or
-  ///
-  ///     class C {
-  ///       m() => ++this.foo;
-  ///     }
-  ///
-  R visitThisPropertyPrefix(
-      Send node, Name name, IncDecOperator operator, A arg);
-
-  /// Prefix expression with [operator] on a static [field].
-  ///
-  /// For instance:
-  ///
-  ///     class C {
-  ///       static var field;
-  ///       m() => ++field;
-  ///     }
-  ///
-  R visitStaticFieldPrefix(
-      Send node, FieldElement field, IncDecOperator operator, A arg);
-
-  /// Prefix expression with [operator] on a final static [field].
-  ///
-  /// For instance:
-  ///
-  ///     class C {
-  ///       static final field = 42;
-  ///       m() => ++field;
-  ///     }
-  ///
-  R visitFinalStaticFieldPrefix(
-      Send node, FieldElement field, IncDecOperator operator, A arg);
-
-  /// Prefix expression with [operator] reading from a static [getter] and
-  /// writing to a static [setter].
-  ///
-  /// For instance:
-  ///
-  ///     class C {
-  ///       static get o => 0;
-  ///       static set o(_) {}
-  ///       m() => ++o;
-  ///     }
-  ///
-  R visitStaticGetterSetterPrefix(Send node, GetterElement getter,
-      SetterElement setter, IncDecOperator operator, A arg);
-
-  /// Prefix expression with [operator] reading from a static [method], that is,
-  /// closurizing [method], and writing to a static [setter].
-  ///
-  /// For instance:
-  ///
-  ///     class C {
-  ///       static o() {}
-  ///       static set o(_) {}
-  ///       m() => ++o;
-  ///     }
-  ///
-  R visitStaticMethodSetterPrefix(Send node, GetterElement getter,
-      SetterElement setter, IncDecOperator operator, A arg);
-
-  /// Prefix expression with [operator] on a top level [field].
-  ///
-  /// For instance:
-  ///
-  ///     var field;
-  ///     m() => ++field;
-  ///
-  R visitTopLevelFieldPrefix(
-      Send node, FieldElement field, IncDecOperator operator, A arg);
-
-  /// Prefix expression with [operator] on a final top level [field].
-  ///
-  /// For instance:
-  ///
-  ///     final field;
-  ///     m() => ++field;
-  ///
-  R visitFinalTopLevelFieldPrefix(
-      Send node, FieldElement field, IncDecOperator operator, A arg);
-
-  /// Prefix expression with [operator] reading from a top level [getter] and
-  /// writing to a top level [setter].
-  ///
-  /// For instance:
-  ///
-  ///     get o => 0;
-  ///     set o(_) {}
-  ///     m() => ++o;
-  ///
-  R visitTopLevelGetterSetterPrefix(Send node, GetterElement getter,
-      SetterElement setter, IncDecOperator operator, A arg);
-
-  /// Prefix expression with [operator] reading from a top level [method], that
-  /// is, closurizing [method], and writing to a top level [setter].
-  ///
-  /// For instance:
-  ///
-  ///     o() {}
-  ///     set o(_) {}
-  ///     m() => ++o;
-  ///
-  R visitTopLevelMethodSetterPrefix(Send node, FunctionElement method,
-      SetterElement setter, IncDecOperator operator, A arg);
-
-  /// Prefix expression with [operator] on a super [field].
-  ///
-  /// For instance:
-  ///
-  ///     class B {
-  ///       var field;
-  ///     }
-  ///     class C extends B {
-  ///       m() => ++super.field;
-  ///     }
-  ///
-  R visitSuperFieldPrefix(
-      SendSet node, FieldElement field, IncDecOperator operator, A arg);
-
-  /// Prefix expression with [operator] reading from the super field [readField]
-  /// and writing to the different super field [writtenField].
-  ///
-  /// For instance:
-  ///
-  ///     class A {
-  ///       var field;
-  ///     }
-  ///     class B extends A {
-  ///       final field;
-  ///     }
-  ///     class C extends B {
-  ///       m() => ++super.field;
-  ///     }
-  ///
-  R visitSuperFieldFieldPrefix(SendSet node, FieldElement readField,
-      FieldElement writtenField, IncDecOperator operator, A arg);
-
-  /// Prefix expression with [operator] reading from a super [field] and writing
-  /// to a super [setter].
-  ///
-  /// For instance:
-  ///
-  ///     class A {
-  ///       var field;
-  ///     }
-  ///     class B extends A {
-  ///       set field(_) {}
-  ///     }
-  ///     class C extends B {
-  ///       m() => ++super.field;
-  ///     }
-  ///
-  R visitSuperFieldSetterPrefix(SendSet node, FieldElement field,
-      SetterElement setter, IncDecOperator operator, A arg);
-
-  /// Prefix expression with [operator] reading from a super [getter] and
-  /// writing to a super [setter].
-  ///
-  /// For instance:
-  ///
-  ///     class B {
-  ///       get field => 0;
-  ///       set field(_) {}
-  ///     }
-  ///     class C extends B {
-  ///       m() => ++super.field;
-  ///     }
-  ///
-  R visitSuperGetterSetterPrefix(SendSet node, GetterElement getter,
-      SetterElement setter, IncDecOperator operator, A arg);
-
-  /// Prefix expression with [operator] reading from a super [getter] and
-  /// writing to a super [field].
-  ///
-  /// For instance:
-  ///
-  ///     class A {
-  ///       var field;
-  ///     }
-  ///     class B extends A {
-  ///       get field => 0;
-  ///     }
-  ///     class C extends B {
-  ///       m() => ++super.field;
-  ///     }
-  ///
-  R visitSuperGetterFieldPrefix(SendSet node, GetterElement getter,
-      FieldElement field, IncDecOperator operator, A arg);
-
-  /// Prefix expression with [operator] reading from a super [method], that is,
-  /// closurizing [method], and writing to a super [setter].
-  ///
-  /// For instance:
-  ///
-  ///     class B {
-  ///       o() {}
-  ///       set o(_) {}
-  ///     }
-  ///     class C extends B {
-  ///       m() => ++super.o;
-  ///     }
-  ///
-  R visitSuperMethodSetterPrefix(SendSet node, FunctionElement method,
-      SetterElement setter, IncDecOperator operator, A arg);
-
-  /// Prefix expression with [operator] reading from a super [method], that is,
-  /// closurizing [method], and writing to an unresolved super setter.
-  ///
-  /// For instance:
-  ///
-  ///     class B {
-  ///       o() {}
-  ///       set o(_) {}
-  ///     }
-  ///     class C extends B {
-  ///       m() => ++super.o;
-  ///     }
-  ///
-  R visitSuperMethodPrefix(
-      Send node, MethodElement method, IncDecOperator operator, A arg);
-
-  /// Prefix expression with [operator] reading from an unresolved super getter
-  /// and writing to a super [setter].
-  ///
-  /// For instance:
-  ///
-  ///     class B {
-  ///       set o(_) {}
-  ///     }
-  ///     class C extends B {
-  ///       m() => ++super.o;
-  ///     }
-  ///
-  ///
-  R visitUnresolvedSuperGetterPrefix(SendSet node, Element element,
-      SetterElement setter, IncDecOperator operator, A arg);
-
-  /// Prefix expression with [operator] reading from a super [getter] and
-  /// writing to an unresolved super setter.
-  ///
-  /// For instance:
-  ///
-  ///     class B {
-  ///       get o => 42
-  ///     }
-  ///     class C extends B {
-  ///       m() => ++super.o;
-  ///     }
-  ///
-  ///
-  R visitUnresolvedSuperSetterPrefix(SendSet node, GetterElement getter,
-      Element element, IncDecOperator operator, A arg);
-
-  /// Prefix expression with [operator] on a type literal for a class [element].
-  ///
-  /// For instance:
-  ///
-  ///     class C {}
-  ///     m() => ++C;
-  ///
-  R visitClassTypeLiteralPrefix(
-      Send node, ConstantExpression constant, IncDecOperator operator, A arg);
-
-  /// Prefix expression with [operator] on a type literal for a typedef
-  /// [element].
-  ///
-  /// For instance:
-  ///
-  ///     typedef F();
-  ///     m() => ++F;
-  ///
-  R visitTypedefTypeLiteralPrefix(
-      Send node, ConstantExpression constant, IncDecOperator operator, A arg);
-
-  /// Prefix expression with [operator] on a type literal for a type variable
-  /// [element].
-  ///
-  /// For instance:
-  ///
-  ///     class C<T> {
-  ///       m() => ++T;
-  ///     }
-  ///
-  R visitTypeVariableTypeLiteralPrefix(
-      Send node, TypeVariableElement element, IncDecOperator operator, A arg);
-
-  /// Prefix expression with [operator] on the type literal for `dynamic`.
-  ///
-  /// For instance:
-  ///
-  ///     m() => ++dynamic;
-  ///
-  R visitDynamicTypeLiteralPrefix(
-      Send node, ConstantExpression constant, IncDecOperator operator, A arg);
-
-  /// Postfix expression with [operator] of the property on [receiver] whose
-  /// getter and setter are defined by [getterSelector] and [setterSelector],
-  /// respectively.
-  ///
-  /// For instance:
-  ///
-  ///     m(receiver) => receiver.foo++;
-  ///
-  R visitDynamicPropertyPostfix(
-      Send node, Node receiver, Name name, IncDecOperator operator, A arg);
-
-  /// Postfix expression with [operator] of the property on a possibly null
-  /// [receiver] whose getter and setter are defined by [getterSelector] and
-  /// [setterSelector], respectively.
-  ///
-  /// For instance:
-  ///
-  ///     m(receiver) => receiver?.foo++;
-  ///
-  R visitIfNotNullDynamicPropertyPostfix(
-      Send node, Node receiver, Name name, IncDecOperator operator, A arg);
-
-  /// Postfix expression with [operator] on a [parameter].
-  ///
-  /// For instance:
-  ///
-  ///     m(parameter) => parameter++;
-  ///
-  R visitParameterPostfix(
-      Send node, ParameterElement parameter, IncDecOperator operator, A arg);
-
-  /// Postfix expression with [operator] on a final [parameter].
-  ///
-  /// For instance:
-  ///
-  ///     m(final parameter) => parameter++;
-  ///
-  R visitFinalParameterPostfix(
-      Send node, ParameterElement parameter, IncDecOperator operator, A arg);
-
-  /// Postfix expression with [operator] on a local [variable].
-  ///
-  /// For instance:
-  ///
-  ///     m() {
-  ///       var variable;
-  ///       variable++;
-  ///     }
-  ///
-  R visitLocalVariablePostfix(
-      Send node, LocalVariableElement variable, IncDecOperator operator, A arg);
-
-  /// Postfix expression with [operator] on a final local [variable].
-  ///
-  /// For instance:
-  ///
-  ///     m() {
-  ///       final variable;
-  ///       variable++;
-  ///     }
-  ///
-  R visitFinalLocalVariablePostfix(
-      Send node, LocalVariableElement variable, IncDecOperator operator, A arg);
-
-  /// Postfix expression with [operator] on a local [function].
-  ///
-  /// For instance:
-  ///
-  ///     m() {
-  ///     function() {}
-  ///      function++;
-  ///     }
-  ///
-  R visitLocalFunctionPostfix(
-      Send node, LocalFunctionElement function, IncDecOperator operator, A arg);
-
-  /// Postfix expression with [operator] of the property on `this` whose getter
-  /// and setter are defined by [getterSelector] and [setterSelector],
-  /// respectively.
-  ///
-  /// For instance:
-  ///
-  ///     class C {
-  ///       m() => foo++;
-  ///     }
-  ///
-  /// or
-  ///
-  ///     class C {
-  ///       m() => this.foo++;
-  ///     }
-  ///
-  R visitThisPropertyPostfix(
-      Send node, Name name, IncDecOperator operator, A arg);
-
-  /// Postfix expression with [operator] on a static [field].
-  ///
-  /// For instance:
-  ///
-  ///     class C {
-  ///       static var field;
-  ///       m() => field++;
-  ///     }
-  ///
-  R visitStaticFieldPostfix(
-      Send node, FieldElement field, IncDecOperator operator, A arg);
-
-  /// Postfix expression with [operator] on a final static [field].
-  ///
-  /// For instance:
-  ///
-  ///     class C {
-  ///       static final field;
-  ///       m() => field++;
-  ///     }
-  ///
-  R visitFinalStaticFieldPostfix(
-      Send node, FieldElement field, IncDecOperator operator, A arg);
-
-  /// Postfix expression with [operator] reading from a static [getter] and
-  /// writing to a static [setter].
-  ///
-  /// For instance:
-  ///
-  ///     class C {
-  ///       static get o => 0;
-  ///       static set o(_) {}
-  ///       m() => o++;
-  ///     }
-  ///
-  R visitStaticGetterSetterPostfix(Send node, GetterElement getter,
-      SetterElement setter, IncDecOperator operator, A arg);
-
-  /// Postfix expression with [operator] reading from a static [method], that
-  /// is, closurizing [method], and writing to a static [setter].
-  ///
-  /// For instance:
-  ///
-  ///     class C {
-  ///       static o() {}
-  ///       static set o(_) {}
-  ///       m() => o++;
-  ///     }
-  ///
-  R visitStaticMethodSetterPostfix(Send node, GetterElement getter,
-      SetterElement setter, IncDecOperator operator, A arg);
-
-  /// Postfix expression with [operator] on a top level [field].
-  ///
-  /// For instance:
-  ///
-  ///     var field;
-  ///     m() => field++;
-  ///
-  R visitTopLevelFieldPostfix(
-      Send node, FieldElement field, IncDecOperator operator, A arg);
-
-  /// Postfix expression with [operator] on a final top level [field].
-  ///
-  /// For instance:
-  ///
-  ///     final field = 42;
-  ///     m() => field++;
-  ///
-  R visitFinalTopLevelFieldPostfix(
-      Send node, FieldElement field, IncDecOperator operator, A arg);
-
-  /// Postfix expression with [operator] reading from a top level [getter] and
-  /// writing to a top level [setter].
-  ///
-  /// For instance:
-  ///
-  ///     get o => 0;
-  ///     set o(_) {}
-  ///     m() => o++;
-  ///
-  R visitTopLevelGetterSetterPostfix(Send node, GetterElement getter,
-      SetterElement setter, IncDecOperator operator, A arg);
-
-  /// Postfix expression with [operator] reading from a top level [method], that
-  /// is, closurizing [method], and writing to a top level [setter].
-  ///
-  /// For instance:
-  ///
-  ///     o() {}
-  ///     set o(_) {}
-  ///     m() => o++;
-  ///
-  R visitTopLevelMethodSetterPostfix(Send node, FunctionElement method,
-      SetterElement setter, IncDecOperator operator, A arg);
-
-  /// Postfix expression with [operator] on a super [field].
-  ///
-  /// For instance:
-  ///
-  ///     class B {
-  ///       var field;
-  ///     }
-  ///     class C extends B {
-  ///       m() => super.field++;
-  ///     }
-  ///
-  R visitSuperFieldPostfix(
-      SendSet node, FieldElement field, IncDecOperator operator, A arg);
-
-  /// Postfix expression with [operator] reading from the super field
-  /// [readField] and writing to the different super field [writtenField].
-  ///
-  /// For instance:
-  ///
-  ///     class A {
-  ///       var field;
-  ///     }
-  ///     class B extends A {
-  ///       final field;
-  ///     }
-  ///     class C extends B {
-  ///       m() => super.field++;
-  ///     }
-  ///
-  R visitSuperFieldFieldPostfix(SendSet node, FieldElement readField,
-      FieldElement writtenField, IncDecOperator operator, A arg);
-
-  /// Postfix expression with [operator] reading from a super [field] and
-  /// writing to a super [setter].
-  ///
-  /// For instance:
-  ///
-  ///     class A {
-  ///       var field;
-  ///     }
-  ///     class B extends A {
-  ///       set field(_) {}
-  ///     }
-  ///     class C extends B {
-  ///       m() => super.field++;
-  ///     }
-  ///
-  R visitSuperFieldSetterPostfix(SendSet node, FieldElement field,
-      SetterElement setter, IncDecOperator operator, A arg);
-
-  /// Postfix expression with [operator] reading from a super [getter] and
-  /// writing to a super [setter].
-  ///
-  /// For instance:
-  ///
-  ///     class B {
-  ///       get field => 0;
-  ///       set field(_) {}
-  ///     }
-  ///     class C extends B {
-  ///       m() => super.field++;
-  ///     }
-  ///
-  R visitSuperGetterSetterPostfix(SendSet node, GetterElement getter,
-      SetterElement setter, IncDecOperator operator, A arg);
-
-  /// Postfix expression with [operator] reading from a super [getter] and
-  /// writing to a super [field].
-  ///
-  /// For instance:
-  ///
-  ///     class A {
-  ///       var field;
-  ///     }
-  ///     class B extends A {
-  ///       get field => 0;
-  ///     }
-  ///     class C extends B {
-  ///       m() => super.field++;
-  ///     }
-  ///
-  R visitSuperGetterFieldPostfix(SendSet node, GetterElement getter,
-      FieldElement field, IncDecOperator operator, A arg);
-
-  /// Postfix expression with [operator] reading from a super [method], that is,
-  /// closurizing [method], and writing to a super [setter].
-  ///
-  /// For instance:
-  ///
-  ///     class B {
-  ///       o() {}
-  ///       set o(_) {}
-  ///     }
-  ///     class C extends B {
-  ///       m() => super.o++;
-  ///     }
-  ///
-  R visitSuperMethodSetterPostfix(SendSet node, FunctionElement method,
-      SetterElement setter, IncDecOperator operator, A arg);
-
-  /// Postfix expression with [operator] reading from a super [method], that is,
-  /// closurizing [method], and writing to an unresolved super.
-  ///
-  /// For instance:
-  ///
-  ///     class B {
-  ///       o() {}
-  ///       set o(_) {}
-  ///     }
-  ///     class C extends B {
-  ///       m() => super.o++;
-  ///     }
-  ///
-  R visitSuperMethodPostfix(
-      Send node, MethodElement method, IncDecOperator operator, A arg);
-
-  /// Prefix expression with [operator] reading from an unresolved super getter
-  /// and writing to a super [setter].
-  ///
-  /// For instance:
-  ///
-  ///     class B {
-  ///       set o(_) {}
-  ///     }
-  ///     class C extends B {
-  ///       m() => super.o++;
-  ///     }
-  ///
-  ///
-  R visitUnresolvedSuperGetterPostfix(SendSet node, Element element,
-      SetterElement setter, IncDecOperator operator, A arg);
-
-  /// Prefix expression with [operator] reading from a super [getter] and
-  /// writing to an unresolved super setter.
-  ///
-  /// For instance:
-  ///
-  ///     class B {
-  ///       get o => 42
-  ///     }
-  ///     class C extends B {
-  ///       m() => super.o++;
-  ///     }
-  ///
-  ///
-  R visitUnresolvedSuperSetterPostfix(SendSet node, GetterElement getter,
-      Element element, IncDecOperator operator, A arg);
-
-  /// Postfix expression with [operator] on a type literal for a class
-  /// [element].
-  ///
-  /// For instance:
-  ///
-  ///     class C {}
-  ///     m() => C++;
-  ///
-  R visitClassTypeLiteralPostfix(
-      Send node, ConstantExpression constant, IncDecOperator operator, A arg);
-
-  /// Postfix expression with [operator] on a type literal for a typedef
-  /// [element].
-  ///
-  /// For instance:
-  ///
-  ///     typedef F();
-  ///     m() => F++;
-  ///
-  R visitTypedefTypeLiteralPostfix(
-      Send node, ConstantExpression constant, IncDecOperator operator, A arg);
-
-  /// Postfix expression with [operator] on a type literal for a type variable
-  /// [element].
-  ///
-  /// For instance:
-  ///
-  ///     class C<T> {
-  ///       m() => T++;
-  ///     }
-  ///
-  R visitTypeVariableTypeLiteralPostfix(
-      Send node, TypeVariableElement element, IncDecOperator operator, A arg);
-
-  /// Postfix expression with [operator] on the type literal for `dynamic`.
-  ///
-  /// For instance:
-  ///
-  ///     m() => dynamic++;
-  ///
-  R visitDynamicTypeLiteralPostfix(
-      Send node, ConstantExpression constant, IncDecOperator operator, A arg);
-
-  /// Read of the [constant].
-  ///
-  /// For instance:
-  ///
-  ///     const c = c;
-  ///     m() => c;
-  ///
-  R visitConstantGet(Send node, ConstantExpression constant, A arg);
-
-  /// Invocation of the [constant] with [arguments].
-  ///
-  /// For instance:
-  ///
-  ///     const c = null;
-  ///     m() => c(null, 42);
-  ///
-  R visitConstantInvoke(Send node, ConstantExpression constant,
-      NodeList arguments, CallStructure callStructure, A arg);
-
-  /// Read of the unresolved [element].
-  ///
-  /// For instance:
-  ///
-  ///     class C {}
-  ///     m1() => unresolved;
-  ///     m2() => prefix.unresolved;
-  ///     m3() => Unresolved.foo;
-  ///     m4() => unresolved.foo;
-  ///     m5() => unresolved.Foo.bar;
-  ///     m6() => C.unresolved;
-  ///     m7() => prefix.C.unresolved;
-  ///     m8() => prefix?.unresolved;
-  ///     m9() => Unresolved?.foo;
-  ///     m10() => unresolved?.foo;
-  ///     m11() => unresolved?.Foo?.bar;
-  ///
-  // TODO(johnniwinther): Split the cases in which a prefix is resolved.
-  R visitUnresolvedGet(Send node, Element element, A arg);
-
-  /// Read of the unresolved super [element].
-  ///
-  /// For instance:
-  ///
-  ///     class B {}
-  ///     class C {
-  ///       m() => super.foo;
-  ///     }
-  ///
-  R visitUnresolvedSuperGet(Send node, Element element, A arg);
-
-  /// Assignment of [rhs] to the unresolved [element].
-  ///
-  /// For instance:
-  ///
-  ///     class C {}
-  ///     m1() => unresolved = 42;
-  ///     m2() => prefix.unresolved = 42;
-  ///     m3() => Unresolved.foo = 42;
-  ///     m4() => unresolved.foo = 42;
-  ///     m5() => unresolved.Foo.bar = 42;
-  ///     m6() => C.unresolved = 42;
-  ///     m7() => prefix.C.unresolved = 42;
-  ///     m8() => prefix?.unresolved = 42;
-  ///     m9() => Unresolved?.foo = 42;
-  ///     m10() => unresolved?.foo = 42;
-  ///     m11() => unresolved?.Foo?.bar = 42;
-  ///
-  // TODO(johnniwinther): Split the cases in which a prefix is resolved.
-  R visitUnresolvedSet(SendSet node, Element element, Node rhs, A arg);
-
-  ///  Assignment of [rhs] to the unresolved super [element].
-  ///
-  /// For instance:
-  ///
-  ///     class B {}
-  ///     class C {
-  ///       m() => super.foo = 42;
-  ///     }
-  ///
-  R visitUnresolvedSuperSet(Send node, Element element, Node rhs, A arg);
-
-  /// Invocation of the unresolved [element] with [arguments].
-  ///
-  /// For instance:
-  ///
-  ///     class C {}
-  ///     m1() => unresolved(null, 42);
-  ///     m2() => prefix.unresolved(null, 42);
-  ///     m3() => Unresolved.foo(null, 42);
-  ///     m4() => unresolved.foo(null, 42);
-  ///     m5() => unresolved.Foo.bar(null, 42);
-  ///     m6() => C.unresolved(null, 42);
-  ///     m7() => prefix.C.unresolved(null, 42);
-  ///     m8() => prefix?.unresolved(null, 42);
-  ///     m9() => Unresolved?.foo(null, 42);
-  ///     m10() => unresolved?.foo(null, 42);
-  ///     m11() => unresolved?.Foo?.bar(null, 42);
-  ///
-  // TODO(johnniwinther): Split the cases in which a prefix is resolved.
-  R visitUnresolvedInvoke(
-      Send node, Element element, NodeList arguments, Selector selector, A arg);
-
-  /// Invocation of the unresolved super [element] with [arguments].
-  ///
-  /// For instance:
-  ///
-  ///     class B {}
-  ///     class C extends B {
-  ///       m() => super.foo();
-  ///     }
-  ///
-  R visitUnresolvedSuperInvoke(
-      Send node, Element element, NodeList arguments, Selector selector, A arg);
-
-  /// Compound assignment of [rhs] with [operator] reading from the
-  /// non-existing static getter and writing to the static [setter].
-  ///
-  /// For instance:
-  ///
-  ///     class C {
-  ///       set foo(_) {}
-  ///     }
-  ///     m1() => C.foo += 42;
-  ///
-  R visitUnresolvedStaticGetterCompound(Send node, Element element,
-      SetterElement setter, AssignmentOperator operator, Node rhs, A arg);
-
-  /// Compound assignment of [rhs] with [operator] reading from the
-  /// non-existing top level getter and writing to the top level [setter].
-  ///
-  /// For instance:
-  ///
-  ///     set foo(_) {}
-  ///     m1() => foo += 42;
-  ///
-  R visitUnresolvedTopLevelGetterCompound(Send node, Element element,
-      SetterElement setter, AssignmentOperator operator, Node rhs, A arg);
-
-  /// Compound assignment of [rhs] with [operator] reading from the static
-  /// [getter] and writing to the non-existing static setter.
-  ///
-  /// For instance:
-  ///
-  ///     class C {
-  ///       get foo => 42;
-  ///     }
-  ///     m1() => C.foo += 42;
-  ///
-  R visitUnresolvedStaticSetterCompound(Send node, GetterElement getter,
-      Element element, AssignmentOperator operator, Node rhs, A arg);
-
-  /// Compound assignment of [rhs] with [operator] reading from the top level
-  /// [getter] and writing to the non-existing top level setter.
-  ///
-  /// For instance:
-  ///
-  ///     get foo => 42;
-  ///     m1() => foo += 42;
-  ///
-  R visitUnresolvedTopLevelSetterCompound(Send node, GetterElement getter,
-      Element element, AssignmentOperator operator, Node rhs, A arg);
-
-  /// Compound assignment of [rhs] with [operator] reading the closurized static
-  /// [method] and trying to invoke the non-existing setter.
-  ///
-  /// For instance:
-  ///
-  ///     class C {
-  ///       foo() {}
-  ///     }
-  ///     m1() => C.foo += 42;
-  ///
-  R visitStaticMethodCompound(Send node, MethodElement method,
-      AssignmentOperator operator, Node rhs, A arg);
-
-  /// Compound assignment of [rhs] where both getter and setter are unresolved.
-  ///
-  /// For instance:
-  ///
-  ///     class C {}
-  ///     m1() => unresolved += 42;
-  ///     m2() => prefix.unresolved += 42;
-  ///     m3() => Unresolved.foo += 42;
-  ///     m4() => unresolved.foo += 42;
-  ///     m5() => unresolved.Foo.bar += 42;
-  ///     m6() => C.unresolved += 42;
-  ///     m7() => prefix.C.unresolved += 42;
-  ///     m8() => prefix?.unresolved += 42;
-  ///     m9() => Unresolved?.foo += 42;
-  ///     m10() => unresolved?.foo += 42;
-  ///     m11() => unresolved?.Foo?.bar += 42;
-  ///
-  // TODO(johnniwinther): Split the cases in which a prefix is resolved.
-  R visitUnresolvedCompound(Send node, ErroneousElement element,
-      AssignmentOperator operator, Node rhs, A arg);
-
-  /// Prefix operation of [operator] reading from the non-existing static getter
-  /// and writing to the static [setter].
-  ///
-  /// For instance:
-  ///
-  ///     class C {
-  ///       set foo(_) {}
-  ///     }
-  ///     m1() => ++C.foo;
-  ///
-  R visitUnresolvedStaticGetterPrefix(Send node, Element element,
-      SetterElement setter, IncDecOperator operator, A arg);
-
-  /// Prefix operation of [operator] reading from the non-existing top level
-  /// getter and writing to the top level [setter].
-  ///
-  /// For instance:
-  ///
-  ///     set foo(_) {}
-  ///     m1() => ++foo;
-  ///
-  R visitUnresolvedTopLevelGetterPrefix(Send node, Element element,
-      SetterElement setter, IncDecOperator operator, A arg);
-
-  /// Prefix operation of [operator] reading from the static [getter] and
-  /// writing to the non-existing static setter.
-  ///
-  /// For instance:
-  ///
-  ///     class C {
-  ///       get foo => 42;
-  ///     }
-  ///     m1() => ++C.foo;
-  ///
-  R visitUnresolvedStaticSetterPrefix(Send node, GetterElement getter,
-      Element element, IncDecOperator operator, A arg);
-
-  /// Postfix operation of [operator] reading from the top level [getter] and
-  /// writing to the non-existing top level setter.
-  ///
-  /// For instance:
-  ///
-  ///     get foo => 42;
-  ///     m1() => ++foo;
-  ///
-  R visitUnresolvedTopLevelSetterPrefix(Send node, GetterElement getter,
-      Element element, IncDecOperator operator, A arg);
-
-  /// Prefix operation of [operator] reading the closurized static [method] and
-  /// trying to invoke the non-existing setter.
-  ///
-  /// For instance:
-  ///
-  ///     class C {
-  ///       foo() {}
-  ///     }
-  ///     m1() => ++C.foo;
-  ///
-  R visitStaticMethodPrefix(
-      Send node, MethodElement method, IncDecOperator operator, A arg);
-
-  /// Prefix operation of [operator] reading the closurized top level [method]
-  /// and trying to invoke the non-existing setter.
-  ///
-  /// For instance:
-  ///
-  ///     class C {
-  ///       foo() {}
-  ///     }
-  ///     m1() => ++C.foo;
-  ///
-  R visitTopLevelMethodPrefix(
-      Send node, MethodElement method, IncDecOperator operator, A arg);
-
-  /// Prefix operation where both getter and setter are unresolved.
-  ///
-  /// For instance:
-  ///
-  ///     class C {}
-  ///     m1() => ++unresolved;
-  ///     m2() => ++prefix.unresolved;
-  ///     m3() => ++Unresolved.foo;
-  ///     m4() => ++unresolved.foo;
-  ///     m5() => ++unresolved.Foo.bar;
-  ///     m6() => ++C.unresolved;
-  ///     m7() => ++prefix.C.unresolved;
-  ///     m8() => ++prefix?.unresolved;
-  ///     m9() => ++Unresolved?.foo;
-  ///     m10() => ++unresolved?.foo;
-  ///     m11() => ++unresolved?.Foo?.bar;
-  ///
-  // TODO(johnniwinther): Split the cases in which a prefix is resolved.
-  R visitUnresolvedPrefix(
-      Send node, ErroneousElement element, IncDecOperator operator, A arg);
-
-  /// Postfix operation of [operator] reading from the non-existing static
-  /// getter and writing to the static [setter].
-  ///
-  /// For instance:
-  ///
-  ///     class C {
-  ///       set foo(_) {}
-  ///     }
-  ///     m1() => C.foo++;
-  ///
-  R visitUnresolvedStaticGetterPostfix(Send node, Element element,
-      SetterElement setter, IncDecOperator operator, A arg);
-
-  /// Postfix operation of [operator] reading from the non-existing top level
-  /// getter and writing to the top level [setter].
-  ///
-  /// For instance:
-  ///
-  ///     set foo(_) {}
-  ///     m1() => foo++;
-  ///
-  R visitUnresolvedTopLevelGetterPostfix(Send node, Element element,
-      SetterElement setter, IncDecOperator operator, A arg);
-
-  /// Postfix operation of [operator] reading from the static [getter] and
-  /// writing to the non-existing static setter.
-  ///
-  /// For instance:
-  ///
-  ///     class C {
-  ///       get foo => 42;
-  ///     }
-  ///     m1() => C.foo++;
-  ///
-  R visitUnresolvedStaticSetterPostfix(Send node, GetterElement getter,
-      Element element, IncDecOperator operator, A arg);
-
-  /// Postfix operation of [operator] reading from the top level [getter] and
-  /// writing to the non-existing top level setter.
-  ///
-  /// For instance:
-  ///
-  ///     get foo => 42;
-  ///     m1() => foo++;
-  ///
-  R visitUnresolvedTopLevelSetterPostfix(Send node, GetterElement getter,
-      Element element, IncDecOperator operator, A arg);
-
-  /// Postfix operation of [operator] reading the closurized static [method] and
-  /// trying to invoke the non-existing setter.
-  ///
-  /// For instance:
-  ///
-  ///     class C {
-  ///       foo() {}
-  ///     }
-  ///     m1() => C.foo++;
-  ///
-  R visitStaticMethodPostfix(
-      Send node, MethodElement method, IncDecOperator operator, A arg);
-
-  /// Postfix operation of [operator] reading the closurized top level [method]
-  /// and trying to invoke the non-existing setter.
-  ///
-  /// For instance:
-  ///
-  ///     class C {
-  ///       foo() {}
-  ///     }
-  ///     m1() => C.foo++;
-  ///
-  R visitTopLevelMethodPostfix(
-      Send node, MethodElement method, IncDecOperator operator, A arg);
-
-  /// Postfix operation where both getter and setter are unresolved.
-  ///
-  /// For instance:
-  ///
-  ///     class C {}
-  ///     m1() => unresolved++;
-  ///     m2() => prefix.unresolved++;
-  ///     m3() => Unresolved.foo++;
-  ///     m4() => unresolved.foo++;
-  ///     m5() => unresolved.Foo.bar++;
-  ///     m6() => C.unresolved++;
-  ///     m7() => prefix.C.unresolved++;
-  ///     m8() => prefix?.unresolved++;
-  ///     m9() => Unresolved?.foo++;
-  ///     m10() => unresolved?.foo++;
-  ///     m11() => unresolved?.Foo?.bar++;
-  ///
-  // TODO(johnniwinther): Split the cases in which a prefix is resolved.
-  R visitUnresolvedPostfix(
-      Send node, ErroneousElement element, IncDecOperator operator, A arg);
-
-  /// Invocation of an undefined unary [operator] on [expression].
-  R errorUndefinedUnaryExpression(
-      Send node, Operator operator, Node expression, A arg);
-
-  /// Invocation of an undefined unary [operator] with operands
-  /// [left] and [right].
-  R errorUndefinedBinaryExpression(
-      Send node, Node left, Operator operator, Node right, A arg);
-
-  /// Const invocation of a [constant] constructor.
-  ///
-  /// For instance:
-  ///
-  ///     class C<T> {
-  ///       const C(a, b);
-  ///     }
-  ///     m() => const C<int>(true, 42);
-  ///
-  R visitConstConstructorInvoke(
-      NewExpression node, ConstructedConstantExpression constant, A arg);
-
-  /// Const invocation of the `bool.fromEnvironment` constructor.
-  ///
-  /// For instance:
-  ///
-  ///     m() => const bool.fromEnvironment('foo', defaultValue: false);
-  ///
-  R visitBoolFromEnvironmentConstructorInvoke(NewExpression node,
-      BoolFromEnvironmentConstantExpression constant, A arg);
-
-  /// Const invocation of the `int.fromEnvironment` constructor.
-  ///
-  /// For instance:
-  ///
-  ///     m() => const int.fromEnvironment('foo', defaultValue: 42);
-  ///
-  R visitIntFromEnvironmentConstructorInvoke(
-      NewExpression node, IntFromEnvironmentConstantExpression constant, A arg);
-
-  /// Const invocation of the `String.fromEnvironment` constructor.
-  ///
-  /// For instance:
-  ///
-  ///     m() => const String.fromEnvironment('foo', defaultValue: 'bar');
-  ///
-  R visitStringFromEnvironmentConstructorInvoke(NewExpression node,
-      StringFromEnvironmentConstantExpression constant, A arg);
-
-  /// Invocation of a generative [constructor] on [type] with [arguments].
-  ///
-  /// For instance:
-  ///
-  ///     class C<T> {
-  ///       C(a, b);
-  ///     }
-  ///     m() => new C<int>(true, 42);
-  ///
-  /// where [type] is `C<int>`.
-  ///
-  R visitGenerativeConstructorInvoke(
-      NewExpression node,
-      ConstructorElement constructor,
-      ResolutionInterfaceType type,
-      NodeList arguments,
-      CallStructure callStructure,
-      A arg);
-
-  /// Invocation of a redirecting generative [constructor] on [type] with
-  /// [arguments].
-  ///
-  /// For instance:
-  ///
-  ///     class C<T> {
-  ///       C(a, b) : this._(b, a);
-  ///       C._(b, a);
-  ///     }
-  ///     m() => new C<int>(true, 42);
-  ///
-  /// where [type] is `C<int>`.
-  ///
-  R visitRedirectingGenerativeConstructorInvoke(
-      NewExpression node,
-      ConstructorElement constructor,
-      ResolutionInterfaceType type,
-      NodeList arguments,
-      CallStructure callStructure,
-      A arg);
-
-  /// Invocation of a factory [constructor] on [type] with [arguments].
-  ///
-  /// For instance:
-  ///
-  ///     class C<T> {
-  ///       factory C(a, b) => new C<T>._(b, a);
-  ///       C._(b, a);
-  ///     }
-  ///     m() => new C<int>(true, 42);
-  ///
-  /// where [type] is `C<int>`.
-  ///
-  R visitFactoryConstructorInvoke(
-      NewExpression node,
-      ConstructorElement constructor,
-      ResolutionInterfaceType type,
-      NodeList arguments,
-      CallStructure callStructure,
-      A arg);
-
-  /// Invocation of a factory [constructor] on [type] with [arguments] where
-  /// [effectiveTarget] and [effectiveTargetType] are the constructor effective
-  /// invoked and its type, respectively.
-  ///
-  /// For instance:
-  ///
-  ///     class C<T> {
-  ///       factory C(a, b) = C<int>.a;
-  ///       factory C.a(a, b) = C<C<T>>.b;
-  ///       C.b(a, b);
-  ///     }
-  ///     m() => new C<double>(true, 42);
-  ///
-  /// where [type] is `C<double>`, [effectiveTarget] is `C.b` and
-  /// [effectiveTargetType] is `C<C<int>>`.
-  ///
-  R visitRedirectingFactoryConstructorInvoke(
-      NewExpression node,
-      ConstructorElement constructor,
-      ResolutionInterfaceType type,
-      ConstructorElement effectiveTarget,
-      ResolutionInterfaceType effectiveTargetType,
-      NodeList arguments,
-      CallStructure callStructure,
-      A arg);
-
-  /// Invocation of an unresolved [constructor] on [type] with [arguments].
-  ///
-  /// For instance:
-  ///
-  ///     class C<T> {
-  ///       C();
-  ///     }
-  ///     m() => new C<int>.unresolved(true, 42);
-  ///
-  /// where [type] is `C<int>`.
-  ///
-  // TODO(johnniwinther): Change [type] to [InterfaceType] when is it not
-  // `dynamic`.
-  R visitUnresolvedConstructorInvoke(NewExpression node, Element constructor,
-      ResolutionDartType type, NodeList arguments, Selector selector, A arg);
-
-  /// Invocation of a constructor on an unresolved [type] with [arguments].
-  ///
-  /// For instance:
-  ///
-  ///     m() => new Unresolved(true, 42);
-  ///
-  /// where [type] is the malformed type `Unresolved`.
-  ///
-  // TODO(johnniwinther): Change [type] to [MalformedType] when is it not
-  // `dynamic`.
-  R visitUnresolvedClassConstructorInvoke(
-      NewExpression node,
-      ErroneousElement element,
-      ResolutionDartType type,
-      NodeList arguments,
-      Selector selector,
-      A arg);
-
-  /// Constant invocation of a non-constant constructor.
-  ///
-  /// For instance:
-  ///
-  ///     class C {
-  ///       C(a, b);
-  ///     }
-  ///     m() => const C(true, 42);
-  ///
-  R errorNonConstantConstructorInvoke(
-      NewExpression node,
-      Element element,
-      ResolutionDartType type,
-      NodeList arguments,
-      CallStructure callStructure,
-      A arg);
-
-  /// Invocation of a constructor on an abstract [type] with [arguments].
-  ///
-  /// For instance:
-  ///
-  ///     m() => new Unresolved(true, 42);
-  ///
-  /// where [type] is the malformed type `Unresolved`.
-  ///
-  R visitAbstractClassConstructorInvoke(
-      NewExpression node,
-      ConstructorElement element,
-      ResolutionInterfaceType type,
-      NodeList arguments,
-      CallStructure callStructure,
-      A arg);
-
-  /// Invocation of a factory [constructor] on [type] with [arguments] where
-  /// [effectiveTarget] and [effectiveTargetType] are the constructor effective
-  /// invoked and its type, respectively.
-  ///
-  /// For instance:
-  ///
-  ///     class C {
-  ///       factory C(a, b) = Unresolved;
-  ///       factory C.a(a, b) = C.unresolved;
-  ///     }
-  ///     m1() => new C(true, 42);
-  ///     m2() => new C.a(true, 42);
-  ///
-  R visitUnresolvedRedirectingFactoryConstructorInvoke(
-      NewExpression node,
-      ConstructorElement constructor,
-      ResolutionInterfaceType type,
-      NodeList arguments,
-      CallStructure callStructure,
-      A arg);
-
-  /// Invocation of [constructor] on [type] with incompatible [arguments].
-  ///
-  /// For instance:
-  ///
-  ///     class C {
-  ///       C(a);
-  ///     }
-  ///     m() => C(true, 42);
-  ///
-  R visitConstructorIncompatibleInvoke(
-      NewExpression node,
-      ConstructorElement constructor,
-      ResolutionInterfaceType type,
-      NodeList arguments,
-      CallStructure callStructure,
-      A arg);
-
-  /// Read access of an invalid expression.
-  ///
-  /// For instance:
-  ///
-  ///     import 'foo.dart' as p;
-  ///
-  ///     m() => p;
-  ///
-  R errorInvalidGet(Send node, ErroneousElement error, A arg);
-
-  /// Invocation of an invalid expression with [arguments].
-  ///
-  /// For instance:
-  ///
-  ///     import 'foo.dart' as p;
-  ///
-  ///     m() => p(null, 42);
-  ///
-  R errorInvalidInvoke(Send node, ErroneousElement error, NodeList arguments,
-      Selector selector, A arg);
-
-  /// Assignment of [rhs] to an invalid expression.
-  ///
-  /// For instance:
-  ///
-  ///     import 'foo.dart' as p;
-  ///
-  ///     m() { p = 42; }
-  ///
-  R errorInvalidSet(Send node, ErroneousElement error, Node rhs, A arg);
-
-  /// Prefix operation on an invalid expression.
-  ///
-  /// For instance:
-  ///
-  ///     import 'foo.dart' as p;
-  ///
-  ///     m() => ++p;
-  ///
-  R errorInvalidPrefix(
-      Send node, ErroneousElement error, IncDecOperator operator, A arg);
-
-  /// Postfix operation on an invalid expression.
-  ///
-  /// For instance:
-  ///
-  ///     import 'foo.dart' as p;
-  ///
-  ///     m() => p--;
-  ///
-  R errorInvalidPostfix(
-      Send node, ErroneousElement error, IncDecOperator operator, A arg);
-
-  /// Compound assignment of [operator] with [rhs] on an invalid expression.
-  ///
-  /// For instance:
-  ///
-  ///     import 'foo.dart' as p;
-  ///
-  ///     m() => p += 42;
-  ///
-  R errorInvalidCompound(Send node, ErroneousElement error,
-      AssignmentOperator operator, Node rhs, A arg);
-
-  /// If-null assignment expression of [rhs] to [index] on the index operators
-  /// of an invalid expression.
-  ///
-  /// For instance:
-  ///
-  ///     import 'foo.dart' as p;
-  ///
-  ///     m(index, rhs) => p[index] ??= rhs;
-  ///
-  R errorInvalidIndexSetIfNull(
-      SendSet node, ErroneousElement error, Node index, Node rhs, A arg);
-
-  /// Unary operation with [operator] on an invalid expression.
-  ///
-  /// For instance:
-  ///
-  ///     class C {
-  ///       static m() => ~super;
-  ///     }
-  ///
-  R errorInvalidUnary(
-      Send node, UnaryOperator operator, ErroneousElement error, A arg);
-
-  /// Equals operation on an invalid left expression.
-  ///
-  /// For instance:
-  ///
-  ///     class C {
-  ///       static m() => super == null;
-  ///     }
-  ///
-  R errorInvalidEquals(Send node, ErroneousElement error, Node right, A arg);
-
-  /// Not equals operation on an invalid left expression.
-  ///
-  /// For instance:
-  ///
-  ///     class C {
-  ///       static m() => super != null;
-  ///     }
-  ///
-  R errorInvalidNotEquals(Send node, ErroneousElement error, Node right, A arg);
-
-  /// Binary operation with [operator] on an invalid left expression.
-  ///
-  /// For instance:
-  ///
-  ///     class C {
-  ///       static m() => super + 0;
-  ///     }
-  ///
-  R errorInvalidBinary(Send node, ErroneousElement error,
-      BinaryOperator operator, Node right, A arg);
-
-  /// Index operation on an invalid expression.
-  ///
-  /// For instance:
-  ///
-  ///     class C {
-  ///       static m() => super[0];
-  ///     }
-  ///
-  R errorInvalidIndex(Send node, ErroneousElement error, Node index, A arg);
-
-  /// Index set operation on an invalid expression.
-  ///
-  /// For instance:
-  ///
-  ///     class C {
-  ///       static m() => super[0] = 42;
-  ///     }
-  ///
-  R errorInvalidIndexSet(
-      Send node, ErroneousElement error, Node index, Node rhs, A arg);
-
-  /// Compound index set operation on an invalid expression.
-  ///
-  /// For instance:
-  ///
-  ///     class C {
-  ///       static m() => super[0] += 42;
-  ///     }
-  ///
-  R errorInvalidCompoundIndexSet(Send node, ErroneousElement error, Node index,
-      AssignmentOperator operator, Node rhs, A arg);
-
-  /// Prefix index operation on an invalid expression.
-  ///
-  /// For instance:
-  ///
-  ///     class C {
-  ///       static m() => --super[0];
-  ///     }
-  ///
-  R errorInvalidIndexPrefix(Send node, ErroneousElement error, Node index,
-      IncDecOperator operator, A arg);
-
-  /// Postfix index operation on an invalid expression.
-  ///
-  /// For instance:
-  ///
-  ///     class C {
-  ///       static m() => super[0]++;
-  ///     }
-  ///
-  R errorInvalidIndexPostfix(Send node, ErroneousElement error, Node index,
-      IncDecOperator operator, A arg);
-
-  /// Access of library through a deferred [prefix].
-  ///
-  /// For instance:
-  ///
-  ///     import 'lib.dart' deferred as prefix;
-  ///
-  ///     m() => prefix.foo;
-  ///
-  /// This visit method is special in that it is called as a pre-step to calling
-  /// the visit method for the actual access. Therefore this method cannot
-  /// return a result to its caller.
-  void previsitDeferredAccess(Send node, PrefixElement prefix, A arg);
-}
-
-abstract class SemanticDeclarationVisitor<R, A> {
-  R apply(Node node, A arg);
-
-  /// Apply this visitor to the [parameters].
-  applyParameters(NodeList parameters, A arg);
-
-  /// Apply this visitor to the initializers of [constructor].
-  applyInitializers(FunctionExpression constructor, A arg);
-
-  /// A declaration of a top level [getter].
-  ///
-  /// For instance:
-  ///
-  ///     get m => 42;
-  ///
-  R visitTopLevelGetterDeclaration(
-      FunctionExpression node, GetterElement getter, Node body, A arg);
-
-  /// A declaration of a top level [setter].
-  ///
-  /// For instance:
-  ///
-  ///     set m(a) {}
-  ///
-  R visitTopLevelSetterDeclaration(FunctionExpression node,
-      SetterElement setter, NodeList parameters, Node body, A arg);
-
-  /// A declaration of a top level [function].
-  ///
-  /// For instance:
-  ///
-  ///     m(a) {}
-  ///
-  R visitTopLevelFunctionDeclaration(FunctionExpression node,
-      MethodElement function, NodeList parameters, Node body, A arg);
-
-  /// A declaration of a static [getter].
-  ///
-  /// For instance:
-  ///
-  ///     class C {
-  ///       static get m => 42;
-  ///     }
-  ///
-  R visitStaticGetterDeclaration(
-      FunctionExpression node, GetterElement getter, Node body, A arg);
-
-  /// A declaration of a static [setter].
-  ///
-  /// For instance:
-  ///
-  ///     class C {
-  ///       static set m(a) {}
-  ///     }
-  ///
-  R visitStaticSetterDeclaration(FunctionExpression node, SetterElement setter,
-      NodeList parameters, Node body, A arg);
-
-  /// A declaration of a static [function].
-  ///
-  /// For instance:
-  ///
-  ///     class C {
-  ///       static m(a) {}
-  ///     }
-  ///
-  R visitStaticFunctionDeclaration(FunctionExpression node,
-      MethodElement function, NodeList parameters, Node body, A arg);
-
-  /// A declaration of an abstract instance [getter].
-  ///
-  /// For instance:
-  ///
-  ///     abstract class C {
-  ///       get m;
-  ///     }
-  ///
-  R visitAbstractGetterDeclaration(
-      FunctionExpression node, GetterElement getter, A arg);
-
-  /// A declaration of an abstract instance [setter].
-  ///
-  /// For instance:
-  ///
-  ///     abstract class C {
-  ///       set m(a);
-  ///     }
-  ///
-  R visitAbstractSetterDeclaration(FunctionExpression node,
-      SetterElement setter, NodeList parameters, A arg);
-
-  /// A declaration of an abstract instance [method].
-  ///
-  /// For instance:
-  ///
-  ///     abstract class C {
-  ///       m(a);
-  ///     }
-  ///
-  R visitAbstractMethodDeclaration(FunctionExpression node,
-      MethodElement method, NodeList parameters, A arg);
-
-  /// A declaration of an instance [getter].
-  ///
-  /// For instance:
-  ///
-  ///     class C {
-  ///       get m => 42;
-  ///     }
-  ///
-  R visitInstanceGetterDeclaration(
-      FunctionExpression node, GetterElement getter, Node body, A arg);
-
-  /// A declaration of an instance [setter].
-  ///
-  /// For instance:
-  ///
-  ///     class C {
-  ///       set m(a) {}
-  ///     }
-  ///
-  R visitInstanceSetterDeclaration(FunctionExpression node,
-      SetterElement setter, NodeList parameters, Node body, A arg);
-
-  /// A declaration of an instance [method].
-  ///
-  /// For instance:
-  ///
-  ///     class C {
-  ///       m(a) {}
-  ///     }
-  ///
-  R visitInstanceMethodDeclaration(FunctionExpression node,
-      MethodElement method, NodeList parameters, Node body, A arg);
-
-  /// A declaration of a local [function].
-  ///
-  /// For instance `local` in:
-  ///
-  ///     m() {
-  ///       local(a) {}
-  ///     }
-  ///
-  R visitLocalFunctionDeclaration(FunctionExpression node,
-      LocalFunctionElement function, NodeList parameters, Node body, A arg);
-
-  /// A declaration of a [closure].
-  ///
-  /// For instance `(a) {}` in:
-  ///
-  ///     m() {
-  ///       var closure = (a) {};
-  ///     }
-  ///
-  R visitClosureDeclaration(FunctionExpression node,
-      LocalFunctionElement closure, NodeList parameters, Node body, A arg);
-
-  /// A declaration of the [index]th [parameter] in a constructor, setter,
-  /// method or function.
-  ///
-  /// For instance `a` in:
-  ///
-  ///     m(a) {}
-  ///
-  R visitParameterDeclaration(VariableDefinitions node, Node definition,
-      ParameterElement parameter, int index, A arg);
-
-  /// A declaration of the [index]th optional [parameter] in a constructor,
-  /// method or function with the explicit [defaultValue]. If no default value
-  /// is declared, [defaultValue] is `null`.
-  ///
-  /// For instance `a` in:
-  ///
-  ///     m([a = 42]) {}
-  ///
-  R visitOptionalParameterDeclaration(
-      VariableDefinitions node,
-      Node definition,
-      ParameterElement parameter,
-      ConstantExpression defaultValue,
-      int index,
-      A arg);
-
-  /// A declaration of a named [parameter] in a constructor, method or function
-  /// with the explicit [defaultValue]. If no default value is declared,
-  /// [defaultValue] is `null`.
-  ///
-  /// For instance `a` in:
-  ///
-  ///     m({a: 42}) {}
-  ///
-  R visitNamedParameterDeclaration(VariableDefinitions node, Node definition,
-      ParameterElement parameter, ConstantExpression defaultValue, A arg);
-
-  /// A declaration of the [index]th [parameter] as an initializing formal in a
-  /// constructor.
-  ///
-  /// For instance `a` in:
-  ///
-  ///     class C {
-  ///       var a;
-  ///       C(this.a);
-  ///     }
-  ///
-  R visitInitializingFormalDeclaration(VariableDefinitions node,
-      Node definition, InitializingFormalElement parameter, int index, A arg);
-
-  /// A declaration of the [index]th optional [parameter] as an initializing
-  /// formal in a constructor with the explicit [defaultValue]. If no default
-  /// value is declared, [defaultValue] is `null`.
-  ///
-  /// For instance `a` in:
-  ///
-  ///     class C {
-  ///       var a;
-  ///       C([this.a = 42]);
-  ///     }
-  ///
-  R visitOptionalInitializingFormalDeclaration(
-      VariableDefinitions node,
-      Node definition,
-      InitializingFormalElement parameter,
-      ConstantExpression defaultValue,
-      int index,
-      A arg);
-
-  /// A declaration of a named [parameter] as an initializing formal in a
-  /// constructor with the explicit [defaultValue]. If no default value is
-  /// declared, [defaultValue] is `null`.
-  ///
-  /// For instance `a` in:
-  ///
-  ///     class C {
-  ///       var a;
-  ///       C({this.a: 42});
-  ///     }
-  ///
-  R visitNamedInitializingFormalDeclaration(
-      VariableDefinitions node,
-      Node definition,
-      InitializingFormalElement parameter,
-      ConstantExpression defaultValue,
-      A arg);
-
-  /// A declaration of a local [variable] with the explicit [initializer]. If
-  /// no initializer is declared, [initializer] is `null`.
-  ///
-  /// For instance `a` in:
-  ///
-  ///     m() {
-  ///       var a = 42;
-  ///     }
-  ///
-  R visitLocalVariableDeclaration(VariableDefinitions node, Node definition,
-      LocalVariableElement variable, Node initializer, A arg);
-
-  /// A declaration of a local constant [variable] initialized to [constant].
-  ///
-  /// For instance `a` in:
-  ///
-  ///     m() {
-  ///       const a = 42;
-  ///     }
-  ///
-  R visitLocalConstantDeclaration(VariableDefinitions node, Node definition,
-      LocalVariableElement variable, ConstantExpression constant, A arg);
-
-  /// A declaration of a top level [field] with the explicit [initializer].
-  /// If no initializer is declared, [initializer] is `null`.
-  ///
-  /// For instance `a` in:
-  ///
-  ///     var a = 42;
-  ///
-  R visitTopLevelFieldDeclaration(VariableDefinitions node, Node definition,
-      FieldElement field, Node initializer, A arg);
-
-  /// A declaration of a top level constant [field] initialized to [constant].
-  ///
-  /// For instance `a` in:
-  ///
-  ///     const a = 42;
-  ///
-  R visitTopLevelConstantDeclaration(VariableDefinitions node, Node definition,
-      FieldElement field, ConstantExpression constant, A arg);
-
-  /// A declaration of a static [field] with the explicit [initializer].
-  /// If no initializer is declared, [initializer] is `null`.
-  ///
-  /// For instance `a` in:
-  ///
-  ///     class C {
-  ///       static var a = 42;
-  ///     }
-  ///
-  R visitStaticFieldDeclaration(VariableDefinitions node, Node definition,
-      FieldElement field, Node initializer, A arg);
-
-  /// A declaration of a static constant [field] initialized to [constant].
-  ///
-  /// For instance `a` in:
-  ///
-  ///     class C {
-  ///       static const a = 42;
-  ///     }
-  ///
-  R visitStaticConstantDeclaration(VariableDefinitions node, Node definition,
-      FieldElement field, ConstantExpression constant, A arg);
-
-  /// A declaration of an instance [field] with the explicit [initializer].
-  /// If no initializer is declared, [initializer] is `null`.
-  ///
-  /// For instance `a` in:
-  ///
-  ///     class C {
-  ///       var a = 42;
-  ///     }
-  ///
-  R visitInstanceFieldDeclaration(VariableDefinitions node, Node definition,
-      FieldElement field, Node initializer, A arg);
-
-  /// A declaration of a generative [constructor] with the explicit constructor
-  /// [initializers].
-  ///
-  /// For instance `C` in:
-  ///
-  ///     class C {
-  ///       var a;
-  ///       C(a) : this.a = a, super();
-  ///     }
-  ///
-  // TODO(johnniwinther): Replace [initializers] with a structure like
-  // [InitializersStructure] when computed in resolution.
-  R visitGenerativeConstructorDeclaration(
-      FunctionExpression node,
-      ConstructorElement constructor,
-      NodeList parameters,
-      NodeList initializers,
-      Node body,
-      A arg);
-
-  /// A declaration of a redirecting generative [constructor] with
-  /// [initializers] containing the redirecting constructor invocation.
-  ///
-  /// For instance `C` in:
-  ///
-  ///     class C {
-  ///       C() : this._();
-  ///       C._();
-  ///     }
-  ///
-  // TODO(johnniwinther): Replace [initializers] with a single
-  // [ThisConstructorInvokeStructure] when computed in resolution.
-  R visitRedirectingGenerativeConstructorDeclaration(
-      FunctionExpression node,
-      ConstructorElement constructor,
-      NodeList parameters,
-      NodeList initializers,
-      A arg);
-
-  /// A declaration of a factory [constructor].
-  ///
-  /// For instance `C` in:
-  ///
-  ///     class C {
-  ///       factory C(a) => null;
-  ///     }
-  ///
-  R visitFactoryConstructorDeclaration(FunctionExpression node,
-      ConstructorElement constructor, NodeList parameters, Node body, A arg);
-
-  /// A declaration of a redirecting factory [constructor]. The immediate
-  /// redirection target and its type is provided in [redirectionTarget] and
-  /// [redirectionType], respectively.
-  ///
-  /// For instance:
-  ///
-  ///    class C<T> {
-  ///      factory C() = C<int>.a;
-  ///      factory C.a() = C<C<T>>.b;
-  ///      C.b();
-  ///    }
-  /// where `C` has the redirection target `C.a` of type `C<int>` and `C.a` has
-  /// the redirection target `C.b` of type `C<C<T>>`.
-  ///
-  R visitRedirectingFactoryConstructorDeclaration(
-      FunctionExpression node,
-      ConstructorElement constructor,
-      NodeList parameters,
-      ResolutionInterfaceType redirectionType,
-      ConstructorElement redirectionTarget,
-      A arg);
-
-  /// An initializer of [field] with [initializer] as found in constructor
-  /// initializers.
-  ///
-  /// For instance `this.a = 42` in:
-  ///
-  ///     class C {
-  ///       var a;
-  ///       C() : this.a = 42;
-  ///     }
-  ///
-  R visitFieldInitializer(
-      SendSet node, FieldElement field, Node initializer, A arg);
-
-  /// An initializer of an unresolved field with [initializer] as found in
-  /// generative constructor initializers.
-  ///
-  /// For instance `this.a = 42` in:
-  ///
-  ///     class C {
-  ///       C() : this.a = 42;
-  ///     }
-  ///
-  R errorUnresolvedFieldInitializer(
-      SendSet node, Element element, Node initializer, A arg);
-
-  /// An super constructor invocation of [superConstructor] with [arguments] as
-  /// found in generative constructor initializers.
-  ///
-  /// For instance `super(42)` in:
-  ///
-  ///     class B {
-  ///       B(a);
-  ///     }
-  ///     class C extends B {
-  ///       C() : super(42);
-  ///     }
-  ///
-  R visitSuperConstructorInvoke(
-      Send node,
-      ConstructorElement superConstructor,
-      ResolutionInterfaceType type,
-      NodeList arguments,
-      CallStructure callStructure,
-      A arg);
-
-  /// An implicit super constructor invocation of [superConstructor] from
-  /// generative constructor initializers.
-  ///
-  /// For instance `super(42)` in:
-  ///
-  ///     class B {
-  ///       B();
-  ///     }
-  ///     class C extends B {
-  ///       C(); // Implicit super call of B().
-  ///     }
-  ///
-  R visitImplicitSuperConstructorInvoke(FunctionExpression node,
-      ConstructorElement superConstructor, ResolutionInterfaceType type, A arg);
-
-  /// An super constructor invocation of an unresolved with [arguments] as
-  /// found in generative constructor initializers.
-  ///
-  /// For instance `super(42)` in:
-  ///
-  ///     class B {
-  ///       B(a);
-  ///     }
-  ///     class C extends B {
-  ///       C() : super.unresolved(42);
-  ///     }
-  ///
-  R errorUnresolvedSuperConstructorInvoke(
-      Send node, Element element, NodeList arguments, Selector selector, A arg);
-
-  /// An this constructor invocation of [thisConstructor] with [arguments] as
-  /// found in a redirecting generative constructors initializer.
-  ///
-  /// For instance `this._(42)` in:
-  ///
-  ///     class C {
-  ///       C() : this._(42);
-  ///       C._(a);
-  ///     }
-  ///
-  R visitThisConstructorInvoke(Send node, ConstructorElement thisConstructor,
-      NodeList arguments, CallStructure callStructure, A arg);
-
-  /// An this constructor invocation of an unresolved constructor with
-  /// [arguments] as found in a redirecting generative constructors initializer.
-  ///
-  /// For instance `this._(42)` in:
-  ///
-  ///     class C {
-  ///       C() : this._(42);
-  ///     }
-  ///
-  R errorUnresolvedThisConstructorInvoke(
-      Send node, Element element, NodeList arguments, Selector selector, A arg);
-}
diff --git a/pkg/compiler/lib/src/resolution/semantic_visitor_mixins.dart b/pkg/compiler/lib/src/resolution/semantic_visitor_mixins.dart
deleted file mode 100644
index 7f6d668..0000000
--- a/pkg/compiler/lib/src/resolution/semantic_visitor_mixins.dart
+++ /dev/null
@@ -1,8337 +0,0 @@
-// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-part of dart2js.semantics_visitor;
-
-/// Interface for bulk handling of a [Node] in a semantic visitor.
-abstract class BulkHandle<R, A> {
-  /// Handle [node] either regardless of semantics or to report that [node] is
-  /// unhandled. [message] contains a message template for the latter case:
-  /// Replace '#' in [message] by `node.toString()` to create a message for the
-  /// error.
-  R bulkHandleNode(Node node, String message, A arg);
-}
-
-/// Mixin that implements all `errorX` methods of [SemanticSendVisitor] by
-/// delegating to a bulk handler.
-///
-/// Use this mixin to provide a trivial implementation for all `errorX` methods.
-abstract class ErrorBulkMixin<R, A>
-    implements SemanticSendVisitor<R, A>, BulkHandle<R, A> {
-  // TODO(johnniwinther): Ensure that all error methods have an
-  // [ErroneousElement].
-  R bulkHandleError(Node node, ErroneousElement error, A arg) {
-    return bulkHandleNode(node, "Error expression `#` unhandled.", arg);
-  }
-
-  @override
-  R errorNonConstantConstructorInvoke(
-      NewExpression node,
-      Element element,
-      ResolutionDartType type,
-      NodeList arguments,
-      CallStructure callStructure,
-      A arg) {
-    return bulkHandleError(node, null, arg);
-  }
-
-  @override
-  R errorUndefinedUnaryExpression(
-      Send node, Operator operator, Node expression, A arg) {
-    return bulkHandleError(node, null, arg);
-  }
-
-  @override
-  R errorUndefinedBinaryExpression(
-      Send node, Node left, Operator operator, Node right, A arg) {
-    return bulkHandleError(node, null, arg);
-  }
-
-  @override
-  R errorInvalidCompound(Send node, ErroneousElement error,
-      AssignmentOperator operator, Node rhs, A arg) {
-    return bulkHandleError(node, error, arg);
-  }
-
-  @override
-  R errorInvalidGet(Send node, ErroneousElement error, A arg) {
-    return bulkHandleError(node, error, arg);
-  }
-
-  @override
-  R errorInvalidInvoke(Send node, ErroneousElement error, NodeList arguments,
-      Selector selector, A arg) {
-    return bulkHandleError(node, error, arg);
-  }
-
-  @override
-  R errorInvalidPostfix(
-      Send node, ErroneousElement error, IncDecOperator operator, A arg) {
-    return bulkHandleError(node, error, arg);
-  }
-
-  @override
-  R errorInvalidPrefix(
-      Send node, ErroneousElement error, IncDecOperator operator, A arg) {
-    return bulkHandleError(node, error, arg);
-  }
-
-  @override
-  R errorInvalidSet(Send node, ErroneousElement error, Node rhs, A arg) {
-    return bulkHandleError(node, error, arg);
-  }
-
-  @override
-  R errorInvalidUnary(
-      Send node, UnaryOperator operator, ErroneousElement error, A arg) {
-    return bulkHandleError(node, error, arg);
-  }
-
-  @override
-  R errorInvalidEquals(Send node, ErroneousElement error, Node right, A arg) {
-    return bulkHandleError(node, error, arg);
-  }
-
-  @override
-  R errorInvalidNotEquals(
-      Send node, ErroneousElement error, Node right, A arg) {
-    return bulkHandleError(node, error, arg);
-  }
-
-  @override
-  R errorInvalidBinary(Send node, ErroneousElement error,
-      BinaryOperator operator, Node right, A arg) {
-    return bulkHandleError(node, error, arg);
-  }
-
-  @override
-  R errorInvalidIndex(Send node, ErroneousElement error, Node index, A arg) {
-    return bulkHandleError(node, error, arg);
-  }
-
-  @override
-  R errorInvalidIndexSet(
-      Send node, ErroneousElement error, Node index, Node rhs, A arg) {
-    return bulkHandleError(node, error, arg);
-  }
-
-  @override
-  R errorInvalidCompoundIndexSet(Send node, ErroneousElement error, Node index,
-      AssignmentOperator operator, Node rhs, A arg) {
-    return bulkHandleError(node, error, arg);
-  }
-
-  @override
-  R errorInvalidIndexSetIfNull(
-      SendSet node, ErroneousElement error, Node index, Node rhs, A arg) {
-    return bulkHandleError(node, error, arg);
-  }
-
-  @override
-  R errorInvalidIndexPrefix(Send node, ErroneousElement error, Node index,
-      IncDecOperator operator, A arg) {
-    return bulkHandleError(node, error, arg);
-  }
-
-  @override
-  R errorInvalidIndexPostfix(Send node, ErroneousElement error, Node index,
-      IncDecOperator operator, A arg) {
-    return bulkHandleError(node, error, arg);
-  }
-
-  @override
-  R errorInvalidSetIfNull(Send node, ErroneousElement error, Node rhs, A arg) {
-    return bulkHandleError(node, error, arg);
-  }
-}
-
-/// Mixin that implements all `visitXPrefix` methods of [SemanticSendVisitor] by
-/// delegating to a bulk handler.
-///
-/// Use this mixin to provide a trivial implementation for all `visitXPrefix`
-/// methods.
-abstract class PrefixBulkMixin<R, A>
-    implements SemanticSendVisitor<R, A>, BulkHandle<R, A> {
-  R bulkHandlePrefix(SendSet node, A arg) {
-    return bulkHandleNode(node, "Prefix expression `#` unhandled.", arg);
-  }
-
-  @override
-  R visitDynamicPropertyPrefix(
-      Send node, Node receiver, Name name, IncDecOperator operator, A arg) {
-    return bulkHandlePrefix(node, arg);
-  }
-
-  R visitIfNotNullDynamicPropertyPrefix(
-      Send node, Node receiver, Name name, IncDecOperator operator, A arg) {
-    return bulkHandlePrefix(node, arg);
-  }
-
-  @override
-  R visitIndexPrefix(
-      Send node, Node receiver, Node index, IncDecOperator operator, A arg) {
-    return bulkHandlePrefix(node, arg);
-  }
-
-  @override
-  R visitLocalVariablePrefix(Send node, LocalVariableElement variable,
-      IncDecOperator operator, A arg) {
-    return bulkHandlePrefix(node, arg);
-  }
-
-  @override
-  R visitParameterPrefix(
-      Send node, ParameterElement parameter, IncDecOperator operator, A arg) {
-    return bulkHandlePrefix(node, arg);
-  }
-
-  @override
-  R visitStaticFieldPrefix(
-      Send node, FieldElement field, IncDecOperator operator, A arg) {
-    return bulkHandlePrefix(node, arg);
-  }
-
-  @override
-  R visitStaticGetterSetterPrefix(Send node, GetterElement getter,
-      SetterElement setter, IncDecOperator operator, A arg) {
-    return bulkHandlePrefix(node, arg);
-  }
-
-  @override
-  R visitStaticMethodSetterPrefix(Send node, GetterElement getter,
-      SetterElement setter, IncDecOperator operator, A arg) {
-    return bulkHandlePrefix(node, arg);
-  }
-
-  @override
-  R visitSuperFieldFieldPrefix(SendSet node, FieldElement readField,
-      FieldElement writtenField, IncDecOperator operator, A arg) {
-    return bulkHandlePrefix(node, arg);
-  }
-
-  @override
-  R visitSuperFieldPrefix(
-      SendSet node, FieldElement field, IncDecOperator operator, A arg) {
-    return bulkHandlePrefix(node, arg);
-  }
-
-  @override
-  R visitSuperFieldSetterPrefix(SendSet node, FieldElement field,
-      SetterElement setter, IncDecOperator operator, A arg) {
-    return bulkHandlePrefix(node, arg);
-  }
-
-  @override
-  R visitSuperGetterFieldPrefix(SendSet node, GetterElement getter,
-      FieldElement field, IncDecOperator operator, A arg) {
-    return bulkHandlePrefix(node, arg);
-  }
-
-  @override
-  R visitSuperGetterSetterPrefix(SendSet node, GetterElement getter,
-      SetterElement setter, IncDecOperator operator, A arg) {
-    return bulkHandlePrefix(node, arg);
-  }
-
-  @override
-  R visitSuperIndexPrefix(
-      Send node,
-      MethodElement indexFunction,
-      MethodElement indexSetFunction,
-      Node index,
-      IncDecOperator operator,
-      A arg) {
-    return bulkHandlePrefix(node, arg);
-  }
-
-  @override
-  R visitUnresolvedSuperGetterIndexPrefix(SendSet node, Element element,
-      MethodElement setter, Node index, IncDecOperator operator, A arg) {
-    return bulkHandlePrefix(node, arg);
-  }
-
-  @override
-  R visitUnresolvedSuperSetterIndexPrefix(SendSet node, MethodElement getter,
-      Element element, Node index, IncDecOperator operator, A arg) {
-    return bulkHandlePrefix(node, arg);
-  }
-
-  @override
-  R visitUnresolvedSuperIndexPrefix(
-      Send node, Element element, Node index, IncDecOperator operator, A arg) {
-    return bulkHandlePrefix(node, arg);
-  }
-
-  @override
-  R visitSuperMethodSetterPrefix(SendSet node, FunctionElement method,
-      SetterElement setter, IncDecOperator operator, A arg) {
-    return bulkHandlePrefix(node, arg);
-  }
-
-  @override
-  R visitThisPropertyPrefix(
-      Send node, Name name, IncDecOperator operator, A arg) {
-    return bulkHandlePrefix(node, arg);
-  }
-
-  @override
-  R visitTopLevelFieldPrefix(
-      Send node, FieldElement field, IncDecOperator operator, A arg) {
-    return bulkHandlePrefix(node, arg);
-  }
-
-  @override
-  R visitTopLevelGetterSetterPrefix(Send node, GetterElement getter,
-      SetterElement setter, IncDecOperator operator, A arg) {
-    return bulkHandlePrefix(node, arg);
-  }
-
-  @override
-  R visitTopLevelMethodSetterPrefix(Send node, FunctionElement method,
-      SetterElement setter, IncDecOperator operator, A arg) {
-    return bulkHandlePrefix(node, arg);
-  }
-
-  @override
-  R visitClassTypeLiteralPrefix(
-      Send node, ConstantExpression constant, IncDecOperator operator, A arg) {
-    return bulkHandlePrefix(node, arg);
-  }
-
-  @override
-  R visitDynamicTypeLiteralPrefix(
-      Send node, ConstantExpression constant, IncDecOperator operator, A arg) {
-    return bulkHandlePrefix(node, arg);
-  }
-
-  @override
-  R visitLocalFunctionPrefix(Send node, LocalFunctionElement function,
-      IncDecOperator operator, A arg) {
-    return bulkHandlePrefix(node, arg);
-  }
-
-  @override
-  R visitTypeVariableTypeLiteralPrefix(
-      Send node, TypeVariableElement element, IncDecOperator operator, A arg) {
-    return bulkHandlePrefix(node, arg);
-  }
-
-  @override
-  R visitTypedefTypeLiteralPrefix(
-      Send node, ConstantExpression constant, IncDecOperator operator, A arg) {
-    return bulkHandlePrefix(node, arg);
-  }
-
-  @override
-  R visitUnresolvedStaticGetterPrefix(Send node, Element element,
-      MethodElement setter, IncDecOperator operator, A arg) {
-    return bulkHandlePrefix(node, arg);
-  }
-
-  @override
-  R visitUnresolvedTopLevelGetterPrefix(Send node, Element element,
-      MethodElement setter, IncDecOperator operator, A arg) {
-    return bulkHandlePrefix(node, arg);
-  }
-
-  @override
-  R visitUnresolvedStaticSetterPrefix(Send node, GetterElement getter,
-      Element element, IncDecOperator operator, A arg) {
-    return bulkHandlePrefix(node, arg);
-  }
-
-  @override
-  R visitUnresolvedTopLevelSetterPrefix(Send node, GetterElement getter,
-      Element element, IncDecOperator operator, A arg) {
-    return bulkHandlePrefix(node, arg);
-  }
-
-  @override
-  R visitStaticMethodPrefix(
-      Send node, MethodElement method, IncDecOperator operator, A arg) {
-    return bulkHandlePrefix(node, arg);
-  }
-
-  @override
-  R visitTopLevelMethodPrefix(
-      Send node, MethodElement method, IncDecOperator operator, A arg) {
-    return bulkHandlePrefix(node, arg);
-  }
-
-  @override
-  R visitUnresolvedPrefix(
-      Send node, ErroneousElement element, IncDecOperator operator, A arg) {
-    return bulkHandlePrefix(node, arg);
-  }
-
-  @override
-  R visitFinalLocalVariablePrefix(Send node, LocalVariableElement variable,
-      IncDecOperator operator, A arg) {
-    return bulkHandlePrefix(node, arg);
-  }
-
-  @override
-  R visitFinalParameterPrefix(
-      Send node, ParameterElement parameter, IncDecOperator operator, A arg) {
-    return bulkHandlePrefix(node, arg);
-  }
-
-  @override
-  R visitFinalStaticFieldPrefix(
-      Send node, FieldElement field, IncDecOperator operator, A arg) {
-    return bulkHandlePrefix(node, arg);
-  }
-
-  @override
-  R visitFinalSuperFieldPrefix(
-      Send node, FieldElement field, IncDecOperator operator, A arg) {
-    return bulkHandlePrefix(node, arg);
-  }
-
-  @override
-  R visitSuperMethodPrefix(
-      Send node, MethodElement method, IncDecOperator operator, A arg) {
-    return bulkHandlePrefix(node, arg);
-  }
-
-  @override
-  R visitFinalTopLevelFieldPrefix(
-      Send node, FieldElement field, IncDecOperator operator, A arg) {
-    return bulkHandlePrefix(node, arg);
-  }
-
-  @override
-  R visitUnresolvedSuperPrefix(
-      SendSet node, Element element, IncDecOperator operator, A arg) {
-    return bulkHandlePrefix(node, arg);
-  }
-
-  @override
-  R visitUnresolvedSuperGetterPrefix(SendSet node, Element element,
-      SetterElement setter, IncDecOperator operator, A arg) {
-    return bulkHandlePrefix(node, arg);
-  }
-
-  @override
-  R visitUnresolvedSuperSetterPrefix(SendSet node, GetterElement getter,
-      Element element, IncDecOperator operator, A arg) {
-    return bulkHandlePrefix(node, arg);
-  }
-}
-
-/// Mixin that implements all `visitXPostfix` methods of [SemanticSendVisitor]
-/// by delegating to a bulk handler.
-///
-/// Use this mixin to provide a trivial implementation for all `visitXPostfix`
-/// methods.
-abstract class PostfixBulkMixin<R, A>
-    implements SemanticSendVisitor<R, A>, BulkHandle<R, A> {
-  R bulkHandlePostfix(SendSet node, A arg) {
-    return bulkHandleNode(node, "Postfix expression `#` unhandled.", arg);
-  }
-
-  @override
-  R visitDynamicPropertyPostfix(
-      Send node, Node receiver, Name name, IncDecOperator operator, A arg) {
-    return bulkHandlePostfix(node, arg);
-  }
-
-  @override
-  R visitIfNotNullDynamicPropertyPostfix(
-      Send node, Node receiver, Name name, IncDecOperator operator, A arg) {
-    return bulkHandlePostfix(node, arg);
-  }
-
-  R visitIndexPostfix(
-      Send node, Node receiver, Node index, IncDecOperator operator, A arg) {
-    return bulkHandlePostfix(node, arg);
-  }
-
-  @override
-  R visitLocalVariablePostfix(Send node, LocalVariableElement variable,
-      IncDecOperator operator, A arg) {
-    return bulkHandlePostfix(node, arg);
-  }
-
-  @override
-  R visitParameterPostfix(
-      Send node, ParameterElement parameter, IncDecOperator operator, A arg) {
-    return bulkHandlePostfix(node, arg);
-  }
-
-  @override
-  R visitStaticFieldPostfix(
-      Send node, FieldElement field, IncDecOperator operator, A arg) {
-    return bulkHandlePostfix(node, arg);
-  }
-
-  @override
-  R visitStaticGetterSetterPostfix(Send node, GetterElement getter,
-      SetterElement setter, IncDecOperator operator, A arg) {
-    return bulkHandlePostfix(node, arg);
-  }
-
-  @override
-  R visitStaticMethodSetterPostfix(Send node, GetterElement getter,
-      SetterElement setter, IncDecOperator operator, A arg) {
-    return bulkHandlePostfix(node, arg);
-  }
-
-  @override
-  R visitSuperFieldFieldPostfix(SendSet node, FieldElement readField,
-      FieldElement writtenField, IncDecOperator operator, A arg) {
-    return bulkHandlePostfix(node, arg);
-  }
-
-  @override
-  R visitSuperFieldPostfix(
-      SendSet node, FieldElement field, IncDecOperator operator, A arg) {
-    return bulkHandlePostfix(node, arg);
-  }
-
-  @override
-  R visitSuperFieldSetterPostfix(SendSet node, FieldElement field,
-      SetterElement setter, IncDecOperator operator, A arg) {
-    return bulkHandlePostfix(node, arg);
-  }
-
-  @override
-  R visitSuperGetterFieldPostfix(SendSet node, GetterElement getter,
-      FieldElement field, IncDecOperator operator, A arg) {
-    return bulkHandlePostfix(node, arg);
-  }
-
-  @override
-  R visitSuperGetterSetterPostfix(SendSet node, GetterElement getter,
-      SetterElement setter, IncDecOperator operator, A arg) {
-    return bulkHandlePostfix(node, arg);
-  }
-
-  @override
-  R visitSuperIndexPostfix(
-      Send node,
-      MethodElement indexFunction,
-      MethodElement indexSetFunction,
-      Node index,
-      IncDecOperator operator,
-      A arg) {
-    return bulkHandlePostfix(node, arg);
-  }
-
-  @override
-  R visitUnresolvedSuperGetterIndexPostfix(SendSet node, Element element,
-      MethodElement setter, Node index, IncDecOperator operator, A arg) {
-    return bulkHandlePostfix(node, arg);
-  }
-
-  @override
-  R visitUnresolvedSuperSetterIndexPostfix(SendSet node, MethodElement getter,
-      Element element, Node index, IncDecOperator operator, A arg) {
-    return bulkHandlePostfix(node, arg);
-  }
-
-  @override
-  R visitUnresolvedSuperIndexPostfix(
-      Send node, Element element, Node index, IncDecOperator operator, A arg) {
-    return bulkHandlePostfix(node, arg);
-  }
-
-  @override
-  R visitSuperMethodSetterPostfix(SendSet node, FunctionElement method,
-      SetterElement setter, IncDecOperator operator, A arg) {
-    return bulkHandlePostfix(node, arg);
-  }
-
-  @override
-  R visitThisPropertyPostfix(
-      Send node, Name name, IncDecOperator operator, A arg) {
-    return bulkHandlePostfix(node, arg);
-  }
-
-  @override
-  R visitTopLevelFieldPostfix(
-      Send node, FieldElement field, IncDecOperator operator, A arg) {
-    return bulkHandlePostfix(node, arg);
-  }
-
-  @override
-  R visitTopLevelGetterSetterPostfix(Send node, GetterElement getter,
-      SetterElement setter, IncDecOperator operator, A arg) {
-    return bulkHandlePostfix(node, arg);
-  }
-
-  @override
-  R visitTopLevelMethodSetterPostfix(Send node, FunctionElement method,
-      SetterElement setter, IncDecOperator operator, A arg) {
-    return bulkHandlePostfix(node, arg);
-  }
-
-  @override
-  R visitClassTypeLiteralPostfix(
-      Send node, ConstantExpression constant, IncDecOperator operator, A arg) {
-    return bulkHandlePostfix(node, arg);
-  }
-
-  @override
-  R visitDynamicTypeLiteralPostfix(
-      Send node, ConstantExpression constant, IncDecOperator operator, A arg) {
-    return bulkHandlePostfix(node, arg);
-  }
-
-  @override
-  R visitLocalFunctionPostfix(Send node, LocalFunctionElement function,
-      IncDecOperator operator, A arg) {
-    return bulkHandlePostfix(node, arg);
-  }
-
-  @override
-  R visitTypeVariableTypeLiteralPostfix(
-      Send node, TypeVariableElement element, IncDecOperator operator, A arg) {
-    return bulkHandlePostfix(node, arg);
-  }
-
-  @override
-  R visitTypedefTypeLiteralPostfix(
-      Send node, ConstantExpression constant, IncDecOperator operator, A arg) {
-    return bulkHandlePostfix(node, arg);
-  }
-
-  @override
-  R visitUnresolvedStaticGetterPostfix(Send node, Element element,
-      MethodElement setter, IncDecOperator operator, A arg) {
-    return bulkHandlePostfix(node, arg);
-  }
-
-  @override
-  R visitUnresolvedTopLevelGetterPostfix(Send node, Element element,
-      MethodElement setter, IncDecOperator operator, A arg) {
-    return bulkHandlePostfix(node, arg);
-  }
-
-  @override
-  R visitUnresolvedStaticSetterPostfix(Send node, GetterElement getter,
-      Element element, IncDecOperator operator, A arg) {
-    return bulkHandlePostfix(node, arg);
-  }
-
-  @override
-  R visitUnresolvedTopLevelSetterPostfix(Send node, GetterElement getter,
-      Element element, IncDecOperator operator, A arg) {
-    return bulkHandlePostfix(node, arg);
-  }
-
-  @override
-  R visitStaticMethodPostfix(
-      Send node, MethodElement method, IncDecOperator operator, A arg) {
-    return bulkHandlePostfix(node, arg);
-  }
-
-  R visitToplevelMethodPostfix(
-      Send node, MethodElement method, IncDecOperator operator, A arg) {
-    return bulkHandlePostfix(node, arg);
-  }
-
-  @override
-  R visitUnresolvedPostfix(
-      Send node, ErroneousElement element, IncDecOperator operator, A arg) {
-    return bulkHandlePostfix(node, arg);
-  }
-
-  @override
-  R visitFinalLocalVariablePostfix(Send node, LocalVariableElement variable,
-      IncDecOperator operator, A arg) {
-    return bulkHandlePostfix(node, arg);
-  }
-
-  @override
-  R visitFinalParameterPostfix(
-      Send node, ParameterElement parameter, IncDecOperator operator, A arg) {
-    return bulkHandlePostfix(node, arg);
-  }
-
-  @override
-  R visitFinalStaticFieldPostfix(
-      Send node, FieldElement field, IncDecOperator operator, A arg) {
-    return bulkHandlePostfix(node, arg);
-  }
-
-  @override
-  R visitFinalSuperFieldPostfix(
-      Send node, FieldElement field, IncDecOperator operator, A arg) {
-    return bulkHandlePostfix(node, arg);
-  }
-
-  @override
-  R visitSuperMethodPostfix(
-      Send node, MethodElement method, IncDecOperator operator, A arg) {
-    return bulkHandlePostfix(node, arg);
-  }
-
-  @override
-  R visitFinalTopLevelFieldPostfix(
-      Send node, FieldElement field, IncDecOperator operator, A arg) {
-    return bulkHandlePostfix(node, arg);
-  }
-
-  @override
-  R visitTopLevelMethodPostfix(
-      Send node, MethodElement method, IncDecOperator operator, A arg) {
-    return bulkHandlePostfix(node, arg);
-  }
-
-  @override
-  R visitUnresolvedSuperPostfix(
-      SendSet node, Element element, IncDecOperator operator, A arg) {
-    return bulkHandlePostfix(node, arg);
-  }
-
-  @override
-  R visitUnresolvedSuperGetterPostfix(SendSet node, Element element,
-      SetterElement setter, IncDecOperator operator, A arg) {
-    return bulkHandlePostfix(node, arg);
-  }
-
-  @override
-  R visitUnresolvedSuperSetterPostfix(SendSet node, GetterElement getter,
-      Element element, IncDecOperator operator, A arg) {
-    return bulkHandlePostfix(node, arg);
-  }
-}
-
-/// Mixin that implements all `visitXCompound` methods of [SemanticSendVisitor]
-/// by delegating to a bulk handler.
-///
-/// Use this mixin to provide a trivial implementation for all `xCompound`
-/// methods.
-abstract class CompoundBulkMixin<R, A>
-    implements SemanticSendVisitor<R, A>, BulkHandle<R, A> {
-  R bulkHandleCompound(SendSet node, A arg) {
-    return bulkHandleNode(node, "Compound assignment `#` unhandled.", arg);
-  }
-
-  @override
-  R visitDynamicPropertyCompound(Send node, Node receiver, Name name,
-      AssignmentOperator operator, Node rhs, A arg) {
-    return bulkHandleCompound(node, arg);
-  }
-
-  @override
-  R visitIfNotNullDynamicPropertyCompound(Send node, Node receiver, Name name,
-      AssignmentOperator operator, Node rhs, A arg) {
-    return bulkHandleCompound(node, arg);
-  }
-
-  @override
-  R visitLocalVariableCompound(Send node, LocalVariableElement variable,
-      AssignmentOperator operator, Node rhs, A arg) {
-    return bulkHandleCompound(node, arg);
-  }
-
-  @override
-  R visitParameterCompound(Send node, ParameterElement parameter,
-      AssignmentOperator operator, Node rhs, A arg) {
-    return bulkHandleCompound(node, arg);
-  }
-
-  @override
-  R visitStaticFieldCompound(Send node, FieldElement field,
-      AssignmentOperator operator, Node rhs, A arg) {
-    return bulkHandleCompound(node, arg);
-  }
-
-  @override
-  R visitStaticGetterSetterCompound(Send node, GetterElement getter,
-      SetterElement setter, AssignmentOperator operator, Node rhs, A arg) {
-    return bulkHandleCompound(node, arg);
-  }
-
-  @override
-  R visitStaticMethodSetterCompound(Send node, FunctionElement method,
-      SetterElement setter, AssignmentOperator operator, Node rhs, A arg) {
-    return bulkHandleCompound(node, arg);
-  }
-
-  @override
-  R visitSuperFieldCompound(Send node, FieldElement field,
-      AssignmentOperator operator, Node rhs, A arg) {
-    return bulkHandleCompound(node, arg);
-  }
-
-  @override
-  R visitSuperFieldSetterCompound(Send node, FieldElement field,
-      SetterElement setter, AssignmentOperator operator, Node rhs, A arg) {
-    return bulkHandleCompound(node, arg);
-  }
-
-  @override
-  R visitSuperGetterFieldCompound(Send node, GetterElement getter,
-      FieldElement field, AssignmentOperator operator, Node rhs, A arg) {
-    return bulkHandleCompound(node, arg);
-  }
-
-  @override
-  R visitSuperGetterSetterCompound(Send node, GetterElement getter,
-      SetterElement setter, AssignmentOperator operator, Node rhs, A arg) {
-    return bulkHandleCompound(node, arg);
-  }
-
-  @override
-  R visitSuperMethodSetterCompound(Send node, FunctionElement method,
-      SetterElement setter, AssignmentOperator operator, Node rhs, A arg) {
-    return bulkHandleCompound(node, arg);
-  }
-
-  @override
-  R visitThisPropertyCompound(
-      Send node, Name name, AssignmentOperator operator, Node rhs, A arg) {
-    return bulkHandleCompound(node, arg);
-  }
-
-  @override
-  R visitTopLevelFieldCompound(Send node, FieldElement field,
-      AssignmentOperator operator, Node rhs, A arg) {
-    return bulkHandleCompound(node, arg);
-  }
-
-  @override
-  R visitTopLevelGetterSetterCompound(Send node, GetterElement getter,
-      SetterElement setter, AssignmentOperator operator, Node rhs, A arg) {
-    return bulkHandleCompound(node, arg);
-  }
-
-  @override
-  R visitTopLevelMethodSetterCompound(Send node, FunctionElement method,
-      SetterElement setter, AssignmentOperator operator, Node rhs, A arg) {
-    return bulkHandleCompound(node, arg);
-  }
-
-  @override
-  R visitFinalParameterCompound(Send node, ParameterElement parameter,
-      AssignmentOperator operator, Node rhs, A arg) {
-    return bulkHandleCompound(node, arg);
-  }
-
-  @override
-  R visitClassTypeLiteralCompound(Send node, ConstantExpression constant,
-      AssignmentOperator operator, Node rhs, A arg) {
-    return bulkHandleCompound(node, arg);
-  }
-
-  @override
-  R visitDynamicTypeLiteralCompound(Send node, ConstantExpression constant,
-      AssignmentOperator operator, Node rhs, A arg) {
-    return bulkHandleCompound(node, arg);
-  }
-
-  @override
-  R visitFinalLocalVariableCompound(Send node, LocalVariableElement variable,
-      AssignmentOperator operator, Node rhs, A arg) {
-    return bulkHandleCompound(node, arg);
-  }
-
-  @override
-  R visitFinalStaticFieldCompound(Send node, FieldElement field,
-      AssignmentOperator operator, Node rhs, A arg) {
-    return bulkHandleCompound(node, arg);
-  }
-
-  @override
-  R visitFinalSuperFieldCompound(Send node, FieldElement field,
-      AssignmentOperator operator, Node rhs, A arg) {
-    return bulkHandleCompound(node, arg);
-  }
-
-  @override
-  R visitFinalTopLevelFieldCompound(Send node, FieldElement field,
-      AssignmentOperator operator, Node rhs, A arg) {
-    return bulkHandleCompound(node, arg);
-  }
-
-  @override
-  R visitLocalFunctionCompound(Send node, LocalFunctionElement function,
-      AssignmentOperator operator, Node rhs, A arg) {
-    return bulkHandleCompound(node, arg);
-  }
-
-  @override
-  R visitTypeVariableTypeLiteralCompound(Send node, TypeVariableElement element,
-      AssignmentOperator operator, Node rhs, A arg) {
-    return bulkHandleCompound(node, arg);
-  }
-
-  @override
-  R visitTypedefTypeLiteralCompound(Send node, ConstantExpression constant,
-      AssignmentOperator operator, Node rhs, A arg) {
-    return bulkHandleCompound(node, arg);
-  }
-
-  @override
-  R visitUnresolvedStaticGetterCompound(Send node, Element element,
-      MethodElement setter, AssignmentOperator operator, Node rhs, A arg) {
-    return bulkHandleCompound(node, arg);
-  }
-
-  @override
-  R visitUnresolvedTopLevelGetterCompound(Send node, Element element,
-      MethodElement setter, AssignmentOperator operator, Node rhs, A arg) {
-    return bulkHandleCompound(node, arg);
-  }
-
-  @override
-  R visitUnresolvedStaticSetterCompound(Send node, GetterElement getter,
-      Element element, AssignmentOperator operator, Node rhs, A arg) {
-    return bulkHandleCompound(node, arg);
-  }
-
-  @override
-  R visitUnresolvedTopLevelSetterCompound(Send node, GetterElement getter,
-      Element element, AssignmentOperator operator, Node rhs, A arg) {
-    return bulkHandleCompound(node, arg);
-  }
-
-  @override
-  R visitStaticMethodCompound(Send node, MethodElement method,
-      AssignmentOperator operator, Node rhs, A arg) {
-    return bulkHandleCompound(node, arg);
-  }
-
-  @override
-  R visitTopLevelMethodCompound(Send node, MethodElement method,
-      AssignmentOperator operator, Node rhs, A arg) {
-    return bulkHandleCompound(node, arg);
-  }
-
-  @override
-  R visitUnresolvedCompound(Send node, ErroneousElement element,
-      AssignmentOperator operator, Node rhs, A arg) {
-    return bulkHandleCompound(node, arg);
-  }
-
-  @override
-  R visitSuperFieldFieldCompound(Send node, FieldElement readField,
-      FieldElement writtenField, AssignmentOperator operator, Node rhs, A arg) {
-    return bulkHandleCompound(node, arg);
-  }
-
-  @override
-  R visitSuperMethodCompound(Send node, MethodElement method,
-      AssignmentOperator operator, Node rhs, A arg) {
-    return bulkHandleCompound(node, arg);
-  }
-
-  @override
-  R visitUnresolvedSuperCompound(Send node, Element element,
-      AssignmentOperator operator, Node rhs, A arg) {
-    return bulkHandleCompound(node, arg);
-  }
-
-  @override
-  R visitUnresolvedSuperGetterCompound(SendSet node, Element element,
-      SetterElement setter, AssignmentOperator operator, Node rhs, A arg) {
-    return bulkHandleCompound(node, arg);
-  }
-
-  @override
-  R visitUnresolvedSuperSetterCompound(Send node, GetterElement getter,
-      Element element, AssignmentOperator operator, Node rhs, A arg) {
-    return bulkHandleCompound(node, arg);
-  }
-}
-
-/// Mixin that implements all `visitXSetIfNull` methods of [SemanticSendVisitor]
-/// by delegating to a bulk handler.
-///
-/// Use this mixin to provide a trivial implementation for all `xSetIfNull`
-/// methods.
-abstract class SetIfNullBulkMixin<R, A>
-    implements SemanticSendVisitor<R, A>, BulkHandle<R, A> {
-  R bulkHandleSetIfNull(SendSet node, A arg) {
-    return bulkHandleNode(node, "If null assignment `#` unhandled.", arg);
-  }
-
-  @override
-  R visitClassTypeLiteralSetIfNull(
-      Send node, ConstantExpression constant, Node rhs, A arg) {
-    return bulkHandleSetIfNull(node, arg);
-  }
-
-  @override
-  R visitDynamicPropertySetIfNull(
-      Send node, Node receiver, Name name, Node rhs, A arg) {
-    return bulkHandleSetIfNull(node, arg);
-  }
-
-  @override
-  R visitDynamicTypeLiteralSetIfNull(
-      Send node, ConstantExpression constant, Node rhs, A arg) {
-    return bulkHandleSetIfNull(node, arg);
-  }
-
-  @override
-  R visitFinalLocalVariableSetIfNull(
-      Send node, LocalVariableElement variable, Node rhs, A arg) {
-    return bulkHandleSetIfNull(node, arg);
-  }
-
-  @override
-  R visitFinalParameterSetIfNull(
-      Send node, ParameterElement parameter, Node rhs, A arg) {
-    return bulkHandleSetIfNull(node, arg);
-  }
-
-  @override
-  R visitFinalStaticFieldSetIfNull(
-      Send node, FieldElement field, Node rhs, A arg) {
-    return bulkHandleSetIfNull(node, arg);
-  }
-
-  @override
-  R visitFinalSuperFieldSetIfNull(
-      Send node, FieldElement field, Node rhs, A arg) {
-    return bulkHandleSetIfNull(node, arg);
-  }
-
-  @override
-  R visitFinalTopLevelFieldSetIfNull(
-      Send node, FieldElement field, Node rhs, A arg) {
-    return bulkHandleSetIfNull(node, arg);
-  }
-
-  @override
-  R visitIfNotNullDynamicPropertySetIfNull(
-      Send node, Node receiver, Name name, Node rhs, A arg) {
-    return bulkHandleSetIfNull(node, arg);
-  }
-
-  @override
-  R visitLocalFunctionSetIfNull(
-      Send node, LocalFunctionElement function, Node rhs, A arg) {
-    return bulkHandleSetIfNull(node, arg);
-  }
-
-  @override
-  R visitLocalVariableSetIfNull(
-      Send node, LocalVariableElement variable, Node rhs, A arg) {
-    return bulkHandleSetIfNull(node, arg);
-  }
-
-  @override
-  R visitParameterSetIfNull(
-      Send node, ParameterElement parameter, Node rhs, A arg) {
-    return bulkHandleSetIfNull(node, arg);
-  }
-
-  @override
-  R visitStaticFieldSetIfNull(Send node, FieldElement field, Node rhs, A arg) {
-    return bulkHandleSetIfNull(node, arg);
-  }
-
-  @override
-  R visitStaticGetterSetterSetIfNull(
-      Send node, GetterElement getter, SetterElement setter, Node rhs, A arg) {
-    return bulkHandleSetIfNull(node, arg);
-  }
-
-  @override
-  R visitStaticMethodSetIfNull(
-      Send node, FunctionElement method, Node rhs, A arg) {
-    return bulkHandleSetIfNull(node, arg);
-  }
-
-  @override
-  R visitStaticMethodSetterSetIfNull(
-      Send node, MethodElement method, MethodElement setter, Node rhs, A arg) {
-    return bulkHandleSetIfNull(node, arg);
-  }
-
-  @override
-  R visitSuperFieldFieldSetIfNull(Send node, FieldElement readField,
-      FieldElement writtenField, Node rhs, A arg) {
-    return bulkHandleSetIfNull(node, arg);
-  }
-
-  @override
-  R visitSuperFieldSetIfNull(Send node, FieldElement field, Node rhs, A arg) {
-    return bulkHandleSetIfNull(node, arg);
-  }
-
-  @override
-  R visitSuperFieldSetterSetIfNull(
-      Send node, FieldElement field, SetterElement setter, Node rhs, A arg) {
-    return bulkHandleSetIfNull(node, arg);
-  }
-
-  @override
-  R visitSuperGetterFieldSetIfNull(
-      Send node, GetterElement getter, FieldElement field, Node rhs, A arg) {
-    return bulkHandleSetIfNull(node, arg);
-  }
-
-  @override
-  R visitSuperGetterSetterSetIfNull(
-      Send node, GetterElement getter, SetterElement setter, Node rhs, A arg) {
-    return bulkHandleSetIfNull(node, arg);
-  }
-
-  @override
-  R visitSuperMethodSetIfNull(
-      Send node, FunctionElement method, Node rhs, A arg) {
-    return bulkHandleSetIfNull(node, arg);
-  }
-
-  @override
-  R visitSuperMethodSetterSetIfNull(Send node, FunctionElement method,
-      SetterElement setter, Node rhs, A arg) {
-    return bulkHandleSetIfNull(node, arg);
-  }
-
-  @override
-  R visitThisPropertySetIfNull(Send node, Name name, Node rhs, A arg) {
-    return bulkHandleSetIfNull(node, arg);
-  }
-
-  @override
-  R visitTopLevelFieldSetIfNull(
-      Send node, FieldElement field, Node rhs, A arg) {
-    return bulkHandleSetIfNull(node, arg);
-  }
-
-  @override
-  R visitTopLevelGetterSetterSetIfNull(
-      Send node, GetterElement getter, SetterElement setter, Node rhs, A arg) {
-    return bulkHandleSetIfNull(node, arg);
-  }
-
-  @override
-  R visitTopLevelMethodSetIfNull(
-      Send node, FunctionElement method, Node rhs, A arg) {
-    return bulkHandleSetIfNull(node, arg);
-  }
-
-  @override
-  R visitTopLevelMethodSetterSetIfNull(Send node, FunctionElement method,
-      SetterElement setter, Node rhs, A arg) {
-    return bulkHandleSetIfNull(node, arg);
-  }
-
-  @override
-  R visitTypeVariableTypeLiteralSetIfNull(
-      Send node, TypeVariableElement element, Node rhs, A arg) {
-    return bulkHandleSetIfNull(node, arg);
-  }
-
-  @override
-  R visitTypedefTypeLiteralSetIfNull(
-      Send node, ConstantExpression constant, Node rhs, A arg) {
-    return bulkHandleSetIfNull(node, arg);
-  }
-
-  @override
-  R visitUnresolvedSetIfNull(Send node, Element element, Node rhs, A arg) {
-    return bulkHandleSetIfNull(node, arg);
-  }
-
-  @override
-  R visitUnresolvedStaticGetterSetIfNull(
-      Send node, Element element, MethodElement setter, Node rhs, A arg) {
-    return bulkHandleSetIfNull(node, arg);
-  }
-
-  @override
-  R visitUnresolvedStaticSetterSetIfNull(
-      Send node, GetterElement getter, Element element, Node rhs, A arg) {
-    return bulkHandleSetIfNull(node, arg);
-  }
-
-  @override
-  R visitUnresolvedSuperGetterSetIfNull(
-      Send node, Element element, MethodElement setter, Node rhs, A arg) {
-    return bulkHandleSetIfNull(node, arg);
-  }
-
-  @override
-  R visitUnresolvedSuperSetIfNull(Send node, Element element, Node rhs, A arg) {
-    return bulkHandleSetIfNull(node, arg);
-  }
-
-  @override
-  R visitUnresolvedSuperSetterSetIfNull(
-      Send node, GetterElement getter, Element element, Node rhs, A arg) {
-    return bulkHandleSetIfNull(node, arg);
-  }
-
-  @override
-  R visitUnresolvedTopLevelGetterSetIfNull(
-      Send node, Element element, MethodElement setter, Node rhs, A arg) {
-    return bulkHandleSetIfNull(node, arg);
-  }
-
-  @override
-  R visitUnresolvedTopLevelSetterSetIfNull(
-      Send node, GetterElement getter, Element element, Node rhs, A arg) {
-    return bulkHandleSetIfNull(node, arg);
-  }
-
-  @override
-  R visitIndexSetIfNull(
-      SendSet node, Node receiver, Node index, Node rhs, A arg) {
-    return bulkHandleSetIfNull(node, arg);
-  }
-
-  @override
-  R visitSuperIndexSetIfNull(SendSet node, MethodElement getter,
-      MethodElement setter, Node index, Node rhs, A arg) {
-    return bulkHandleSetIfNull(node, arg);
-  }
-
-  @override
-  R visitUnresolvedSuperGetterIndexSetIfNull(SendSet node, Element element,
-      MethodElement setter, Node index, Node rhs, A arg) {
-    return bulkHandleSetIfNull(node, arg);
-  }
-
-  @override
-  R visitUnresolvedSuperSetterIndexSetIfNull(SendSet node, MethodElement getter,
-      Element element, Node index, Node rhs, A arg) {
-    return bulkHandleSetIfNull(node, arg);
-  }
-
-  @override
-  R visitUnresolvedSuperIndexSetIfNull(
-      Send node, Element element, Node index, Node rhs, A arg) {
-    return bulkHandleSetIfNull(node, arg);
-  }
-}
-
-/// Mixin that implements all `visitXInvoke` methods of [SemanticSendVisitor] by
-/// delegating to a bulk handler.
-///
-/// Use this mixin to provide a trivial implementation for all `visitXInvoke`
-/// methods.
-abstract class InvokeBulkMixin<R, A>
-    implements SemanticSendVisitor<R, A>, BulkHandle<R, A> {
-  R bulkHandleInvoke(Send node, A arg) {
-    return bulkHandleNode(node, "Invocation `#` unhandled.", arg);
-  }
-
-  @override
-  R visitClassTypeLiteralInvoke(Send node, ConstantExpression constant,
-      NodeList arguments, CallStructure callStructure, A arg) {
-    return bulkHandleInvoke(node, arg);
-  }
-
-  @override
-  R visitDynamicPropertyInvoke(
-      Send node, Node receiver, NodeList arguments, Selector selector, A arg) {
-    return bulkHandleInvoke(node, arg);
-  }
-
-  @override
-  R visitIfNotNullDynamicPropertyInvoke(
-      Send node, Node receiver, NodeList arguments, Selector selector, A arg) {
-    return bulkHandleInvoke(node, arg);
-  }
-
-  @override
-  R visitDynamicTypeLiteralInvoke(Send node, ConstantExpression constant,
-      NodeList arguments, CallStructure callStructure, A arg) {
-    return bulkHandleInvoke(node, arg);
-  }
-
-  @override
-  R visitExpressionInvoke(Send node, Node expression, NodeList arguments,
-      CallStructure callStructure, A arg) {
-    return bulkHandleInvoke(node, arg);
-  }
-
-  @override
-  R visitLocalFunctionInvoke(Send node, LocalFunctionElement function,
-      NodeList arguments, CallStructure callStructure, A arg) {
-    return bulkHandleInvoke(node, arg);
-  }
-
-  @override
-  R visitLocalFunctionIncompatibleInvoke(
-      Send node,
-      LocalFunctionElement function,
-      NodeList arguments,
-      CallStructure callStructure,
-      A arg) {
-    return bulkHandleInvoke(node, arg);
-  }
-
-  @override
-  R visitLocalVariableInvoke(Send node, LocalVariableElement variable,
-      NodeList arguments, CallStructure callStructure, A arg) {
-    return bulkHandleInvoke(node, arg);
-  }
-
-  @override
-  R visitParameterInvoke(Send node, ParameterElement parameter,
-      NodeList arguments, CallStructure callStructure, A arg) {
-    return bulkHandleInvoke(node, arg);
-  }
-
-  @override
-  R visitStaticFieldInvoke(Send node, FieldElement field, NodeList arguments,
-      CallStructure callStructure, A arg) {
-    return bulkHandleInvoke(node, arg);
-  }
-
-  @override
-  R visitStaticFunctionInvoke(Send node, MethodElement function,
-      NodeList arguments, CallStructure callStructure, A arg) {
-    return bulkHandleInvoke(node, arg);
-  }
-
-  @override
-  R visitStaticFunctionIncompatibleInvoke(Send node, MethodElement function,
-      NodeList arguments, CallStructure callStructure, A arg) {
-    return bulkHandleInvoke(node, arg);
-  }
-
-  @override
-  R visitStaticGetterInvoke(Send node, GetterElement getter, NodeList arguments,
-      CallStructure callStructure, A arg) {
-    return bulkHandleInvoke(node, arg);
-  }
-
-  @override
-  R visitSuperFieldInvoke(Send node, FieldElement field, NodeList arguments,
-      CallStructure callStructure, A arg) {
-    return bulkHandleInvoke(node, arg);
-  }
-
-  @override
-  R visitSuperGetterInvoke(Send node, GetterElement getter, NodeList arguments,
-      CallStructure callStructure, A arg) {
-    return bulkHandleInvoke(node, arg);
-  }
-
-  @override
-  R visitSuperMethodInvoke(Send node, MethodElement method, NodeList arguments,
-      CallStructure callStructure, A arg) {
-    return bulkHandleInvoke(node, arg);
-  }
-
-  @override
-  R visitSuperMethodIncompatibleInvoke(Send node, MethodElement method,
-      NodeList arguments, CallStructure callStructure, A arg) {
-    return bulkHandleInvoke(node, arg);
-  }
-
-  @override
-  R visitThisInvoke(
-      Send node, NodeList arguments, CallStructure callStructure, A arg) {
-    return bulkHandleInvoke(node, arg);
-  }
-
-  @override
-  R visitThisPropertyInvoke(
-      Send node, NodeList arguments, Selector selector, A arg) {
-    return bulkHandleInvoke(node, arg);
-  }
-
-  @override
-  R visitTopLevelFieldInvoke(Send node, FieldElement field, NodeList arguments,
-      CallStructure callStructure, A arg) {
-    return bulkHandleInvoke(node, arg);
-  }
-
-  @override
-  R visitTopLevelFunctionInvoke(Send node, MethodElement function,
-      NodeList arguments, CallStructure callStructure, A arg) {
-    return bulkHandleInvoke(node, arg);
-  }
-
-  @override
-  R visitTopLevelFunctionIncompatibleInvoke(Send node, MethodElement function,
-      NodeList arguments, CallStructure callStructure, A arg) {
-    return bulkHandleInvoke(node, arg);
-  }
-
-  @override
-  R visitTopLevelGetterInvoke(Send node, GetterElement getter,
-      NodeList arguments, CallStructure callStructure, A arg) {
-    return bulkHandleInvoke(node, arg);
-  }
-
-  @override
-  R visitTypeVariableTypeLiteralInvoke(Send node, TypeVariableElement element,
-      NodeList arguments, CallStructure callStructure, A arg) {
-    return bulkHandleInvoke(node, arg);
-  }
-
-  @override
-  R visitTypedefTypeLiteralInvoke(Send node, ConstantExpression constant,
-      NodeList arguments, CallStructure callStructure, A arg) {
-    return bulkHandleInvoke(node, arg);
-  }
-
-  @override
-  R visitConstantInvoke(Send node, ConstantExpression constant,
-      NodeList arguments, CallStructure callStructure, A arg) {
-    return bulkHandleInvoke(node, arg);
-  }
-
-  @override
-  R visitUnresolvedInvoke(Send node, Element element, NodeList arguments,
-      Selector selector, A arg) {
-    return bulkHandleInvoke(node, arg);
-  }
-
-  @override
-  R visitUnresolvedSuperInvoke(Send node, Element function, NodeList arguments,
-      Selector selector, A arg) {
-    return bulkHandleInvoke(node, arg);
-  }
-
-  @override
-  R visitStaticSetterInvoke(Send node, SetterElement setter, NodeList arguments,
-      CallStructure callStructure, A arg) {
-    return bulkHandleInvoke(node, arg);
-  }
-
-  @override
-  R visitSuperSetterInvoke(Send node, SetterElement setter, NodeList arguments,
-      CallStructure callStructure, A arg) {
-    return bulkHandleInvoke(node, arg);
-  }
-
-  @override
-  R visitTopLevelSetterInvoke(Send node, SetterElement setter,
-      NodeList arguments, CallStructure callStructure, A arg) {
-    return bulkHandleInvoke(node, arg);
-  }
-}
-
-/// Mixin that implements all `visitXGet` methods of [SemanticSendVisitor] by
-/// delegating to a bulk handler.
-///
-/// Use this mixin to provide a trivial implementation for all `visitXGet`
-/// methods.
-abstract class GetBulkMixin<R, A>
-    implements SemanticSendVisitor<R, A>, BulkHandle<R, A> {
-  R bulkHandleGet(Node node, A arg) {
-    return bulkHandleNode(node, "Read `#` unhandled.", arg);
-  }
-
-  @override
-  R visitClassTypeLiteralGet(Send node, ConstantExpression constant, A arg) {
-    return bulkHandleGet(node, arg);
-  }
-
-  @override
-  R visitDynamicPropertyGet(Send node, Node receiver, Name name, A arg) {
-    return bulkHandleGet(node, arg);
-  }
-
-  @override
-  R visitIfNotNullDynamicPropertyGet(
-      Send node, Node receiver, Name name, A arg) {
-    return bulkHandleGet(node, arg);
-  }
-
-  @override
-  R visitDynamicTypeLiteralGet(Send node, ConstantExpression constant, A arg) {
-    return bulkHandleGet(node, arg);
-  }
-
-  @override
-  R visitLocalFunctionGet(Send node, LocalFunctionElement function, A arg) {
-    return bulkHandleGet(node, arg);
-  }
-
-  @override
-  R visitLocalVariableGet(Send node, LocalVariableElement variable, A arg) {
-    return bulkHandleGet(node, arg);
-  }
-
-  @override
-  R visitParameterGet(Send node, ParameterElement parameter, A arg) {
-    return bulkHandleGet(node, arg);
-  }
-
-  @override
-  R visitStaticFieldGet(Send node, FieldElement field, A arg) {
-    return bulkHandleGet(node, arg);
-  }
-
-  @override
-  R visitStaticFunctionGet(Send node, MethodElement function, A arg) {
-    return bulkHandleGet(node, arg);
-  }
-
-  @override
-  R visitStaticGetterGet(Send node, GetterElement getter, A arg) {
-    return bulkHandleGet(node, arg);
-  }
-
-  @override
-  R visitSuperFieldGet(Send node, FieldElement field, A arg) {
-    return bulkHandleGet(node, arg);
-  }
-
-  @override
-  R visitSuperGetterGet(Send node, GetterElement getter, A arg) {
-    return bulkHandleGet(node, arg);
-  }
-
-  @override
-  R visitSuperMethodGet(Send node, MethodElement method, A arg) {
-    return bulkHandleGet(node, arg);
-  }
-
-  @override
-  R visitThisGet(Identifier node, A arg) {
-    return bulkHandleGet(node, arg);
-  }
-
-  @override
-  R visitThisPropertyGet(Send node, Name name, A arg) {
-    return bulkHandleGet(node, arg);
-  }
-
-  @override
-  R visitTopLevelFieldGet(Send node, FieldElement field, A arg) {
-    return bulkHandleGet(node, arg);
-  }
-
-  @override
-  R visitTopLevelFunctionGet(Send node, MethodElement function, A arg) {
-    return bulkHandleGet(node, arg);
-  }
-
-  @override
-  R visitTopLevelGetterGet(Send node, GetterElement getter, A arg) {
-    return bulkHandleGet(node, arg);
-  }
-
-  @override
-  R visitTypeVariableTypeLiteralGet(
-      Send node, TypeVariableElement element, A arg) {
-    return bulkHandleGet(node, arg);
-  }
-
-  @override
-  R visitTypedefTypeLiteralGet(Send node, ConstantExpression constant, A arg) {
-    return bulkHandleGet(node, arg);
-  }
-
-  @override
-  R visitConstantGet(Send node, ConstantExpression constant, A arg) {
-    return bulkHandleGet(node, arg);
-  }
-
-  @override
-  R visitUnresolvedGet(Send node, Element element, A arg) {
-    return bulkHandleGet(node, arg);
-  }
-
-  @override
-  R visitUnresolvedSuperGet(Send node, Element element, A arg) {
-    return bulkHandleGet(node, arg);
-  }
-
-  @override
-  R visitStaticSetterGet(Send node, SetterElement setter, A arg) {
-    return bulkHandleGet(node, arg);
-  }
-
-  @override
-  R visitSuperSetterGet(Send node, SetterElement setter, A arg) {
-    return bulkHandleGet(node, arg);
-  }
-
-  @override
-  R visitTopLevelSetterGet(Send node, SetterElement setter, A arg) {
-    return bulkHandleGet(node, arg);
-  }
-}
-
-/// Mixin that implements all `visitXSet` methods of [SemanticSendVisitor] by
-/// delegating to a bulk handler.
-///
-/// Use this mixin to provide a trivial implementation for all `visitXSet`
-/// methods.
-abstract class SetBulkMixin<R, A>
-    implements SemanticSendVisitor<R, A>, BulkHandle<R, A> {
-  R bulkHandleSet(SendSet node, A arg) {
-    return bulkHandleNode(node, "Assignment `#` unhandled.", arg);
-  }
-
-  @override
-  R visitDynamicPropertySet(
-      SendSet node, Node receiver, Name name, Node rhs, A arg) {
-    return bulkHandleSet(node, arg);
-  }
-
-  @override
-  R visitIfNotNullDynamicPropertySet(
-      SendSet node, Node receiver, Name name, Node rhs, A arg) {
-    return bulkHandleSet(node, arg);
-  }
-
-  @override
-  R visitLocalVariableSet(
-      SendSet node, LocalVariableElement variable, Node rhs, A arg) {
-    return bulkHandleSet(node, arg);
-  }
-
-  @override
-  R visitParameterSet(
-      SendSet node, ParameterElement parameter, Node rhs, A arg) {
-    return bulkHandleSet(node, arg);
-  }
-
-  @override
-  R visitStaticFieldSet(SendSet node, FieldElement field, Node rhs, A arg) {
-    return bulkHandleSet(node, arg);
-  }
-
-  @override
-  R visitStaticSetterSet(SendSet node, SetterElement setter, Node rhs, A arg) {
-    return bulkHandleSet(node, arg);
-  }
-
-  @override
-  R visitSuperFieldSet(SendSet node, FieldElement field, Node rhs, A arg) {
-    return bulkHandleSet(node, arg);
-  }
-
-  @override
-  R visitSuperSetterSet(SendSet node, SetterElement setter, Node rhs, A arg) {
-    return bulkHandleSet(node, arg);
-  }
-
-  @override
-  R visitThisPropertySet(SendSet node, Name name, Node rhs, A arg) {
-    return bulkHandleSet(node, arg);
-  }
-
-  @override
-  R visitTopLevelFieldSet(SendSet node, FieldElement field, Node rhs, A arg) {
-    return bulkHandleSet(node, arg);
-  }
-
-  @override
-  R visitTopLevelSetterSet(
-      SendSet node, SetterElement setter, Node rhs, A arg) {
-    return bulkHandleSet(node, arg);
-  }
-
-  @override
-  R visitClassTypeLiteralSet(
-      SendSet node, TypeConstantExpression constant, Node rhs, A arg) {
-    return bulkHandleSet(node, arg);
-  }
-
-  @override
-  R visitDynamicTypeLiteralSet(
-      SendSet node, TypeConstantExpression constant, Node rhs, A arg) {
-    return bulkHandleSet(node, arg);
-  }
-
-  @override
-  R visitFinalLocalVariableSet(
-      SendSet node, LocalVariableElement variable, Node rhs, A arg) {
-    return bulkHandleSet(node, arg);
-  }
-
-  @override
-  R visitFinalParameterSet(
-      SendSet node, ParameterElement parameter, Node rhs, A arg) {
-    return bulkHandleSet(node, arg);
-  }
-
-  @override
-  R visitFinalStaticFieldSet(
-      SendSet node, FieldElement field, Node rhs, A arg) {
-    return bulkHandleSet(node, arg);
-  }
-
-  @override
-  R visitFinalSuperFieldSet(SendSet node, FieldElement field, Node rhs, A arg) {
-    return bulkHandleSet(node, arg);
-  }
-
-  @override
-  R visitFinalTopLevelFieldSet(
-      SendSet node, FieldElement field, Node rhs, A arg) {
-    return bulkHandleSet(node, arg);
-  }
-
-  @override
-  R visitLocalFunctionSet(
-      SendSet node, LocalFunctionElement function, Node rhs, A arg) {
-    return bulkHandleSet(node, arg);
-  }
-
-  @override
-  R visitStaticFunctionSet(
-      SendSet node, MethodElement function, Node rhs, A arg) {
-    return bulkHandleSet(node, arg);
-  }
-
-  @override
-  R visitStaticGetterSet(SendSet node, GetterElement getter, Node rhs, A arg) {
-    return bulkHandleSet(node, arg);
-  }
-
-  @override
-  R visitSuperGetterSet(SendSet node, GetterElement getter, Node rhs, A arg) {
-    return bulkHandleSet(node, arg);
-  }
-
-  @override
-  R visitSuperMethodSet(SendSet node, MethodElement method, Node rhs, A arg) {
-    return bulkHandleSet(node, arg);
-  }
-
-  @override
-  R visitTopLevelFunctionSet(
-      SendSet node, MethodElement function, Node rhs, A arg) {
-    return bulkHandleSet(node, arg);
-  }
-
-  @override
-  R visitTopLevelGetterSet(
-      SendSet node, GetterElement getter, Node rhs, A arg) {
-    return bulkHandleSet(node, arg);
-  }
-
-  @override
-  R visitTypeVariableTypeLiteralSet(
-      SendSet node, TypeVariableElement element, Node rhs, A arg) {
-    return bulkHandleSet(node, arg);
-  }
-
-  @override
-  R visitTypedefTypeLiteralSet(
-      SendSet node, TypeConstantExpression constant, Node rhs, A arg) {
-    return bulkHandleSet(node, arg);
-  }
-
-  @override
-  R visitUnresolvedSet(SendSet node, Element element, Node rhs, A arg) {
-    return bulkHandleSet(node, arg);
-  }
-
-  @override
-  R visitUnresolvedSuperSet(Send node, Element element, Node rhs, A arg) {
-    return bulkHandleSet(node, arg);
-  }
-}
-
-/// Mixin that implements all `visitXIndexSet` methods of [SemanticSendVisitor]
-/// by delegating to a bulk handler.
-///
-/// Use this mixin to provide a trivial implementation for all `visitXIndexSet`
-/// methods.
-abstract class IndexSetBulkMixin<R, A>
-    implements SemanticSendVisitor<R, A>, BulkHandle<R, A> {
-  R bulkHandleIndexSet(Send node, A arg) {
-    return bulkHandleNode(node, "Index set expression `#` unhandled.", arg);
-  }
-
-  @override
-  R visitCompoundIndexSet(SendSet node, Node receiver, Node index,
-      AssignmentOperator operator, Node rhs, A arg) {
-    return bulkHandleIndexSet(node, arg);
-  }
-
-  @override
-  R visitIndexSet(SendSet node, Node receiver, Node index, Node rhs, A arg) {
-    return bulkHandleIndexSet(node, arg);
-  }
-
-  @override
-  R visitSuperCompoundIndexSet(
-      SendSet node,
-      MethodElement getter,
-      MethodElement setter,
-      Node index,
-      AssignmentOperator operator,
-      Node rhs,
-      A arg) {
-    return bulkHandleIndexSet(node, arg);
-  }
-
-  @override
-  R visitUnresolvedSuperGetterCompoundIndexSet(
-      SendSet node,
-      Element element,
-      MethodElement setter,
-      Node index,
-      AssignmentOperator operator,
-      Node rhs,
-      A arg) {
-    return bulkHandleIndexSet(node, arg);
-  }
-
-  @override
-  R visitUnresolvedSuperSetterCompoundIndexSet(
-      SendSet node,
-      MethodElement getter,
-      Element element,
-      Node index,
-      AssignmentOperator operator,
-      Node rhs,
-      A arg) {
-    return bulkHandleIndexSet(node, arg);
-  }
-
-  @override
-  R visitUnresolvedSuperCompoundIndexSet(SendSet node, Element element,
-      Node index, AssignmentOperator operator, Node rhs, A arg) {
-    return bulkHandleIndexSet(node, arg);
-  }
-
-  @override
-  R visitSuperIndexSet(
-      SendSet node, FunctionElement function, Node index, Node rhs, A arg) {
-    return bulkHandleIndexSet(node, arg);
-  }
-
-  @override
-  R visitUnresolvedSuperIndexSet(
-      SendSet node, ErroneousElement element, Node index, Node rhs, A arg) {
-    return bulkHandleIndexSet(node, arg);
-  }
-}
-
-/// Mixin that implements all binary visitor methods in [SemanticSendVisitor] by
-/// delegating to a bulk handler.
-///
-/// Use this mixin to provide a trivial implementation for all binary visitor
-/// methods.
-abstract class BinaryBulkMixin<R, A>
-    implements SemanticSendVisitor<R, A>, BulkHandle<R, A> {
-  R bulkHandleBinary(Send node, A arg) {
-    return bulkHandleNode(node, "Binary expression `#` unhandled.", arg);
-  }
-
-  @override
-  R visitBinary(
-      Send node, Node left, BinaryOperator operator, Node right, A arg) {
-    return bulkHandleBinary(node, arg);
-  }
-
-  @override
-  R visitEquals(Send node, Node left, Node right, A arg) {
-    return bulkHandleBinary(node, arg);
-  }
-
-  @override
-  R visitNotEquals(Send node, Node left, Node right, A arg) {
-    return bulkHandleBinary(node, arg);
-  }
-
-  @override
-  R visitIndex(Send node, Node receiver, Node index, A arg) {
-    return bulkHandleBinary(node, arg);
-  }
-
-  @override
-  R visitSuperBinary(Send node, MethodElement function, BinaryOperator operator,
-      Node argument, A arg) {
-    return bulkHandleBinary(node, arg);
-  }
-
-  @override
-  R visitSuperEquals(Send node, MethodElement function, Node argument, A arg) {
-    return bulkHandleBinary(node, arg);
-  }
-
-  @override
-  R visitSuperNotEquals(
-      Send node, MethodElement function, Node argument, A arg) {
-    return bulkHandleBinary(node, arg);
-  }
-
-  @override
-  R visitSuperIndex(Send node, MethodElement function, Node index, A arg) {
-    return bulkHandleBinary(node, arg);
-  }
-
-  @override
-  R visitUnresolvedSuperBinary(Send node, Element function,
-      BinaryOperator operator, Node argument, A arg) {
-    return bulkHandleBinary(node, arg);
-  }
-
-  @override
-  R visitUnresolvedSuperInvoke(Send node, Element function, NodeList arguments,
-      Selector selector, A arg) {
-    return bulkHandleBinary(node, arg);
-  }
-
-  @override
-  R visitUnresolvedSuperIndex(Send node, Element function, Node index, A arg) {
-    return bulkHandleBinary(node, arg);
-  }
-}
-
-/// Mixin that implements all unary visitor methods in [SemanticSendVisitor] by
-/// delegating to a bulk handler.
-///
-/// Use this mixin to provide a trivial implementation for all unary visitor
-/// methods.
-abstract class UnaryBulkMixin<R, A>
-    implements SemanticSendVisitor<R, A>, BulkHandle<R, A> {
-  R bulkHandleUnary(Send node, A arg) {
-    return bulkHandleNode(node, "Unary expression `#` unhandled.", arg);
-  }
-
-  @override
-  R visitNot(Send node, Node expression, A arg) {
-    return bulkHandleUnary(node, arg);
-  }
-
-  @override
-  R visitSuperUnary(
-      Send node, UnaryOperator operator, MethodElement function, A arg) {
-    return bulkHandleUnary(node, arg);
-  }
-
-  @override
-  R visitUnary(Send node, UnaryOperator operator, Node expression, A arg) {
-    return bulkHandleUnary(node, arg);
-  }
-
-  @override
-  R visitUnresolvedSuperUnary(
-      Send node, UnaryOperator operator, Element function, A arg) {
-    return bulkHandleUnary(node, arg);
-  }
-}
-
-/// Mixin that implements all purely structural visitor methods in
-/// [SemanticSendVisitor] by delegating to a bulk handler.
-///
-/// Use this mixin to provide a trivial implementation for all purely structural
-/// visitor methods.
-abstract class BaseBulkMixin<R, A>
-    implements SemanticSendVisitor<R, A>, BulkHandle<R, A> {
-  @override
-  R visitAs(Send node, Node expression, ResolutionDartType type, A arg) {
-    return bulkHandleNode(node, 'As cast `#` unhandled.', arg);
-  }
-
-  @override
-  R visitIs(Send node, Node expression, ResolutionDartType type, A arg) {
-    return bulkHandleNode(node, 'Is test `#` unhandled.', arg);
-  }
-
-  @override
-  R visitIsNot(Send node, Node expression, ResolutionDartType type, A arg) {
-    return bulkHandleNode(node, 'Is not test `#` unhandled.', arg);
-  }
-
-  @override
-  R visitIfNull(Send node, Node left, Node right, A arg) {
-    return bulkHandleNode(node, 'If-null (Lazy ?? `#`) unhandled.', arg);
-  }
-
-  @override
-  R visitLogicalAnd(Send node, Node left, Node right, A arg) {
-    return bulkHandleNode(node, 'Lazy and `#` unhandled.', arg);
-  }
-
-  @override
-  R visitLogicalOr(Send node, Node left, Node right, A arg) {
-    return bulkHandleNode(node, 'Lazy or `#` unhandled.', arg);
-  }
-
-  @override
-  void previsitDeferredAccess(Send node, PrefixElement prefix, A arg) {
-    bulkHandleNode(node, 'Deferred access `#` unhandled.', arg);
-  }
-}
-
-/// Mixin that implements all visitor methods for `super` calls in
-/// [SemanticSendVisitor] by delegating to a bulk handler.
-///
-/// Use this mixin to provide a trivial implementation for `super` calls
-/// visitor methods.
-abstract class SuperBulkMixin<R, A>
-    implements SemanticSendVisitor<R, A>, BulkHandle<R, A> {
-  R bulkHandleSuper(Send node, A arg) {
-    return bulkHandleNode(node, "Super call `#` unhandled.", arg);
-  }
-
-  @override
-  R visitSuperBinary(Send node, MethodElement function, BinaryOperator operator,
-      Node argument, A arg) {
-    return bulkHandleSuper(node, arg);
-  }
-
-  @override
-  R visitSuperCompoundIndexSet(
-      SendSet node,
-      MethodElement getter,
-      MethodElement setter,
-      Node index,
-      AssignmentOperator operator,
-      Node rhs,
-      A arg) {
-    return bulkHandleSuper(node, arg);
-  }
-
-  @override
-  R visitSuperEquals(Send node, MethodElement function, Node argument, A arg) {
-    return bulkHandleSuper(node, arg);
-  }
-
-  @override
-  R visitSuperFieldCompound(Send node, FieldElement field,
-      AssignmentOperator operator, Node rhs, A arg) {
-    return bulkHandleSuper(node, arg);
-  }
-
-  @override
-  R visitSuperFieldFieldPostfix(SendSet node, FieldElement readField,
-      FieldElement writtenField, IncDecOperator operator, A arg) {
-    return bulkHandleSuper(node, arg);
-  }
-
-  @override
-  R visitSuperFieldFieldPrefix(SendSet node, FieldElement readField,
-      FieldElement writtenField, IncDecOperator operator, A arg) {
-    return bulkHandleSuper(node, arg);
-  }
-
-  @override
-  R visitSuperFieldGet(Send node, FieldElement field, A arg) {
-    return bulkHandleSuper(node, arg);
-  }
-
-  @override
-  R visitSuperFieldInvoke(Send node, FieldElement field, NodeList arguments,
-      CallStructure callStructure, A arg) {
-    return bulkHandleSuper(node, arg);
-  }
-
-  @override
-  R visitSuperFieldPostfix(
-      SendSet node, FieldElement field, IncDecOperator operator, A arg) {
-    return bulkHandleSuper(node, arg);
-  }
-
-  @override
-  R visitSuperFieldPrefix(
-      SendSet node, FieldElement field, IncDecOperator operator, A arg) {
-    return bulkHandleSuper(node, arg);
-  }
-
-  @override
-  R visitSuperFieldSet(SendSet node, FieldElement field, Node rhs, A arg) {
-    return bulkHandleSuper(node, arg);
-  }
-
-  @override
-  R visitSuperFieldSetterCompound(Send node, FieldElement field,
-      SetterElement setter, AssignmentOperator operator, Node rhs, A arg) {
-    return bulkHandleSuper(node, arg);
-  }
-
-  @override
-  R visitSuperFieldSetterPostfix(SendSet node, FieldElement field,
-      SetterElement setter, IncDecOperator operator, A arg) {
-    return bulkHandleSuper(node, arg);
-  }
-
-  @override
-  R visitSuperFieldSetterPrefix(SendSet node, FieldElement field,
-      SetterElement setter, IncDecOperator operator, A arg) {
-    return bulkHandleSuper(node, arg);
-  }
-
-  @override
-  R visitSuperGetterFieldCompound(Send node, GetterElement getter,
-      FieldElement field, AssignmentOperator operator, Node rhs, A arg) {
-    return bulkHandleSuper(node, arg);
-  }
-
-  @override
-  R visitSuperGetterFieldPostfix(SendSet node, GetterElement getter,
-      FieldElement field, IncDecOperator operator, A arg) {
-    return bulkHandleSuper(node, arg);
-  }
-
-  @override
-  R visitSuperGetterFieldPrefix(SendSet node, GetterElement getter,
-      FieldElement field, IncDecOperator operator, A arg) {
-    return bulkHandleSuper(node, arg);
-  }
-
-  @override
-  R visitSuperGetterGet(Send node, GetterElement getter, A arg) {
-    return bulkHandleSuper(node, arg);
-  }
-
-  @override
-  R visitSuperGetterInvoke(Send node, GetterElement getter, NodeList arguments,
-      CallStructure callStructure, A arg) {
-    return bulkHandleSuper(node, arg);
-  }
-
-  @override
-  R visitSuperGetterSetterCompound(Send node, GetterElement getter,
-      SetterElement setter, AssignmentOperator operator, Node rhs, A arg) {
-    return bulkHandleSuper(node, arg);
-  }
-
-  @override
-  R visitSuperGetterSetterPostfix(SendSet node, GetterElement getter,
-      SetterElement setter, IncDecOperator operator, A arg) {
-    return bulkHandleSuper(node, arg);
-  }
-
-  @override
-  R visitSuperGetterSetterPrefix(SendSet node, GetterElement getter,
-      SetterElement setter, IncDecOperator operator, A arg) {
-    return bulkHandleSuper(node, arg);
-  }
-
-  @override
-  R visitSuperIndexSet(
-      SendSet node, FunctionElement function, Node index, Node rhs, A arg) {
-    return bulkHandleSuper(node, arg);
-  }
-
-  @override
-  R visitSuperMethodGet(Send node, MethodElement method, A arg) {
-    return bulkHandleSuper(node, arg);
-  }
-
-  @override
-  R visitSuperMethodInvoke(Send node, MethodElement method, NodeList arguments,
-      CallStructure callStructure, A arg) {
-    return bulkHandleSuper(node, arg);
-  }
-
-  @override
-  R visitSuperMethodIncompatibleInvoke(Send node, MethodElement method,
-      NodeList arguments, CallStructure callStructure, A arg) {
-    return bulkHandleSuper(node, arg);
-  }
-
-  @override
-  R visitSuperMethodSetterCompound(Send node, FunctionElement method,
-      SetterElement setter, AssignmentOperator operator, Node rhs, A arg) {
-    return bulkHandleSuper(node, arg);
-  }
-
-  @override
-  R visitSuperMethodSetterPostfix(SendSet node, FunctionElement method,
-      SetterElement setter, IncDecOperator operator, A arg) {
-    return bulkHandleSuper(node, arg);
-  }
-
-  @override
-  R visitSuperMethodSetterPrefix(SendSet node, FunctionElement method,
-      SetterElement setter, IncDecOperator operator, A arg) {
-    return bulkHandleSuper(node, arg);
-  }
-
-  @override
-  R visitSuperNotEquals(
-      Send node, MethodElement function, Node argument, A arg) {
-    return bulkHandleSuper(node, arg);
-  }
-
-  @override
-  R visitSuperSetterSet(SendSet node, SetterElement setter, Node rhs, A arg) {
-    return bulkHandleSuper(node, arg);
-  }
-
-  @override
-  R visitSuperUnary(
-      Send node, UnaryOperator operator, MethodElement function, A arg) {
-    return bulkHandleSuper(node, arg);
-  }
-
-  @override
-  R visitUnresolvedSuperBinary(Send node, Element element,
-      BinaryOperator operator, Node argument, A arg) {
-    return bulkHandleSuper(node, arg);
-  }
-
-  @override
-  R visitUnresolvedSuperGet(Send node, Element element, A arg) {
-    return bulkHandleSuper(node, arg);
-  }
-
-  @override
-  R visitUnresolvedSuperSet(Send node, Element element, Node rhs, A arg) {
-    return bulkHandleSuper(node, arg);
-  }
-
-  @override
-  R visitUnresolvedSuperInvoke(Send node, Element function, NodeList arguments,
-      Selector selector, A arg) {
-    return bulkHandleSuper(node, arg);
-  }
-
-  @override
-  R visitUnresolvedSuperIndex(Send node, Element function, Node index, A arg) {
-    return bulkHandleSuper(node, arg);
-  }
-
-  @override
-  R visitUnresolvedSuperUnary(
-      Send node, UnaryOperator operator, Element element, A arg) {
-    return bulkHandleSuper(node, arg);
-  }
-}
-
-abstract class NewBulkMixin<R, A>
-    implements SemanticSendVisitor<R, A>, BulkHandle<R, A> {
-  R bulkHandleNew(NewExpression node, A arg) {
-    return bulkHandleNode(node, "Constructor invocation `#` unhandled.", arg);
-  }
-
-  @override
-  R visitAbstractClassConstructorInvoke(
-      NewExpression node,
-      ConstructorElement element,
-      ResolutionInterfaceType type,
-      NodeList arguments,
-      CallStructure callStructure,
-      A arg) {
-    return bulkHandleNew(node, arg);
-  }
-
-  @override
-  R visitConstConstructorInvoke(
-      NewExpression node, ConstructedConstantExpression constant, A arg) {
-    return bulkHandleNew(node, arg);
-  }
-
-  @override
-  R visitBoolFromEnvironmentConstructorInvoke(NewExpression node,
-      BoolFromEnvironmentConstantExpression constant, A arg) {
-    return bulkHandleNew(node, arg);
-  }
-
-  @override
-  R visitIntFromEnvironmentConstructorInvoke(NewExpression node,
-      IntFromEnvironmentConstantExpression constant, A arg) {
-    return bulkHandleNew(node, arg);
-  }
-
-  @override
-  R visitStringFromEnvironmentConstructorInvoke(NewExpression node,
-      StringFromEnvironmentConstantExpression constant, A arg) {
-    return bulkHandleNew(node, arg);
-  }
-
-  @override
-  R visitConstructorIncompatibleInvoke(
-      NewExpression node,
-      ConstructorElement constructor,
-      ResolutionInterfaceType type,
-      NodeList arguments,
-      CallStructure callStructure,
-      A arg) {
-    return bulkHandleNew(node, arg);
-  }
-
-  @override
-  R visitGenerativeConstructorInvoke(
-      NewExpression node,
-      ConstructorElement constructor,
-      ResolutionInterfaceType type,
-      NodeList arguments,
-      CallStructure callStructure,
-      A arg) {
-    return bulkHandleNew(node, arg);
-  }
-
-  @override
-  R visitRedirectingGenerativeConstructorInvoke(
-      NewExpression node,
-      ConstructorElement constructor,
-      ResolutionInterfaceType type,
-      NodeList arguments,
-      CallStructure callStructure,
-      A arg) {
-    return bulkHandleNew(node, arg);
-  }
-
-  @override
-  R visitFactoryConstructorInvoke(
-      NewExpression node,
-      ConstructorElement constructor,
-      ResolutionInterfaceType type,
-      NodeList arguments,
-      CallStructure callStructure,
-      A arg) {
-    return bulkHandleNew(node, arg);
-  }
-
-  @override
-  R visitRedirectingFactoryConstructorInvoke(
-      NewExpression node,
-      ConstructorElement constructor,
-      ResolutionInterfaceType type,
-      ConstructorElement effectiveTarget,
-      ResolutionInterfaceType effectiveTargetType,
-      NodeList arguments,
-      CallStructure callStructure,
-      A arg) {
-    return bulkHandleNew(node, arg);
-  }
-
-  @override
-  R visitUnresolvedClassConstructorInvoke(
-      NewExpression node,
-      ErroneousElement element,
-      ResolutionDartType type,
-      NodeList arguments,
-      Selector selector,
-      A arg) {
-    return bulkHandleNew(node, arg);
-  }
-
-  @override
-  R visitUnresolvedConstructorInvoke(NewExpression node, Element constructor,
-      ResolutionDartType type, NodeList arguments, Selector selector, A arg) {
-    return bulkHandleNew(node, arg);
-  }
-
-  @override
-  R visitUnresolvedRedirectingFactoryConstructorInvoke(
-      NewExpression node,
-      ConstructorElement constructor,
-      ResolutionInterfaceType type,
-      NodeList arguments,
-      CallStructure callStructure,
-      A arg) {
-    return bulkHandleNew(node, arg);
-  }
-}
-
-/// Visitor that implements [SemanticSendVisitor] by the use of `BulkX` mixins.
-///
-/// This class is useful in itself, but shows how to use the `BulkX` mixins and
-/// tests that the union of the `BulkX` mixins implement all `visit` and `error`
-/// methods of [SemanticSendVisitor].
-class BulkSendVisitor<R, A> extends SemanticSendVisitor<R, A>
-    with
-        GetBulkMixin<R, A>,
-        SetBulkMixin<R, A>,
-        ErrorBulkMixin<R, A>,
-        InvokeBulkMixin<R, A>,
-        IndexSetBulkMixin<R, A>,
-        CompoundBulkMixin<R, A>,
-        SetIfNullBulkMixin<R, A>,
-        UnaryBulkMixin<R, A>,
-        BaseBulkMixin<R, A>,
-        BinaryBulkMixin<R, A>,
-        PrefixBulkMixin<R, A>,
-        PostfixBulkMixin<R, A>,
-        NewBulkMixin<R, A> {
-  @override
-  R apply(Node node, A arg) {
-    throw new UnimplementedError("BulkSendVisitor.apply unimplemented");
-  }
-
-  @override
-  R bulkHandleNode(Node node, String message, A arg) {
-    throw new UnimplementedError(
-        "BulkSendVisitor.bulkHandleNode unimplemented");
-  }
-}
-
-/// Mixin that implements all `visitXParameterDecl` and
-/// `visitXInitializingFormalDecl` methods of [SemanticDeclarationVisitor]
-/// by delegating to a bulk handler.
-///
-/// Use this mixin to provide a trivial implementation for these methods.
-abstract class ParameterBulkMixin<R, A>
-    implements SemanticDeclarationVisitor<R, A>, BulkHandle<R, A> {
-  R bulkHandleParameterDeclaration(VariableDefinitions node, A arg) {
-    return bulkHandleNode(node, "Parameter declaration `#` unhandled.", arg);
-  }
-
-  @override
-  R visitInitializingFormalDeclaration(VariableDefinitions node,
-      Node definition, InitializingFormalElement parameter, int index, A arg) {
-    return bulkHandleParameterDeclaration(node, arg);
-  }
-
-  @override
-  R visitNamedInitializingFormalDeclaration(
-      VariableDefinitions node,
-      Node definition,
-      InitializingFormalElement parameter,
-      ConstantExpression defaultValue,
-      A arg) {
-    return bulkHandleParameterDeclaration(node, arg);
-  }
-
-  @override
-  R visitNamedParameterDeclaration(VariableDefinitions node, Node definition,
-      ParameterElement parameter, ConstantExpression defaultValue, A arg) {
-    return bulkHandleParameterDeclaration(node, arg);
-  }
-
-  @override
-  R visitOptionalInitializingFormalDeclaration(
-      VariableDefinitions node,
-      Node definition,
-      InitializingFormalElement parameter,
-      ConstantExpression defaultValue,
-      int index,
-      A arg) {
-    return bulkHandleParameterDeclaration(node, arg);
-  }
-
-  @override
-  R visitOptionalParameterDeclaration(
-      VariableDefinitions node,
-      Node definition,
-      ParameterElement parameter,
-      ConstantExpression defaultValue,
-      int index,
-      A arg) {
-    return bulkHandleParameterDeclaration(node, arg);
-  }
-
-  @override
-  R visitParameterDeclaration(VariableDefinitions node, Node definition,
-      ParameterElement parameter, int index, A arg) {
-    return bulkHandleParameterDeclaration(node, arg);
-  }
-}
-
-/// Mixin that implements all `visitXConstructorDecl` methods of
-/// [SemanticDeclarationVisitor] by delegating to a bulk handler.
-///
-/// Use this mixin to provide a trivial implementation for these methods.
-abstract class ConstructorBulkMixin<R, A>
-    implements SemanticDeclarationVisitor<R, A>, BulkHandle<R, A> {
-  R bulkHandleConstructorDeclaration(FunctionExpression node, A arg) {
-    return bulkHandleNode(node, "Constructor declaration `#` unhandled.", arg);
-  }
-
-  @override
-  R visitFactoryConstructorDeclaration(FunctionExpression node,
-      ConstructorElement constructor, NodeList parameters, Node body, A arg) {
-    return bulkHandleConstructorDeclaration(node, arg);
-  }
-
-  @override
-  R visitGenerativeConstructorDeclaration(
-      FunctionExpression node,
-      ConstructorElement constructor,
-      NodeList parameters,
-      NodeList initializers,
-      Node body,
-      A arg) {
-    return bulkHandleConstructorDeclaration(node, arg);
-  }
-
-  @override
-  R visitRedirectingFactoryConstructorDeclaration(
-      FunctionExpression node,
-      ConstructorElement constructor,
-      NodeList parameters,
-      ResolutionInterfaceType redirectionType,
-      ConstructorElement redirectionTarget,
-      A arg) {
-    return bulkHandleConstructorDeclaration(node, arg);
-  }
-
-  @override
-  R visitRedirectingGenerativeConstructorDeclaration(
-      FunctionExpression node,
-      ConstructorElement constructor,
-      NodeList parameters,
-      NodeList initializers,
-      A arg) {
-    return bulkHandleConstructorDeclaration(node, arg);
-  }
-}
-
-/// Mixin that implements all constructor initializer visitor methods of
-/// [SemanticDeclarationVisitor] by delegating to a bulk handler.
-///
-/// Use this mixin to provide a trivial implementation for these methods.
-abstract class InitializerBulkMixin<R, A>
-    implements SemanticDeclarationVisitor<R, A>, BulkHandle<R, A> {
-  R bulkHandleInitializer(Node node, A arg) {
-    return bulkHandleNode(node, "Initializer `#` unhandled.", arg);
-  }
-
-  @override
-  R errorUnresolvedFieldInitializer(
-      SendSet node, Element element, Node initializer, A arg) {
-    return bulkHandleInitializer(node, arg);
-  }
-
-  @override
-  R errorUnresolvedSuperConstructorInvoke(Send node, Element element,
-      NodeList arguments, Selector selector, A arg) {
-    return bulkHandleInitializer(node, arg);
-  }
-
-  @override
-  R errorUnresolvedThisConstructorInvoke(Send node, Element element,
-      NodeList arguments, Selector selector, A arg) {
-    return bulkHandleInitializer(node, arg);
-  }
-
-  @override
-  R visitFieldInitializer(
-      SendSet node, FieldElement field, Node initializer, A arg) {
-    return bulkHandleInitializer(node, arg);
-  }
-
-  @override
-  R visitSuperConstructorInvoke(
-      Send node,
-      ConstructorElement superConstructor,
-      ResolutionInterfaceType type,
-      NodeList arguments,
-      CallStructure callStructure,
-      A arg) {
-    return bulkHandleInitializer(node, arg);
-  }
-
-  @override
-  R visitImplicitSuperConstructorInvoke(
-      FunctionExpression node,
-      ConstructorElement superConstructor,
-      ResolutionInterfaceType type,
-      A arg) {
-    return bulkHandleInitializer(node, arg);
-  }
-
-  @override
-  R visitThisConstructorInvoke(Send node, ConstructorElement thisConstructor,
-      NodeList arguments, CallStructure callStructure, A arg) {
-    return bulkHandleInitializer(node, arg);
-  }
-}
-
-/// Mixin that implements all function declaration visitor methods of
-/// [SemanticDeclarationVisitor] by delegating to a bulk handler.
-///
-/// Use this mixin to provide a trivial implementation for these methods.
-abstract class FunctionBulkMixin<R, A>
-    implements SemanticDeclarationVisitor<R, A>, BulkHandle<R, A> {
-  R bulkHandleFunctionDeclaration(FunctionExpression node, A arg) {
-    return bulkHandleNode(node, "Function declaration `#` unhandled.", arg);
-  }
-
-  @override
-  R visitAbstractGetterDeclaration(
-      FunctionExpression node, GetterElement getter, A arg) {
-    return bulkHandleFunctionDeclaration(node, arg);
-  }
-
-  @override
-  R visitAbstractMethodDeclaration(FunctionExpression node,
-      MethodElement method, NodeList parameters, A arg) {
-    return bulkHandleFunctionDeclaration(node, arg);
-  }
-
-  @override
-  R visitAbstractSetterDeclaration(FunctionExpression node,
-      MethodElement setter, NodeList parameters, A arg) {
-    return bulkHandleFunctionDeclaration(node, arg);
-  }
-
-  @override
-  R visitClosureDeclaration(FunctionExpression node,
-      LocalFunctionElement closure, NodeList parameters, Node body, A arg) {
-    return bulkHandleFunctionDeclaration(node, arg);
-  }
-
-  @override
-  R visitInstanceGetterDeclaration(
-      FunctionExpression node, GetterElement getter, Node body, A arg) {
-    return bulkHandleFunctionDeclaration(node, arg);
-  }
-
-  @override
-  R visitInstanceMethodDeclaration(FunctionExpression node,
-      MethodElement method, NodeList parameters, Node body, A arg) {
-    return bulkHandleFunctionDeclaration(node, arg);
-  }
-
-  @override
-  R visitInstanceSetterDeclaration(FunctionExpression node,
-      MethodElement setter, NodeList parameters, Node body, A arg) {
-    return bulkHandleFunctionDeclaration(node, arg);
-  }
-
-  @override
-  R visitLocalFunctionDeclaration(FunctionExpression node,
-      LocalFunctionElement function, NodeList parameters, Node body, A arg) {
-    return bulkHandleFunctionDeclaration(node, arg);
-  }
-
-  @override
-  R visitStaticFunctionDeclaration(FunctionExpression node,
-      MethodElement function, NodeList parameters, Node body, A arg) {
-    return bulkHandleFunctionDeclaration(node, arg);
-  }
-
-  @override
-  R visitStaticGetterDeclaration(
-      FunctionExpression node, GetterElement getter, Node body, A arg) {
-    return bulkHandleFunctionDeclaration(node, arg);
-  }
-
-  @override
-  R visitStaticSetterDeclaration(FunctionExpression node, MethodElement setter,
-      NodeList parameters, Node body, A arg) {
-    return bulkHandleFunctionDeclaration(node, arg);
-  }
-
-  @override
-  R visitTopLevelFunctionDeclaration(FunctionExpression node,
-      MethodElement function, NodeList parameters, Node body, A arg) {
-    return bulkHandleFunctionDeclaration(node, arg);
-  }
-
-  @override
-  R visitTopLevelGetterDeclaration(
-      FunctionExpression node, GetterElement getter, Node body, A arg) {
-    return bulkHandleFunctionDeclaration(node, arg);
-  }
-
-  @override
-  R visitTopLevelSetterDeclaration(FunctionExpression node,
-      MethodElement setter, NodeList parameters, Node body, A arg) {
-    return bulkHandleFunctionDeclaration(node, arg);
-  }
-}
-
-/// Mixin that implements all variable/field declaration visitor methods of
-/// [SemanticDeclarationVisitor] by delegating to a bulk handler.
-///
-/// Use this mixin to provide a trivial implementation for these methods.
-abstract class VariableBulkMixin<R, A>
-    implements SemanticDeclarationVisitor<R, A>, BulkHandle<R, A> {
-  R bulkHandleVariableDeclaration(VariableDefinitions node, A arg) {
-    return bulkHandleNode(node, "Variable declaration `#` unhandled.", arg);
-  }
-
-  @override
-  R visitInstanceFieldDeclaration(VariableDefinitions node, Node definition,
-      FieldElement field, Node initializer, A arg) {
-    return bulkHandleVariableDeclaration(node, arg);
-  }
-
-  @override
-  R visitLocalConstantDeclaration(VariableDefinitions node, Node definition,
-      LocalVariableElement variable, ConstantExpression constant, A arg) {
-    return bulkHandleVariableDeclaration(node, arg);
-  }
-
-  @override
-  R visitLocalVariableDeclaration(VariableDefinitions node, Node definition,
-      LocalVariableElement variable, Node initializer, A arg) {
-    return bulkHandleVariableDeclaration(node, arg);
-  }
-
-  @override
-  R visitStaticConstantDeclaration(VariableDefinitions node, Node definition,
-      FieldElement field, ConstantExpression constant, A arg) {
-    return bulkHandleVariableDeclaration(node, arg);
-  }
-
-  @override
-  R visitStaticFieldDeclaration(VariableDefinitions node, Node definition,
-      FieldElement field, Node initializer, A arg) {
-    return bulkHandleVariableDeclaration(node, arg);
-  }
-
-  @override
-  R visitTopLevelConstantDeclaration(VariableDefinitions node, Node definition,
-      FieldElement field, ConstantExpression constant, A arg) {
-    return bulkHandleVariableDeclaration(node, arg);
-  }
-
-  @override
-  R visitTopLevelFieldDeclaration(VariableDefinitions node, Node definition,
-      FieldElement field, Node initializer, A arg) {
-    return bulkHandleVariableDeclaration(node, arg);
-  }
-}
-
-/// Visitor that implements [SemanticDeclarationVisitor] by the use of `BulkX`
-/// mixins.
-///
-/// This class is useful in itself, but shows how to use the `BulkX` mixins and
-/// tests that the union of the `BulkX` mixins implement all `visit` and `error`
-/// methods of [SemanticDeclarationVisitor].
-class BulkDeclarationVisitor<R, A> extends SemanticDeclarationVisitor<R, A>
-    with
-        ConstructorBulkMixin<R, A>,
-        FunctionBulkMixin<R, A>,
-        VariableBulkMixin<R, A>,
-        ParameterBulkMixin<R, A>,
-        InitializerBulkMixin<R, A> {
-  @override
-  R apply(Node node, A arg) {
-    throw new UnimplementedError("BulkDeclVisitor.apply unimplemented");
-  }
-
-  @override
-  R bulkHandleNode(Node node, String message, A arg) {
-    throw new UnimplementedError(
-        "BulkDeclVisitor.bulkHandleNode unimplemented");
-  }
-
-  @override
-  applyInitializers(FunctionExpression constructor, A arg) {
-    throw new UnimplementedError(
-        "BulkDeclVisitor.applyInitializers unimplemented");
-  }
-
-  @override
-  applyParameters(NodeList parameters, A arg) {
-    throw new UnimplementedError(
-        "BulkDeclVisitor.applyParameters unimplemented");
-  }
-}
-
-/// [SemanticSendVisitor] that visits subnodes.
-class TraversalSendMixin<R, A> implements SemanticSendVisitor<R, A> {
-  @override
-  R apply(Node node, A arg) {
-    throw new UnimplementedError("TraversalMixin.apply unimplemented");
-  }
-
-  @override
-  void previsitDeferredAccess(Send node, PrefixElement prefix, A arg) {}
-
-  @override
-  R errorInvalidCompound(Send node, ErroneousElement error,
-      AssignmentOperator operator, Node rhs, A arg) {
-    apply(rhs, arg);
-    return null;
-  }
-
-  @override
-  R errorInvalidGet(Send node, ErroneousElement error, A arg) {
-    return null;
-  }
-
-  @override
-  R errorInvalidInvoke(Send node, ErroneousElement error, NodeList arguments,
-      Selector selector, A arg) {
-    apply(arguments, arg);
-    return null;
-  }
-
-  @override
-  R errorInvalidPostfix(
-      Send node, ErroneousElement error, IncDecOperator operator, A arg) {
-    return null;
-  }
-
-  @override
-  R errorInvalidPrefix(
-      Send node, ErroneousElement error, IncDecOperator operator, A arg) {
-    return null;
-  }
-
-  @override
-  R errorInvalidSet(Send node, ErroneousElement error, Node rhs, A arg) {
-    apply(rhs, arg);
-    return null;
-  }
-
-  @override
-  R errorInvalidUnary(
-      Send node, UnaryOperator operator, ErroneousElement error, A arg) {
-    return null;
-  }
-
-  @override
-  R errorInvalidEquals(Send node, ErroneousElement error, Node right, A arg) {
-    apply(right, arg);
-    return null;
-  }
-
-  @override
-  R errorInvalidNotEquals(
-      Send node, ErroneousElement error, Node right, A arg) {
-    apply(right, arg);
-    return null;
-  }
-
-  @override
-  R errorInvalidBinary(Send node, ErroneousElement error,
-      BinaryOperator operator, Node right, A arg) {
-    apply(right, arg);
-    return null;
-  }
-
-  @override
-  R errorInvalidIndex(Send node, ErroneousElement error, Node index, A arg) {
-    apply(index, arg);
-    return null;
-  }
-
-  @override
-  R errorInvalidIndexSet(
-      Send node, ErroneousElement error, Node index, Node rhs, A arg) {
-    apply(index, arg);
-    apply(rhs, arg);
-    return null;
-  }
-
-  @override
-  R errorInvalidCompoundIndexSet(Send node, ErroneousElement error, Node index,
-      AssignmentOperator operator, Node rhs, A arg) {
-    apply(index, arg);
-    apply(rhs, arg);
-    return null;
-  }
-
-  @override
-  R errorInvalidIndexPrefix(Send node, ErroneousElement error, Node index,
-      IncDecOperator operator, A arg) {
-    apply(index, arg);
-    return null;
-  }
-
-  @override
-  R errorInvalidIndexPostfix(Send node, ErroneousElement error, Node index,
-      IncDecOperator operator, A arg) {
-    apply(index, arg);
-    return null;
-  }
-
-  @override
-  R visitClassTypeLiteralSet(
-      SendSet node, TypeConstantExpression constant, Node rhs, A arg) {
-    apply(rhs, arg);
-    return null;
-  }
-
-  @override
-  R visitDynamicTypeLiteralSet(
-      SendSet node, TypeConstantExpression constant, Node rhs, A arg) {
-    apply(rhs, arg);
-    return null;
-  }
-
-  @override
-  R visitFinalLocalVariableCompound(Send node, LocalVariableElement variable,
-      AssignmentOperator operator, Node rhs, A arg) {
-    apply(rhs, arg);
-    return null;
-  }
-
-  @override
-  R visitFinalLocalVariableSet(
-      SendSet node, LocalVariableElement variable, Node rhs, A arg) {
-    apply(rhs, arg);
-    return null;
-  }
-
-  @override
-  R visitFinalParameterCompound(Send node, ParameterElement parameter,
-      AssignmentOperator operator, Node rhs, A arg) {
-    apply(rhs, arg);
-    return null;
-  }
-
-  @override
-  R visitFinalParameterSet(
-      SendSet node, ParameterElement parameter, Node rhs, A arg) {
-    apply(rhs, arg);
-    return null;
-  }
-
-  @override
-  R visitFinalStaticFieldCompound(Send node, FieldElement field,
-      AssignmentOperator operator, Node rhs, A arg) {
-    apply(rhs, arg);
-    return null;
-  }
-
-  @override
-  R visitFinalStaticFieldSet(
-      SendSet node, FieldElement field, Node rhs, A arg) {
-    apply(rhs, arg);
-    return null;
-  }
-
-  @override
-  R visitFinalSuperFieldSet(SendSet node, FieldElement field, Node rhs, A arg) {
-    apply(rhs, arg);
-    return null;
-  }
-
-  @override
-  R visitFinalTopLevelFieldCompound(Send node, FieldElement field,
-      AssignmentOperator operator, Node rhs, A arg) {
-    apply(rhs, arg);
-    return null;
-  }
-
-  @override
-  R visitFinalTopLevelFieldSet(
-      SendSet node, FieldElement field, Node rhs, A arg) {
-    apply(rhs, arg);
-    return null;
-  }
-
-  @override
-  R visitLocalFunctionCompound(Send node, LocalFunctionElement function,
-      AssignmentOperator operator, Node rhs, A arg) {
-    apply(rhs, arg);
-    return null;
-  }
-
-  @override
-  R visitLocalFunctionPostfix(Send node, LocalFunctionElement function,
-      IncDecOperator operator, A arg) {
-    return null;
-  }
-
-  @override
-  R visitLocalFunctionPrefix(Send node, LocalFunctionElement function,
-      IncDecOperator operator, A arg) {
-    return null;
-  }
-
-  @override
-  R visitLocalFunctionSet(
-      SendSet node, LocalFunctionElement function, Node rhs, A arg) {
-    apply(rhs, arg);
-    return null;
-  }
-
-  @override
-  R visitStaticFunctionSet(
-      SendSet node, MethodElement function, Node rhs, A arg) {
-    apply(rhs, arg);
-    return null;
-  }
-
-  @override
-  R visitStaticGetterSet(SendSet node, GetterElement getter, Node rhs, A arg) {
-    apply(rhs, arg);
-    return null;
-  }
-
-  @override
-  R visitStaticSetterGet(Send node, SetterElement setter, A arg) {
-    return null;
-  }
-
-  @override
-  R visitStaticSetterInvoke(Send node, SetterElement setter, NodeList arguments,
-      CallStructure callStructure, A arg) {
-    apply(arguments, arg);
-    return null;
-  }
-
-  @override
-  R visitSuperGetterSet(SendSet node, GetterElement getter, Node rhs, A arg) {
-    apply(rhs, arg);
-    return null;
-  }
-
-  @override
-  R visitSuperMethodSet(SendSet node, MethodElement method, Node rhs, A arg) {
-    apply(rhs, arg);
-    return null;
-  }
-
-  @override
-  R visitSuperSetterGet(Send node, SetterElement setter, A arg) {
-    return null;
-  }
-
-  @override
-  R visitSuperSetterInvoke(Send node, SetterElement setter, NodeList arguments,
-      CallStructure callStructure, A arg) {
-    apply(arguments, arg);
-    return null;
-  }
-
-  @override
-  R visitTopLevelFunctionSet(
-      SendSet node, MethodElement function, Node rhs, A arg) {
-    apply(rhs, arg);
-    return null;
-  }
-
-  @override
-  R visitTopLevelGetterSet(
-      SendSet node, GetterElement getter, Node rhs, A arg) {
-    apply(rhs, arg);
-    return null;
-  }
-
-  @override
-  R visitTopLevelSetterGet(Send node, SetterElement setter, A arg) {
-    return null;
-  }
-
-  @override
-  R visitTopLevelSetterInvoke(Send node, SetterElement setter,
-      NodeList arguments, CallStructure callStructure, A arg) {
-    apply(arguments, arg);
-    return null;
-  }
-
-  @override
-  R visitTypeVariableTypeLiteralSet(
-      SendSet node, TypeVariableElement element, Node rhs, A arg) {
-    apply(rhs, arg);
-    return null;
-  }
-
-  @override
-  R visitTypedefTypeLiteralSet(
-      SendSet node, TypeConstantExpression constant, Node rhs, A arg) {
-    apply(rhs, arg);
-    return null;
-  }
-
-  @override
-  R visitUnresolvedSuperIndex(Send node, Element function, Node index, A arg) {
-    apply(index, arg);
-    return null;
-  }
-
-  @override
-  R visitUnresolvedSuperGet(Send node, Element element, A arg) {
-    return null;
-  }
-
-  @override
-  R visitUnresolvedSuperSet(Send node, Element element, Node rhs, A arg) {
-    apply(rhs, arg);
-    return null;
-  }
-
-  @override
-  R visitUnresolvedSuperInvoke(Send node, Element function, NodeList arguments,
-      Selector selector, A arg) {
-    apply(arguments, arg);
-    return null;
-  }
-
-  @override
-  R visitAs(Send node, Node expression, ResolutionDartType type, A arg) {
-    apply(expression, arg);
-    return null;
-  }
-
-  @override
-  R visitBinary(
-      Send node, Node left, BinaryOperator operator, Node right, A arg) {
-    apply(left, arg);
-    apply(right, arg);
-    return null;
-  }
-
-  @override
-  R visitClassTypeLiteralCompound(Send node, ConstantExpression constant,
-      AssignmentOperator operator, Node rhs, A arg) {
-    apply(rhs, arg);
-    return null;
-  }
-
-  @override
-  R visitClassTypeLiteralGet(Send node, ConstantExpression constant, A arg) {
-    return null;
-  }
-
-  @override
-  R visitClassTypeLiteralInvoke(Send node, ConstantExpression constant,
-      NodeList arguments, CallStructure callStructure, A arg) {
-    apply(arguments, arg);
-    return null;
-  }
-
-  @override
-  R visitClassTypeLiteralPostfix(
-      Send node, ConstantExpression constant, IncDecOperator operator, A arg) {
-    return null;
-  }
-
-  @override
-  R visitClassTypeLiteralPrefix(
-      Send node, ConstantExpression constant, IncDecOperator operator, A arg) {
-    return null;
-  }
-
-  @override
-  R visitCompoundIndexSet(SendSet node, Node receiver, Node index,
-      AssignmentOperator operator, Node rhs, A arg) {
-    apply(receiver, arg);
-    apply(index, arg);
-    apply(rhs, arg);
-    return null;
-  }
-
-  @override
-  R visitConstantGet(Send node, ConstantExpression constant, A arg) {
-    return null;
-  }
-
-  @override
-  R visitConstantInvoke(Send node, ConstantExpression constant,
-      NodeList arguments, CallStructure callStructure, A arg) {
-    apply(arguments, arg);
-    return null;
-  }
-
-  @override
-  R visitDynamicPropertyCompound(Send node, Node receiver, Name name,
-      AssignmentOperator operator, Node rhs, A arg) {
-    apply(receiver, arg);
-    apply(rhs, arg);
-    return null;
-  }
-
-  @override
-  R visitIfNotNullDynamicPropertyCompound(Send node, Node receiver, Name name,
-      AssignmentOperator operator, Node rhs, A arg) {
-    apply(receiver, arg);
-    apply(rhs, arg);
-    return null;
-  }
-
-  @override
-  R visitDynamicPropertyGet(Send node, Node receiver, Name name, A arg) {
-    apply(receiver, arg);
-    return null;
-  }
-
-  @override
-  R visitIfNotNullDynamicPropertyGet(
-      Send node, Node receiver, Name name, A arg) {
-    apply(receiver, arg);
-    return null;
-  }
-
-  @override
-  R visitDynamicPropertyInvoke(
-      Send node, Node receiver, NodeList arguments, Selector selector, A arg) {
-    apply(receiver, arg);
-    apply(arguments, arg);
-    return null;
-  }
-
-  @override
-  R visitIfNotNullDynamicPropertyInvoke(
-      Send node, Node receiver, NodeList arguments, Selector selector, A arg) {
-    apply(receiver, arg);
-    apply(arguments, arg);
-    return null;
-  }
-
-  @override
-  R visitDynamicPropertyPostfix(
-      Send node, Node receiver, Name name, IncDecOperator operator, A arg) {
-    apply(receiver, arg);
-    return null;
-  }
-
-  @override
-  R visitIfNotNullDynamicPropertyPostfix(
-      Send node, Node receiver, Name name, IncDecOperator operator, A arg) {
-    apply(receiver, arg);
-    return null;
-  }
-
-  @override
-  R visitDynamicPropertyPrefix(
-      Send node, Node receiver, Name name, IncDecOperator operator, A arg) {
-    apply(receiver, arg);
-    return null;
-  }
-
-  @override
-  R visitIfNotNullDynamicPropertyPrefix(
-      Send node, Node receiver, Name name, IncDecOperator operator, A arg) {
-    apply(receiver, arg);
-    return null;
-  }
-
-  @override
-  R visitDynamicPropertySet(
-      SendSet node, Node receiver, Name name, Node rhs, A arg) {
-    apply(receiver, arg);
-    apply(rhs, arg);
-    return null;
-  }
-
-  @override
-  R visitIfNotNullDynamicPropertySet(
-      SendSet node, Node receiver, Name name, Node rhs, A arg) {
-    apply(receiver, arg);
-    apply(rhs, arg);
-    return null;
-  }
-
-  @override
-  R visitDynamicTypeLiteralCompound(Send node, ConstantExpression constant,
-      AssignmentOperator operator, Node rhs, A arg) {
-    apply(rhs, arg);
-    return null;
-  }
-
-  @override
-  R visitDynamicTypeLiteralGet(Send node, ConstantExpression constant, A arg) {
-    return null;
-  }
-
-  @override
-  R visitDynamicTypeLiteralInvoke(Send node, ConstantExpression constant,
-      NodeList arguments, CallStructure callStructure, A arg) {
-    apply(arguments, arg);
-    return null;
-  }
-
-  @override
-  R visitDynamicTypeLiteralPostfix(
-      Send node, ConstantExpression constant, IncDecOperator operator, A arg) {
-    return null;
-  }
-
-  @override
-  R visitDynamicTypeLiteralPrefix(
-      Send node, ConstantExpression constant, IncDecOperator operator, A arg) {
-    return null;
-  }
-
-  @override
-  R visitEquals(Send node, Node left, Node right, A arg) {
-    apply(left, arg);
-    apply(right, arg);
-    return null;
-  }
-
-  @override
-  R visitExpressionInvoke(Send node, Node expression, NodeList arguments,
-      CallStructure callStructure, A arg) {
-    apply(expression, arg);
-    apply(arguments, arg);
-    return null;
-  }
-
-  @override
-  R visitIndex(Send node, Node receiver, Node index, A arg) {
-    apply(receiver, arg);
-    apply(index, arg);
-    return null;
-  }
-
-  @override
-  R visitIndexSet(SendSet node, Node receiver, Node index, Node rhs, A arg) {
-    apply(receiver, arg);
-    apply(index, arg);
-    apply(rhs, arg);
-    return null;
-  }
-
-  @override
-  R visitIs(Send node, Node expression, ResolutionDartType type, A arg) {
-    apply(expression, arg);
-    return null;
-  }
-
-  @override
-  R visitIsNot(Send node, Node expression, ResolutionDartType type, A arg) {
-    apply(expression, arg);
-    return null;
-  }
-
-  @override
-  R visitLocalFunctionGet(Send node, LocalFunctionElement function, A arg) {
-    return null;
-  }
-
-  @override
-  R visitLocalFunctionInvoke(Send node, LocalFunctionElement function,
-      NodeList arguments, CallStructure callStructure, A arg) {
-    apply(arguments, arg);
-    return null;
-  }
-
-  @override
-  R visitLocalFunctionIncompatibleInvoke(
-      Send node,
-      LocalFunctionElement function,
-      NodeList arguments,
-      CallStructure callStructure,
-      A arg) {
-    apply(arguments, arg);
-    return null;
-  }
-
-  @override
-  R visitLocalVariableCompound(Send node, LocalVariableElement variable,
-      AssignmentOperator operator, Node rhs, A arg) {
-    apply(rhs, arg);
-    return null;
-  }
-
-  @override
-  R visitLocalVariableGet(Send node, LocalVariableElement variable, A arg) {
-    return null;
-  }
-
-  @override
-  R visitLocalVariableInvoke(Send node, LocalVariableElement variable,
-      NodeList arguments, CallStructure callStructure, A arg) {
-    apply(arguments, arg);
-    return null;
-  }
-
-  @override
-  R visitLocalVariablePostfix(Send node, LocalVariableElement variable,
-      IncDecOperator operator, A arg) {
-    return null;
-  }
-
-  @override
-  R visitLocalVariablePrefix(Send node, LocalVariableElement variable,
-      IncDecOperator operator, A arg) {
-    return null;
-  }
-
-  @override
-  R visitLocalVariableSet(
-      SendSet node, LocalVariableElement variable, Node rhs, A arg) {
-    apply(rhs, arg);
-    return null;
-  }
-
-  @override
-  R visitIfNull(Send node, Node left, Node right, A arg) {
-    apply(left, arg);
-    apply(right, arg);
-    return null;
-  }
-
-  @override
-  R visitLogicalAnd(Send node, Node left, Node right, A arg) {
-    apply(left, arg);
-    apply(right, arg);
-    return null;
-  }
-
-  @override
-  R visitLogicalOr(Send node, Node left, Node right, A arg) {
-    apply(left, arg);
-    apply(right, arg);
-    return null;
-  }
-
-  @override
-  R visitNot(Send node, Node expression, A arg) {
-    apply(expression, arg);
-    return null;
-  }
-
-  @override
-  R visitNotEquals(Send node, Node left, Node right, A arg) {
-    apply(left, arg);
-    apply(right, arg);
-    return null;
-  }
-
-  @override
-  R visitParameterCompound(Send node, ParameterElement parameter,
-      AssignmentOperator operator, Node rhs, A arg) {
-    apply(rhs, arg);
-    return null;
-  }
-
-  @override
-  R visitParameterGet(Send node, ParameterElement parameter, A arg) {
-    return null;
-  }
-
-  @override
-  R visitParameterInvoke(Send node, ParameterElement parameter,
-      NodeList arguments, CallStructure callStructure, A arg) {
-    apply(arguments, arg);
-    return null;
-  }
-
-  @override
-  R visitParameterPostfix(
-      Send node, ParameterElement parameter, IncDecOperator operator, A arg) {
-    return null;
-  }
-
-  @override
-  R visitParameterPrefix(
-      Send node, ParameterElement parameter, IncDecOperator operator, A arg) {
-    return null;
-  }
-
-  @override
-  R visitParameterSet(
-      SendSet node, ParameterElement parameter, Node rhs, A arg) {
-    apply(rhs, arg);
-    return null;
-  }
-
-  @override
-  R visitStaticFieldCompound(Send node, FieldElement field,
-      AssignmentOperator operator, Node rhs, A arg) {
-    apply(rhs, arg);
-    return null;
-  }
-
-  @override
-  R visitStaticFieldGet(Send node, FieldElement field, A arg) {
-    return null;
-  }
-
-  @override
-  R visitStaticFieldInvoke(Send node, FieldElement field, NodeList arguments,
-      CallStructure callStructure, A arg) {
-    apply(arguments, arg);
-    return null;
-  }
-
-  @override
-  R visitStaticFieldPostfix(
-      Send node, FieldElement field, IncDecOperator operator, A arg) {
-    return null;
-  }
-
-  @override
-  R visitStaticFieldPrefix(
-      Send node, FieldElement field, IncDecOperator operator, A arg) {
-    return null;
-  }
-
-  @override
-  R visitStaticFieldSet(SendSet node, FieldElement field, Node rhs, A arg) {
-    apply(rhs, arg);
-    return null;
-  }
-
-  @override
-  R visitStaticFunctionGet(Send node, MethodElement function, A arg) {
-    return null;
-  }
-
-  @override
-  R visitStaticFunctionInvoke(Send node, MethodElement function,
-      NodeList arguments, CallStructure callStructure, A arg) {
-    apply(arguments, arg);
-    return null;
-  }
-
-  @override
-  R visitStaticFunctionIncompatibleInvoke(Send node, MethodElement function,
-      NodeList arguments, CallStructure callStructure, A arg) {
-    apply(arguments, arg);
-    return null;
-  }
-
-  @override
-  R visitStaticGetterGet(Send node, GetterElement getter, A arg) {
-    return null;
-  }
-
-  @override
-  R visitStaticGetterInvoke(Send node, GetterElement getter, NodeList arguments,
-      CallStructure callStructure, A arg) {
-    apply(arguments, arg);
-    return null;
-  }
-
-  @override
-  R visitStaticGetterSetterCompound(Send node, GetterElement getter,
-      SetterElement setter, AssignmentOperator operator, Node rhs, A arg) {
-    apply(rhs, arg);
-    return null;
-  }
-
-  @override
-  R visitStaticGetterSetterPostfix(Send node, GetterElement getter,
-      SetterElement setter, IncDecOperator operator, A arg) {
-    return null;
-  }
-
-  @override
-  R visitStaticGetterSetterPrefix(Send node, GetterElement getter,
-      SetterElement setter, IncDecOperator operator, A arg) {
-    return null;
-  }
-
-  @override
-  R visitStaticMethodSetterCompound(Send node, FunctionElement method,
-      SetterElement setter, AssignmentOperator operator, Node rhs, A arg) {
-    apply(rhs, arg);
-    return null;
-  }
-
-  @override
-  R visitStaticMethodSetterPostfix(Send node, GetterElement getter,
-      SetterElement setter, IncDecOperator operator, A arg) {
-    return null;
-  }
-
-  @override
-  R visitStaticMethodSetterPrefix(Send node, GetterElement getter,
-      SetterElement setter, IncDecOperator operator, A arg) {
-    return null;
-  }
-
-  @override
-  R visitStaticSetterSet(SendSet node, SetterElement setter, Node rhs, A arg) {
-    apply(rhs, arg);
-    return null;
-  }
-
-  @override
-  R visitSuperBinary(Send node, MethodElement function, BinaryOperator operator,
-      Node argument, A arg) {
-    apply(argument, arg);
-    return null;
-  }
-
-  @override
-  R visitSuperCompoundIndexSet(
-      SendSet node,
-      MethodElement getter,
-      MethodElement setter,
-      Node index,
-      AssignmentOperator operator,
-      Node rhs,
-      A arg) {
-    apply(rhs, arg);
-    return null;
-  }
-
-  @override
-  R visitSuperEquals(Send node, MethodElement function, Node argument, A arg) {
-    apply(argument, arg);
-    return null;
-  }
-
-  @override
-  R visitSuperFieldCompound(Send node, FieldElement field,
-      AssignmentOperator operator, Node rhs, A arg) {
-    apply(rhs, arg);
-    return null;
-  }
-
-  @override
-  R visitSuperFieldFieldPostfix(SendSet node, FieldElement readField,
-      FieldElement writtenField, IncDecOperator operator, A arg) {
-    return null;
-  }
-
-  @override
-  R visitSuperFieldFieldPrefix(SendSet node, FieldElement readField,
-      FieldElement writtenField, IncDecOperator operator, A arg) {
-    return null;
-  }
-
-  @override
-  R visitSuperFieldGet(Send node, FieldElement field, A arg) {
-    return null;
-  }
-
-  @override
-  R visitSuperFieldInvoke(Send node, FieldElement field, NodeList arguments,
-      CallStructure callStructure, A arg) {
-    apply(arguments, arg);
-    return null;
-  }
-
-  @override
-  R visitSuperFieldPostfix(
-      SendSet node, FieldElement field, IncDecOperator operator, A arg) {
-    return null;
-  }
-
-  @override
-  R visitSuperFieldPrefix(
-      SendSet node, FieldElement field, IncDecOperator operator, A arg) {
-    return null;
-  }
-
-  @override
-  R visitSuperFieldSet(SendSet node, FieldElement field, Node rhs, A arg) {
-    apply(rhs, arg);
-    return null;
-  }
-
-  @override
-  R visitSuperFieldSetterCompound(Send node, FieldElement field,
-      SetterElement setter, AssignmentOperator operator, Node rhs, A arg) {
-    apply(rhs, arg);
-    return null;
-  }
-
-  @override
-  R visitSuperFieldSetterPostfix(SendSet node, FieldElement field,
-      SetterElement setter, IncDecOperator operator, A arg) {
-    return null;
-  }
-
-  @override
-  R visitSuperFieldSetterPrefix(SendSet node, FieldElement field,
-      SetterElement setter, IncDecOperator operator, A arg) {
-    return null;
-  }
-
-  @override
-  R visitSuperGetterFieldCompound(Send node, GetterElement getter,
-      FieldElement field, AssignmentOperator operator, Node rhs, A arg) {
-    apply(rhs, arg);
-    return null;
-  }
-
-  @override
-  R visitSuperGetterFieldPostfix(SendSet node, GetterElement getter,
-      FieldElement field, IncDecOperator operator, A arg) {
-    return null;
-  }
-
-  @override
-  R visitSuperGetterFieldPrefix(SendSet node, GetterElement getter,
-      FieldElement field, IncDecOperator operator, A arg) {
-    return null;
-  }
-
-  @override
-  R visitSuperGetterGet(Send node, GetterElement getter, A arg) {
-    return null;
-  }
-
-  @override
-  R visitSuperGetterInvoke(Send node, GetterElement getter, NodeList arguments,
-      CallStructure callStructure, A arg) {
-    apply(arguments, arg);
-    return null;
-  }
-
-  @override
-  R visitSuperGetterSetterCompound(Send node, GetterElement getter,
-      SetterElement setter, AssignmentOperator operator, Node rhs, A arg) {
-    apply(rhs, arg);
-    return null;
-  }
-
-  @override
-  R visitSuperGetterSetterPostfix(SendSet node, GetterElement getter,
-      SetterElement setter, IncDecOperator operator, A arg) {
-    return null;
-  }
-
-  @override
-  R visitSuperGetterSetterPrefix(SendSet node, GetterElement getter,
-      SetterElement setter, IncDecOperator operator, A arg) {
-    return null;
-  }
-
-  @override
-  R visitSuperIndex(Send node, MethodElement function, Node index, A arg) {
-    apply(index, arg);
-    return null;
-  }
-
-  @override
-  R visitSuperIndexSet(
-      SendSet node, FunctionElement function, Node index, Node rhs, A arg) {
-    apply(index, arg);
-    apply(rhs, arg);
-    return null;
-  }
-
-  @override
-  R visitSuperMethodGet(Send node, MethodElement method, A arg) {
-    return null;
-  }
-
-  @override
-  R visitSuperMethodInvoke(Send node, MethodElement method, NodeList arguments,
-      CallStructure callStructure, A arg) {
-    apply(arguments, arg);
-    return null;
-  }
-
-  @override
-  R visitSuperMethodIncompatibleInvoke(Send node, MethodElement method,
-      NodeList arguments, CallStructure callStructure, A arg) {
-    apply(arguments, arg);
-    return null;
-  }
-
-  @override
-  R visitSuperMethodSetterCompound(Send node, FunctionElement method,
-      SetterElement setter, AssignmentOperator operator, Node rhs, A arg) {
-    apply(rhs, arg);
-    return null;
-  }
-
-  @override
-  R visitSuperMethodSetterPostfix(SendSet node, FunctionElement method,
-      SetterElement setter, IncDecOperator operator, A arg) {
-    return null;
-  }
-
-  @override
-  R visitSuperMethodSetterPrefix(SendSet node, FunctionElement method,
-      SetterElement setter, IncDecOperator operator, A arg) {
-    return null;
-  }
-
-  @override
-  R visitSuperNotEquals(
-      Send node, MethodElement function, Node argument, A arg) {
-    apply(argument, arg);
-    return null;
-  }
-
-  @override
-  R visitSuperSetterSet(SendSet node, SetterElement setter, Node rhs, A arg) {
-    apply(rhs, arg);
-    return null;
-  }
-
-  @override
-  R visitSuperUnary(
-      Send node, UnaryOperator operator, MethodElement function, A arg) {
-    return null;
-  }
-
-  @override
-  R visitThisGet(Identifier node, A arg) {
-    return null;
-  }
-
-  @override
-  R visitThisInvoke(
-      Send node, NodeList arguments, CallStructure callStructure, A arg) {
-    apply(arguments, arg);
-    return null;
-  }
-
-  @override
-  R visitThisPropertyCompound(
-      Send node, Name name, AssignmentOperator operator, Node rhs, A arg) {
-    apply(rhs, arg);
-    return null;
-  }
-
-  @override
-  R visitThisPropertyGet(Send node, Name name, A arg) {
-    return null;
-  }
-
-  @override
-  R visitThisPropertyInvoke(
-      Send node, NodeList arguments, Selector selector, A arg) {
-    apply(arguments, arg);
-    return null;
-  }
-
-  @override
-  R visitThisPropertyPostfix(
-      Send node, Name name, IncDecOperator operator, A arg) {
-    return null;
-  }
-
-  @override
-  R visitThisPropertyPrefix(
-      Send node, Name name, IncDecOperator operator, A arg) {
-    return null;
-  }
-
-  @override
-  R visitThisPropertySet(SendSet node, Name name, Node rhs, A arg) {
-    apply(rhs, arg);
-    return null;
-  }
-
-  @override
-  R visitTopLevelFieldCompound(Send node, FieldElement field,
-      AssignmentOperator operator, Node rhs, A arg) {
-    apply(rhs, arg);
-    return null;
-  }
-
-  @override
-  R visitTopLevelFieldGet(Send node, FieldElement field, A arg) {
-    return null;
-  }
-
-  @override
-  R visitTopLevelFieldInvoke(Send node, FieldElement field, NodeList arguments,
-      CallStructure callStructure, A arg) {
-    apply(arguments, arg);
-    return null;
-  }
-
-  @override
-  R visitTopLevelFieldPostfix(
-      Send node, FieldElement field, IncDecOperator operator, A arg) {
-    return null;
-  }
-
-  @override
-  R visitTopLevelFieldPrefix(
-      Send node, FieldElement field, IncDecOperator operator, A arg) {
-    return null;
-  }
-
-  @override
-  R visitTopLevelFieldSet(SendSet node, FieldElement field, Node rhs, A arg) {
-    apply(rhs, arg);
-    return null;
-  }
-
-  @override
-  R visitTopLevelFunctionGet(Send node, MethodElement function, A arg) {
-    return null;
-  }
-
-  @override
-  R visitTopLevelFunctionInvoke(Send node, MethodElement function,
-      NodeList arguments, CallStructure callStructure, A arg) {
-    apply(arguments, arg);
-    return null;
-  }
-
-  @override
-  R visitTopLevelFunctionIncompatibleInvoke(Send node, MethodElement function,
-      NodeList arguments, CallStructure callStructure, A arg) {
-    apply(arguments, arg);
-    return null;
-  }
-
-  @override
-  R visitTopLevelGetterGet(Send node, GetterElement getter, A arg) {
-    return null;
-  }
-
-  @override
-  R visitTopLevelGetterInvoke(Send node, GetterElement getter,
-      NodeList arguments, CallStructure callStructure, A arg) {
-    apply(arguments, arg);
-    return null;
-  }
-
-  @override
-  R visitTopLevelGetterSetterCompound(Send node, GetterElement getter,
-      SetterElement setter, AssignmentOperator operator, Node rhs, A arg) {
-    apply(rhs, arg);
-    return null;
-  }
-
-  @override
-  R visitTopLevelGetterSetterPostfix(Send node, GetterElement getter,
-      SetterElement setter, IncDecOperator operator, A arg) {
-    return null;
-  }
-
-  @override
-  R visitTopLevelGetterSetterPrefix(Send node, GetterElement getter,
-      SetterElement setter, IncDecOperator operator, A arg) {
-    return null;
-  }
-
-  @override
-  R visitTopLevelMethodSetterCompound(Send node, FunctionElement method,
-      SetterElement setter, AssignmentOperator operator, Node rhs, A arg) {
-    apply(rhs, arg);
-    return null;
-  }
-
-  @override
-  R visitTopLevelMethodSetterPostfix(Send node, FunctionElement method,
-      SetterElement setter, IncDecOperator operator, A arg) {
-    return null;
-  }
-
-  @override
-  R visitTopLevelMethodSetterPrefix(Send node, FunctionElement method,
-      SetterElement setter, IncDecOperator operator, A arg) {
-    return null;
-  }
-
-  @override
-  R visitTopLevelSetterSet(
-      SendSet node, SetterElement setter, Node rhs, A arg) {
-    apply(rhs, arg);
-    return null;
-  }
-
-  @override
-  R visitTypeVariableTypeLiteralCompound(Send node, TypeVariableElement element,
-      AssignmentOperator operator, Node rhs, A arg) {
-    apply(rhs, arg);
-    return null;
-  }
-
-  @override
-  R visitTypeVariableTypeLiteralGet(
-      Send node, TypeVariableElement element, A arg) {
-    return null;
-  }
-
-  @override
-  R visitTypeVariableTypeLiteralInvoke(Send node, TypeVariableElement element,
-      NodeList arguments, CallStructure callStructure, A arg) {
-    apply(arguments, arg);
-    return null;
-  }
-
-  @override
-  R visitTypeVariableTypeLiteralPostfix(
-      Send node, TypeVariableElement element, IncDecOperator operator, A arg) {
-    return null;
-  }
-
-  @override
-  R visitTypeVariableTypeLiteralPrefix(
-      Send node, TypeVariableElement element, IncDecOperator operator, A arg) {
-    return null;
-  }
-
-  @override
-  R visitTypedefTypeLiteralCompound(Send node, ConstantExpression constant,
-      AssignmentOperator operator, Node rhs, A arg) {
-    apply(rhs, arg);
-    return null;
-  }
-
-  @override
-  R visitTypedefTypeLiteralGet(Send node, ConstantExpression constant, A arg) {
-    return null;
-  }
-
-  @override
-  R visitTypedefTypeLiteralInvoke(Send node, ConstantExpression constant,
-      NodeList arguments, CallStructure callStructure, A arg) {
-    apply(arguments, arg);
-    return null;
-  }
-
-  @override
-  R visitTypedefTypeLiteralPostfix(
-      Send node, ConstantExpression constant, IncDecOperator operator, A arg) {
-    return null;
-  }
-
-  @override
-  R visitTypedefTypeLiteralPrefix(
-      Send node, ConstantExpression constant, IncDecOperator operator, A arg) {
-    return null;
-  }
-
-  @override
-  R visitUnary(Send node, UnaryOperator operator, Node expression, A arg) {
-    apply(expression, arg);
-    return null;
-  }
-
-  @override
-  R visitUnresolvedCompound(Send node, ErroneousElement element,
-      AssignmentOperator operator, Node rhs, A arg) {
-    apply(rhs, arg);
-    return null;
-  }
-
-  @override
-  R visitUnresolvedGet(Send node, Element element, A arg) {
-    return null;
-  }
-
-  @override
-  R visitUnresolvedInvoke(Send node, Element element, NodeList arguments,
-      Selector selector, A arg) {
-    apply(arguments, arg);
-    return null;
-  }
-
-  @override
-  R visitUnresolvedPostfix(
-      Send node, ErroneousElement element, IncDecOperator operator, A arg) {
-    return null;
-  }
-
-  @override
-  R visitUnresolvedPrefix(
-      Send node, ErroneousElement element, IncDecOperator operator, A arg) {
-    return null;
-  }
-
-  @override
-  R visitUnresolvedSet(SendSet node, Element element, Node rhs, A arg) {
-    apply(rhs, arg);
-    return null;
-  }
-
-  @override
-  R errorUndefinedBinaryExpression(
-      Send node, Node left, Operator operator, Node right, A arg) {
-    apply(left, arg);
-    apply(right, arg);
-    return null;
-  }
-
-  @override
-  R errorUndefinedUnaryExpression(
-      Send node, Operator operator, Node expression, A arg) {
-    apply(expression, arg);
-    return null;
-  }
-
-  @override
-  R visitUnresolvedSuperIndexSet(
-      SendSet node, ErroneousElement element, Node index, Node rhs, A arg) {
-    apply(index, arg);
-    apply(rhs, arg);
-    return null;
-  }
-
-  @override
-  R visitUnresolvedSuperGetterCompoundIndexSet(
-      SendSet node,
-      Element element,
-      MethodElement setter,
-      Node index,
-      AssignmentOperator operator,
-      Node rhs,
-      A arg) {
-    apply(index, arg);
-    apply(rhs, arg);
-    return null;
-  }
-
-  @override
-  R visitUnresolvedSuperSetterCompoundIndexSet(
-      SendSet node,
-      MethodElement getter,
-      Element element,
-      Node index,
-      AssignmentOperator operator,
-      Node rhs,
-      A arg) {
-    apply(index, arg);
-    apply(rhs, arg);
-    return null;
-  }
-
-  @override
-  R visitUnresolvedSuperCompoundIndexSet(SendSet node, Element element,
-      Node index, AssignmentOperator operator, Node rhs, A arg) {
-    apply(index, arg);
-    apply(rhs, arg);
-    return null;
-  }
-
-  @override
-  R visitUnresolvedSuperBinary(Send node, Element element,
-      BinaryOperator operator, Node argument, A arg) {
-    apply(argument, arg);
-    return null;
-  }
-
-  @override
-  R visitUnresolvedSuperUnary(
-      Send node, UnaryOperator operator, Element element, A arg) {
-    return null;
-  }
-
-  @override
-  R visitUnresolvedSuperGetterIndexPostfix(SendSet node, Element element,
-      MethodElement setter, Node index, IncDecOperator operator, A arg) {
-    apply(index, arg);
-    return null;
-  }
-
-  @override
-  R visitUnresolvedSuperSetterIndexPostfix(SendSet node, MethodElement getter,
-      Element element, Node index, IncDecOperator operator, A arg) {
-    apply(index, arg);
-    return null;
-  }
-
-  @override
-  R visitUnresolvedSuperIndexPostfix(
-      Send node, Element element, Node index, IncDecOperator operator, A arg) {
-    apply(index, arg);
-    return null;
-  }
-
-  @override
-  R visitUnresolvedSuperGetterIndexPrefix(SendSet node, Element element,
-      MethodElement setter, Node index, IncDecOperator operator, A arg) {
-    apply(index, arg);
-    return null;
-  }
-
-  @override
-  R visitUnresolvedSuperSetterIndexPrefix(SendSet node, MethodElement getter,
-      Element element, Node index, IncDecOperator operator, A arg) {
-    apply(index, arg);
-    return null;
-  }
-
-  @override
-  R visitUnresolvedSuperIndexPrefix(
-      Send node, Element element, Node index, IncDecOperator operator, A arg) {
-    apply(index, arg);
-    return null;
-  }
-
-  @override
-  R visitIndexPostfix(
-      Send node, Node receiver, Node index, IncDecOperator operator, A arg) {
-    apply(receiver, arg);
-    apply(index, arg);
-    return null;
-  }
-
-  @override
-  R visitIndexPrefix(
-      Send node, Node receiver, Node index, IncDecOperator operator, A arg) {
-    apply(receiver, arg);
-    apply(index, arg);
-    return null;
-  }
-
-  @override
-  R visitSuperIndexPostfix(
-      Send node,
-      MethodElement indexFunction,
-      MethodElement indexSetFunction,
-      Node index,
-      IncDecOperator operator,
-      A arg) {
-    apply(index, arg);
-    return null;
-  }
-
-  @override
-  R visitSuperIndexPrefix(
-      Send node,
-      MethodElement indexFunction,
-      MethodElement indexSetFunction,
-      Node index,
-      IncDecOperator operator,
-      A arg) {
-    apply(index, arg);
-    return null;
-  }
-
-  @override
-  R errorInvalidSetIfNull(Send node, ErroneousElement error, Node rhs, A arg) {
-    apply(rhs, arg);
-    return null;
-  }
-
-  @override
-  R visitClassTypeLiteralSetIfNull(
-      Send node, ConstantExpression constant, Node rhs, A arg) {
-    apply(rhs, arg);
-    return null;
-  }
-
-  @override
-  R visitDynamicPropertySetIfNull(
-      Send node, Node receiver, Name name, Node rhs, A arg) {
-    apply(receiver, arg);
-    apply(rhs, arg);
-    return null;
-  }
-
-  @override
-  R visitDynamicTypeLiteralSetIfNull(
-      Send node, ConstantExpression constant, Node rhs, A arg) {
-    apply(rhs, arg);
-    return null;
-  }
-
-  @override
-  R visitFinalLocalVariableSetIfNull(
-      Send node, LocalVariableElement variable, Node rhs, A arg) {
-    apply(rhs, arg);
-    return null;
-  }
-
-  @override
-  R visitFinalParameterSetIfNull(
-      Send node, ParameterElement parameter, Node rhs, A arg) {
-    apply(rhs, arg);
-    return null;
-  }
-
-  @override
-  R visitFinalStaticFieldSetIfNull(
-      Send node, FieldElement field, Node rhs, A arg) {
-    apply(rhs, arg);
-    return null;
-  }
-
-  @override
-  R visitFinalSuperFieldSetIfNull(
-      Send node, FieldElement field, Node rhs, A arg) {
-    apply(rhs, arg);
-    return null;
-  }
-
-  @override
-  R visitFinalTopLevelFieldSetIfNull(
-      Send node, FieldElement field, Node rhs, A arg) {
-    apply(rhs, arg);
-    return null;
-  }
-
-  @override
-  R visitIfNotNullDynamicPropertySetIfNull(
-      Send node, Node receiver, Name name, Node rhs, A arg) {
-    apply(receiver, arg);
-    apply(rhs, arg);
-    return null;
-  }
-
-  @override
-  R visitLocalFunctionSetIfNull(
-      Send node, LocalFunctionElement function, Node rhs, A arg) {
-    apply(rhs, arg);
-    return null;
-  }
-
-  @override
-  R visitLocalVariableSetIfNull(
-      Send node, LocalVariableElement variable, Node rhs, A arg) {
-    apply(rhs, arg);
-    return null;
-  }
-
-  @override
-  R visitParameterSetIfNull(
-      Send node, ParameterElement parameter, Node rhs, A arg) {
-    apply(rhs, arg);
-    return null;
-  }
-
-  @override
-  R visitStaticFieldSetIfNull(Send node, FieldElement field, Node rhs, A arg) {
-    apply(rhs, arg);
-    return null;
-  }
-
-  @override
-  R visitStaticGetterSetterSetIfNull(
-      Send node, GetterElement getter, SetterElement setter, Node rhs, A arg) {
-    apply(rhs, arg);
-    return null;
-  }
-
-  @override
-  R visitStaticMethodSetIfNull(
-      Send node, FunctionElement method, Node rhs, A arg) {
-    apply(rhs, arg);
-    return null;
-  }
-
-  @override
-  R visitStaticMethodSetterSetIfNull(
-      Send node, MethodElement method, MethodElement setter, Node rhs, A arg) {
-    apply(rhs, arg);
-    return null;
-  }
-
-  @override
-  R visitSuperFieldFieldSetIfNull(Send node, FieldElement readField,
-      FieldElement writtenField, Node rhs, A arg) {
-    apply(rhs, arg);
-    return null;
-  }
-
-  @override
-  R visitSuperFieldSetIfNull(Send node, FieldElement field, Node rhs, A arg) {
-    apply(rhs, arg);
-    return null;
-  }
-
-  @override
-  R visitSuperFieldSetterSetIfNull(
-      Send node, FieldElement field, SetterElement setter, Node rhs, A arg) {
-    apply(rhs, arg);
-    return null;
-  }
-
-  @override
-  R visitSuperGetterFieldSetIfNull(
-      Send node, GetterElement getter, FieldElement field, Node rhs, A arg) {
-    apply(rhs, arg);
-    return null;
-  }
-
-  @override
-  R visitSuperGetterSetterSetIfNull(
-      Send node, GetterElement getter, SetterElement setter, Node rhs, A arg) {
-    apply(rhs, arg);
-    return null;
-  }
-
-  @override
-  R visitSuperMethodSetIfNull(
-      Send node, FunctionElement method, Node rhs, A arg) {
-    apply(rhs, arg);
-    return null;
-  }
-
-  @override
-  R visitSuperMethodSetterSetIfNull(Send node, FunctionElement method,
-      SetterElement setter, Node rhs, A arg) {
-    apply(rhs, arg);
-    return null;
-  }
-
-  @override
-  R visitThisPropertySetIfNull(Send node, Name name, Node rhs, A arg) {
-    apply(rhs, arg);
-    return null;
-  }
-
-  @override
-  R visitTopLevelFieldSetIfNull(
-      Send node, FieldElement field, Node rhs, A arg) {
-    apply(rhs, arg);
-    return null;
-  }
-
-  @override
-  R visitTopLevelGetterSetterSetIfNull(
-      Send node, GetterElement getter, SetterElement setter, Node rhs, A arg) {
-    apply(rhs, arg);
-    return null;
-  }
-
-  @override
-  R visitTopLevelMethodSetIfNull(
-      Send node, FunctionElement method, Node rhs, A arg) {
-    apply(rhs, arg);
-    return null;
-  }
-
-  @override
-  R visitTopLevelMethodSetterSetIfNull(Send node, FunctionElement method,
-      SetterElement setter, Node rhs, A arg) {
-    apply(rhs, arg);
-    return null;
-  }
-
-  @override
-  R visitTypeVariableTypeLiteralSetIfNull(
-      Send node, TypeVariableElement element, Node rhs, A arg) {
-    apply(rhs, arg);
-    return null;
-  }
-
-  @override
-  R visitTypedefTypeLiteralSetIfNull(
-      Send node, ConstantExpression constant, Node rhs, A arg) {
-    apply(rhs, arg);
-    return null;
-  }
-
-  @override
-  R visitUnresolvedSetIfNull(Send node, Element element, Node rhs, A arg) {
-    apply(rhs, arg);
-    return null;
-  }
-
-  @override
-  R visitUnresolvedStaticGetterSetIfNull(
-      Send node, Element element, MethodElement setter, Node rhs, A arg) {
-    apply(rhs, arg);
-    return null;
-  }
-
-  @override
-  R visitUnresolvedStaticSetterSetIfNull(
-      Send node, GetterElement getter, Element element, Node rhs, A arg) {
-    apply(rhs, arg);
-    return null;
-  }
-
-  @override
-  R visitUnresolvedSuperGetterSetIfNull(
-      Send node, Element element, MethodElement setter, Node rhs, A arg) {
-    apply(rhs, arg);
-    return null;
-  }
-
-  @override
-  R visitUnresolvedSuperSetIfNull(Send node, Element element, Node rhs, A arg) {
-    apply(rhs, arg);
-    return null;
-  }
-
-  @override
-  R visitUnresolvedSuperSetterSetIfNull(
-      Send node, GetterElement getter, Element element, Node rhs, A arg) {
-    apply(rhs, arg);
-    return null;
-  }
-
-  @override
-  R visitUnresolvedTopLevelGetterSetIfNull(
-      Send node, Element element, MethodElement setter, Node rhs, A arg) {
-    apply(rhs, arg);
-    return null;
-  }
-
-  @override
-  R visitUnresolvedTopLevelSetterSetIfNull(
-      Send node, GetterElement getter, Element element, Node rhs, A arg) {
-    apply(rhs, arg);
-    return null;
-  }
-
-  @override
-  R visitConstConstructorInvoke(
-      NewExpression node, ConstructedConstantExpression constant, A arg) {
-    return null;
-  }
-
-  @override
-  R visitBoolFromEnvironmentConstructorInvoke(NewExpression node,
-      BoolFromEnvironmentConstantExpression constant, A arg) {
-    return null;
-  }
-
-  @override
-  R visitIntFromEnvironmentConstructorInvoke(NewExpression node,
-      IntFromEnvironmentConstantExpression constant, A arg) {
-    return null;
-  }
-
-  @override
-  R visitStringFromEnvironmentConstructorInvoke(NewExpression node,
-      StringFromEnvironmentConstantExpression constant, A arg) {
-    return null;
-  }
-
-  @override
-  R visitConstructorIncompatibleInvoke(
-      NewExpression node,
-      ConstructorElement constructor,
-      ResolutionInterfaceType type,
-      NodeList arguments,
-      CallStructure callStructure,
-      A arg) {
-    apply(arguments, arg);
-    return null;
-  }
-
-  @override
-  R visitUnresolvedClassConstructorInvoke(
-      NewExpression node,
-      ErroneousElement constructor,
-      ResolutionDartType type,
-      NodeList arguments,
-      Selector selector,
-      A arg) {
-    apply(arguments, arg);
-    return null;
-  }
-
-  @override
-  R visitUnresolvedConstructorInvoke(NewExpression node, Element constructor,
-      ResolutionDartType type, NodeList arguments, Selector selector, A arg) {
-    apply(arguments, arg);
-    return null;
-  }
-
-  @override
-  R visitFactoryConstructorInvoke(
-      NewExpression node,
-      ConstructorElement constructor,
-      ResolutionInterfaceType type,
-      NodeList arguments,
-      CallStructure callStructure,
-      A arg) {
-    apply(arguments, arg);
-    return null;
-  }
-
-  @override
-  R visitGenerativeConstructorInvoke(
-      NewExpression node,
-      ConstructorElement constructor,
-      ResolutionInterfaceType type,
-      NodeList arguments,
-      CallStructure callStructure,
-      A arg) {
-    apply(arguments, arg);
-    return null;
-  }
-
-  @override
-  R visitRedirectingFactoryConstructorInvoke(
-      NewExpression node,
-      ConstructorElement constructor,
-      ResolutionInterfaceType type,
-      ConstructorElement effectiveTarget,
-      ResolutionInterfaceType effectiveTargetType,
-      NodeList arguments,
-      CallStructure callStructure,
-      A arg) {
-    apply(arguments, arg);
-    return null;
-  }
-
-  @override
-  R visitRedirectingGenerativeConstructorInvoke(
-      NewExpression node,
-      ConstructorElement constructor,
-      ResolutionInterfaceType type,
-      NodeList arguments,
-      CallStructure callStructure,
-      A arg) {
-    apply(arguments, arg);
-    return null;
-  }
-
-  @override
-  R visitAbstractClassConstructorInvoke(
-      NewExpression node,
-      ConstructorElement element,
-      ResolutionInterfaceType type,
-      NodeList arguments,
-      CallStructure callStructure,
-      A arg) {
-    apply(arguments, arg);
-    return null;
-  }
-
-  @override
-  R visitUnresolvedRedirectingFactoryConstructorInvoke(
-      NewExpression node,
-      ConstructorElement constructor,
-      ResolutionInterfaceType type,
-      NodeList arguments,
-      CallStructure callStructure,
-      A arg) {
-    apply(arguments, arg);
-    return null;
-  }
-
-  @override
-  R errorNonConstantConstructorInvoke(
-      NewExpression node,
-      Element element,
-      ResolutionDartType type,
-      NodeList arguments,
-      CallStructure callStructure,
-      A arg) {
-    apply(arguments, arg);
-    return null;
-  }
-
-  @override
-  R visitUnresolvedStaticGetterCompound(Send node, Element element,
-      MethodElement setter, AssignmentOperator operator, Node rhs, A arg) {
-    apply(rhs, arg);
-    return null;
-  }
-
-  @override
-  R visitUnresolvedTopLevelGetterCompound(Send node, Element element,
-      MethodElement setter, AssignmentOperator operator, Node rhs, A arg) {
-    apply(rhs, arg);
-    return null;
-  }
-
-  @override
-  R visitUnresolvedStaticSetterCompound(Send node, GetterElement getter,
-      Element element, AssignmentOperator operator, Node rhs, A arg) {
-    apply(rhs, arg);
-    return null;
-  }
-
-  @override
-  R visitUnresolvedTopLevelSetterCompound(Send node, GetterElement getter,
-      Element element, AssignmentOperator operator, Node rhs, A arg) {
-    apply(rhs, arg);
-    return null;
-  }
-
-  @override
-  R visitStaticMethodCompound(Send node, MethodElement method,
-      AssignmentOperator operator, Node rhs, A arg) {
-    apply(rhs, arg);
-    return null;
-  }
-
-  @override
-  R visitUnresolvedStaticGetterPrefix(Send node, Element element,
-      MethodElement setter, IncDecOperator operator, A arg) {
-    return null;
-  }
-
-  @override
-  R visitUnresolvedTopLevelGetterPrefix(Send node, Element element,
-      MethodElement setter, IncDecOperator operator, A arg) {
-    return null;
-  }
-
-  @override
-  R visitUnresolvedStaticSetterPrefix(Send node, GetterElement getter,
-      Element element, IncDecOperator operator, A arg) {
-    return null;
-  }
-
-  @override
-  R visitUnresolvedTopLevelSetterPrefix(Send node, GetterElement getter,
-      Element element, IncDecOperator operator, A arg) {
-    return null;
-  }
-
-  @override
-  R visitStaticMethodPrefix(
-      Send node, MethodElement method, IncDecOperator operator, A arg) {
-    return null;
-  }
-
-  @override
-  R visitTopLevelMethodPrefix(
-      Send node, MethodElement method, IncDecOperator operator, A arg) {
-    return null;
-  }
-
-  @override
-  R visitUnresolvedStaticGetterPostfix(Send node, Element element,
-      MethodElement setter, IncDecOperator operator, A arg) {
-    return null;
-  }
-
-  @override
-  R visitUnresolvedTopLevelGetterPostfix(Send node, Element element,
-      MethodElement setter, IncDecOperator operator, A arg) {
-    return null;
-  }
-
-  @override
-  R visitUnresolvedStaticSetterPostfix(Send node, GetterElement getter,
-      Element element, IncDecOperator operator, A arg) {
-    return null;
-  }
-
-  @override
-  R visitUnresolvedTopLevelSetterPostfix(Send node, GetterElement getter,
-      Element element, IncDecOperator operator, A arg) {
-    return null;
-  }
-
-  @override
-  R visitStaticMethodPostfix(
-      Send node, MethodElement method, IncDecOperator operator, A arg) {
-    return null;
-  }
-
-  @override
-  R visitTopLevelMethodPostfix(
-      Send node, MethodElement method, IncDecOperator operator, A arg) {
-    return null;
-  }
-
-  @override
-  R visitFinalLocalVariablePostfix(Send node, LocalVariableElement variable,
-      IncDecOperator operator, A arg) {
-    return null;
-  }
-
-  @override
-  R visitFinalLocalVariablePrefix(Send node, LocalVariableElement variable,
-      IncDecOperator operator, A arg) {
-    return null;
-  }
-
-  @override
-  R visitFinalParameterPostfix(
-      Send node, ParameterElement parameter, IncDecOperator operator, A arg) {
-    return null;
-  }
-
-  @override
-  R visitFinalParameterPrefix(
-      Send node, ParameterElement parameter, IncDecOperator operator, A arg) {
-    return null;
-  }
-
-  @override
-  R visitFinalStaticFieldPostfix(
-      Send node, FieldElement field, IncDecOperator operator, A arg) {
-    return null;
-  }
-
-  @override
-  R visitFinalStaticFieldPrefix(
-      Send node, FieldElement field, IncDecOperator operator, A arg) {
-    return null;
-  }
-
-  @override
-  R visitSuperFieldFieldCompound(Send node, FieldElement readField,
-      FieldElement writtenField, AssignmentOperator operator, Node rhs, A arg) {
-    apply(rhs, arg);
-    return null;
-  }
-
-  @override
-  R visitFinalSuperFieldCompound(Send node, FieldElement field,
-      AssignmentOperator operator, Node rhs, A arg) {
-    apply(rhs, arg);
-    return null;
-  }
-
-  @override
-  R visitFinalSuperFieldPostfix(
-      Send node, FieldElement field, IncDecOperator operator, A arg) {
-    return null;
-  }
-
-  @override
-  R visitFinalSuperFieldPrefix(
-      Send node, FieldElement field, IncDecOperator operator, A arg) {
-    return null;
-  }
-
-  @override
-  R visitSuperMethodCompound(Send node, MethodElement method,
-      AssignmentOperator operator, Node rhs, A arg) {
-    apply(rhs, arg);
-    return null;
-  }
-
-  @override
-  R visitSuperMethodPostfix(
-      Send node, MethodElement method, IncDecOperator operator, A arg) {
-    return null;
-  }
-
-  @override
-  R visitSuperMethodPrefix(
-      Send node, MethodElement method, IncDecOperator operator, A arg) {
-    return null;
-  }
-
-  @override
-  R visitFinalTopLevelFieldPostfix(
-      Send node, FieldElement field, IncDecOperator operator, A arg) {
-    return null;
-  }
-
-  @override
-  R visitFinalTopLevelFieldPrefix(
-      Send node, FieldElement field, IncDecOperator operator, A arg) {
-    return null;
-  }
-
-  @override
-  R visitTopLevelMethodCompound(Send node, MethodElement method,
-      AssignmentOperator operator, Node rhs, A arg) {
-    apply(rhs, arg);
-    return null;
-  }
-
-  @override
-  R visitUnresolvedSuperCompound(Send node, Element element,
-      AssignmentOperator operator, Node rhs, A arg) {
-    apply(rhs, arg);
-    return null;
-  }
-
-  @override
-  R visitUnresolvedSuperPostfix(
-      SendSet node, Element element, IncDecOperator operator, A arg) {
-    return null;
-  }
-
-  @override
-  R visitUnresolvedSuperPrefix(
-      SendSet node, Element element, IncDecOperator operator, A arg) {
-    return null;
-  }
-
-  @override
-  R visitUnresolvedSuperGetterCompound(SendSet node, Element element,
-      SetterElement setter, AssignmentOperator operator, Node rhs, A arg) {
-    apply(rhs, arg);
-    return null;
-  }
-
-  @override
-  R visitUnresolvedSuperGetterPostfix(SendSet node, Element element,
-      SetterElement setter, IncDecOperator operator, A arg) {
-    return null;
-  }
-
-  @override
-  R visitUnresolvedSuperGetterPrefix(SendSet node, Element element,
-      SetterElement setter, IncDecOperator operator, A arg) {
-    return null;
-  }
-
-  @override
-  R visitUnresolvedSuperSetterCompound(Send node, GetterElement getter,
-      Element element, AssignmentOperator operator, Node rhs, A arg) {
-    apply(rhs, arg);
-    return null;
-  }
-
-  @override
-  R visitUnresolvedSuperSetterPostfix(SendSet node, GetterElement getter,
-      Element element, IncDecOperator operator, A arg) {
-    return null;
-  }
-
-  @override
-  R visitUnresolvedSuperSetterPrefix(SendSet node, GetterElement getter,
-      Element element, IncDecOperator operator, A arg) {
-    return null;
-  }
-
-  @override
-  R visitIndexSetIfNull(
-      SendSet node, Node receiver, Node index, Node rhs, A arg) {
-    apply(receiver, arg);
-    apply(index, arg);
-    apply(rhs, arg);
-    return null;
-  }
-
-  @override
-  R visitSuperIndexSetIfNull(SendSet node, MethodElement getter,
-      MethodElement setter, Node index, Node rhs, A arg) {
-    apply(index, arg);
-    apply(rhs, arg);
-    return null;
-  }
-
-  @override
-  R visitUnresolvedSuperGetterIndexSetIfNull(SendSet node, Element element,
-      MethodElement setter, Node index, Node rhs, A arg) {
-    apply(index, arg);
-    apply(rhs, arg);
-    return null;
-  }
-
-  @override
-  R visitUnresolvedSuperSetterIndexSetIfNull(SendSet node, MethodElement getter,
-      Element element, Node index, Node rhs, A arg) {
-    apply(index, arg);
-    apply(rhs, arg);
-    return null;
-  }
-
-  @override
-  R visitUnresolvedSuperIndexSetIfNull(
-      Send node, Element element, Node index, Node rhs, A arg) {
-    apply(index, arg);
-    apply(rhs, arg);
-    return null;
-  }
-
-  @override
-  R errorInvalidIndexSetIfNull(
-      SendSet node, ErroneousElement error, Node index, Node rhs, A arg) {
-    apply(index, arg);
-    apply(rhs, arg);
-    return null;
-  }
-}
-
-/// [SemanticDeclarationVisitor] that visits subnodes.
-class TraversalDeclarationMixin<R, A>
-    implements SemanticDeclarationVisitor<R, A> {
-  @override
-  R apply(Node node, A arg) {
-    throw new UnimplementedError("TraversalMixin.apply unimplemented");
-  }
-
-  @override
-  applyInitializers(FunctionExpression constructor, A arg) {
-    throw new UnimplementedError(
-        "TraversalMixin.applyInitializers unimplemented");
-  }
-
-  @override
-  applyParameters(NodeList parameters, A arg) {
-    throw new UnimplementedError(
-        "TraversalMixin.applyParameters unimplemented");
-  }
-
-  @override
-  R visitAbstractMethodDeclaration(FunctionExpression node,
-      MethodElement method, NodeList parameters, A arg) {
-    applyParameters(parameters, arg);
-    return null;
-  }
-
-  @override
-  R visitClosureDeclaration(FunctionExpression node,
-      LocalFunctionElement function, NodeList parameters, Node body, A arg) {
-    applyParameters(parameters, arg);
-    apply(body, arg);
-    return null;
-  }
-
-  @override
-  R visitFactoryConstructorDeclaration(FunctionExpression node,
-      ConstructorElement constructor, NodeList parameters, Node body, A arg) {
-    applyParameters(parameters, arg);
-    apply(body, arg);
-    return null;
-  }
-
-  @override
-  R visitFieldInitializer(
-      SendSet node, FieldElement field, Node initializer, A arg) {
-    apply(initializer, arg);
-    return null;
-  }
-
-  @override
-  R visitGenerativeConstructorDeclaration(
-      FunctionExpression node,
-      ConstructorElement constructor,
-      NodeList parameters,
-      NodeList initializers,
-      Node body,
-      A arg) {
-    applyParameters(parameters, arg);
-    applyInitializers(node, arg);
-    apply(body, arg);
-    return null;
-  }
-
-  @override
-  R visitInstanceMethodDeclaration(FunctionExpression node,
-      MethodElement method, NodeList parameters, Node body, A arg) {
-    applyParameters(parameters, arg);
-    apply(body, arg);
-    return null;
-  }
-
-  @override
-  R visitLocalFunctionDeclaration(FunctionExpression node,
-      LocalFunctionElement function, NodeList parameters, Node body, A arg) {
-    applyParameters(parameters, arg);
-    apply(body, arg);
-    return null;
-  }
-
-  @override
-  R visitRedirectingFactoryConstructorDeclaration(
-      FunctionExpression node,
-      ConstructorElement constructor,
-      NodeList parameters,
-      ResolutionInterfaceType redirectionType,
-      ConstructorElement redirectionTarget,
-      A arg) {
-    applyParameters(parameters, arg);
-    return null;
-  }
-
-  @override
-  R visitRedirectingGenerativeConstructorDeclaration(
-      FunctionExpression node,
-      ConstructorElement constructor,
-      NodeList parameters,
-      NodeList initializers,
-      A arg) {
-    applyParameters(parameters, arg);
-    applyInitializers(node, arg);
-    return null;
-  }
-
-  @override
-  R visitStaticFunctionDeclaration(FunctionExpression node,
-      MethodElement function, NodeList parameters, Node body, A arg) {
-    applyParameters(parameters, arg);
-    apply(body, arg);
-    return null;
-  }
-
-  @override
-  R visitSuperConstructorInvoke(
-      Send node,
-      ConstructorElement superConstructor,
-      ResolutionInterfaceType type,
-      NodeList arguments,
-      CallStructure callStructure,
-      A arg) {
-    apply(arguments, arg);
-    return null;
-  }
-
-  @override
-  R visitImplicitSuperConstructorInvoke(
-      FunctionExpression node,
-      ConstructorElement superConstructor,
-      ResolutionInterfaceType type,
-      A arg) {
-    return null;
-  }
-
-  @override
-  R visitThisConstructorInvoke(Send node, ConstructorElement thisConstructor,
-      NodeList arguments, CallStructure callStructure, A arg) {
-    apply(arguments, arg);
-    return null;
-  }
-
-  @override
-  R visitTopLevelFunctionDeclaration(FunctionExpression node,
-      MethodElement function, NodeList parameters, Node body, A arg) {
-    applyParameters(parameters, arg);
-    apply(body, arg);
-    return null;
-  }
-
-  @override
-  R errorUnresolvedFieldInitializer(
-      SendSet node, Element element, Node initializer, A arg) {
-    apply(initializer, arg);
-    return null;
-  }
-
-  @override
-  R errorUnresolvedSuperConstructorInvoke(Send node, Element element,
-      NodeList arguments, Selector selector, A arg) {
-    apply(arguments, arg);
-    return null;
-  }
-
-  @override
-  R errorUnresolvedThisConstructorInvoke(Send node, Element element,
-      NodeList arguments, Selector selector, A arg) {
-    apply(arguments, arg);
-    return null;
-  }
-
-  @override
-  R visitLocalVariableDeclaration(VariableDefinitions node, Node definition,
-      LocalVariableElement variable, Node initializer, A arg) {
-    if (initializer != null) {
-      apply(initializer, arg);
-    }
-    return null;
-  }
-
-  @override
-  R visitOptionalParameterDeclaration(
-      VariableDefinitions node,
-      Node definition,
-      ParameterElement parameter,
-      ConstantExpression defaultValue,
-      int index,
-      A arg) {
-    return null;
-  }
-
-  @override
-  R visitParameterDeclaration(VariableDefinitions node, Node definition,
-      ParameterElement parameter, int index, A arg) {
-    return null;
-  }
-
-  @override
-  R visitInitializingFormalDeclaration(
-      VariableDefinitions node,
-      Node definition,
-      InitializingFormalElement initializingFormal,
-      int index,
-      A arg) {
-    return null;
-  }
-
-  @override
-  R visitLocalConstantDeclaration(VariableDefinitions node, Node definition,
-      LocalVariableElement variable, ConstantExpression constant, A arg) {
-    return null;
-  }
-
-  @override
-  R visitNamedInitializingFormalDeclaration(
-      VariableDefinitions node,
-      Node definition,
-      InitializingFormalElement initializingFormal,
-      ConstantExpression defaultValue,
-      A arg) {
-    return null;
-  }
-
-  @override
-  R visitNamedParameterDeclaration(VariableDefinitions node, Node definition,
-      ParameterElement parameter, ConstantExpression defaultValue, A arg) {
-    return null;
-  }
-
-  @override
-  R visitOptionalInitializingFormalDeclaration(
-      VariableDefinitions node,
-      Node definition,
-      InitializingFormalElement initializingFormal,
-      ConstantExpression defaultValue,
-      int index,
-      A arg) {
-    return null;
-  }
-
-  @override
-  R visitInstanceFieldDeclaration(VariableDefinitions node, Node definition,
-      FieldElement field, Node initializer, A arg) {
-    if (initializer != null) {
-      apply(initializer, arg);
-    }
-    return null;
-  }
-
-  @override
-  R visitStaticConstantDeclaration(VariableDefinitions node, Node definition,
-      FieldElement field, ConstantExpression constant, A arg) {
-    return null;
-  }
-
-  @override
-  R visitStaticFieldDeclaration(VariableDefinitions node, Node definition,
-      FieldElement field, Node initializer, A arg) {
-    if (initializer != null) {
-      apply(initializer, arg);
-    }
-    return null;
-  }
-
-  @override
-  R visitTopLevelConstantDeclaration(VariableDefinitions node, Node definition,
-      FieldElement field, ConstantExpression constant, A arg) {
-    return null;
-  }
-
-  @override
-  R visitTopLevelFieldDeclaration(VariableDefinitions node, Node definition,
-      FieldElement field, Node initializer, A arg) {
-    if (initializer != null) {
-      apply(initializer, arg);
-    }
-    return null;
-  }
-
-  @override
-  R visitAbstractGetterDeclaration(
-      FunctionExpression node, GetterElement getter, A arg) {
-    return null;
-  }
-
-  @override
-  R visitAbstractSetterDeclaration(FunctionExpression node,
-      MethodElement setter, NodeList parameters, A arg) {
-    applyParameters(parameters, arg);
-    return null;
-  }
-
-  @override
-  R visitInstanceGetterDeclaration(
-      FunctionExpression node, GetterElement getter, Node body, A arg) {
-    apply(body, arg);
-    return null;
-  }
-
-  @override
-  R visitInstanceSetterDeclaration(FunctionExpression node,
-      MethodElement setter, NodeList parameters, Node body, A arg) {
-    applyParameters(parameters, arg);
-    apply(body, arg);
-    return null;
-  }
-
-  @override
-  R visitStaticGetterDeclaration(
-      FunctionExpression node, GetterElement getter, Node body, A arg) {
-    apply(body, arg);
-    return null;
-  }
-
-  @override
-  R visitStaticSetterDeclaration(FunctionExpression node, MethodElement setter,
-      NodeList parameters, Node body, A arg) {
-    applyParameters(parameters, arg);
-    apply(body, arg);
-    return null;
-  }
-
-  @override
-  R visitTopLevelGetterDeclaration(
-      FunctionExpression node, GetterElement getter, Node body, A arg) {
-    apply(body, arg);
-    return null;
-  }
-
-  @override
-  R visitTopLevelSetterDeclaration(FunctionExpression node,
-      MethodElement setter, NodeList parameters, Node body, A arg) {
-    applyParameters(parameters, arg);
-    apply(body, arg);
-    return null;
-  }
-}
-
-/// AST visitor that visits all normal [Send] and [SendSet] nodes using the
-/// [SemanticVisitor].
-class TraversalVisitor<R, A> extends SemanticVisitor<R, A>
-    with TraversalSendMixin<R, A>, TraversalDeclarationMixin<R, A> {
-  TraversalVisitor(TreeElements elements) : super(elements);
-
-  SemanticSendVisitor<R, A> get sendVisitor => this;
-
-  SemanticDeclarationVisitor<R, A> get declVisitor => this;
-
-  R apply(Node node, A arg) {
-    node.accept(this);
-    return null;
-  }
-
-  @override
-  applyInitializers(FunctionExpression constructor, A arg) {
-    visitInitializers(constructor, arg);
-  }
-
-  @override
-  applyParameters(NodeList parameters, A arg) {
-    visitParameters(parameters, arg);
-  }
-
-  @override
-  internalError(Spannable spannable, String message) {
-    failedAt(spannable, message);
-  }
-
-  @override
-  R visitNode(Node node) {
-    node.visitChildren(this);
-    return null;
-  }
-
-  @override
-  R visitTypeAnnotation(TypeAnnotation node) {
-    // Skip [Send] contained in type annotations, like `prefix.Type`.
-    return null;
-  }
-}
-
-/// Mixin that groups all non-compound `visitStaticX` and `visitTopLevelX`
-/// method by delegating calls to `handleStaticX` methods.
-///
-/// This mixin is useful for the cases where both top level members and static
-/// class members are handled uniformly.
-abstract class BaseImplementationOfStaticsMixin<R, A>
-    implements SemanticSendVisitor<R, A> {
-  R handleStaticFieldGet(Send node, FieldElement field, A arg);
-
-  R handleStaticFieldInvoke(Send node, FieldElement field, NodeList arguments,
-      CallStructure callStructure, A arg);
-
-  R handleStaticFieldSet(SendSet node, FieldElement field, Node rhs, A arg);
-
-  R handleStaticFunctionGet(Send node, MethodElement function, A arg);
-
-  R handleStaticFunctionInvoke(Send node, MethodElement function,
-      NodeList arguments, CallStructure callStructure, A arg);
-
-  R handleStaticFunctionIncompatibleInvoke(Send node, MethodElement function,
-      NodeList arguments, CallStructure callStructure, A arg);
-
-  R handleStaticGetterGet(Send node, GetterElement getter, A arg);
-
-  R handleStaticGetterSet(SendSet node, GetterElement getter, Node rhs, A arg);
-
-  R handleStaticGetterInvoke(Send node, GetterElement getter,
-      NodeList arguments, CallStructure callStructure, A arg);
-
-  R handleStaticSetterGet(SendSet node, SetterElement setter, A arg);
-
-  R handleStaticSetterSet(SendSet node, SetterElement setter, Node rhs, A arg);
-
-  R handleStaticSetterInvoke(Send node, SetterElement setter,
-      NodeList arguments, CallStructure callStructure, A arg);
-
-  R handleFinalStaticFieldSet(
-      SendSet node, FieldElement field, Node rhs, A arg);
-
-  R handleStaticFunctionSet(
-      SendSet node, MethodElement function, Node rhs, A arg);
-
-  @override
-  R visitStaticFieldGet(Send node, FieldElement field, A arg) {
-    return handleStaticFieldGet(node, field, arg);
-  }
-
-  @override
-  R visitStaticFieldInvoke(Send node, FieldElement field, NodeList arguments,
-      CallStructure callStructure, A arg) {
-    return handleStaticFieldInvoke(node, field, arguments, callStructure, arg);
-  }
-
-  @override
-  R visitStaticFieldSet(SendSet node, FieldElement field, Node rhs, A arg) {
-    return handleStaticFieldSet(node, field, rhs, arg);
-  }
-
-  @override
-  R visitStaticFunctionGet(Send node, MethodElement function, A arg) {
-    return handleStaticFunctionGet(node, function, arg);
-  }
-
-  @override
-  R visitStaticFunctionInvoke(Send node, MethodElement function,
-      NodeList arguments, CallStructure callStructure, A arg) {
-    return handleStaticFunctionInvoke(
-        node, function, arguments, callStructure, arg);
-  }
-
-  @override
-  R visitStaticFunctionIncompatibleInvoke(Send node, MethodElement function,
-      NodeList arguments, CallStructure callStructure, A arg) {
-    return handleStaticFunctionIncompatibleInvoke(
-        node, function, arguments, callStructure, arg);
-  }
-
-  @override
-  R visitStaticGetterGet(Send node, GetterElement getter, A arg) {
-    return handleStaticGetterGet(node, getter, arg);
-  }
-
-  @override
-  R visitStaticGetterInvoke(Send node, GetterElement getter, NodeList arguments,
-      CallStructure callStructure, A arg) {
-    return handleStaticGetterInvoke(
-        node, getter, arguments, callStructure, arg);
-  }
-
-  @override
-  R visitStaticSetterSet(SendSet node, SetterElement setter, Node rhs, A arg) {
-    return handleStaticSetterSet(node, setter, rhs, arg);
-  }
-
-  @override
-  R visitTopLevelFieldGet(Send node, FieldElement field, A arg) {
-    return handleStaticFieldGet(node, field, arg);
-  }
-
-  @override
-  R visitTopLevelFieldInvoke(Send node, FieldElement field, NodeList arguments,
-      CallStructure callStructure, A arg) {
-    return handleStaticFieldInvoke(node, field, arguments, callStructure, arg);
-  }
-
-  @override
-  R visitTopLevelFieldSet(SendSet node, FieldElement field, Node rhs, A arg) {
-    return handleStaticFieldSet(node, field, rhs, arg);
-  }
-
-  @override
-  R visitTopLevelFunctionGet(Send node, MethodElement function, A arg) {
-    return handleStaticFunctionGet(node, function, arg);
-  }
-
-  @override
-  R visitTopLevelFunctionInvoke(Send node, MethodElement function,
-      NodeList arguments, CallStructure callStructure, A arg) {
-    return handleStaticFunctionInvoke(
-        node, function, arguments, callStructure, arg);
-  }
-
-  @override
-  R visitTopLevelFunctionIncompatibleInvoke(Send node, MethodElement function,
-      NodeList arguments, CallStructure callStructure, A arg) {
-    return handleStaticFunctionIncompatibleInvoke(
-        node, function, arguments, callStructure, arg);
-  }
-
-  @override
-  R visitTopLevelGetterGet(Send node, GetterElement getter, A arg) {
-    return handleStaticGetterGet(node, getter, arg);
-  }
-
-  @override
-  R visitTopLevelGetterSet(
-      SendSet node, GetterElement getter, Node rhs, A arg) {
-    return handleStaticGetterSet(node, getter, rhs, arg);
-  }
-
-  @override
-  R visitTopLevelGetterInvoke(Send node, GetterElement getter,
-      NodeList arguments, CallStructure callStructure, A arg) {
-    return handleStaticGetterInvoke(
-        node, getter, arguments, callStructure, arg);
-  }
-
-  @override
-  R visitTopLevelSetterSet(
-      SendSet node, SetterElement setter, Node rhs, A arg) {
-    return handleStaticSetterSet(node, setter, rhs, arg);
-  }
-
-  @override
-  R visitStaticSetterInvoke(Send node, SetterElement setter, NodeList arguments,
-      CallStructure callStructure, A arg) {
-    return handleStaticSetterInvoke(
-        node, setter, arguments, callStructure, arg);
-  }
-
-  @override
-  R visitTopLevelSetterInvoke(Send node, SetterElement setter,
-      NodeList arguments, CallStructure callStructure, A arg) {
-    return handleStaticSetterInvoke(
-        node, setter, arguments, callStructure, arg);
-  }
-
-  @override
-  R visitStaticSetterGet(Send node, SetterElement setter, A arg) {
-    return handleStaticSetterGet(node, setter, arg);
-  }
-
-  @override
-  R visitStaticGetterSet(SendSet node, GetterElement getter, Node rhs, A arg) {
-    return handleStaticGetterSet(node, getter, rhs, arg);
-  }
-
-  @override
-  R visitTopLevelSetterGet(Send node, SetterElement setter, A arg) {
-    return handleStaticSetterGet(node, setter, arg);
-  }
-
-  @override
-  R visitFinalStaticFieldSet(
-      SendSet node, FieldElement field, Node rhs, A arg) {
-    return handleFinalStaticFieldSet(node, field, rhs, arg);
-  }
-
-  @override
-  R visitFinalTopLevelFieldSet(
-      SendSet node, FieldElement field, Node rhs, A arg) {
-    return handleFinalStaticFieldSet(node, field, rhs, arg);
-  }
-
-  @override
-  R visitStaticFunctionSet(
-      SendSet node, MethodElement function, Node rhs, A arg) {
-    return handleStaticFunctionSet(node, function, rhs, arg);
-  }
-
-  @override
-  R visitTopLevelFunctionSet(
-      SendSet node, MethodElement function, Node rhs, A arg) {
-    return handleStaticFunctionSet(node, function, rhs, arg);
-  }
-}
-
-/// Mixin that groups all compounds visitors `visitStaticX` and `visitTopLevelX`
-/// method by delegating calls to `handleStaticX` methods.
-///
-/// This mixin is useful for the cases where both top level members and static
-/// class members are handled uniformly.
-abstract class BaseImplementationOfStaticCompoundsMixin<R, A>
-    implements SemanticSendVisitor<R, A> {
-  R handleStaticFieldCompound(Send node, FieldElement field,
-      AssignmentOperator operator, Node rhs, A arg);
-
-  R handleStaticFieldPostfixPrefix(
-      Send node, FieldElement field, IncDecOperator operator, A arg,
-      {bool isPrefix});
-
-  R handleStaticGetterSetterCompound(Send node, GetterElement getter,
-      SetterElement setter, AssignmentOperator operator, Node rhs, A arg);
-
-  R handleStaticGetterSetterPostfixPrefix(Send node, GetterElement getter,
-      SetterElement setter, IncDecOperator operator, A arg,
-      {bool isPrefix});
-
-  R handleStaticMethodSetterCompound(Send node, FunctionElement method,
-      SetterElement setter, AssignmentOperator operator, Node rhs, A arg);
-
-  R handleStaticMethodSetterPostfixPrefix(Send node, GetterElement getter,
-      SetterElement setter, IncDecOperator operator, A arg,
-      {bool isPrefix});
-
-  R handleFinalStaticFieldCompound(Send node, FieldElement field,
-      AssignmentOperator operator, Node rhs, A arg);
-
-  R handleFinalStaticFieldPostfixPrefix(
-      Send node, FieldElement field, IncDecOperator operator, A arg,
-      {bool isPrefix});
-
-  R handleStaticMethodCompound(Send node, FunctionElement method,
-      AssignmentOperator operator, Node rhs, A arg);
-
-  R handleStaticMethodPostfixPrefix(
-      Send node, FunctionElement method, IncDecOperator operator, A arg,
-      {bool isPrefix});
-
-  R handleUnresolvedStaticGetterCompound(Send node, Element element,
-      SetterElement setter, AssignmentOperator operator, Node rhs, A arg);
-
-  R handleUnresolvedStaticGetterPostfixPrefix(Send node, Element element,
-      SetterElement setter, IncDecOperator operator, A arg,
-      {bool isPrefix});
-
-  R handleUnresolvedStaticSetterCompound(Send node, GetterElement getter,
-      Element element, AssignmentOperator operator, Node rhs, A arg);
-
-  R handleUnresolvedStaticSetterPostfixPrefix(Send node, GetterElement getter,
-      Element element, IncDecOperator operator, A arg,
-      {bool isPrefix});
-
-  @override
-  R visitStaticFieldCompound(Send node, FieldElement field,
-      AssignmentOperator operator, Node rhs, A arg) {
-    return handleStaticFieldCompound(node, field, operator, rhs, arg);
-  }
-
-  @override
-  R visitStaticFieldPostfix(
-      Send node, FieldElement field, IncDecOperator operator, A arg) {
-    return handleStaticFieldPostfixPrefix(node, field, operator, arg,
-        isPrefix: false);
-  }
-
-  @override
-  R visitStaticFieldPrefix(
-      Send node, FieldElement field, IncDecOperator operator, A arg) {
-    return handleStaticFieldPostfixPrefix(node, field, operator, arg,
-        isPrefix: true);
-  }
-
-  @override
-  R visitStaticGetterSetterCompound(Send node, GetterElement getter,
-      SetterElement setter, AssignmentOperator operator, Node rhs, A arg) {
-    return handleStaticGetterSetterCompound(
-        node, getter, setter, operator, rhs, arg);
-  }
-
-  @override
-  R visitStaticGetterSetterPostfix(Send node, GetterElement getter,
-      SetterElement setter, IncDecOperator operator, A arg) {
-    return handleStaticGetterSetterPostfixPrefix(
-        node, getter, setter, operator, arg,
-        isPrefix: false);
-  }
-
-  @override
-  R visitStaticGetterSetterPrefix(Send node, GetterElement getter,
-      SetterElement setter, IncDecOperator operator, A arg) {
-    return handleStaticGetterSetterPostfixPrefix(
-        node, getter, setter, operator, arg,
-        isPrefix: true);
-  }
-
-  @override
-  R visitStaticMethodSetterCompound(Send node, FunctionElement method,
-      SetterElement setter, AssignmentOperator operator, Node rhs, A arg) {
-    return handleStaticMethodSetterCompound(
-        node, method, setter, operator, rhs, arg);
-  }
-
-  @override
-  R visitStaticMethodSetterPostfix(Send node, GetterElement getter,
-      SetterElement setter, IncDecOperator operator, A arg) {
-    return handleStaticMethodSetterPostfixPrefix(
-        node, getter, setter, operator, arg,
-        isPrefix: false);
-  }
-
-  @override
-  R visitStaticMethodSetterPrefix(Send node, GetterElement getter,
-      SetterElement setter, IncDecOperator operator, A arg) {
-    return handleStaticMethodSetterPostfixPrefix(
-        node, getter, setter, operator, arg,
-        isPrefix: true);
-  }
-
-  @override
-  R visitTopLevelFieldCompound(Send node, FieldElement field,
-      AssignmentOperator operator, Node rhs, A arg) {
-    return handleStaticFieldCompound(node, field, operator, rhs, arg);
-  }
-
-  @override
-  R visitTopLevelFieldPostfix(
-      Send node, FieldElement field, IncDecOperator operator, A arg) {
-    return handleStaticFieldPostfixPrefix(node, field, operator, arg,
-        isPrefix: false);
-  }
-
-  @override
-  R visitTopLevelFieldPrefix(
-      Send node, FieldElement field, IncDecOperator operator, A arg) {
-    return handleStaticFieldPostfixPrefix(node, field, operator, arg,
-        isPrefix: true);
-  }
-
-  @override
-  R visitTopLevelGetterSetterCompound(Send node, GetterElement getter,
-      SetterElement setter, AssignmentOperator operator, Node rhs, A arg) {
-    return handleStaticGetterSetterCompound(
-        node, getter, setter, operator, rhs, arg);
-  }
-
-  @override
-  R visitTopLevelGetterSetterPostfix(Send node, GetterElement getter,
-      SetterElement setter, IncDecOperator operator, A arg) {
-    return handleStaticGetterSetterPostfixPrefix(
-        node, getter, setter, operator, arg,
-        isPrefix: false);
-  }
-
-  @override
-  R visitTopLevelGetterSetterPrefix(Send node, GetterElement getter,
-      SetterElement setter, IncDecOperator operator, A arg) {
-    return handleStaticGetterSetterPostfixPrefix(
-        node, getter, setter, operator, arg,
-        isPrefix: true);
-  }
-
-  @override
-  R visitTopLevelMethodSetterCompound(Send node, FunctionElement method,
-      SetterElement setter, AssignmentOperator operator, Node rhs, A arg) {
-    return handleStaticMethodSetterCompound(
-        node, method, setter, operator, rhs, arg);
-  }
-
-  @override
-  R visitTopLevelMethodSetterPostfix(Send node, FunctionElement method,
-      SetterElement setter, IncDecOperator operator, A arg) {
-    return handleStaticMethodSetterPostfixPrefix(
-        node, method, setter, operator, arg,
-        isPrefix: false);
-  }
-
-  @override
-  R visitTopLevelMethodSetterPrefix(Send node, FunctionElement method,
-      SetterElement setter, IncDecOperator operator, A arg) {
-    return handleStaticMethodSetterPostfixPrefix(
-        node, method, setter, operator, arg,
-        isPrefix: true);
-  }
-
-  @override
-  R visitFinalStaticFieldCompound(Send node, FieldElement field,
-      AssignmentOperator operator, Node rhs, A arg) {
-    return handleFinalStaticFieldCompound(node, field, operator, rhs, arg);
-  }
-
-  @override
-  R visitFinalStaticFieldPostfix(
-      Send node, FieldElement field, IncDecOperator operator, A arg) {
-    return handleFinalStaticFieldPostfixPrefix(node, field, operator, arg,
-        isPrefix: false);
-  }
-
-  @override
-  R visitFinalStaticFieldPrefix(
-      Send node, FieldElement field, IncDecOperator operator, A arg) {
-    return handleFinalStaticFieldPostfixPrefix(node, field, operator, arg,
-        isPrefix: true);
-  }
-
-  @override
-  R visitStaticMethodCompound(Send node, FunctionElement method,
-      AssignmentOperator operator, Node rhs, A arg) {
-    return handleStaticMethodCompound(node, method, operator, rhs, arg);
-  }
-
-  @override
-  R visitStaticMethodPostfix(
-      Send node, FunctionElement method, IncDecOperator operator, A arg) {
-    return handleStaticMethodPostfixPrefix(node, method, operator, arg,
-        isPrefix: false);
-  }
-
-  @override
-  R visitStaticMethodPrefix(
-      Send node, FunctionElement method, IncDecOperator operator, A arg) {
-    return handleStaticMethodPostfixPrefix(node, method, operator, arg,
-        isPrefix: true);
-  }
-
-  @override
-  R visitUnresolvedStaticGetterCompound(Send node, Element element,
-      SetterElement setter, AssignmentOperator operator, Node rhs, A arg) {
-    return handleUnresolvedStaticGetterCompound(
-        node, element, setter, operator, rhs, arg);
-  }
-
-  @override
-  R visitUnresolvedStaticGetterPostfix(Send node, Element element,
-      SetterElement setter, IncDecOperator operator, A arg) {
-    return handleUnresolvedStaticGetterPostfixPrefix(
-        node, element, setter, operator, arg,
-        isPrefix: false);
-  }
-
-  @override
-  R visitUnresolvedStaticGetterPrefix(Send node, Element element,
-      SetterElement setter, IncDecOperator operator, A arg) {
-    return handleUnresolvedStaticGetterPostfixPrefix(
-        node, element, setter, operator, arg,
-        isPrefix: true);
-  }
-
-  @override
-  R visitUnresolvedStaticSetterCompound(Send node, GetterElement getter,
-      Element element, AssignmentOperator operator, Node rhs, A arg) {
-    return handleUnresolvedStaticSetterCompound(
-        node, getter, element, operator, rhs, arg);
-  }
-
-  @override
-  R visitUnresolvedStaticSetterPostfix(Send node, GetterElement getter,
-      Element element, IncDecOperator operator, A arg) {
-    return handleUnresolvedStaticSetterPostfixPrefix(
-        node, getter, element, operator, arg,
-        isPrefix: false);
-  }
-
-  @override
-  R visitUnresolvedStaticSetterPrefix(Send node, GetterElement getter,
-      Element element, IncDecOperator operator, A arg) {
-    return handleUnresolvedStaticSetterPostfixPrefix(
-        node, getter, element, operator, arg,
-        isPrefix: true);
-  }
-}
-
-/// Mixin that groups all non-compound `visitLocalX` and `visitParameterX`
-/// methods by delegating calls to `handleLocalX` methods.
-///
-/// This mixin is useful for the cases where both parameters, local variables,
-/// and local functions, captured or not, are handled uniformly.
-abstract class BaseImplementationOfLocalsMixin<R, A>
-    implements SemanticSendVisitor<R, A> {
-  R handleLocalGet(Send node, LocalElement element, A arg);
-
-  R handleLocalInvoke(Send node, LocalElement element, NodeList arguments,
-      CallStructure callStructure, A arg);
-
-  R handleLocalSet(SendSet node, LocalElement element, Node rhs, A arg);
-
-  R handleImmutableLocalSet(
-      SendSet node, LocalElement element, Node rhs, A arg);
-
-  @override
-  R visitLocalFunctionGet(Send node, LocalFunctionElement function, A arg) {
-    return handleLocalGet(node, function, arg);
-  }
-
-  @override
-  R visitLocalFunctionInvoke(Send node, LocalFunctionElement function,
-      NodeList arguments, CallStructure callStructure, A arg) {
-    return handleLocalInvoke(node, function, arguments, callStructure, arg);
-  }
-
-  @override
-  R visitLocalFunctionIncompatibleInvoke(
-      Send node,
-      LocalFunctionElement function,
-      NodeList arguments,
-      CallStructure callStructure,
-      A arg) {
-    return handleLocalInvoke(node, function, arguments, callStructure, arg);
-  }
-
-  @override
-  R visitLocalVariableGet(Send node, LocalVariableElement variable, A arg) {
-    return handleLocalGet(node, variable, arg);
-  }
-
-  @override
-  R visitLocalVariableInvoke(Send node, LocalVariableElement variable,
-      NodeList arguments, CallStructure callStructure, A arg) {
-    return handleLocalInvoke(node, variable, arguments, callStructure, arg);
-  }
-
-  @override
-  R visitLocalVariableSet(
-      SendSet node, LocalVariableElement variable, Node rhs, A arg) {
-    return handleLocalSet(node, variable, rhs, arg);
-  }
-
-  @override
-  R visitParameterGet(Send node, ParameterElement parameter, A arg) {
-    return handleLocalGet(node, parameter, arg);
-  }
-
-  @override
-  R visitParameterInvoke(Send node, ParameterElement parameter,
-      NodeList arguments, CallStructure callStructure, A arg) {
-    return handleLocalInvoke(node, parameter, arguments, callStructure, arg);
-  }
-
-  @override
-  R visitParameterSet(
-      SendSet node, ParameterElement parameter, Node rhs, A arg) {
-    return handleLocalSet(node, parameter, rhs, arg);
-  }
-
-  @override
-  R visitFinalLocalVariableSet(
-      SendSet node, LocalVariableElement variable, Node rhs, A arg) {
-    return handleImmutableLocalSet(node, variable, rhs, arg);
-  }
-
-  @override
-  R visitFinalParameterSet(
-      SendSet node, ParameterElement parameter, Node rhs, A arg) {
-    return handleImmutableLocalSet(node, parameter, rhs, arg);
-  }
-
-  @override
-  R visitLocalFunctionSet(
-      SendSet node, LocalFunctionElement function, Node rhs, A arg) {
-    return handleImmutableLocalSet(node, function, rhs, arg);
-  }
-}
-
-/// Mixin that groups all compound `visitLocalX` and `visitParameterX` methods
-/// by delegating calls to `handleLocalX` methods.
-///
-/// This mixin is useful for the cases where both parameters, local variables,
-/// and local functions, captured or not, are handled uniformly.
-abstract class BaseImplementationOfLocalCompoundsMixin<R, A>
-    implements SemanticSendVisitor<R, A> {
-  R handleLocalCompound(Send node, LocalElement element,
-      AssignmentOperator operator, Node rhs, A arg);
-
-  R handleLocalPostfixPrefix(
-      Send node, LocalElement element, IncDecOperator operator, A arg,
-      {bool isPrefix});
-
-  @override
-  R visitLocalVariableCompound(Send node, LocalVariableElement variable,
-      AssignmentOperator operator, Node rhs, A arg) {
-    return handleLocalCompound(node, variable, operator, rhs, arg);
-  }
-
-  @override
-  R visitLocalVariablePostfix(Send node, LocalVariableElement variable,
-      IncDecOperator operator, A arg) {
-    return handleLocalPostfixPrefix(node, variable, operator, arg,
-        isPrefix: false);
-  }
-
-  @override
-  R visitLocalVariablePrefix(Send node, LocalVariableElement variable,
-      IncDecOperator operator, A arg) {
-    return handleLocalPostfixPrefix(node, variable, operator, arg,
-        isPrefix: true);
-  }
-
-  @override
-  R visitParameterCompound(Send node, ParameterElement parameter,
-      AssignmentOperator operator, Node rhs, A arg) {
-    return handleLocalCompound(node, parameter, operator, rhs, arg);
-  }
-
-  @override
-  R visitParameterPostfix(
-      Send node, ParameterElement parameter, IncDecOperator operator, A arg) {
-    return handleLocalPostfixPrefix(node, parameter, operator, arg,
-        isPrefix: false);
-  }
-
-  @override
-  R visitParameterPrefix(
-      Send node, ParameterElement parameter, IncDecOperator operator, A arg) {
-    return handleLocalPostfixPrefix(node, parameter, operator, arg,
-        isPrefix: true);
-  }
-}
-
-/// Mixin that groups all `visitConstantX` and `visitXTypeLiteralY` methods for
-/// constant type literals by delegating calls to `handleConstantX` methods.
-///
-/// This mixin is useful for the cases where expressions on constants are
-/// handled uniformly.
-abstract class BaseImplementationOfConstantsMixin<R, A>
-    implements SemanticSendVisitor<R, A> {
-  R handleConstantGet(Node node, ConstantExpression constant, A arg);
-
-  R handleConstantInvoke(Send node, ConstantExpression constant,
-      NodeList arguments, CallStructure callStructure, A arg);
-
-  @override
-  R visitClassTypeLiteralGet(Send node, ConstantExpression constant, A arg) {
-    return handleConstantGet(node, constant, arg);
-  }
-
-  @override
-  R visitClassTypeLiteralInvoke(Send node, ConstantExpression constant,
-      NodeList arguments, CallStructure callStructure, A arg) {
-    return handleConstantInvoke(node, constant, arguments, callStructure, arg);
-  }
-
-  @override
-  R visitConstConstructorInvoke(
-      NewExpression node, ConstructedConstantExpression constant, A arg) {
-    return handleConstantGet(node, constant, arg);
-  }
-
-  @override
-  R visitBoolFromEnvironmentConstructorInvoke(NewExpression node,
-      BoolFromEnvironmentConstantExpression constant, A arg) {
-    return handleConstantGet(node, constant, arg);
-  }
-
-  @override
-  R visitIntFromEnvironmentConstructorInvoke(NewExpression node,
-      IntFromEnvironmentConstantExpression constant, A arg) {
-    return handleConstantGet(node, constant, arg);
-  }
-
-  @override
-  R visitStringFromEnvironmentConstructorInvoke(NewExpression node,
-      StringFromEnvironmentConstantExpression constant, A arg) {
-    return handleConstantGet(node, constant, arg);
-  }
-
-  @override
-  R visitConstantGet(Send node, ConstantExpression constant, A arg) {
-    return handleConstantGet(node, constant, arg);
-  }
-
-  @override
-  R visitConstantInvoke(Send node, ConstantExpression constant,
-      NodeList arguments, CallStructure callStructure, A arg) {
-    return handleConstantInvoke(node, constant, arguments, callStructure, arg);
-  }
-
-  @override
-  R visitDynamicTypeLiteralGet(Send node, ConstantExpression constant, A arg) {
-    return handleConstantGet(node, constant, arg);
-  }
-
-  @override
-  R visitDynamicTypeLiteralInvoke(Send node, ConstantExpression constant,
-      NodeList arguments, CallStructure callStructure, A arg) {
-    return handleConstantInvoke(node, constant, arguments, callStructure, arg);
-  }
-
-  @override
-  R visitTypedefTypeLiteralGet(Send node, ConstantExpression constant, A arg) {
-    return handleConstantGet(node, constant, arg);
-  }
-
-  @override
-  R visitTypedefTypeLiteralInvoke(Send node, ConstantExpression constant,
-      NodeList arguments, CallStructure callStructure, A arg) {
-    return handleConstantInvoke(node, constant, arguments, callStructure, arg);
-  }
-}
-
-/// Mixin that groups all non-compound `visitDynamicPropertyX` and
-/// `visitThisPropertyY` methods for by delegating calls to `handleDynamicX`
-/// methods, providing `null` as the receiver for the this properties.
-///
-/// This mixin is useful for the cases where dynamic and this properties are
-/// handled uniformly.
-abstract class BaseImplementationOfDynamicsMixin<R, A>
-    implements SemanticSendVisitor<R, A> {
-  R handleDynamicGet(Send node, Node receiver, Name name, A arg);
-
-  R handleDynamicInvoke(
-      Send node, Node receiver, NodeList arguments, Selector selector, A arg);
-
-  R handleDynamicSet(SendSet node, Node receiver, Name name, Node rhs, A arg);
-
-  @override
-  R visitDynamicPropertyGet(Send node, Node receiver, Name name, A arg) {
-    return handleDynamicGet(node, receiver, name, arg);
-  }
-
-  @override
-  R visitIfNotNullDynamicPropertyGet(
-      Send node, Node receiver, Name name, A arg) {
-    // TODO(johnniwinther): should these redirect to handleDynamicX?
-    return handleDynamicGet(node, receiver, name, arg);
-  }
-
-  @override
-  R visitDynamicPropertyInvoke(
-      Send node, Node receiver, NodeList arguments, Selector selector, A arg) {
-    return handleDynamicInvoke(node, receiver, arguments, selector, arg);
-  }
-
-  @override
-  R visitIfNotNullDynamicPropertyInvoke(
-      Send node, Node receiver, NodeList arguments, Selector selector, A arg) {
-    return handleDynamicInvoke(node, receiver, arguments, selector, arg);
-  }
-
-  @override
-  R visitDynamicPropertySet(
-      SendSet node, Node receiver, Name name, Node rhs, A arg) {
-    return handleDynamicSet(node, receiver, name, rhs, arg);
-  }
-
-  @override
-  R visitIfNotNullDynamicPropertySet(
-      SendSet node, Node receiver, Name name, Node rhs, A arg) {
-    return handleDynamicSet(node, receiver, name, rhs, arg);
-  }
-
-  @override
-  R visitThisPropertyGet(Send node, Name name, A arg) {
-    return handleDynamicGet(node, null, name, arg);
-  }
-
-  @override
-  R visitThisPropertyInvoke(
-      Send node, NodeList arguments, Selector selector, A arg) {
-    return handleDynamicInvoke(node, null, arguments, selector, arg);
-  }
-
-  @override
-  R visitThisPropertySet(SendSet node, Name name, Node rhs, A arg) {
-    return handleDynamicSet(node, null, name, rhs, arg);
-  }
-}
-
-/// Mixin that groups all compounds of `visitDynamicPropertyX` and
-/// `visitThisPropertyY` methods for by delegating calls to `handleDynamicX`
-/// methods, providing `null` as the receiver for the this properties.
-///
-/// This mixin is useful for the cases where dynamic and this properties are
-/// handled uniformly.
-abstract class BaseImplementationOfDynamicCompoundsMixin<R, A>
-    implements SemanticSendVisitor<R, A> {
-  R handleDynamicCompound(Send node, Node receiver, Name name,
-      AssignmentOperator operator, Node rhs, A arg);
-
-  R handleDynamicPostfixPrefix(
-      Send node, Node receiver, Name name, IncDecOperator operator, A arg,
-      {bool isPrefix});
-
-  R handleDynamicIndexPostfixPrefix(
-      Send node, Node receiver, Node index, IncDecOperator operator, A arg,
-      {bool isPrefix});
-
-  @override
-  R visitDynamicPropertyCompound(Send node, Node receiver, Name name,
-      AssignmentOperator operator, Node rhs, A arg) {
-    return handleDynamicCompound(node, receiver, name, operator, rhs, arg);
-  }
-
-  @override
-  R visitIfNotNullDynamicPropertyCompound(Send node, Node receiver, Name name,
-      AssignmentOperator operator, Node rhs, A arg) {
-    return handleDynamicCompound(node, receiver, name, operator, rhs, arg);
-  }
-
-  @override
-  R visitDynamicPropertyPostfix(
-      Send node, Node receiver, Name name, IncDecOperator operator, A arg) {
-    return handleDynamicPostfixPrefix(node, receiver, name, operator, arg,
-        isPrefix: false);
-  }
-
-  @override
-  R visitIfNotNullDynamicPropertyPostfix(
-      Send node, Node receiver, Name name, IncDecOperator operator, A arg) {
-    return handleDynamicPostfixPrefix(node, receiver, name, operator, arg,
-        isPrefix: false);
-  }
-
-  @override
-  R visitDynamicPropertyPrefix(
-      Send node, Node receiver, Name name, IncDecOperator operator, A arg) {
-    return handleDynamicPostfixPrefix(node, receiver, name, operator, arg,
-        isPrefix: true);
-  }
-
-  @override
-  R visitIfNotNullDynamicPropertyPrefix(
-      Send node, Node receiver, Name name, IncDecOperator operator, A arg) {
-    return handleDynamicPostfixPrefix(node, receiver, name, operator, arg,
-        isPrefix: true);
-  }
-
-  @override
-  R visitThisPropertyCompound(
-      Send node, Name name, AssignmentOperator operator, Node rhs, A arg) {
-    return handleDynamicCompound(node, null, name, operator, rhs, arg);
-  }
-
-  @override
-  R visitThisPropertyPostfix(
-      Send node, Name name, IncDecOperator operator, A arg) {
-    return handleDynamicPostfixPrefix(node, null, name, operator, arg,
-        isPrefix: false);
-  }
-
-  @override
-  R visitThisPropertyPrefix(
-      Send node, Name name, IncDecOperator operator, A arg) {
-    return handleDynamicPostfixPrefix(node, null, name, operator, arg,
-        isPrefix: true);
-  }
-
-  @override
-  R visitIndexPostfix(
-      Send node, Node receiver, Node index, IncDecOperator operator, A arg) {
-    return handleDynamicIndexPostfixPrefix(node, receiver, index, operator, arg,
-        isPrefix: false);
-  }
-
-  @override
-  R visitIndexPrefix(
-      Send node, Node receiver, Node index, IncDecOperator operator, A arg) {
-    return handleDynamicIndexPostfixPrefix(node, receiver, index, operator, arg,
-        isPrefix: true);
-  }
-}
-
-/// The getter kind for statically resolved compound expressions.
-enum CompoundGetter {
-  /// The compound reads from a field.
-  FIELD,
-
-  /// The compound reads from a getter.
-  GETTER,
-
-  /// The compound reads (closurizes) a method.
-  METHOD,
-
-  /// The getter is unresolved. The accompanied element is an erroneous element.
-  UNRESOLVED,
-}
-
-/// The setter kind for statically resolved compound expressions.
-enum CompoundSetter {
-  /// The compound writes to a field.
-  FIELD,
-
-  /// The compound writes to a setter.
-  SETTER,
-
-  /// The setter is unresolved or unassignable. The accompanied element may be
-  /// `null`, and erroneous element, or the unassignable element.
-  INVALID,
-}
-
-/// The kind of a [CompoundRhs].
-enum CompoundKind {
-  /// A prefix expression, like `--a`.
-  PREFIX,
-
-  /// A postfix expression, like `a++`.
-  POSTFIX,
-
-  /// A compound assignment, like `a *= b`.
-  ASSIGNMENT,
-}
-
-/// The right-hand side of a compound expression.
-abstract class CompoundRhs {
-  /// The kind of compound.
-  CompoundKind get kind;
-
-  /// The binary operator implied by the compound operator.
-  BinaryOperator get operator;
-
-  /// The explicit right hand side in case of a compound assignment, `null`
-  /// otherwise.
-  Node get rhs;
-}
-
-/// A prefix or postfix of [incDecOperator].
-class IncDecCompound implements CompoundRhs {
-  final CompoundKind kind;
-  final IncDecOperator incDecOperator;
-
-  IncDecCompound(this.kind, this.incDecOperator);
-
-  BinaryOperator get operator => incDecOperator.binaryOperator;
-
-  Node get rhs => null;
-}
-
-/// A compound assignment with [assignmentOperator] and [rhs].
-class AssignmentCompound implements CompoundRhs {
-  final AssignmentOperator assignmentOperator;
-  final Node rhs;
-
-  AssignmentCompound(this.assignmentOperator, this.rhs);
-
-  CompoundKind get kind => CompoundKind.ASSIGNMENT;
-
-  BinaryOperator get operator => assignmentOperator.binaryOperator;
-}
-
-/// Simplified handling of compound assignments and prefix/postfix expressions.
-abstract class BaseImplementationOfCompoundsMixin<R, A>
-    implements SemanticSendVisitor<R, A> {
-  /// Handle a super compounds, like `super.foo += 42` or `--super.bar`.
-  R handleSuperCompounds(
-      SendSet node,
-      Element getter,
-      CompoundGetter getterKind,
-      Element setter,
-      CompoundSetter setterKind,
-      CompoundRhs rhs,
-      A arg);
-
-  /// Handle a static or top level compounds, like `foo += 42` or `--bar`.
-  R handleStaticCompounds(
-      SendSet node,
-      Element getter,
-      CompoundGetter getterKind,
-      Element setter,
-      CompoundSetter setterKind,
-      CompoundRhs rhs,
-      A arg);
-
-  /// Handle a local compounds, like `foo += 42` or `--bar`. If [isSetterValid]
-  /// is false [local] is unassignable.
-  R handleLocalCompounds(
-      SendSet node, LocalElement local, CompoundRhs rhs, A arg,
-      {bool isSetterValid});
-
-  /// Handle a compounds on a type literal constant, like `Object += 42` or
-  /// `--Object`.
-  R handleTypeLiteralConstantCompounds(
-      SendSet node, ConstantExpression constant, CompoundRhs rhs, A arg);
-
-  /// Handle a compounds on a type variable type literal, like `T += 42` or
-  /// `--T`.
-  R handleTypeVariableTypeLiteralCompounds(
-      SendSet node, TypeVariableElement typeVariable, CompoundRhs rhs, A arg);
-
-  /// Handle a dynamic compounds, like `o.foo += 42` or `--o.foo`. [receiver] is
-  /// `null` for properties on `this`, like `--this.foo` or `--foo`.
-  R handleDynamicCompounds(
-      Send node, Node receiver, Name name, CompoundRhs rhs, A arg);
-
-  R visitDynamicPropertyCompound(Send node, Node receiver, Name name,
-      AssignmentOperator operator, Node rhs, A arg) {
-    return handleDynamicCompounds(
-        node, receiver, name, new AssignmentCompound(operator, rhs), arg);
-  }
-
-  R visitIfNotNullDynamicPropertyCompound(Send node, Node receiver, Name name,
-      AssignmentOperator operator, Node rhs, A arg) {
-    return handleDynamicCompounds(
-        node, receiver, name, new AssignmentCompound(operator, rhs), arg);
-  }
-
-  @override
-  R visitThisPropertyCompound(
-      Send node, Name name, AssignmentOperator operator, Node rhs, A arg) {
-    return handleDynamicCompounds(
-        node, null, name, new AssignmentCompound(operator, rhs), arg);
-  }
-
-  @override
-  R visitParameterCompound(Send node, ParameterElement parameter,
-      AssignmentOperator operator, Node rhs, A arg) {
-    return handleLocalCompounds(
-        node, parameter, new AssignmentCompound(operator, rhs), arg,
-        isSetterValid: true);
-  }
-
-  @override
-  R visitFinalParameterCompound(Send node, ParameterElement parameter,
-      AssignmentOperator operator, Node rhs, A arg) {
-    return handleLocalCompounds(
-        node, parameter, new AssignmentCompound(operator, rhs), arg,
-        isSetterValid: false);
-  }
-
-  @override
-  R visitLocalVariableCompound(Send node, LocalVariableElement variable,
-      AssignmentOperator operator, Node rhs, A arg) {
-    return handleLocalCompounds(
-        node, variable, new AssignmentCompound(operator, rhs), arg,
-        isSetterValid: true);
-  }
-
-  @override
-  R visitFinalLocalVariableCompound(Send node, LocalVariableElement variable,
-      AssignmentOperator operator, Node rhs, A arg) {
-    return handleLocalCompounds(
-        node, variable, new AssignmentCompound(operator, rhs), arg,
-        isSetterValid: false);
-  }
-
-  @override
-  R visitLocalFunctionCompound(Send node, LocalFunctionElement function,
-      AssignmentOperator operator, Node rhs, A arg) {
-    return handleLocalCompounds(
-        node, function, new AssignmentCompound(operator, rhs), arg,
-        isSetterValid: false);
-  }
-
-  @override
-  R visitStaticFieldCompound(Send node, FieldElement field,
-      AssignmentOperator operator, Node rhs, A arg) {
-    return handleStaticCompounds(node, field, CompoundGetter.FIELD, field,
-        CompoundSetter.FIELD, new AssignmentCompound(operator, rhs), arg);
-  }
-
-  @override
-  R visitFinalStaticFieldCompound(Send node, FieldElement field,
-      AssignmentOperator operator, Node rhs, A arg) {
-    return handleStaticCompounds(node, field, CompoundGetter.FIELD, null,
-        CompoundSetter.INVALID, new AssignmentCompound(operator, rhs), arg);
-  }
-
-  @override
-  R visitStaticGetterSetterCompound(Send node, GetterElement getter,
-      SetterElement setter, AssignmentOperator operator, Node rhs, A arg) {
-    return handleStaticCompounds(node, getter, CompoundGetter.GETTER, setter,
-        CompoundSetter.SETTER, new AssignmentCompound(operator, rhs), arg);
-  }
-
-  @override
-  R visitStaticMethodSetterCompound(Send node, FunctionElement method,
-      SetterElement setter, AssignmentOperator operator, Node rhs, A arg) {
-    return handleStaticCompounds(node, method, CompoundGetter.METHOD, setter,
-        CompoundSetter.SETTER, new AssignmentCompound(operator, rhs), arg);
-  }
-
-  @override
-  R visitTopLevelFieldCompound(Send node, FieldElement field,
-      AssignmentOperator operator, Node rhs, A arg) {
-    return handleStaticCompounds(node, field, CompoundGetter.FIELD, field,
-        CompoundSetter.FIELD, new AssignmentCompound(operator, rhs), arg);
-  }
-
-  @override
-  R visitFinalTopLevelFieldCompound(Send node, FieldElement field,
-      AssignmentOperator operator, Node rhs, A arg) {
-    return handleStaticCompounds(node, field, CompoundGetter.FIELD, null,
-        CompoundSetter.INVALID, new AssignmentCompound(operator, rhs), arg);
-  }
-
-  @override
-  R visitTopLevelGetterSetterCompound(Send node, GetterElement getter,
-      SetterElement setter, AssignmentOperator operator, Node rhs, A arg) {
-    return handleStaticCompounds(node, getter, CompoundGetter.GETTER, setter,
-        CompoundSetter.SETTER, new AssignmentCompound(operator, rhs), arg);
-  }
-
-  @override
-  R visitTopLevelMethodSetterCompound(Send node, FunctionElement method,
-      SetterElement setter, AssignmentOperator operator, Node rhs, A arg) {
-    return handleStaticCompounds(node, method, CompoundGetter.METHOD, setter,
-        CompoundSetter.SETTER, new AssignmentCompound(operator, rhs), arg);
-  }
-
-  @override
-  R visitSuperFieldCompound(Send node, FieldElement field,
-      AssignmentOperator operator, Node rhs, A arg) {
-    return handleSuperCompounds(node, field, CompoundGetter.FIELD, field,
-        CompoundSetter.FIELD, new AssignmentCompound(operator, rhs), arg);
-  }
-
-  @override
-  R visitFinalSuperFieldCompound(Send node, FieldElement field,
-      AssignmentOperator operator, Node rhs, A arg) {
-    return handleSuperCompounds(node, field, CompoundGetter.FIELD, field,
-        CompoundSetter.INVALID, new AssignmentCompound(operator, rhs), arg);
-  }
-
-  @override
-  R visitSuperGetterSetterCompound(Send node, GetterElement getter,
-      SetterElement setter, AssignmentOperator operator, Node rhs, A arg) {
-    return handleSuperCompounds(node, getter, CompoundGetter.GETTER, setter,
-        CompoundSetter.SETTER, new AssignmentCompound(operator, rhs), arg);
-  }
-
-  @override
-  R visitSuperMethodSetterCompound(Send node, FunctionElement method,
-      SetterElement setter, AssignmentOperator operator, Node rhs, A arg) {
-    return handleSuperCompounds(node, method, CompoundGetter.METHOD, setter,
-        CompoundSetter.SETTER, new AssignmentCompound(operator, rhs), arg);
-  }
-
-  @override
-  R visitSuperFieldSetterCompound(Send node, FieldElement field,
-      SetterElement setter, AssignmentOperator operator, Node rhs, A arg) {
-    return handleSuperCompounds(node, field, CompoundGetter.FIELD, setter,
-        CompoundSetter.SETTER, new AssignmentCompound(operator, rhs), arg);
-  }
-
-  @override
-  R visitSuperGetterFieldCompound(Send node, GetterElement getter,
-      FieldElement field, AssignmentOperator operator, Node rhs, A arg) {
-    return handleSuperCompounds(node, getter, CompoundGetter.GETTER, field,
-        CompoundSetter.FIELD, new AssignmentCompound(operator, rhs), arg);
-  }
-
-  @override
-  R visitClassTypeLiteralCompound(Send node, ConstantExpression constant,
-      AssignmentOperator operator, Node rhs, A arg) {
-    return handleTypeLiteralConstantCompounds(
-        node, constant, new AssignmentCompound(operator, rhs), arg);
-  }
-
-  @override
-  R visitTypedefTypeLiteralCompound(Send node, ConstantExpression constant,
-      AssignmentOperator operator, Node rhs, A arg) {
-    return handleTypeLiteralConstantCompounds(
-        node, constant, new AssignmentCompound(operator, rhs), arg);
-  }
-
-  @override
-  R visitTypeVariableTypeLiteralCompound(Send node, TypeVariableElement element,
-      AssignmentOperator operator, Node rhs, A arg) {
-    return handleTypeVariableTypeLiteralCompounds(
-        node, element, new AssignmentCompound(operator, rhs), arg);
-  }
-
-  @override
-  R visitDynamicTypeLiteralCompound(Send node, ConstantExpression constant,
-      AssignmentOperator operator, Node rhs, A arg) {
-    return handleTypeLiteralConstantCompounds(
-        node, constant, new AssignmentCompound(operator, rhs), arg);
-  }
-
-  R visitDynamicPropertyPrefix(
-      Send node, Node receiver, Name name, IncDecOperator operator, A arg) {
-    return handleDynamicCompounds(node, receiver, name,
-        new IncDecCompound(CompoundKind.PREFIX, operator), arg);
-  }
-
-  R visitIfNotNullDynamicPropertyPrefix(
-      Send node, Node receiver, Name name, IncDecOperator operator, A arg) {
-    return handleDynamicCompounds(node, receiver, name,
-        new IncDecCompound(CompoundKind.PREFIX, operator), arg);
-  }
-
-  @override
-  R visitParameterPrefix(
-      Send node, ParameterElement parameter, IncDecOperator operator, A arg) {
-    return handleLocalCompounds(
-        node, parameter, new IncDecCompound(CompoundKind.PREFIX, operator), arg,
-        isSetterValid: true);
-  }
-
-  @override
-  R visitLocalVariablePrefix(Send node, LocalVariableElement variable,
-      IncDecOperator operator, A arg) {
-    return handleLocalCompounds(
-        node, variable, new IncDecCompound(CompoundKind.PREFIX, operator), arg,
-        isSetterValid: true);
-  }
-
-  @override
-  R visitLocalFunctionPrefix(Send node, LocalFunctionElement function,
-      IncDecOperator operator, A arg) {
-    return handleLocalCompounds(
-        node, function, new IncDecCompound(CompoundKind.PREFIX, operator), arg,
-        isSetterValid: false);
-  }
-
-  R visitThisPropertyPrefix(
-      Send node, Name name, IncDecOperator operator, A arg) {
-    return handleDynamicCompounds(node, null, name,
-        new IncDecCompound(CompoundKind.PREFIX, operator), arg);
-  }
-
-  @override
-  R visitStaticFieldPrefix(
-      Send node, FieldElement field, IncDecOperator operator, A arg) {
-    return handleStaticCompounds(
-        node,
-        field,
-        CompoundGetter.FIELD,
-        field,
-        CompoundSetter.FIELD,
-        new IncDecCompound(CompoundKind.PREFIX, operator),
-        arg);
-  }
-
-  @override
-  R visitStaticGetterSetterPrefix(Send node, GetterElement getter,
-      SetterElement setter, IncDecOperator operator, A arg) {
-    return handleStaticCompounds(
-        node,
-        getter,
-        CompoundGetter.GETTER,
-        setter,
-        CompoundSetter.SETTER,
-        new IncDecCompound(CompoundKind.PREFIX, operator),
-        arg);
-  }
-
-  R visitStaticMethodSetterPrefix(Send node, GetterElement getter,
-      SetterElement setter, IncDecOperator operator, A arg) {
-    return handleStaticCompounds(
-        node,
-        getter,
-        CompoundGetter.METHOD,
-        setter,
-        CompoundSetter.SETTER,
-        new IncDecCompound(CompoundKind.PREFIX, operator),
-        arg);
-  }
-
-  @override
-  R visitTopLevelFieldPrefix(
-      Send node, FieldElement field, IncDecOperator operator, A arg) {
-    return handleStaticCompounds(
-        node,
-        field,
-        CompoundGetter.FIELD,
-        field,
-        CompoundSetter.FIELD,
-        new IncDecCompound(CompoundKind.PREFIX, operator),
-        arg);
-  }
-
-  @override
-  R visitTopLevelGetterSetterPrefix(Send node, GetterElement getter,
-      SetterElement setter, IncDecOperator operator, A arg) {
-    return handleStaticCompounds(
-        node,
-        getter,
-        CompoundGetter.GETTER,
-        setter,
-        CompoundSetter.SETTER,
-        new IncDecCompound(CompoundKind.PREFIX, operator),
-        arg);
-  }
-
-  @override
-  R visitTopLevelMethodSetterPrefix(Send node, FunctionElement method,
-      SetterElement setter, IncDecOperator operator, A arg) {
-    return handleStaticCompounds(
-        node,
-        method,
-        CompoundGetter.METHOD,
-        setter,
-        CompoundSetter.SETTER,
-        new IncDecCompound(CompoundKind.PREFIX, operator),
-        arg);
-  }
-
-  @override
-  R visitSuperFieldPrefix(
-      SendSet node, FieldElement field, IncDecOperator operator, A arg) {
-    return handleSuperCompounds(
-        node,
-        field,
-        CompoundGetter.FIELD,
-        field,
-        CompoundSetter.FIELD,
-        new IncDecCompound(CompoundKind.PREFIX, operator),
-        arg);
-  }
-
-  @override
-  R visitSuperFieldFieldPrefix(SendSet node, FieldElement readField,
-      FieldElement writtenField, IncDecOperator operator, A arg) {
-    return handleSuperCompounds(
-        node,
-        readField,
-        CompoundGetter.FIELD,
-        writtenField,
-        CompoundSetter.FIELD,
-        new IncDecCompound(CompoundKind.PREFIX, operator),
-        arg);
-  }
-
-  @override
-  R visitSuperFieldSetterPrefix(SendSet node, FieldElement field,
-      SetterElement setter, IncDecOperator operator, A arg) {
-    return handleSuperCompounds(
-        node,
-        field,
-        CompoundGetter.FIELD,
-        setter,
-        CompoundSetter.SETTER,
-        new IncDecCompound(CompoundKind.PREFIX, operator),
-        arg);
-  }
-
-  @override
-  R visitSuperGetterSetterPrefix(SendSet node, GetterElement getter,
-      SetterElement setter, IncDecOperator operator, A arg) {
-    return handleSuperCompounds(
-        node,
-        getter,
-        CompoundGetter.GETTER,
-        setter,
-        CompoundSetter.SETTER,
-        new IncDecCompound(CompoundKind.PREFIX, operator),
-        arg);
-  }
-
-  @override
-  R visitSuperGetterFieldPrefix(SendSet node, GetterElement getter,
-      FieldElement field, IncDecOperator operator, A arg) {
-    return handleSuperCompounds(
-        node,
-        getter,
-        CompoundGetter.GETTER,
-        field,
-        CompoundSetter.FIELD,
-        new IncDecCompound(CompoundKind.PREFIX, operator),
-        arg);
-  }
-
-  @override
-  R visitSuperMethodSetterPrefix(SendSet node, FunctionElement method,
-      SetterElement setter, IncDecOperator operator, A arg) {
-    return handleSuperCompounds(
-        node,
-        method,
-        CompoundGetter.METHOD,
-        setter,
-        CompoundSetter.SETTER,
-        new IncDecCompound(CompoundKind.PREFIX, operator),
-        arg);
-  }
-
-  @override
-  R visitClassTypeLiteralPrefix(
-      Send node, ConstantExpression constant, IncDecOperator operator, A arg) {
-    return handleTypeLiteralConstantCompounds(
-        node, constant, new IncDecCompound(CompoundKind.PREFIX, operator), arg);
-  }
-
-  @override
-  R visitTypedefTypeLiteralPrefix(
-      Send node, ConstantExpression constant, IncDecOperator operator, A arg) {
-    return handleTypeLiteralConstantCompounds(
-        node, constant, new IncDecCompound(CompoundKind.PREFIX, operator), arg);
-  }
-
-  @override
-  R visitTypeVariableTypeLiteralPrefix(
-      Send node, TypeVariableElement element, IncDecOperator operator, A arg) {
-    return handleTypeVariableTypeLiteralCompounds(
-        node, element, new IncDecCompound(CompoundKind.PREFIX, operator), arg);
-  }
-
-  @override
-  R visitDynamicTypeLiteralPrefix(
-      Send node, ConstantExpression constant, IncDecOperator operator, A arg) {
-    return handleTypeLiteralConstantCompounds(
-        node, constant, new IncDecCompound(CompoundKind.PREFIX, operator), arg);
-  }
-
-  @override
-  R visitDynamicPropertyPostfix(
-      Send node, Node receiver, Name name, IncDecOperator operator, A arg) {
-    return handleDynamicCompounds(node, receiver, name,
-        new IncDecCompound(CompoundKind.POSTFIX, operator), arg);
-  }
-
-  @override
-  R visitIfNotNullDynamicPropertyPostfix(
-      Send node, Node receiver, Name name, IncDecOperator operator, A arg) {
-    return handleDynamicCompounds(node, receiver, name,
-        new IncDecCompound(CompoundKind.POSTFIX, operator), arg);
-  }
-
-  @override
-  R visitParameterPostfix(
-      Send node, ParameterElement parameter, IncDecOperator operator, A arg) {
-    return handleLocalCompounds(node, parameter,
-        new IncDecCompound(CompoundKind.POSTFIX, operator), arg,
-        isSetterValid: true);
-  }
-
-  @override
-  R visitLocalVariablePostfix(Send node, LocalVariableElement variable,
-      IncDecOperator operator, A arg) {
-    return handleLocalCompounds(
-        node, variable, new IncDecCompound(CompoundKind.POSTFIX, operator), arg,
-        isSetterValid: true);
-  }
-
-  @override
-  R visitLocalFunctionPostfix(Send node, LocalFunctionElement function,
-      IncDecOperator operator, A arg) {
-    return handleLocalCompounds(
-        node, function, new IncDecCompound(CompoundKind.POSTFIX, operator), arg,
-        isSetterValid: false);
-  }
-
-  R visitThisPropertyPostfix(
-      Send node, Name name, IncDecOperator operator, A arg) {
-    return handleDynamicCompounds(node, null, name,
-        new IncDecCompound(CompoundKind.POSTFIX, operator), arg);
-  }
-
-  @override
-  R visitStaticFieldPostfix(
-      Send node, FieldElement field, IncDecOperator operator, A arg) {
-    return handleStaticCompounds(
-        node,
-        field,
-        CompoundGetter.FIELD,
-        field,
-        CompoundSetter.FIELD,
-        new IncDecCompound(CompoundKind.POSTFIX, operator),
-        arg);
-  }
-
-  @override
-  R visitStaticGetterSetterPostfix(Send node, GetterElement getter,
-      SetterElement setter, IncDecOperator operator, A arg) {
-    return handleStaticCompounds(
-        node,
-        getter,
-        CompoundGetter.GETTER,
-        setter,
-        CompoundSetter.SETTER,
-        new IncDecCompound(CompoundKind.POSTFIX, operator),
-        arg);
-  }
-
-  R visitStaticMethodSetterPostfix(Send node, GetterElement getter,
-      SetterElement setter, IncDecOperator operator, A arg) {
-    return handleStaticCompounds(
-        node,
-        getter,
-        CompoundGetter.METHOD,
-        setter,
-        CompoundSetter.SETTER,
-        new IncDecCompound(CompoundKind.POSTFIX, operator),
-        arg);
-  }
-
-  @override
-  R visitTopLevelFieldPostfix(
-      Send node, FieldElement field, IncDecOperator operator, A arg) {
-    return handleStaticCompounds(
-        node,
-        field,
-        CompoundGetter.FIELD,
-        field,
-        CompoundSetter.FIELD,
-        new IncDecCompound(CompoundKind.POSTFIX, operator),
-        arg);
-  }
-
-  @override
-  R visitTopLevelGetterSetterPostfix(Send node, GetterElement getter,
-      SetterElement setter, IncDecOperator operator, A arg) {
-    return handleStaticCompounds(
-        node,
-        getter,
-        CompoundGetter.GETTER,
-        setter,
-        CompoundSetter.SETTER,
-        new IncDecCompound(CompoundKind.POSTFIX, operator),
-        arg);
-  }
-
-  @override
-  R visitTopLevelMethodSetterPostfix(Send node, FunctionElement method,
-      SetterElement setter, IncDecOperator operator, A arg) {
-    return handleStaticCompounds(
-        node,
-        method,
-        CompoundGetter.METHOD,
-        setter,
-        CompoundSetter.SETTER,
-        new IncDecCompound(CompoundKind.POSTFIX, operator),
-        arg);
-  }
-
-  @override
-  R visitSuperFieldPostfix(
-      SendSet node, FieldElement field, IncDecOperator operator, A arg) {
-    return handleSuperCompounds(
-        node,
-        field,
-        CompoundGetter.FIELD,
-        field,
-        CompoundSetter.FIELD,
-        new IncDecCompound(CompoundKind.POSTFIX, operator),
-        arg);
-  }
-
-  @override
-  R visitSuperFieldFieldPostfix(SendSet node, FieldElement readField,
-      FieldElement writtenField, IncDecOperator operator, A arg) {
-    return handleSuperCompounds(
-        node,
-        readField,
-        CompoundGetter.FIELD,
-        writtenField,
-        CompoundSetter.FIELD,
-        new IncDecCompound(CompoundKind.POSTFIX, operator),
-        arg);
-  }
-
-  @override
-  R visitSuperFieldSetterPostfix(SendSet node, FieldElement field,
-      SetterElement setter, IncDecOperator operator, A arg) {
-    return handleSuperCompounds(
-        node,
-        field,
-        CompoundGetter.FIELD,
-        setter,
-        CompoundSetter.SETTER,
-        new IncDecCompound(CompoundKind.POSTFIX, operator),
-        arg);
-  }
-
-  R visitSuperGetterSetterPostfix(SendSet node, GetterElement getter,
-      SetterElement setter, IncDecOperator operator, A arg) {
-    return handleSuperCompounds(
-        node,
-        getter,
-        CompoundGetter.GETTER,
-        setter,
-        CompoundSetter.SETTER,
-        new IncDecCompound(CompoundKind.POSTFIX, operator),
-        arg);
-  }
-
-  @override
-  R visitSuperGetterFieldPostfix(SendSet node, GetterElement getter,
-      FieldElement field, IncDecOperator operator, A arg) {
-    return handleSuperCompounds(
-        node,
-        getter,
-        CompoundGetter.GETTER,
-        field,
-        CompoundSetter.FIELD,
-        new IncDecCompound(CompoundKind.POSTFIX, operator),
-        arg);
-  }
-
-  @override
-  R visitSuperMethodSetterPostfix(SendSet node, FunctionElement method,
-      SetterElement setter, IncDecOperator operator, A arg) {
-    return handleSuperCompounds(
-        node,
-        method,
-        CompoundGetter.METHOD,
-        setter,
-        CompoundSetter.SETTER,
-        new IncDecCompound(CompoundKind.POSTFIX, operator),
-        arg);
-  }
-
-  @override
-  R visitClassTypeLiteralPostfix(
-      Send node, ConstantExpression constant, IncDecOperator operator, A arg) {
-    return handleTypeLiteralConstantCompounds(node, constant,
-        new IncDecCompound(CompoundKind.POSTFIX, operator), arg);
-  }
-
-  @override
-  R visitTypedefTypeLiteralPostfix(
-      Send node, ConstantExpression constant, IncDecOperator operator, A arg) {
-    return handleTypeLiteralConstantCompounds(node, constant,
-        new IncDecCompound(CompoundKind.POSTFIX, operator), arg);
-  }
-
-  @override
-  R visitTypeVariableTypeLiteralPostfix(
-      Send node, TypeVariableElement element, IncDecOperator operator, A arg) {
-    return handleTypeVariableTypeLiteralCompounds(
-        node, element, new IncDecCompound(CompoundKind.POSTFIX, operator), arg);
-  }
-
-  @override
-  R visitDynamicTypeLiteralPostfix(
-      Send node, ConstantExpression constant, IncDecOperator operator, A arg) {
-    return handleTypeLiteralConstantCompounds(node, constant,
-        new IncDecCompound(CompoundKind.POSTFIX, operator), arg);
-  }
-
-  @override
-  R visitUnresolvedStaticGetterPostfix(Send node, Element element,
-      MethodElement setter, IncDecOperator operator, A arg) {
-    return handleStaticCompounds(
-        node,
-        element,
-        CompoundGetter.UNRESOLVED,
-        setter,
-        CompoundSetter.SETTER,
-        new IncDecCompound(CompoundKind.POSTFIX, operator),
-        arg);
-  }
-
-  @override
-  R visitUnresolvedTopLevelGetterPostfix(Send node, Element element,
-      MethodElement setter, IncDecOperator operator, A arg) {
-    return handleStaticCompounds(
-        node,
-        element,
-        CompoundGetter.UNRESOLVED,
-        setter,
-        CompoundSetter.SETTER,
-        new IncDecCompound(CompoundKind.POSTFIX, operator),
-        arg);
-  }
-
-  @override
-  R visitUnresolvedStaticSetterPostfix(Send node, GetterElement getter,
-      Element element, IncDecOperator operator, A arg) {
-    return handleStaticCompounds(
-        node,
-        getter,
-        CompoundGetter.GETTER,
-        element,
-        CompoundSetter.INVALID,
-        new IncDecCompound(CompoundKind.POSTFIX, operator),
-        arg);
-  }
-
-  @override
-  R visitUnresolvedTopLevelSetterPostfix(Send node, GetterElement getter,
-      Element element, IncDecOperator operator, A arg) {
-    return handleStaticCompounds(
-        node,
-        getter,
-        CompoundGetter.GETTER,
-        element,
-        CompoundSetter.INVALID,
-        new IncDecCompound(CompoundKind.POSTFIX, operator),
-        arg);
-  }
-
-  @override
-  R visitStaticMethodPostfix(
-      Send node, MethodElement method, IncDecOperator operator, A arg) {
-    return handleStaticCompounds(
-        node,
-        method,
-        CompoundGetter.METHOD,
-        method,
-        CompoundSetter.INVALID,
-        new IncDecCompound(CompoundKind.POSTFIX, operator),
-        arg);
-  }
-
-  @override
-  R visitTopLevelMethodPostfix(
-      Send node, MethodElement method, IncDecOperator operator, A arg) {
-    return handleStaticCompounds(
-        node,
-        method,
-        CompoundGetter.METHOD,
-        method,
-        CompoundSetter.INVALID,
-        new IncDecCompound(CompoundKind.POSTFIX, operator),
-        arg);
-  }
-
-  @override
-  R visitUnresolvedPostfix(
-      Send node, ErroneousElement element, IncDecOperator operator, A arg) {
-    return handleStaticCompounds(
-        node,
-        element,
-        CompoundGetter.UNRESOLVED,
-        element,
-        CompoundSetter.INVALID,
-        new IncDecCompound(CompoundKind.POSTFIX, operator),
-        arg);
-  }
-
-  @override
-  R visitUnresolvedStaticGetterPrefix(Send node, Element element,
-      MethodElement setter, IncDecOperator operator, A arg) {
-    return handleStaticCompounds(
-        node,
-        element,
-        CompoundGetter.UNRESOLVED,
-        setter,
-        CompoundSetter.SETTER,
-        new IncDecCompound(CompoundKind.PREFIX, operator),
-        arg);
-  }
-
-  @override
-  R visitUnresolvedTopLevelGetterPrefix(Send node, Element element,
-      MethodElement setter, IncDecOperator operator, A arg) {
-    return handleStaticCompounds(
-        node,
-        element,
-        CompoundGetter.UNRESOLVED,
-        setter,
-        CompoundSetter.SETTER,
-        new IncDecCompound(CompoundKind.PREFIX, operator),
-        arg);
-  }
-
-  @override
-  R visitUnresolvedStaticSetterPrefix(Send node, GetterElement getter,
-      Element element, IncDecOperator operator, A arg) {
-    return handleStaticCompounds(
-        node,
-        getter,
-        CompoundGetter.GETTER,
-        element,
-        CompoundSetter.INVALID,
-        new IncDecCompound(CompoundKind.PREFIX, operator),
-        arg);
-  }
-
-  @override
-  R visitUnresolvedTopLevelSetterPrefix(Send node, GetterElement getter,
-      Element element, IncDecOperator operator, A arg) {
-    return handleStaticCompounds(
-        node,
-        getter,
-        CompoundGetter.GETTER,
-        element,
-        CompoundSetter.INVALID,
-        new IncDecCompound(CompoundKind.PREFIX, operator),
-        arg);
-  }
-
-  @override
-  R visitStaticMethodPrefix(
-      Send node, MethodElement method, IncDecOperator operator, A arg) {
-    return handleStaticCompounds(
-        node,
-        method,
-        CompoundGetter.METHOD,
-        method,
-        CompoundSetter.INVALID,
-        new IncDecCompound(CompoundKind.PREFIX, operator),
-        arg);
-  }
-
-  @override
-  R visitTopLevelMethodPrefix(
-      Send node, MethodElement method, IncDecOperator operator, A arg) {
-    return handleStaticCompounds(
-        node,
-        method,
-        CompoundGetter.METHOD,
-        method,
-        CompoundSetter.INVALID,
-        new IncDecCompound(CompoundKind.PREFIX, operator),
-        arg);
-  }
-
-  @override
-  R visitUnresolvedPrefix(
-      Send node, ErroneousElement element, IncDecOperator operator, A arg) {
-    return handleStaticCompounds(
-        node,
-        element,
-        CompoundGetter.UNRESOLVED,
-        element,
-        CompoundSetter.INVALID,
-        new IncDecCompound(CompoundKind.PREFIX, operator),
-        arg);
-  }
-
-  @override
-  R visitUnresolvedStaticGetterCompound(Send node, Element element,
-      MethodElement setter, AssignmentOperator operator, Node rhs, A arg) {
-    return handleStaticCompounds(
-        node,
-        element,
-        CompoundGetter.UNRESOLVED,
-        setter,
-        CompoundSetter.SETTER,
-        new AssignmentCompound(operator, rhs),
-        arg);
-  }
-
-  @override
-  R visitUnresolvedTopLevelGetterCompound(Send node, Element element,
-      MethodElement setter, AssignmentOperator operator, Node rhs, A arg) {
-    return handleStaticCompounds(
-        node,
-        element,
-        CompoundGetter.UNRESOLVED,
-        setter,
-        CompoundSetter.SETTER,
-        new AssignmentCompound(operator, rhs),
-        arg);
-  }
-
-  @override
-  R visitUnresolvedStaticSetterCompound(Send node, GetterElement getter,
-      Element element, AssignmentOperator operator, Node rhs, A arg) {
-    return handleStaticCompounds(node, getter, CompoundGetter.GETTER, element,
-        CompoundSetter.INVALID, new AssignmentCompound(operator, rhs), arg);
-  }
-
-  @override
-  R visitUnresolvedTopLevelSetterCompound(Send node, GetterElement getter,
-      Element element, AssignmentOperator operator, Node rhs, A arg) {
-    return handleStaticCompounds(node, getter, CompoundGetter.GETTER, element,
-        CompoundSetter.INVALID, new AssignmentCompound(operator, rhs), arg);
-  }
-
-  @override
-  R visitStaticMethodCompound(Send node, MethodElement method,
-      AssignmentOperator operator, Node rhs, A arg) {
-    return handleStaticCompounds(node, method, CompoundGetter.METHOD, method,
-        CompoundSetter.INVALID, new AssignmentCompound(operator, rhs), arg);
-  }
-
-  @override
-  R visitTopLevelMethodCompound(Send node, MethodElement method,
-      AssignmentOperator operator, Node rhs, A arg) {
-    return handleStaticCompounds(node, method, CompoundGetter.METHOD, method,
-        CompoundSetter.INVALID, new AssignmentCompound(operator, rhs), arg);
-  }
-
-  @override
-  R visitUnresolvedCompound(Send node, ErroneousElement element,
-      AssignmentOperator operator, Node rhs, A arg) {
-    return handleStaticCompounds(
-        node,
-        element,
-        CompoundGetter.UNRESOLVED,
-        element,
-        CompoundSetter.INVALID,
-        new AssignmentCompound(operator, rhs),
-        arg);
-  }
-
-  @override
-  R visitFinalLocalVariablePostfix(Send node, LocalVariableElement variable,
-      IncDecOperator operator, A arg) {
-    return handleLocalCompounds(
-        node, variable, new IncDecCompound(CompoundKind.POSTFIX, operator), arg,
-        isSetterValid: false);
-  }
-
-  @override
-  R visitFinalLocalVariablePrefix(Send node, LocalVariableElement variable,
-      IncDecOperator operator, A arg) {
-    return handleLocalCompounds(
-        node, variable, new IncDecCompound(CompoundKind.PREFIX, operator), arg,
-        isSetterValid: false);
-  }
-
-  @override
-  R visitFinalParameterPostfix(
-      Send node, ParameterElement parameter, IncDecOperator operator, A arg) {
-    return handleLocalCompounds(node, parameter,
-        new IncDecCompound(CompoundKind.POSTFIX, operator), arg,
-        isSetterValid: false);
-  }
-
-  @override
-  R visitFinalParameterPrefix(
-      Send node, ParameterElement parameter, IncDecOperator operator, A arg) {
-    return handleLocalCompounds(
-        node, parameter, new IncDecCompound(CompoundKind.PREFIX, operator), arg,
-        isSetterValid: false);
-  }
-
-  @override
-  R visitFinalStaticFieldPostfix(
-      Send node, FieldElement field, IncDecOperator operator, A arg) {
-    return handleStaticCompounds(
-        node,
-        field,
-        CompoundGetter.FIELD,
-        field,
-        CompoundSetter.INVALID,
-        new IncDecCompound(CompoundKind.POSTFIX, operator),
-        arg);
-  }
-
-  @override
-  R visitFinalStaticFieldPrefix(
-      Send node, FieldElement field, IncDecOperator operator, A arg) {
-    return handleStaticCompounds(
-        node,
-        field,
-        CompoundGetter.FIELD,
-        field,
-        CompoundSetter.INVALID,
-        new IncDecCompound(CompoundKind.PREFIX, operator),
-        arg);
-  }
-
-  @override
-  R visitSuperFieldFieldCompound(Send node, FieldElement readField,
-      FieldElement writtenField, AssignmentOperator operator, Node rhs, A arg) {
-    return handleSuperCompounds(
-        node,
-        readField,
-        CompoundGetter.FIELD,
-        writtenField,
-        CompoundSetter.FIELD,
-        new AssignmentCompound(operator, rhs),
-        arg);
-  }
-
-  @override
-  R visitFinalSuperFieldPostfix(
-      Send node, FieldElement field, IncDecOperator operator, A arg) {
-    return handleSuperCompounds(
-        node,
-        field,
-        CompoundGetter.FIELD,
-        field,
-        CompoundSetter.INVALID,
-        new IncDecCompound(CompoundKind.POSTFIX, operator),
-        arg);
-  }
-
-  @override
-  R visitFinalSuperFieldPrefix(
-      Send node, FieldElement field, IncDecOperator operator, A arg) {
-    return handleSuperCompounds(
-        node,
-        field,
-        CompoundGetter.FIELD,
-        field,
-        CompoundSetter.INVALID,
-        new IncDecCompound(CompoundKind.PREFIX, operator),
-        arg);
-  }
-
-  @override
-  R visitSuperMethodCompound(Send node, MethodElement method,
-      AssignmentOperator operator, Node rhs, A arg) {
-    return handleSuperCompounds(node, method, CompoundGetter.METHOD, method,
-        CompoundSetter.INVALID, new AssignmentCompound(operator, rhs), arg);
-  }
-
-  @override
-  R visitSuperMethodPostfix(
-      Send node, MethodElement method, IncDecOperator operator, A arg) {
-    return handleSuperCompounds(
-        node,
-        method,
-        CompoundGetter.METHOD,
-        method,
-        CompoundSetter.INVALID,
-        new IncDecCompound(CompoundKind.POSTFIX, operator),
-        arg);
-  }
-
-  @override
-  R visitSuperMethodPrefix(
-      Send node, MethodElement method, IncDecOperator operator, A arg) {
-    return handleSuperCompounds(
-        node,
-        method,
-        CompoundGetter.METHOD,
-        method,
-        CompoundSetter.INVALID,
-        new IncDecCompound(CompoundKind.PREFIX, operator),
-        arg);
-  }
-
-  @override
-  R visitFinalTopLevelFieldPostfix(
-      Send node, FieldElement field, IncDecOperator operator, A arg) {
-    return handleStaticCompounds(
-        node,
-        field,
-        CompoundGetter.FIELD,
-        field,
-        CompoundSetter.INVALID,
-        new IncDecCompound(CompoundKind.POSTFIX, operator),
-        arg);
-  }
-
-  @override
-  R visitFinalTopLevelFieldPrefix(
-      Send node, FieldElement field, IncDecOperator operator, A arg) {
-    return handleStaticCompounds(
-        node,
-        field,
-        CompoundGetter.FIELD,
-        field,
-        CompoundSetter.INVALID,
-        new IncDecCompound(CompoundKind.PREFIX, operator),
-        arg);
-  }
-
-  @override
-  R visitUnresolvedSuperCompound(Send node, Element element,
-      AssignmentOperator operator, Node rhs, A arg) {
-    return handleSuperCompounds(
-        node,
-        element,
-        CompoundGetter.UNRESOLVED,
-        element,
-        CompoundSetter.INVALID,
-        new AssignmentCompound(operator, rhs),
-        arg);
-  }
-
-  @override
-  R visitUnresolvedSuperPostfix(
-      SendSet node, Element element, IncDecOperator operator, A arg) {
-    return handleSuperCompounds(
-        node,
-        element,
-        CompoundGetter.UNRESOLVED,
-        element,
-        CompoundSetter.INVALID,
-        new IncDecCompound(CompoundKind.POSTFIX, operator),
-        arg);
-  }
-
-  @override
-  R visitUnresolvedSuperPrefix(
-      SendSet node, Element element, IncDecOperator operator, A arg) {
-    return handleSuperCompounds(
-        node,
-        element,
-        CompoundGetter.UNRESOLVED,
-        element,
-        CompoundSetter.INVALID,
-        new IncDecCompound(CompoundKind.PREFIX, operator),
-        arg);
-  }
-
-  @override
-  R visitUnresolvedSuperGetterCompound(SendSet node, Element element,
-      SetterElement setter, AssignmentOperator operator, Node rhs, A arg) {
-    return handleSuperCompounds(
-        node,
-        element,
-        CompoundGetter.UNRESOLVED,
-        setter,
-        CompoundSetter.SETTER,
-        new AssignmentCompound(operator, rhs),
-        arg);
-  }
-
-  @override
-  R visitUnresolvedSuperGetterPostfix(SendSet node, Element element,
-      SetterElement setter, IncDecOperator operator, A arg) {
-    return handleSuperCompounds(
-        node,
-        element,
-        CompoundGetter.UNRESOLVED,
-        setter,
-        CompoundSetter.SETTER,
-        new IncDecCompound(CompoundKind.POSTFIX, operator),
-        arg);
-  }
-
-  @override
-  R visitUnresolvedSuperGetterPrefix(SendSet node, Element element,
-      SetterElement setter, IncDecOperator operator, A arg) {
-    return handleSuperCompounds(
-        node,
-        element,
-        CompoundGetter.UNRESOLVED,
-        setter,
-        CompoundSetter.SETTER,
-        new IncDecCompound(CompoundKind.PREFIX, operator),
-        arg);
-  }
-
-  @override
-  R visitUnresolvedSuperSetterCompound(Send node, GetterElement getter,
-      Element element, AssignmentOperator operator, Node rhs, A arg) {
-    return handleSuperCompounds(node, getter, CompoundGetter.GETTER, element,
-        CompoundSetter.INVALID, new AssignmentCompound(operator, rhs), arg);
-  }
-
-  @override
-  R visitUnresolvedSuperSetterPostfix(SendSet node, GetterElement getter,
-      Element element, IncDecOperator operator, A arg) {
-    return handleSuperCompounds(
-        node,
-        getter,
-        CompoundGetter.GETTER,
-        element,
-        CompoundSetter.INVALID,
-        new IncDecCompound(CompoundKind.POSTFIX, operator),
-        arg);
-  }
-
-  @override
-  R visitUnresolvedSuperSetterPrefix(SendSet node, GetterElement getter,
-      Element element, IncDecOperator operator, A arg) {
-    return handleSuperCompounds(
-        node,
-        getter,
-        CompoundGetter.GETTER,
-        element,
-        CompoundSetter.INVALID,
-        new IncDecCompound(CompoundKind.PREFIX, operator),
-        arg);
-  }
-}
-
-/// Simplified handling of if-null assignments.
-abstract class BaseImplementationOfSetIfNullsMixin<R, A>
-    implements SemanticSendVisitor<R, A> {
-  /// Handle a super if-null assignments, like `super.foo ??= 42`.
-  R handleSuperSetIfNulls(
-      SendSet node,
-      Element getter,
-      CompoundGetter getterKind,
-      Element setter,
-      CompoundSetter setterKind,
-      Node rhs,
-      A arg);
-
-  /// Handle a static or top level if-null assignments, like `foo ??= 42`.
-  R handleStaticSetIfNulls(
-      SendSet node,
-      Element getter,
-      CompoundGetter getterKind,
-      Element setter,
-      CompoundSetter setterKind,
-      Node rhs,
-      A arg);
-
-  /// Handle a local if-null assignments, like `foo ??= 42`. If [isSetterValid]
-  /// is false [local] is unassignable.
-  R handleLocalSetIfNulls(SendSet node, LocalElement local, Node rhs, A arg,
-      {bool isSetterValid});
-
-  /// Handle a if-null assignments on a type literal constant, like
-  /// `Object ??= 42`.
-  R handleTypeLiteralConstantSetIfNulls(
-      SendSet node, ConstantExpression constant, Node rhs, A arg);
-
-  /// Handle a dynamic if-null assignments, like `o.foo ??= 42`. [receiver] is
-  /// `null` for properties on `this`, like `this.foo ??= 42` or `foo ??= 42`.
-  R handleDynamicSetIfNulls(
-      Send node, Node receiver, Name name, Node rhs, A arg);
-
-  @override
-  R visitClassTypeLiteralSetIfNull(
-      Send node, ConstantExpression constant, Node rhs, A arg) {
-    return handleTypeLiteralConstantSetIfNulls(node, constant, rhs, arg);
-  }
-
-  @override
-  R visitDynamicPropertySetIfNull(
-      Send node, Node receiver, Name name, Node rhs, A arg) {
-    return handleDynamicSetIfNulls(node, receiver, name, rhs, arg);
-  }
-
-  @override
-  R visitDynamicTypeLiteralSetIfNull(
-      Send node, ConstantExpression constant, Node rhs, A arg) {
-    return handleTypeLiteralConstantSetIfNulls(node, constant, rhs, arg);
-  }
-
-  @override
-  R visitFinalLocalVariableSetIfNull(
-      Send node, LocalVariableElement variable, Node rhs, A arg) {
-    return handleLocalSetIfNulls(node, variable, rhs, arg,
-        isSetterValid: false);
-  }
-
-  @override
-  R visitFinalParameterSetIfNull(
-      Send node, ParameterElement parameter, Node rhs, A arg) {
-    return handleLocalSetIfNulls(node, parameter, rhs, arg,
-        isSetterValid: false);
-  }
-
-  @override
-  R visitFinalStaticFieldSetIfNull(
-      Send node, FieldElement field, Node rhs, A arg) {
-    return handleStaticSetIfNulls(node, field, CompoundGetter.FIELD, field,
-        CompoundSetter.INVALID, rhs, arg);
-  }
-
-  @override
-  R visitFinalSuperFieldSetIfNull(
-      Send node, FieldElement field, Node rhs, A arg) {
-    return handleSuperSetIfNulls(node, field, CompoundGetter.FIELD, field,
-        CompoundSetter.INVALID, rhs, arg);
-  }
-
-  @override
-  R visitFinalTopLevelFieldSetIfNull(
-      Send node, FieldElement field, Node rhs, A arg) {
-    return handleStaticSetIfNulls(node, field, CompoundGetter.FIELD, field,
-        CompoundSetter.INVALID, rhs, arg);
-  }
-
-  @override
-  R visitIfNotNullDynamicPropertySetIfNull(
-      Send node, Node receiver, Name name, Node rhs, A arg) {
-    return handleDynamicSetIfNulls(node, receiver, name, rhs, arg);
-  }
-
-  @override
-  R visitLocalFunctionSetIfNull(
-      Send node, LocalFunctionElement function, Node rhs, A arg) {
-    return handleLocalSetIfNulls(node, function, rhs, arg,
-        isSetterValid: false);
-  }
-
-  @override
-  R visitLocalVariableSetIfNull(
-      Send node, LocalVariableElement variable, Node rhs, A arg) {
-    return handleLocalSetIfNulls(node, variable, rhs, arg, isSetterValid: true);
-  }
-
-  @override
-  R visitParameterSetIfNull(
-      Send node, ParameterElement parameter, Node rhs, A arg) {
-    return handleLocalSetIfNulls(node, parameter, rhs, arg,
-        isSetterValid: true);
-  }
-
-  @override
-  R visitStaticFieldSetIfNull(Send node, FieldElement field, Node rhs, A arg) {
-    return handleStaticSetIfNulls(node, field, CompoundGetter.FIELD, field,
-        CompoundSetter.FIELD, rhs, arg);
-  }
-
-  @override
-  R visitStaticGetterSetterSetIfNull(
-      Send node, GetterElement getter, SetterElement setter, Node rhs, A arg) {
-    return handleStaticSetIfNulls(node, getter, CompoundGetter.GETTER, setter,
-        CompoundSetter.SETTER, rhs, arg);
-  }
-
-  @override
-  R visitStaticMethodSetIfNull(
-      Send node, FunctionElement method, Node rhs, A arg) {
-    return handleStaticSetIfNulls(node, method, CompoundGetter.METHOD, method,
-        CompoundSetter.INVALID, rhs, arg);
-  }
-
-  @override
-  R visitStaticMethodSetterSetIfNull(
-      Send node, MethodElement method, MethodElement setter, Node rhs, A arg) {
-    return handleStaticSetIfNulls(node, method, CompoundGetter.METHOD, setter,
-        CompoundSetter.SETTER, rhs, arg);
-  }
-
-  @override
-  R visitSuperFieldFieldSetIfNull(Send node, FieldElement readField,
-      FieldElement writtenField, Node rhs, A arg) {
-    return handleSuperSetIfNulls(node, readField, CompoundGetter.FIELD,
-        writtenField, CompoundSetter.FIELD, rhs, arg);
-  }
-
-  @override
-  R visitSuperFieldSetIfNull(Send node, FieldElement field, Node rhs, A arg) {
-    return handleSuperSetIfNulls(node, field, CompoundGetter.FIELD, field,
-        CompoundSetter.FIELD, rhs, arg);
-  }
-
-  @override
-  R visitSuperFieldSetterSetIfNull(
-      Send node, FieldElement field, SetterElement setter, Node rhs, A arg) {
-    return handleSuperSetIfNulls(node, field, CompoundGetter.FIELD, setter,
-        CompoundSetter.SETTER, rhs, arg);
-  }
-
-  @override
-  R visitSuperGetterFieldSetIfNull(
-      Send node, GetterElement getter, FieldElement field, Node rhs, A arg) {
-    return handleSuperSetIfNulls(node, getter, CompoundGetter.GETTER, field,
-        CompoundSetter.FIELD, rhs, arg);
-  }
-
-  @override
-  R visitSuperGetterSetterSetIfNull(
-      Send node, GetterElement getter, SetterElement setter, Node rhs, A arg) {
-    return handleSuperSetIfNulls(node, getter, CompoundGetter.GETTER, setter,
-        CompoundSetter.SETTER, rhs, arg);
-  }
-
-  @override
-  R visitSuperMethodSetIfNull(
-      Send node, FunctionElement method, Node rhs, A arg) {
-    return handleSuperSetIfNulls(node, method, CompoundGetter.METHOD, method,
-        CompoundSetter.INVALID, rhs, arg);
-  }
-
-  @override
-  R visitSuperMethodSetterSetIfNull(Send node, FunctionElement method,
-      SetterElement setter, Node rhs, A arg) {
-    return handleSuperSetIfNulls(node, method, CompoundGetter.METHOD, setter,
-        CompoundSetter.SETTER, rhs, arg);
-  }
-
-  @override
-  R visitThisPropertySetIfNull(Send node, Name name, Node rhs, A arg) {
-    return handleDynamicSetIfNulls(node, null, name, rhs, arg);
-  }
-
-  @override
-  R visitTopLevelFieldSetIfNull(
-      Send node, FieldElement field, Node rhs, A arg) {
-    return handleStaticSetIfNulls(node, field, CompoundGetter.FIELD, field,
-        CompoundSetter.FIELD, rhs, arg);
-  }
-
-  @override
-  R visitTopLevelGetterSetterSetIfNull(
-      Send node, GetterElement getter, SetterElement setter, Node rhs, A arg) {
-    return handleStaticSetIfNulls(node, getter, CompoundGetter.GETTER, setter,
-        CompoundSetter.SETTER, rhs, arg);
-  }
-
-  @override
-  R visitTopLevelMethodSetIfNull(
-      Send node, FunctionElement method, Node rhs, A arg) {
-    return handleStaticSetIfNulls(node, method, CompoundGetter.METHOD, method,
-        CompoundSetter.INVALID, rhs, arg);
-  }
-
-  @override
-  R visitTopLevelMethodSetterSetIfNull(Send node, FunctionElement method,
-      SetterElement setter, Node rhs, A arg) {
-    return handleStaticSetIfNulls(node, method, CompoundGetter.METHOD, setter,
-        CompoundSetter.SETTER, rhs, arg);
-  }
-
-  @override
-  R visitTypedefTypeLiteralSetIfNull(
-      Send node, ConstantExpression constant, Node rhs, A arg) {
-    return handleTypeLiteralConstantSetIfNulls(node, constant, rhs, arg);
-  }
-
-  @override
-  R visitUnresolvedSetIfNull(Send node, Element element, Node rhs, A arg) {
-    return handleStaticSetIfNulls(node, element, CompoundGetter.UNRESOLVED,
-        element, CompoundSetter.INVALID, rhs, arg);
-  }
-
-  @override
-  R visitUnresolvedStaticGetterSetIfNull(
-      Send node, Element element, MethodElement setter, Node rhs, A arg) {
-    return handleStaticSetIfNulls(node, element, CompoundGetter.UNRESOLVED,
-        setter, CompoundSetter.SETTER, rhs, arg);
-  }
-
-  @override
-  R visitUnresolvedStaticSetterSetIfNull(
-      Send node, GetterElement getter, Element element, Node rhs, A arg) {
-    return handleStaticSetIfNulls(node, getter, CompoundGetter.GETTER, element,
-        CompoundSetter.INVALID, rhs, arg);
-  }
-
-  @override
-  R visitUnresolvedSuperGetterSetIfNull(
-      Send node, Element element, MethodElement setter, Node rhs, A arg) {
-    return handleSuperSetIfNulls(node, element, CompoundGetter.UNRESOLVED,
-        setter, CompoundSetter.SETTER, rhs, arg);
-  }
-
-  @override
-  R visitUnresolvedSuperSetIfNull(Send node, Element element, Node rhs, A arg) {
-    return handleSuperSetIfNulls(node, element, CompoundGetter.UNRESOLVED,
-        element, CompoundSetter.INVALID, rhs, arg);
-  }
-
-  @override
-  R visitUnresolvedSuperSetterSetIfNull(
-      Send node, GetterElement getter, Element element, Node rhs, A arg) {
-    return handleSuperSetIfNulls(node, getter, CompoundGetter.GETTER, element,
-        CompoundSetter.INVALID, rhs, arg);
-  }
-
-  @override
-  R visitUnresolvedTopLevelGetterSetIfNull(
-      Send node, Element element, MethodElement setter, Node rhs, A arg) {
-    return handleStaticSetIfNulls(node, element, CompoundGetter.UNRESOLVED,
-        setter, CompoundSetter.SETTER, rhs, arg);
-  }
-
-  @override
-  R visitUnresolvedTopLevelSetterSetIfNull(
-      Send node, GetterElement getter, Element element, Node rhs, A arg) {
-    return handleStaticSetIfNulls(node, getter, CompoundGetter.GETTER, element,
-        CompoundSetter.INVALID, rhs, arg);
-  }
-}
-
-/// Simplified handling of indexed compound assignments and prefix/postfix
-/// expressions.
-abstract class BaseImplementationOfIndexCompoundsMixin<R, A>
-    implements SemanticSendVisitor<R, A> {
-  /// Handle a dynamic index compounds, like `receiver[index] += rhs` or
-  /// `--receiver[index]`.
-  R handleIndexCompounds(
-      SendSet node, Node receiver, Node index, CompoundRhs rhs, A arg);
-
-  /// Handle a super index compounds, like `super[index] += rhs` or
-  /// `--super[index]`.
-  R handleSuperIndexCompounds(SendSet node, Element indexFunction,
-      Element indexSetFunction, Node index, CompoundRhs rhs, A arg,
-      {bool isGetterValid, bool isSetterValid});
-
-  @override
-  R visitSuperCompoundIndexSet(
-      Send node,
-      MethodElement indexFunction,
-      MethodElement indexSetFunction,
-      Node index,
-      AssignmentOperator operator,
-      Node rhs,
-      A arg) {
-    return handleSuperIndexCompounds(node, indexFunction, indexSetFunction,
-        index, new AssignmentCompound(operator, rhs), arg,
-        isGetterValid: true, isSetterValid: true);
-  }
-
-  @override
-  R visitSuperIndexPostfix(
-      Send node,
-      MethodElement indexFunction,
-      MethodElement indexSetFunction,
-      Node index,
-      IncDecOperator operator,
-      A arg) {
-    return handleSuperIndexCompounds(node, indexFunction, indexSetFunction,
-        index, new IncDecCompound(CompoundKind.POSTFIX, operator), arg,
-        isGetterValid: true, isSetterValid: true);
-  }
-
-  @override
-  R visitSuperIndexPrefix(
-      Send node,
-      MethodElement indexFunction,
-      MethodElement indexSetFunction,
-      Node index,
-      IncDecOperator operator,
-      A arg) {
-    return handleSuperIndexCompounds(node, indexFunction, indexSetFunction,
-        index, new IncDecCompound(CompoundKind.PREFIX, operator), arg,
-        isGetterValid: true, isSetterValid: true);
-  }
-
-  @override
-  R visitUnresolvedSuperGetterCompoundIndexSet(
-      SendSet node,
-      Element indexFunction,
-      FunctionElement indexSetFunction,
-      Node index,
-      AssignmentOperator operator,
-      Node rhs,
-      A arg) {
-    return handleSuperIndexCompounds(node, indexFunction, indexSetFunction,
-        index, new AssignmentCompound(operator, rhs), arg,
-        isGetterValid: false, isSetterValid: true);
-  }
-
-  @override
-  R visitUnresolvedSuperSetterCompoundIndexSet(
-      SendSet node,
-      MethodElement indexFunction,
-      Element indexSetFunction,
-      Node index,
-      AssignmentOperator operator,
-      Node rhs,
-      A arg) {
-    return handleSuperIndexCompounds(node, indexFunction, indexSetFunction,
-        index, new AssignmentCompound(operator, rhs), arg,
-        isGetterValid: true, isSetterValid: false);
-  }
-
-  @override
-  R visitUnresolvedSuperCompoundIndexSet(SendSet node, Element element,
-      Node index, AssignmentOperator operator, Node rhs, A arg) {
-    return handleSuperIndexCompounds(node, element, element, index,
-        new AssignmentCompound(operator, rhs), arg,
-        isGetterValid: false, isSetterValid: false);
-  }
-
-  @override
-  R visitUnresolvedSuperGetterIndexPostfix(
-      SendSet node,
-      Element element,
-      FunctionElement indexSetFunction,
-      Node index,
-      IncDecOperator operator,
-      A arg) {
-    return handleSuperIndexCompounds(node, element, indexSetFunction, index,
-        new IncDecCompound(CompoundKind.POSTFIX, operator), arg,
-        isGetterValid: false, isSetterValid: true);
-  }
-
-  @override
-  R visitUnresolvedSuperGetterIndexPrefix(
-      SendSet node,
-      Element element,
-      FunctionElement indexSetFunction,
-      Node index,
-      IncDecOperator operator,
-      A arg) {
-    return handleSuperIndexCompounds(node, element, indexSetFunction, index,
-        new IncDecCompound(CompoundKind.PREFIX, operator), arg,
-        isGetterValid: false, isSetterValid: true);
-  }
-
-  @override
-  R visitUnresolvedSuperSetterIndexPostfix(
-      SendSet node,
-      MethodElement indexFunction,
-      Element element,
-      Node index,
-      IncDecOperator operator,
-      A arg) {
-    return handleSuperIndexCompounds(node, indexFunction, element, index,
-        new IncDecCompound(CompoundKind.POSTFIX, operator), arg,
-        isGetterValid: true, isSetterValid: false);
-  }
-
-  @override
-  R visitUnresolvedSuperSetterIndexPrefix(
-      SendSet node,
-      MethodElement indexFunction,
-      Element element,
-      Node index,
-      IncDecOperator operator,
-      A arg) {
-    return handleSuperIndexCompounds(node, indexFunction, element, index,
-        new IncDecCompound(CompoundKind.PREFIX, operator), arg,
-        isGetterValid: true, isSetterValid: false);
-  }
-
-  @override
-  R visitUnresolvedSuperIndexPostfix(
-      Send node, Element element, Node index, IncDecOperator operator, A arg) {
-    return handleSuperIndexCompounds(node, element, element, index,
-        new IncDecCompound(CompoundKind.POSTFIX, operator), arg,
-        isGetterValid: false, isSetterValid: false);
-  }
-
-  @override
-  R visitUnresolvedSuperIndexPrefix(
-      Send node, Element element, Node index, IncDecOperator operator, A arg) {
-    return handleSuperIndexCompounds(node, element, element, index,
-        new IncDecCompound(CompoundKind.PREFIX, operator), arg,
-        isGetterValid: false, isSetterValid: false);
-  }
-
-  @override
-  R visitCompoundIndexSet(SendSet node, Node receiver, Node index,
-      AssignmentOperator operator, Node rhs, A arg) {
-    return handleIndexCompounds(
-        node, receiver, index, new AssignmentCompound(operator, rhs), arg);
-  }
-
-  @override
-  R visitIndexPostfix(
-      Send node, Node receiver, Node index, IncDecOperator operator, A arg) {
-    return handleIndexCompounds(node, receiver, index,
-        new IncDecCompound(CompoundKind.POSTFIX, operator), arg);
-  }
-
-  @override
-  R visitIndexPrefix(
-      Send node, Node receiver, Node index, IncDecOperator operator, A arg) {
-    return handleIndexCompounds(node, receiver, index,
-        new IncDecCompound(CompoundKind.PREFIX, operator), arg);
-  }
-}
-
-/// Simplified handling of super if-null assignments.
-abstract class BaseImplementationOfSuperIndexSetIfNullMixin<R, A>
-    implements SemanticSendVisitor<R, A> {
-  /// Handle a super index if-null assignments, like `super[index] ??= rhs`.
-  R handleSuperIndexSetIfNull(SendSet node, Element indexFunction,
-      Element indexSetFunction, Node index, Node rhs, A arg,
-      {bool isGetterValid, bool isSetterValid});
-
-  @override
-  R visitSuperIndexSetIfNull(Send node, FunctionElement indexFunction,
-      FunctionElement indexSetFunction, Node index, Node rhs, A arg) {
-    return handleSuperIndexSetIfNull(
-        node, indexFunction, indexSetFunction, index, rhs, arg,
-        isGetterValid: true, isSetterValid: true);
-  }
-
-  @override
-  R visitUnresolvedSuperGetterIndexSetIfNull(
-      SendSet node,
-      Element indexFunction,
-      FunctionElement indexSetFunction,
-      Node index,
-      Node rhs,
-      A arg) {
-    return handleSuperIndexSetIfNull(
-        node, indexFunction, indexSetFunction, index, rhs, arg,
-        isGetterValid: false, isSetterValid: true);
-  }
-
-  @override
-  R visitUnresolvedSuperSetterIndexSetIfNull(
-      SendSet node,
-      MethodElement indexFunction,
-      Element indexSetFunction,
-      Node index,
-      Node rhs,
-      A arg) {
-    return handleSuperIndexSetIfNull(
-        node, indexFunction, indexSetFunction, index, rhs, arg,
-        isGetterValid: true, isSetterValid: false);
-  }
-
-  @override
-  R visitUnresolvedSuperIndexSetIfNull(
-      Send node, Element element, Node index, Node rhs, A arg) {
-    return handleSuperIndexSetIfNull(node, element, element, index, rhs, arg,
-        isGetterValid: false, isSetterValid: false);
-  }
-}
-
-/// Mixin that groups all `visitSuperXPrefix`, `visitSuperXPostfix` methods by
-/// delegating calls to `handleSuperXPostfixPrefix` methods.
-///
-/// This mixin is useful for the cases where super prefix/postfix expression are
-/// handled uniformly.
-abstract class BaseImplementationOfSuperIncDecsMixin<R, A>
-    implements SemanticSendVisitor<R, A> {
-  R handleSuperFieldFieldPostfixPrefix(Send node, FieldElement readField,
-      FieldElement writtenField, IncDecOperator operator, A arg,
-      {bool isPrefix});
-
-  R handleSuperFieldSetterPostfixPrefix(Send node, FieldElement field,
-      SetterElement setter, IncDecOperator operator, A arg,
-      {bool isPrefix});
-
-  R handleSuperGetterFieldPostfixPrefix(Send node, GetterElement getter,
-      FieldElement field, IncDecOperator operator, A arg,
-      {bool isPrefix});
-
-  R handleSuperGetterSetterPostfixPrefix(Send node, GetterElement getter,
-      SetterElement setter, IncDecOperator operator, A arg,
-      {bool isPrefix});
-
-  R handleSuperMethodSetterPostfixPrefix(Send node, FunctionElement method,
-      SetterElement setter, IncDecOperator operator, A arg,
-      {bool isPrefix});
-
-  R handleSuperIndexPostfixPrefix(
-      Send node,
-      FunctionElement indexFunction,
-      FunctionElement indexSetFunction,
-      Node index,
-      IncDecOperator operator,
-      A arg,
-      {bool isPrefix});
-
-  R handleUnresolvedSuperGetterIndexPostfixPrefix(Send node, Element element,
-      MethodElement setter, Node index, IncDecOperator operator, A arg,
-      {bool isPrefix});
-
-  R handleUnresolvedSuperSetterIndexPostfixPrefix(
-      Send node,
-      FunctionElement indexFunction,
-      Element element,
-      Node index,
-      IncDecOperator operator,
-      A arg,
-      {bool isPrefix});
-
-  R handleUnresolvedSuperIndexPostfixPrefix(
-      Send node, Element element, Node index, IncDecOperator operator, A arg,
-      {bool isPrefix});
-
-  R handleFinalSuperFieldPostfixPrefix(
-      Send node, FieldElement field, IncDecOperator operator, A arg,
-      {bool isPrefix});
-
-  R handleSuperMethodPostfixPrefix(
-      Send node, MethodElement method, IncDecOperator operator, A arg,
-      {bool isPrefix});
-
-  R handleUnresolvedSuperPostfixPrefix(
-      Send node, Element element, IncDecOperator operator, A arg,
-      {bool isPrefix});
-
-  R handleUnresolvedSuperGetterPostfixPrefix(Send node, Element element,
-      MethodElement setter, IncDecOperator operator, A arg,
-      {bool isPrefix});
-
-  R handleUnresolvedSuperSetterPostfixPrefix(Send node, GetterElement getter,
-      Element element, IncDecOperator operator, A arg,
-      {bool isPrefix});
-
-  @override
-  R visitSuperFieldFieldPostfix(SendSet node, FieldElement readField,
-      FieldElement writtenField, IncDecOperator operator, A arg) {
-    return handleSuperFieldFieldPostfixPrefix(
-        node, readField, writtenField, operator, arg,
-        isPrefix: false);
-  }
-
-  @override
-  R visitSuperFieldFieldPrefix(SendSet node, FieldElement readField,
-      FieldElement writtenField, IncDecOperator operator, A arg) {
-    return handleSuperFieldFieldPostfixPrefix(
-        node, readField, writtenField, operator, arg,
-        isPrefix: true);
-  }
-
-  @override
-  R visitSuperFieldPostfix(
-      SendSet node, FieldElement field, IncDecOperator operator, A arg) {
-    return handleSuperFieldFieldPostfixPrefix(node, field, field, operator, arg,
-        isPrefix: false);
-  }
-
-  @override
-  R visitSuperFieldPrefix(
-      SendSet node, FieldElement field, IncDecOperator operator, A arg) {
-    return handleSuperFieldFieldPostfixPrefix(node, field, field, operator, arg,
-        isPrefix: true);
-  }
-
-  @override
-  R visitSuperFieldSetterPostfix(SendSet node, FieldElement field,
-      SetterElement setter, IncDecOperator operator, A arg) {
-    return handleSuperFieldSetterPostfixPrefix(
-        node, field, setter, operator, arg,
-        isPrefix: false);
-  }
-
-  @override
-  R visitSuperFieldSetterPrefix(SendSet node, FieldElement field,
-      SetterElement setter, IncDecOperator operator, A arg) {
-    return handleSuperFieldSetterPostfixPrefix(
-        node, field, setter, operator, arg,
-        isPrefix: true);
-  }
-
-  @override
-  R visitSuperGetterFieldPostfix(SendSet node, GetterElement getter,
-      FieldElement field, IncDecOperator operator, A arg) {
-    return handleSuperGetterFieldPostfixPrefix(
-        node, getter, field, operator, arg,
-        isPrefix: false);
-  }
-
-  @override
-  R visitSuperGetterFieldPrefix(SendSet node, GetterElement getter,
-      FieldElement field, IncDecOperator operator, A arg) {
-    return handleSuperGetterFieldPostfixPrefix(
-        node, getter, field, operator, arg,
-        isPrefix: true);
-  }
-
-  @override
-  R visitSuperGetterSetterPostfix(SendSet node, GetterElement getter,
-      SetterElement setter, IncDecOperator operator, A arg) {
-    return handleSuperGetterSetterPostfixPrefix(
-        node, getter, setter, operator, arg,
-        isPrefix: false);
-  }
-
-  @override
-  R visitSuperGetterSetterPrefix(SendSet node, GetterElement getter,
-      SetterElement setter, IncDecOperator operator, A arg) {
-    return handleSuperGetterSetterPostfixPrefix(
-        node, getter, setter, operator, arg,
-        isPrefix: true);
-  }
-
-  @override
-  R visitSuperMethodSetterPostfix(SendSet node, FunctionElement method,
-      SetterElement setter, IncDecOperator operator, A arg) {
-    return handleSuperMethodSetterPostfixPrefix(
-        node, method, setter, operator, arg,
-        isPrefix: false);
-  }
-
-  @override
-  R visitSuperMethodSetterPrefix(SendSet node, FunctionElement method,
-      SetterElement setter, IncDecOperator operator, A arg) {
-    return handleSuperMethodSetterPostfixPrefix(
-        node, method, setter, operator, arg,
-        isPrefix: true);
-  }
-
-  @override
-  R visitSuperIndexPostfix(
-      Send node,
-      MethodElement indexFunction,
-      MethodElement indexSetFunction,
-      Node index,
-      IncDecOperator operator,
-      A arg) {
-    return handleSuperIndexPostfixPrefix(
-        node, indexFunction, indexSetFunction, index, operator, arg,
-        isPrefix: false);
-  }
-
-  @override
-  R visitSuperIndexPrefix(
-      Send node,
-      MethodElement indexFunction,
-      MethodElement indexSetFunction,
-      Node index,
-      IncDecOperator operator,
-      A arg) {
-    return handleSuperIndexPostfixPrefix(
-        node, indexFunction, indexSetFunction, index, operator, arg,
-        isPrefix: true);
-  }
-
-  @override
-  R visitUnresolvedSuperGetterIndexPostfix(SendSet node, Element element,
-      MethodElement setter, Node index, IncDecOperator operator, A arg) {
-    return handleUnresolvedSuperGetterIndexPostfixPrefix(
-        node, element, setter, index, operator, arg,
-        isPrefix: false);
-  }
-
-  @override
-  R visitUnresolvedSuperGetterIndexPrefix(SendSet node, Element element,
-      MethodElement setter, Node index, IncDecOperator operator, A arg) {
-    return handleUnresolvedSuperGetterIndexPostfixPrefix(
-        node, element, setter, index, operator, arg,
-        isPrefix: true);
-  }
-
-  @override
-  R visitUnresolvedSuperSetterIndexPostfix(
-      SendSet node,
-      MethodElement indexFunction,
-      Element element,
-      Node index,
-      IncDecOperator operator,
-      A arg) {
-    return handleUnresolvedSuperSetterIndexPostfixPrefix(
-        node, indexFunction, element, index, operator, arg,
-        isPrefix: false);
-  }
-
-  @override
-  R visitUnresolvedSuperSetterIndexPrefix(
-      SendSet node,
-      MethodElement indexFunction,
-      Element element,
-      Node index,
-      IncDecOperator operator,
-      A arg) {
-    return handleUnresolvedSuperSetterIndexPostfixPrefix(
-        node, indexFunction, element, index, operator, arg,
-        isPrefix: true);
-  }
-
-  @override
-  R visitUnresolvedSuperIndexPostfix(
-      Send node, Element element, Node index, IncDecOperator operator, A arg) {
-    return handleUnresolvedSuperIndexPostfixPrefix(
-        node, element, index, operator, arg,
-        isPrefix: false);
-  }
-
-  @override
-  R visitUnresolvedSuperIndexPrefix(
-      Send node, Element element, Node index, IncDecOperator operator, A arg) {
-    return handleUnresolvedSuperIndexPostfixPrefix(
-        node, element, index, operator, arg,
-        isPrefix: true);
-  }
-
-  @override
-  R visitFinalSuperFieldPostfix(
-      Send node, FieldElement field, IncDecOperator operator, A arg) {
-    return handleFinalSuperFieldPostfixPrefix(node, field, operator, arg,
-        isPrefix: false);
-  }
-
-  @override
-  R visitFinalSuperFieldPrefix(
-      Send node, FieldElement field, IncDecOperator operator, A arg) {
-    return handleFinalSuperFieldPostfixPrefix(node, field, operator, arg,
-        isPrefix: true);
-  }
-
-  @override
-  R visitSuperMethodPostfix(
-      Send node, MethodElement method, IncDecOperator operator, A arg) {
-    return handleSuperMethodPostfixPrefix(node, method, operator, arg,
-        isPrefix: false);
-  }
-
-  @override
-  R visitSuperMethodPrefix(
-      Send node, MethodElement method, IncDecOperator operator, A arg) {
-    return handleSuperMethodPostfixPrefix(node, method, operator, arg,
-        isPrefix: true);
-  }
-
-  @override
-  R visitUnresolvedSuperPostfix(
-      SendSet node, Element element, IncDecOperator operator, A arg) {
-    return handleUnresolvedSuperPostfixPrefix(node, element, operator, arg,
-        isPrefix: false);
-  }
-
-  @override
-  R visitUnresolvedSuperPrefix(
-      Send node, Element element, IncDecOperator operator, A arg) {
-    return handleUnresolvedSuperPostfixPrefix(node, element, operator, arg,
-        isPrefix: true);
-  }
-
-  @override
-  R visitUnresolvedSuperGetterPostfix(SendSet node, Element element,
-      SetterElement setter, IncDecOperator operator, A arg) {
-    return handleUnresolvedSuperGetterPostfixPrefix(
-        node, element, setter, operator, arg,
-        isPrefix: false);
-  }
-
-  @override
-  R visitUnresolvedSuperGetterPrefix(SendSet node, Element element,
-      SetterElement setter, IncDecOperator operator, A arg) {
-    return handleUnresolvedSuperGetterPostfixPrefix(
-        node, element, setter, operator, arg,
-        isPrefix: true);
-  }
-
-  @override
-  R visitUnresolvedSuperSetterPostfix(SendSet node, GetterElement getter,
-      Element element, IncDecOperator operator, A arg) {
-    return handleUnresolvedSuperSetterPostfixPrefix(
-        node, getter, element, operator, arg,
-        isPrefix: false);
-  }
-
-  @override
-  R visitUnresolvedSuperSetterPrefix(SendSet node, GetterElement getter,
-      Element element, IncDecOperator operator, A arg) {
-    return handleUnresolvedSuperSetterPostfixPrefix(
-        node, getter, element, operator, arg,
-        isPrefix: true);
-  }
-}
-
-/// Mixin that groups the non-constant `visitXConstructorInvoke` methods by
-/// delegating calls to the `handleConstructorInvoke` method.
-///
-/// This mixin is useful for the cases where all constructor invocations are
-/// handled uniformly.
-abstract class BaseImplementationOfNewMixin<R, A>
-    implements SemanticSendVisitor<R, A> {
-  R handleConstructorInvoke(
-      NewExpression node,
-      ConstructorElement constructor,
-      ResolutionDartType type,
-      NodeList arguments,
-      CallStructure callStructure,
-      A arg);
-
-  R visitGenerativeConstructorInvoke(
-      NewExpression node,
-      ConstructorElement constructor,
-      ResolutionInterfaceType type,
-      NodeList arguments,
-      CallStructure callStructure,
-      A arg) {
-    return handleConstructorInvoke(
-        node, constructor, type, arguments, callStructure, arg);
-  }
-
-  @override
-  R visitRedirectingGenerativeConstructorInvoke(
-      NewExpression node,
-      ConstructorElement constructor,
-      ResolutionInterfaceType type,
-      NodeList arguments,
-      CallStructure callStructure,
-      A arg) {
-    return handleConstructorInvoke(
-        node, constructor, type, arguments, callStructure, arg);
-  }
-
-  @override
-  R visitFactoryConstructorInvoke(
-      NewExpression node,
-      ConstructorElement constructor,
-      ResolutionInterfaceType type,
-      NodeList arguments,
-      CallStructure callStructure,
-      A arg) {
-    return handleConstructorInvoke(
-        node, constructor, type, arguments, callStructure, arg);
-  }
-
-  @override
-  R visitRedirectingFactoryConstructorInvoke(
-      NewExpression node,
-      ConstructorElement constructor,
-      ResolutionInterfaceType type,
-      ConstructorElement effectiveTarget,
-      ResolutionInterfaceType effectiveTargetType,
-      NodeList arguments,
-      CallStructure callStructure,
-      A arg) {
-    return handleConstructorInvoke(
-        node, constructor, type, arguments, callStructure, arg);
-  }
-
-  @override
-  R visitUnresolvedConstructorInvoke(NewExpression node, Element constructor,
-      ResolutionDartType type, NodeList arguments, Selector selector, A arg) {
-    return handleConstructorInvoke(
-        node, constructor, type, arguments, selector.callStructure, arg);
-  }
-
-  @override
-  R visitUnresolvedClassConstructorInvoke(
-      NewExpression node,
-      ErroneousElement element,
-      ResolutionDartType type,
-      NodeList arguments,
-      Selector selector,
-      A arg) {
-    return handleConstructorInvoke(
-        node, element, type, arguments, selector.callStructure, arg);
-  }
-
-  @override
-  R visitAbstractClassConstructorInvoke(
-      NewExpression node,
-      ConstructorElement constructor,
-      ResolutionInterfaceType type,
-      NodeList arguments,
-      CallStructure callStructure,
-      A arg) {
-    return handleConstructorInvoke(
-        node, constructor, type, arguments, callStructure, arg);
-  }
-
-  @override
-  R visitUnresolvedRedirectingFactoryConstructorInvoke(
-      NewExpression node,
-      ConstructorElement constructor,
-      ResolutionInterfaceType type,
-      NodeList arguments,
-      CallStructure callStructure,
-      A arg) {
-    return handleConstructorInvoke(
-        node, constructor, type, arguments, callStructure, arg);
-  }
-}
diff --git a/pkg/compiler/lib/src/resolution/send_resolver.dart b/pkg/compiler/lib/src/resolution/send_resolver.dart
deleted file mode 100644
index f9e8cf0..0000000
--- a/pkg/compiler/lib/src/resolution/send_resolver.dart
+++ /dev/null
@@ -1,336 +0,0 @@
-// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library dart2js.semantics_visitor.resolver;
-
-import '../common.dart';
-import '../constants/expressions.dart';
-import '../elements/resolution_types.dart';
-import '../elements/elements.dart';
-import '../tree/tree.dart';
-import 'semantic_visitor.dart';
-import 'send_structure.dart';
-import 'tree_elements.dart';
-
-abstract class DeclStructure<R, A> {
-  final FunctionElement element;
-
-  DeclStructure(this.element);
-
-  /// Calls the matching visit method on [visitor] with [node] and [arg].
-  R dispatch(
-      SemanticDeclarationVisitor<R, A> visitor, FunctionExpression node, A arg);
-}
-
-enum ConstructorKind {
-  GENERATIVE,
-  REDIRECTING_GENERATIVE,
-  FACTORY,
-  REDIRECTING_FACTORY,
-}
-
-class ConstructorDeclStructure<R, A> extends DeclStructure<R, A> {
-  final ConstructorKind kind;
-
-  ConstructorDeclStructure(this.kind, ConstructorElement constructor)
-      : super(constructor);
-
-  R dispatch(SemanticDeclarationVisitor<R, A> visitor, FunctionExpression node,
-      A arg) {
-    switch (kind) {
-      case ConstructorKind.GENERATIVE:
-        return visitor.visitGenerativeConstructorDeclaration(
-            node, element, node.parameters, node.initializers, node.body, arg);
-      case ConstructorKind.REDIRECTING_GENERATIVE:
-        return visitor.visitRedirectingGenerativeConstructorDeclaration(
-            node, element, node.parameters, node.initializers, arg);
-      case ConstructorKind.FACTORY:
-        return visitor.visitFactoryConstructorDeclaration(
-            node, element, node.parameters, node.body, arg);
-      default:
-        break;
-    }
-    throw failedAt(node, "Unhandled constructor declaration kind: ${kind}");
-  }
-}
-
-class RedirectingFactoryConstructorDeclStructure<R, A>
-    extends DeclStructure<R, A> {
-  ResolutionInterfaceType redirectionTargetType;
-  ConstructorElement redirectionTarget;
-
-  RedirectingFactoryConstructorDeclStructure(ConstructorElement constructor,
-      this.redirectionTargetType, this.redirectionTarget)
-      : super(constructor);
-
-  R dispatch(SemanticDeclarationVisitor<R, A> visitor, FunctionExpression node,
-      A arg) {
-    return visitor.visitRedirectingFactoryConstructorDeclaration(node, element,
-        node.parameters, redirectionTargetType, redirectionTarget, arg);
-  }
-}
-
-enum FunctionKind {
-  TOP_LEVEL_GETTER,
-  TOP_LEVEL_SETTER,
-  TOP_LEVEL_FUNCTION,
-  STATIC_GETTER,
-  STATIC_SETTER,
-  STATIC_FUNCTION,
-  ABSTRACT_GETTER,
-  ABSTRACT_SETTER,
-  ABSTRACT_METHOD,
-  INSTANCE_GETTER,
-  INSTANCE_SETTER,
-  INSTANCE_METHOD,
-  LOCAL_FUNCTION,
-  CLOSURE,
-}
-
-class FunctionDeclStructure<R, A> extends DeclStructure<R, A> {
-  final FunctionKind kind;
-
-  FunctionDeclStructure(this.kind, FunctionElement function) : super(function);
-
-  // ignore: MISSING_RETURN
-  R dispatch(SemanticDeclarationVisitor<R, A> visitor, FunctionExpression node,
-      A arg) {
-    switch (kind) {
-      case FunctionKind.TOP_LEVEL_GETTER:
-        return visitor.visitTopLevelGetterDeclaration(
-            node, element, node.body, arg);
-      case FunctionKind.TOP_LEVEL_SETTER:
-        return visitor.visitTopLevelSetterDeclaration(
-            node, element, node.parameters, node.body, arg);
-      case FunctionKind.TOP_LEVEL_FUNCTION:
-        return visitor.visitTopLevelFunctionDeclaration(
-            node, element, node.parameters, node.body, arg);
-      case FunctionKind.STATIC_GETTER:
-        return visitor.visitStaticGetterDeclaration(
-            node, element, node.body, arg);
-      case FunctionKind.STATIC_SETTER:
-        return visitor.visitStaticSetterDeclaration(
-            node, element, node.parameters, node.body, arg);
-      case FunctionKind.STATIC_FUNCTION:
-        return visitor.visitStaticFunctionDeclaration(
-            node, element, node.parameters, node.body, arg);
-      case FunctionKind.ABSTRACT_GETTER:
-        return visitor.visitAbstractGetterDeclaration(node, element, arg);
-      case FunctionKind.ABSTRACT_SETTER:
-        return visitor.visitAbstractSetterDeclaration(
-            node, element, node.parameters, arg);
-      case FunctionKind.ABSTRACT_METHOD:
-        return visitor.visitAbstractMethodDeclaration(
-            node, element, node.parameters, arg);
-      case FunctionKind.INSTANCE_GETTER:
-        return visitor.visitInstanceGetterDeclaration(
-            node, element, node.body, arg);
-      case FunctionKind.INSTANCE_SETTER:
-        return visitor.visitInstanceSetterDeclaration(
-            node, element, node.parameters, node.body, arg);
-      case FunctionKind.INSTANCE_METHOD:
-        return visitor.visitInstanceMethodDeclaration(
-            node, element, node.parameters, node.body, arg);
-      case FunctionKind.LOCAL_FUNCTION:
-        return visitor.visitLocalFunctionDeclaration(
-            node, element, node.parameters, node.body, arg);
-      case FunctionKind.CLOSURE:
-        return visitor.visitClosureDeclaration(
-            node, element, node.parameters, node.body, arg);
-    }
-  }
-}
-
-abstract class DeclarationResolverMixin {
-  TreeElements get elements;
-
-  internalError(Spannable spannable, String message);
-
-  ConstructorKind computeConstructorKind(ConstructorElement constructor) {
-    if (constructor.isRedirectingFactory) {
-      return ConstructorKind.REDIRECTING_FACTORY;
-    } else if (constructor.isFactoryConstructor) {
-      return ConstructorKind.FACTORY;
-    } else if (constructor.isRedirectingGenerative) {
-      return ConstructorKind.REDIRECTING_GENERATIVE;
-    } else {
-      return ConstructorKind.GENERATIVE;
-    }
-  }
-
-  DeclStructure computeFunctionStructure(FunctionExpression node) {
-    FunctionElement element = elements.getFunctionDefinition(node);
-    if (element.isConstructor) {
-      ConstructorElement constructor = element;
-      ConstructorKind kind = computeConstructorKind(constructor);
-      if (kind == ConstructorKind.REDIRECTING_FACTORY) {
-        return new RedirectingFactoryConstructorDeclStructure(
-            constructor,
-            elements.getType(node.body),
-            constructor.immediateRedirectionTarget);
-      } else {
-        return new ConstructorDeclStructure(kind, element);
-      }
-    } else {
-      FunctionKind kind;
-      if (element.isLocal) {
-        if (element.name.isEmpty) {
-          kind = FunctionKind.CLOSURE;
-        } else {
-          kind = FunctionKind.LOCAL_FUNCTION;
-        }
-      } else if (element.isInstanceMember) {
-        if (element.isGetter) {
-          kind = element.isAbstract
-              ? FunctionKind.ABSTRACT_GETTER
-              : FunctionKind.INSTANCE_GETTER;
-        } else if (element.isSetter) {
-          kind = element.isAbstract
-              ? FunctionKind.ABSTRACT_SETTER
-              : FunctionKind.INSTANCE_SETTER;
-        } else {
-          kind = element.isAbstract
-              ? FunctionKind.ABSTRACT_METHOD
-              : FunctionKind.INSTANCE_METHOD;
-        }
-      } else if (element.isStatic) {
-        if (element.isGetter) {
-          kind = FunctionKind.STATIC_GETTER;
-        } else if (element.isSetter) {
-          kind = FunctionKind.STATIC_SETTER;
-        } else {
-          kind = FunctionKind.STATIC_FUNCTION;
-        }
-      } else if (element.isTopLevel) {
-        if (element.isGetter) {
-          kind = FunctionKind.TOP_LEVEL_GETTER;
-        } else if (element.isSetter) {
-          kind = FunctionKind.TOP_LEVEL_SETTER;
-        } else {
-          kind = FunctionKind.TOP_LEVEL_FUNCTION;
-        }
-      } else {
-        return internalError(node, "Unhandled function expression.");
-      }
-      return new FunctionDeclStructure(kind, element);
-    }
-  }
-
-  InitializersStructure computeInitializersStructure(FunctionExpression node) {
-    List<InitializerStructure> initializers = <InitializerStructure>[];
-    NodeList list = node.initializers;
-    bool constructorInvocationSeen = false;
-    if (list != null) {
-      for (Node initializer in list) {
-        InitializerStructure structure =
-            computeInitializerStructure(initializer);
-        if (structure.isConstructorInvoke) {
-          constructorInvocationSeen = true;
-        }
-        initializers.add(structure);
-      }
-    }
-    if (!constructorInvocationSeen) {
-      ConstructorElement currentConstructor = elements[node];
-      ClassElement currentClass = currentConstructor.enclosingClass;
-      ResolutionInterfaceType supertype = currentClass.supertype;
-      if (supertype != null) {
-        ClassElement superclass = supertype.element;
-        ConstructorElement superConstructor =
-            superclass.lookupDefaultConstructor();
-        initializers.add(new ImplicitSuperConstructorInvokeStructure(
-            node, superConstructor, supertype));
-      }
-    }
-    return new InitializersStructure(initializers);
-  }
-
-  InitializerStructure computeInitializerStructure(Send node) {
-    Element element = elements[node];
-    if (node.asSendSet() != null) {
-      return new FieldInitializerStructure(node, element);
-    } else if (Initializers.isConstructorRedirect(node)) {
-      return new ThisConstructorInvokeStructure(
-          node, element, elements.getSelector(node).callStructure);
-    } else if (Initializers.isSuperConstructorCall(node)) {
-      return new SuperConstructorInvokeStructure(
-          node,
-          element,
-          elements.analyzedElement.enclosingClass.supertype,
-          elements.getSelector(node).callStructure);
-    }
-    return internalError(node, "Unhandled initializer.");
-  }
-
-  List<ParameterStructure> computeParameterStructures(NodeList parameters) {
-    List<ParameterStructure> list = <ParameterStructure>[];
-    int index = 0;
-    for (Node node in parameters) {
-      NodeList optionalParameters = node.asNodeList();
-      if (optionalParameters != null) {
-        bool isNamed = optionalParameters.beginToken.stringValue == '{';
-        for (Node node in optionalParameters) {
-          list.add(computeParameterStructure(node, index++,
-              isRequired: false, isNamed: isNamed));
-        }
-      } else {
-        list.add(computeParameterStructure(node, index++));
-      }
-    }
-    return list;
-  }
-
-  ParameterStructure computeParameterStructure(
-      VariableDefinitions definitions, int index,
-      {bool isRequired: true, bool isNamed: false}) {
-    Node node = definitions.definitions.nodes.single;
-    ParameterElement element = elements[node];
-    if (element == null) {
-      throw failedAt(node, "No parameter structure for $node.");
-    }
-    if (isRequired) {
-      return new RequiredParameterStructure(definitions, node, element, index);
-    } else {
-      // TODO(johnniwinther): Should we differentiate between implicit (null)
-      // and explicit values? What about optional parameters on redirecting
-      // factories?
-      if (isNamed) {
-        return new NamedParameterStructure(
-            definitions, node, element, element.constant);
-      } else {
-        return new OptionalParameterStructure(
-            definitions, node, element, element.constant, index);
-      }
-    }
-  }
-
-  void computeVariableStructures(VariableDefinitions definitions,
-      void callback(Node node, VariableStructure structure)) {
-    for (Node node in definitions.definitions) {
-      callback(definitions, computeVariableStructure(node));
-    }
-  }
-
-  VariableStructure computeVariableStructure(Node node) {
-    VariableElement element = elements[node];
-    VariableKind kind;
-    if (element.isLocal) {
-      kind = VariableKind.LOCAL_VARIABLE;
-    } else if (element.isInstanceMember) {
-      kind = VariableKind.INSTANCE_FIELD;
-    } else if (element.isStatic) {
-      kind = VariableKind.STATIC_FIELD;
-    } else if (element.isTopLevel) {
-      kind = VariableKind.TOP_LEVEL_FIELD;
-    } else {
-      return internalError(node, "Unexpected variable $element.");
-    }
-    if (element.isConst) {
-      ConstantExpression constant = elements.getConstant(element.initializer);
-      return new ConstantVariableStructure(kind, node, element, constant);
-    } else {
-      return new NonConstantVariableStructure(kind, node, element);
-    }
-  }
-}
diff --git a/pkg/compiler/lib/src/resolution/send_structure.dart b/pkg/compiler/lib/src/resolution/send_structure.dart
deleted file mode 100644
index 0c22657..0000000
--- a/pkg/compiler/lib/src/resolution/send_structure.dart
+++ /dev/null
@@ -1,2512 +0,0 @@
-// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library dart2js.resolution.send_structure;
-
-import '../common.dart';
-import '../constants/expressions.dart';
-import '../elements/elements.dart';
-import '../elements/operators.dart';
-import '../elements/resolution_types.dart';
-import '../resolution/tree_elements.dart' show TreeElements;
-import '../tree/tree.dart';
-import '../universe/call_structure.dart' show CallStructure;
-import '../universe/selector.dart' show Selector;
-import 'access_semantics.dart';
-import 'semantic_visitor.dart';
-
-/// Interface for the structure of the semantics of a [Send] or [NewExpression]
-/// node.
-abstract class SemanticSendStructure<R, A> {
-  /// Calls the matching visit method on [visitor] with [node] and [arg].
-  R dispatch(SemanticSendVisitor<R, A> visitor, covariant Node node, A arg);
-}
-
-enum SendStructureKind {
-  IF_NULL,
-  LOGICAL_AND,
-  LOGICAL_OR,
-  IS,
-  IS_NOT,
-  AS,
-  INVOKE,
-  INCOMPATIBLE_INVOKE,
-  GET,
-  SET,
-  NOT,
-  UNARY,
-  INVALID_UNARY,
-  INDEX,
-  EQUALS,
-  NOT_EQUALS,
-  BINARY,
-  INVALID_BINARY,
-  INDEX_SET,
-  INDEX_PREFIX,
-  INDEX_POSTFIX,
-  COMPOUND,
-  SET_IF_NULL,
-  COMPOUND_INDEX_SET,
-  INDEX_SET_IF_NULL,
-  PREFIX,
-  POSTFIX,
-  DEFERRED_PREFIX,
-}
-
-/// Interface for the structure of the semantics of a [Send] node.
-///
-/// Subclasses handle each of the [Send] variations; `assert(e)`, `a && b`,
-/// `a.b`, `a.b(c)`, etc.
-abstract class SendStructure<R, A> extends SemanticSendStructure<R, A> {
-  /// Calls the matching visit method on [visitor] with [send] and [arg].
-  R dispatch(SemanticSendVisitor<R, A> visitor, Send send, A arg);
-
-  SendStructureKind get kind;
-}
-
-/// The structure for a [Send] of the form `a ?? b`.
-class IfNullStructure<R, A> implements SendStructure<R, A> {
-  const IfNullStructure();
-
-  R dispatch(SemanticSendVisitor<R, A> visitor, Send node, A arg) {
-    return visitor.visitIfNull(node, node.receiver, node.arguments.single, arg);
-  }
-
-  @override
-  SendStructureKind get kind => SendStructureKind.IF_NULL;
-
-  String toString() => '??';
-}
-
-/// The structure for a [Send] of the form `a && b`.
-class LogicalAndStructure<R, A> implements SendStructure<R, A> {
-  const LogicalAndStructure();
-
-  R dispatch(SemanticSendVisitor<R, A> visitor, Send node, A arg) {
-    return visitor.visitLogicalAnd(
-        node, node.receiver, node.arguments.single, arg);
-  }
-
-  @override
-  SendStructureKind get kind => SendStructureKind.LOGICAL_AND;
-
-  String toString() => '&&';
-}
-
-/// The structure for a [Send] of the form `a || b`.
-class LogicalOrStructure<R, A> implements SendStructure<R, A> {
-  const LogicalOrStructure();
-
-  R dispatch(SemanticSendVisitor<R, A> visitor, Send node, A arg) {
-    return visitor.visitLogicalOr(
-        node, node.receiver, node.arguments.single, arg);
-  }
-
-  @override
-  SendStructureKind get kind => SendStructureKind.LOGICAL_OR;
-
-  String toString() => '||';
-}
-
-/// The structure for a [Send] of the form `a is T`.
-class IsStructure<R, A> implements SendStructure<R, A> {
-  /// The type that the expression is tested against.
-  final ResolutionDartType type;
-
-  IsStructure(this.type);
-
-  R dispatch(SemanticSendVisitor<R, A> visitor, Send node, A arg) {
-    return visitor.visitIs(node, node.receiver, type, arg);
-  }
-
-  @override
-  SendStructureKind get kind => SendStructureKind.IS;
-
-  String toString() => 'is $type';
-}
-
-/// The structure for a [Send] of the form `a is! T`.
-class IsNotStructure<R, A> implements SendStructure<R, A> {
-  /// The type that the expression is tested against.
-  final ResolutionDartType type;
-
-  IsNotStructure(this.type);
-
-  R dispatch(SemanticSendVisitor<R, A> visitor, Send node, A arg) {
-    return visitor.visitIsNot(node, node.receiver, type, arg);
-  }
-
-  @override
-  SendStructureKind get kind => SendStructureKind.IS_NOT;
-
-  String toString() => 'is! $type';
-}
-
-/// The structure for a [Send] of the form `a as T`.
-class AsStructure<R, A> implements SendStructure<R, A> {
-  /// The type that the expression is cast to.
-  final ResolutionDartType type;
-
-  AsStructure(this.type);
-
-  R dispatch(SemanticSendVisitor<R, A> visitor, Send node, A arg) {
-    return visitor.visitAs(node, node.receiver, type, arg);
-  }
-
-  @override
-  SendStructureKind get kind => SendStructureKind.AS;
-
-  String toString() => 'as $type';
-}
-
-/// The structure for a [Send] that is an invocation.
-class InvokeStructure<R, A> implements SendStructure<R, A> {
-  /// The target of the invocation.
-  final AccessSemantics semantics;
-
-  /// The [Selector] for the invocation.
-  // TODO(johnniwinther): Store this only for dynamic invocations.
-  final Selector selector;
-
-  /// The [CallStructure] of the invocation.
-  // TODO(johnniwinther): Store this directly for static invocations.
-  CallStructure get callStructure => selector.callStructure;
-
-  InvokeStructure(this.semantics, this.selector);
-
-  @override
-  SendStructureKind get kind => SendStructureKind.INVOKE;
-
-  R dispatch(SemanticSendVisitor<R, A> visitor, Send node, A arg) {
-    switch (semantics.kind) {
-      case AccessKind.CONDITIONAL_DYNAMIC_PROPERTY:
-        return visitor.visitIfNotNullDynamicPropertyInvoke(
-            node, node.receiver, node.argumentsNode, selector, arg);
-      case AccessKind.DYNAMIC_PROPERTY:
-        return visitor.visitDynamicPropertyInvoke(
-            node, node.receiver, node.argumentsNode, selector, arg);
-      case AccessKind.LOCAL_FUNCTION:
-        return visitor.visitLocalFunctionInvoke(
-            node,
-            semantics.element,
-            node.argumentsNode,
-            // TODO(johnniwinther): Store the call selector instead of the
-            // selector using the name of the function.
-            callStructure,
-            arg);
-      case AccessKind.LOCAL_VARIABLE:
-      case AccessKind.FINAL_LOCAL_VARIABLE:
-        return visitor.visitLocalVariableInvoke(
-            node,
-            semantics.element,
-            node.argumentsNode,
-            // TODO(johnniwinther): Store the call selector instead of the
-            // selector using the name of the variable.
-            callStructure,
-            arg);
-      case AccessKind.PARAMETER:
-      case AccessKind.FINAL_PARAMETER:
-        return visitor.visitParameterInvoke(
-            node,
-            semantics.element,
-            node.argumentsNode,
-            // TODO(johnniwinther): Store the call selector instead of the
-            // selector using the name of the parameter.
-            callStructure,
-            arg);
-      case AccessKind.STATIC_FIELD:
-      case AccessKind.FINAL_STATIC_FIELD:
-        return visitor.visitStaticFieldInvoke(
-            node, semantics.element, node.argumentsNode, callStructure, arg);
-      case AccessKind.STATIC_METHOD:
-        return visitor.visitStaticFunctionInvoke(
-            node, semantics.element, node.argumentsNode, callStructure, arg);
-      case AccessKind.STATIC_GETTER:
-        return visitor.visitStaticGetterInvoke(
-            node, semantics.element, node.argumentsNode, callStructure, arg);
-      case AccessKind.STATIC_SETTER:
-        return visitor.visitStaticSetterInvoke(
-            node, semantics.element, node.argumentsNode, callStructure, arg);
-      case AccessKind.TOPLEVEL_FIELD:
-      case AccessKind.FINAL_TOPLEVEL_FIELD:
-        return visitor.visitTopLevelFieldInvoke(
-            node, semantics.element, node.argumentsNode, callStructure, arg);
-      case AccessKind.TOPLEVEL_METHOD:
-        return visitor.visitTopLevelFunctionInvoke(
-            node, semantics.element, node.argumentsNode, callStructure, arg);
-      case AccessKind.TOPLEVEL_GETTER:
-        return visitor.visitTopLevelGetterInvoke(
-            node, semantics.element, node.argumentsNode, callStructure, arg);
-      case AccessKind.TOPLEVEL_SETTER:
-        return visitor.visitTopLevelSetterInvoke(
-            node, semantics.element, node.argumentsNode, callStructure, arg);
-      case AccessKind.CLASS_TYPE_LITERAL:
-        return visitor.visitClassTypeLiteralInvoke(
-            node, semantics.constant, node.argumentsNode, callStructure, arg);
-      case AccessKind.TYPEDEF_TYPE_LITERAL:
-        return visitor.visitTypedefTypeLiteralInvoke(
-            node, semantics.constant, node.argumentsNode, callStructure, arg);
-      case AccessKind.DYNAMIC_TYPE_LITERAL:
-        return visitor.visitDynamicTypeLiteralInvoke(
-            node, semantics.constant, node.argumentsNode, callStructure, arg);
-      case AccessKind.TYPE_PARAMETER_TYPE_LITERAL:
-        return visitor.visitTypeVariableTypeLiteralInvoke(
-            node, semantics.element, node.argumentsNode, callStructure, arg);
-      case AccessKind.EXPRESSION:
-        return visitor.visitExpressionInvoke(
-            node, node.selector, node.argumentsNode, callStructure, arg);
-      case AccessKind.THIS:
-        return visitor.visitThisInvoke(
-            node, node.argumentsNode, callStructure, arg);
-      case AccessKind.THIS_PROPERTY:
-        return visitor.visitThisPropertyInvoke(
-            node, node.argumentsNode, selector, arg);
-      case AccessKind.SUPER_FIELD:
-      case AccessKind.SUPER_FINAL_FIELD:
-        return visitor.visitSuperFieldInvoke(
-            node, semantics.element, node.argumentsNode, callStructure, arg);
-      case AccessKind.SUPER_METHOD:
-        return visitor.visitSuperMethodInvoke(
-            node, semantics.element, node.argumentsNode, callStructure, arg);
-      case AccessKind.SUPER_GETTER:
-        return visitor.visitSuperGetterInvoke(
-            node, semantics.element, node.argumentsNode, callStructure, arg);
-      case AccessKind.SUPER_SETTER:
-        return visitor.visitSuperSetterInvoke(
-            node, semantics.element, node.argumentsNode, callStructure, arg);
-      case AccessKind.CONSTANT:
-        return visitor.visitConstantInvoke(
-            node, semantics.constant, node.argumentsNode, callStructure, arg);
-      case AccessKind.UNRESOLVED:
-        return visitor.visitUnresolvedInvoke(
-            node, semantics.element, node.argumentsNode, selector, arg);
-      case AccessKind.UNRESOLVED_SUPER:
-        return visitor.visitUnresolvedSuperInvoke(
-            node, semantics.element, node.argumentsNode, selector, arg);
-      case AccessKind.INVALID:
-        return visitor.errorInvalidInvoke(
-            node, semantics.element, node.argumentsNode, selector, arg);
-      case AccessKind.COMPOUND:
-        // This is not a valid case.
-        break;
-    }
-    throw failedAt(node, "Invalid invoke: ${semantics}");
-  }
-
-  String toString() => 'invoke($selector, $semantics)';
-}
-
-/// The structure for a [Send] that is an incompatible invocation, i.e. an
-/// invocation of a known target where the call structure does not match.
-class IncompatibleInvokeStructure<R, A> implements SendStructure<R, A> {
-  /// The target of the invocation.
-  final AccessSemantics semantics;
-
-  /// The [Selector] for the invocation.
-  // TODO(johnniwinther): Store this only for dynamic invocations.
-  final Selector selector;
-
-  /// The [CallStructure] of the invocation.
-  // TODO(johnniwinther): Store this directly for static invocations.
-  CallStructure get callStructure => selector.callStructure;
-
-  IncompatibleInvokeStructure(this.semantics, this.selector);
-
-  @override
-  SendStructureKind get kind => SendStructureKind.INCOMPATIBLE_INVOKE;
-
-  R dispatch(SemanticSendVisitor<R, A> visitor, Send node, A arg) {
-    switch (semantics.kind) {
-      case AccessKind.STATIC_METHOD:
-        return visitor.visitStaticFunctionIncompatibleInvoke(
-            node, semantics.element, node.argumentsNode, callStructure, arg);
-      case AccessKind.SUPER_METHOD:
-        return visitor.visitSuperMethodIncompatibleInvoke(
-            node, semantics.element, node.argumentsNode, callStructure, arg);
-      case AccessKind.TOPLEVEL_METHOD:
-        return visitor.visitTopLevelFunctionIncompatibleInvoke(
-            node, semantics.element, node.argumentsNode, callStructure, arg);
-      case AccessKind.LOCAL_FUNCTION:
-        return visitor.visitLocalFunctionIncompatibleInvoke(
-            node, semantics.element, node.argumentsNode, callStructure, arg);
-      default:
-        // TODO(johnniwinther): Support more variants of this invoke structure.
-        break;
-    }
-    throw failedAt(node, "Invalid incompatible invoke: ${semantics}");
-  }
-
-  String toString() => 'incompatible-invoke($selector, $semantics)';
-}
-
-/// The structure for a [Send] that is a read access.
-class GetStructure<R, A> implements SendStructure<R, A> {
-  /// The target of the read access.
-  final AccessSemantics semantics;
-
-  GetStructure(this.semantics);
-
-  @override
-  SendStructureKind get kind => SendStructureKind.GET;
-
-  R dispatch(SemanticSendVisitor<R, A> visitor, Send node, A arg) {
-    switch (semantics.kind) {
-      case AccessKind.CONDITIONAL_DYNAMIC_PROPERTY:
-        return visitor.visitIfNotNullDynamicPropertyGet(
-            node, node.receiver, semantics.name, arg);
-      case AccessKind.DYNAMIC_PROPERTY:
-        return visitor.visitDynamicPropertyGet(
-            node, node.receiver, semantics.name, arg);
-      case AccessKind.LOCAL_FUNCTION:
-        return visitor.visitLocalFunctionGet(node, semantics.element, arg);
-      case AccessKind.LOCAL_VARIABLE:
-      case AccessKind.FINAL_LOCAL_VARIABLE:
-        return visitor.visitLocalVariableGet(node, semantics.element, arg);
-      case AccessKind.PARAMETER:
-      case AccessKind.FINAL_PARAMETER:
-        return visitor.visitParameterGet(node, semantics.element, arg);
-      case AccessKind.STATIC_FIELD:
-      case AccessKind.FINAL_STATIC_FIELD:
-        return visitor.visitStaticFieldGet(node, semantics.element, arg);
-      case AccessKind.STATIC_METHOD:
-        return visitor.visitStaticFunctionGet(node, semantics.element, arg);
-      case AccessKind.STATIC_GETTER:
-        return visitor.visitStaticGetterGet(node, semantics.element, arg);
-      case AccessKind.STATIC_SETTER:
-        return visitor.visitStaticSetterGet(node, semantics.element, arg);
-      case AccessKind.TOPLEVEL_FIELD:
-      case AccessKind.FINAL_TOPLEVEL_FIELD:
-        return visitor.visitTopLevelFieldGet(node, semantics.element, arg);
-      case AccessKind.TOPLEVEL_METHOD:
-        return visitor.visitTopLevelFunctionGet(node, semantics.element, arg);
-      case AccessKind.TOPLEVEL_GETTER:
-        return visitor.visitTopLevelGetterGet(node, semantics.element, arg);
-      case AccessKind.TOPLEVEL_SETTER:
-        return visitor.visitTopLevelSetterGet(node, semantics.element, arg);
-      case AccessKind.CLASS_TYPE_LITERAL:
-        return visitor.visitClassTypeLiteralGet(node, semantics.constant, arg);
-      case AccessKind.TYPEDEF_TYPE_LITERAL:
-        return visitor.visitTypedefTypeLiteralGet(
-            node, semantics.constant, arg);
-      case AccessKind.DYNAMIC_TYPE_LITERAL:
-        return visitor.visitDynamicTypeLiteralGet(
-            node, semantics.constant, arg);
-      case AccessKind.TYPE_PARAMETER_TYPE_LITERAL:
-        return visitor.visitTypeVariableTypeLiteralGet(
-            node, semantics.element, arg);
-      case AccessKind.EXPRESSION:
-        // This is not a valid case.
-        break;
-      case AccessKind.THIS:
-        // TODO(johnniwinther): Handle this when `this` is a [Send].
-        break;
-      case AccessKind.THIS_PROPERTY:
-        return visitor.visitThisPropertyGet(node, semantics.name, arg);
-      case AccessKind.SUPER_FIELD:
-      case AccessKind.SUPER_FINAL_FIELD:
-        return visitor.visitSuperFieldGet(node, semantics.element, arg);
-      case AccessKind.SUPER_METHOD:
-        return visitor.visitSuperMethodGet(node, semantics.element, arg);
-      case AccessKind.SUPER_GETTER:
-        return visitor.visitSuperGetterGet(node, semantics.element, arg);
-      case AccessKind.SUPER_SETTER:
-        return visitor.visitSuperSetterGet(node, semantics.element, arg);
-      case AccessKind.CONSTANT:
-        return visitor.visitConstantGet(node, semantics.constant, arg);
-      case AccessKind.UNRESOLVED:
-        return visitor.visitUnresolvedGet(node, semantics.element, arg);
-      case AccessKind.UNRESOLVED_SUPER:
-        return visitor.visitUnresolvedSuperGet(node, semantics.element, arg);
-      case AccessKind.INVALID:
-        return visitor.errorInvalidGet(node, semantics.element, arg);
-      case AccessKind.COMPOUND:
-        // This is not a valid case.
-        break;
-    }
-    throw failedAt(node, "Invalid getter: ${semantics}");
-  }
-
-  String toString() => 'get($semantics)';
-}
-
-/// The structure for a [Send] that is an assignment.
-class SetStructure<R, A> implements SendStructure<R, A> {
-  /// The target of the assignment.
-  final AccessSemantics semantics;
-
-  SetStructure(this.semantics);
-
-  @override
-  SendStructureKind get kind => SendStructureKind.SET;
-
-  R dispatch(SemanticSendVisitor<R, A> visitor, Send node, A arg) {
-    switch (semantics.kind) {
-      case AccessKind.CONDITIONAL_DYNAMIC_PROPERTY:
-        return visitor.visitIfNotNullDynamicPropertySet(
-            node, node.receiver, semantics.name, node.arguments.single, arg);
-      case AccessKind.DYNAMIC_PROPERTY:
-        return visitor.visitDynamicPropertySet(
-            node, node.receiver, semantics.name, node.arguments.single, arg);
-      case AccessKind.LOCAL_FUNCTION:
-        return visitor.visitLocalFunctionSet(
-            node, semantics.element, node.arguments.single, arg);
-      case AccessKind.LOCAL_VARIABLE:
-        return visitor.visitLocalVariableSet(
-            node, semantics.element, node.arguments.single, arg);
-      case AccessKind.FINAL_LOCAL_VARIABLE:
-        return visitor.visitFinalLocalVariableSet(
-            node, semantics.element, node.arguments.single, arg);
-      case AccessKind.PARAMETER:
-        return visitor.visitParameterSet(
-            node, semantics.element, node.arguments.single, arg);
-      case AccessKind.FINAL_PARAMETER:
-        return visitor.visitFinalParameterSet(
-            node, semantics.element, node.arguments.single, arg);
-      case AccessKind.STATIC_FIELD:
-        return visitor.visitStaticFieldSet(
-            node, semantics.element, node.arguments.single, arg);
-      case AccessKind.FINAL_STATIC_FIELD:
-        return visitor.visitFinalStaticFieldSet(
-            node, semantics.element, node.arguments.single, arg);
-      case AccessKind.STATIC_METHOD:
-        return visitor.visitStaticFunctionSet(
-            node, semantics.element, node.arguments.single, arg);
-      case AccessKind.STATIC_GETTER:
-        return visitor.visitStaticGetterSet(
-            node, semantics.element, node.arguments.single, arg);
-      case AccessKind.STATIC_SETTER:
-        return visitor.visitStaticSetterSet(
-            node, semantics.element, node.arguments.single, arg);
-      case AccessKind.TOPLEVEL_FIELD:
-        return visitor.visitTopLevelFieldSet(
-            node, semantics.element, node.arguments.single, arg);
-      case AccessKind.FINAL_TOPLEVEL_FIELD:
-        return visitor.visitFinalTopLevelFieldSet(
-            node, semantics.element, node.arguments.single, arg);
-      case AccessKind.TOPLEVEL_METHOD:
-        return visitor.visitTopLevelFunctionSet(
-            node, semantics.element, node.arguments.single, arg);
-      case AccessKind.TOPLEVEL_GETTER:
-        return visitor.visitTopLevelGetterSet(
-            node, semantics.element, node.arguments.single, arg);
-      case AccessKind.TOPLEVEL_SETTER:
-        return visitor.visitTopLevelSetterSet(
-            node, semantics.element, node.arguments.single, arg);
-      case AccessKind.CLASS_TYPE_LITERAL:
-        return visitor.visitClassTypeLiteralSet(
-            node, semantics.constant, node.arguments.single, arg);
-      case AccessKind.TYPEDEF_TYPE_LITERAL:
-        return visitor.visitTypedefTypeLiteralSet(
-            node, semantics.constant, node.arguments.single, arg);
-      case AccessKind.DYNAMIC_TYPE_LITERAL:
-        return visitor.visitDynamicTypeLiteralSet(
-            node, semantics.constant, node.arguments.single, arg);
-      case AccessKind.TYPE_PARAMETER_TYPE_LITERAL:
-        return visitor.visitTypeVariableTypeLiteralSet(
-            node, semantics.element, node.arguments.single, arg);
-      case AccessKind.EXPRESSION:
-        // This is not a valid case.
-        break;
-      case AccessKind.THIS:
-        // This is not a valid case.
-        break;
-      case AccessKind.THIS_PROPERTY:
-        return visitor.visitThisPropertySet(
-            node, semantics.name, node.arguments.single, arg);
-      case AccessKind.SUPER_FIELD:
-        return visitor.visitSuperFieldSet(
-            node, semantics.element, node.arguments.single, arg);
-      case AccessKind.SUPER_FINAL_FIELD:
-        return visitor.visitFinalSuperFieldSet(
-            node, semantics.element, node.arguments.single, arg);
-      case AccessKind.SUPER_METHOD:
-        return visitor.visitSuperMethodSet(
-            node, semantics.element, node.arguments.single, arg);
-      case AccessKind.SUPER_GETTER:
-        return visitor.visitSuperGetterSet(
-            node, semantics.element, node.arguments.single, arg);
-      case AccessKind.SUPER_SETTER:
-        return visitor.visitSuperSetterSet(
-            node, semantics.element, node.arguments.single, arg);
-      case AccessKind.CONSTANT:
-        // TODO(johnniwinther): Should this be a valid case?
-        break;
-      case AccessKind.UNRESOLVED_SUPER:
-        return visitor.visitUnresolvedSuperSet(
-            node, semantics.element, node.arguments.single, arg);
-      case AccessKind.UNRESOLVED:
-        return visitor.visitUnresolvedSet(
-            node, semantics.element, node.arguments.single, arg);
-      case AccessKind.INVALID:
-        return visitor.errorInvalidSet(
-            node, semantics.element, node.arguments.single, arg);
-      case AccessKind.COMPOUND:
-        // This is not a valid case.
-        break;
-    }
-    throw failedAt(node, "Invalid setter: ${semantics}");
-  }
-
-  String toString() => 'set($semantics)';
-}
-
-/// The structure for a [Send] that is a negation, i.e. of the form `!e`.
-class NotStructure<R, A> implements SendStructure<R, A> {
-  const NotStructure();
-
-  R dispatch(SemanticSendVisitor<R, A> visitor, Send node, A arg) {
-    return visitor.visitNot(node, node.receiver, arg);
-  }
-
-  @override
-  SendStructureKind get kind => SendStructureKind.NOT;
-
-  String toString() => 'not()';
-}
-
-/// The structure for a [Send] that is an invocation of a user definable unary
-/// operator.
-class UnaryStructure<R, A> implements SendStructure<R, A> {
-  /// The target of the unary operation.
-  final AccessSemantics semantics;
-
-  /// The user definable unary operator.
-  final UnaryOperator operator;
-
-  UnaryStructure(this.semantics, this.operator);
-
-  @override
-  SendStructureKind get kind => SendStructureKind.UNARY;
-
-  R dispatch(SemanticSendVisitor<R, A> visitor, Send node, A arg) {
-    switch (semantics.kind) {
-      case AccessKind.EXPRESSION:
-        return visitor.visitUnary(node, operator, node.receiver, arg);
-      case AccessKind.SUPER_METHOD:
-        return visitor.visitSuperUnary(node, operator, semantics.element, arg);
-      case AccessKind.UNRESOLVED_SUPER:
-        return visitor.visitUnresolvedSuperUnary(
-            node, operator, semantics.element, arg);
-      case AccessKind.INVALID:
-        return visitor.errorInvalidUnary(
-            node, operator, semantics.element, arg);
-      default:
-        // This is not a valid case.
-        break;
-    }
-    throw failedAt(node, "Invalid setter: ${semantics}");
-  }
-
-  String toString() => 'unary($operator,$semantics)';
-}
-
-/// The structure for a [Send] that is an invocation of a undefined unary
-/// operator.
-class InvalidUnaryStructure<R, A> implements SendStructure<R, A> {
-  const InvalidUnaryStructure();
-
-  @override
-  R dispatch(SemanticSendVisitor<R, A> visitor, Send node, A arg) {
-    return visitor.errorUndefinedUnaryExpression(
-        node, node.selector, node.receiver, arg);
-  }
-
-  @override
-  SendStructureKind get kind => SendStructureKind.INVALID_UNARY;
-
-  String toString() => 'invalid unary';
-}
-
-/// The structure for a [Send] that is an index expression, i.e. of the form
-/// `a[b]`.
-class IndexStructure<R, A> implements SendStructure<R, A> {
-  /// The target of the left operand.
-  final AccessSemantics semantics;
-
-  IndexStructure(this.semantics);
-
-  @override
-  SendStructureKind get kind => SendStructureKind.INDEX;
-
-  R dispatch(SemanticSendVisitor<R, A> visitor, Send node, A arg) {
-    switch (semantics.kind) {
-      case AccessKind.EXPRESSION:
-        return visitor.visitIndex(
-            node, node.receiver, node.arguments.single, arg);
-      case AccessKind.SUPER_METHOD:
-        return visitor.visitSuperIndex(
-            node, semantics.element, node.arguments.single, arg);
-      case AccessKind.UNRESOLVED_SUPER:
-        return visitor.visitUnresolvedSuperIndex(
-            node, semantics.element, node.arguments.single, arg);
-      case AccessKind.INVALID:
-        return visitor.errorInvalidIndex(
-            node, semantics.element, node.arguments.single, arg);
-      default:
-        // This is not a valid case.
-        break;
-    }
-    throw failedAt(node, "Invalid index: ${semantics}");
-  }
-}
-
-/// The structure for a [Send] that is an equals test, i.e. of the form
-/// `a == b`.
-class EqualsStructure<R, A> implements SendStructure<R, A> {
-  /// The target of the left operand.
-  final AccessSemantics semantics;
-
-  EqualsStructure(this.semantics);
-
-  @override
-  SendStructureKind get kind => SendStructureKind.EQUALS;
-
-  R dispatch(SemanticSendVisitor<R, A> visitor, Send node, A arg) {
-    switch (semantics.kind) {
-      case AccessKind.EXPRESSION:
-        return visitor.visitEquals(
-            node, node.receiver, node.arguments.single, arg);
-      case AccessKind.SUPER_METHOD:
-        return visitor.visitSuperEquals(
-            node, semantics.element, node.arguments.single, arg);
-      case AccessKind.INVALID:
-        return visitor.errorInvalidEquals(
-            node, semantics.element, node.arguments.single, arg);
-      default:
-        // This is not a valid case.
-        break;
-    }
-    throw failedAt(node, "Invalid equals: ${semantics}");
-  }
-
-  String toString() => '==($semantics)';
-}
-
-/// The structure for a [Send] that is a not-equals test, i.e. of the form
-/// `a != b`.
-class NotEqualsStructure<R, A> implements SendStructure<R, A> {
-  /// The target of the left operand.
-  final AccessSemantics semantics;
-
-  NotEqualsStructure(this.semantics);
-
-  @override
-  SendStructureKind get kind => SendStructureKind.NOT_EQUALS;
-
-  R dispatch(SemanticSendVisitor<R, A> visitor, Send node, A arg) {
-    switch (semantics.kind) {
-      case AccessKind.EXPRESSION:
-        return visitor.visitNotEquals(
-            node, node.receiver, node.arguments.single, arg);
-      case AccessKind.SUPER_METHOD:
-        return visitor.visitSuperNotEquals(
-            node, semantics.element, node.arguments.single, arg);
-      case AccessKind.INVALID:
-        return visitor.errorInvalidNotEquals(
-            node, semantics.element, node.arguments.single, arg);
-      default:
-        // This is not a valid case.
-        break;
-    }
-    throw failedAt(node, "Invalid not equals: ${semantics}");
-  }
-
-  String toString() => '!=($semantics)';
-}
-
-/// The structure for a [Send] that is an invocation of a user-definable binary
-/// operator.
-class BinaryStructure<R, A> implements SendStructure<R, A> {
-  /// The target of the left operand.
-  final AccessSemantics semantics;
-
-  /// The user definable binary operator.
-  final BinaryOperator operator;
-
-  BinaryStructure(this.semantics, this.operator);
-
-  @override
-  SendStructureKind get kind => SendStructureKind.BINARY;
-
-  R dispatch(SemanticSendVisitor<R, A> visitor, Send node, A arg) {
-    switch (semantics.kind) {
-      case AccessKind.EXPRESSION:
-        return visitor.visitBinary(
-            node, node.receiver, operator, node.arguments.single, arg);
-      case AccessKind.SUPER_METHOD:
-        return visitor.visitSuperBinary(
-            node, semantics.element, operator, node.arguments.single, arg);
-      case AccessKind.UNRESOLVED_SUPER:
-        return visitor.visitUnresolvedSuperBinary(
-            node, semantics.element, operator, node.arguments.single, arg);
-      case AccessKind.INVALID:
-        return visitor.errorInvalidBinary(
-            node, semantics.element, operator, node.arguments.single, arg);
-      default:
-        // This is not a valid case.
-        break;
-    }
-    throw failedAt(node, "Invalid binary: ${semantics}");
-  }
-
-  String toString() => 'binary($operator,$semantics)';
-}
-
-/// The structure for a [Send] that is an invocation of a undefined binary
-/// operator.
-class InvalidBinaryStructure<R, A> implements SendStructure<R, A> {
-  const InvalidBinaryStructure();
-
-  @override
-  R dispatch(SemanticSendVisitor<R, A> visitor, Send node, A arg) {
-    return visitor.errorUndefinedBinaryExpression(
-        node, node.receiver, node.selector, node.arguments.single, arg);
-  }
-
-  @override
-  SendStructureKind get kind => SendStructureKind.INVALID_BINARY;
-
-  String toString() => 'invalid binary';
-}
-
-/// The structure for a [Send] that is of the form `a[b] = c`.
-class IndexSetStructure<R, A> implements SendStructure<R, A> {
-  /// The target of the index set operation.
-  final AccessSemantics semantics;
-
-  IndexSetStructure(this.semantics);
-
-  @override
-  SendStructureKind get kind => SendStructureKind.INDEX_SET;
-
-  R dispatch(SemanticSendVisitor<R, A> visitor, Send node, A arg) {
-    switch (semantics.kind) {
-      case AccessKind.EXPRESSION:
-        return visitor.visitIndexSet(node, node.receiver, node.arguments.first,
-            node.arguments.tail.head, arg);
-      case AccessKind.SUPER_METHOD:
-        return visitor.visitSuperIndexSet(node, semantics.element,
-            node.arguments.first, node.arguments.tail.head, arg);
-      case AccessKind.UNRESOLVED_SUPER:
-      case AccessKind.UNRESOLVED:
-        return visitor.visitUnresolvedSuperIndexSet(node, semantics.element,
-            node.arguments.first, node.arguments.tail.head, arg);
-      case AccessKind.INVALID:
-        return visitor.errorInvalidIndexSet(node, semantics.element,
-            node.arguments.first, node.arguments.tail.head, arg);
-      default:
-        // This is not a valid case.
-        break;
-    }
-    throw failedAt(node, "Invalid index set: ${semantics}");
-  }
-
-  String toString() => '[]=($semantics)';
-}
-
-/// The structure for a [Send] that is an prefix operation on an index
-/// expression, i.e. of the form `--a[b]`.
-class IndexPrefixStructure<R, A> implements SendStructure<R, A> {
-  /// The target of the left operand.
-  final AccessSemantics semantics;
-
-  /// The `++` or `--` operator used in the operation.
-  final IncDecOperator operator;
-
-  IndexPrefixStructure(this.semantics, this.operator);
-
-  @override
-  SendStructureKind get kind => SendStructureKind.INDEX_PREFIX;
-
-  R dispatch(SemanticSendVisitor<R, A> visitor, Send node, A arg) {
-    switch (semantics.kind) {
-      case AccessKind.EXPRESSION:
-        return visitor.visitIndexPrefix(
-            node, node.receiver, node.arguments.single, operator, arg);
-      case AccessKind.UNRESOLVED_SUPER:
-        return visitor.visitUnresolvedSuperIndexPrefix(
-            node, semantics.element, node.arguments.single, operator, arg);
-      case AccessKind.INVALID:
-        return visitor.errorInvalidIndexPrefix(
-            node, semantics.element, node.arguments.single, operator, arg);
-      case AccessKind.COMPOUND:
-        CompoundAccessSemantics compoundSemantics = semantics;
-        switch (compoundSemantics.compoundAccessKind) {
-          case CompoundAccessKind.SUPER_GETTER_SETTER:
-            return visitor.visitSuperIndexPrefix(node, compoundSemantics.getter,
-                compoundSemantics.setter, node.arguments.single, operator, arg);
-          case CompoundAccessKind.UNRESOLVED_SUPER_GETTER:
-            return visitor.visitUnresolvedSuperGetterIndexPrefix(
-                node,
-                compoundSemantics.getter,
-                compoundSemantics.setter,
-                node.arguments.single,
-                operator,
-                arg);
-          case CompoundAccessKind.UNRESOLVED_SUPER_SETTER:
-            return visitor.visitUnresolvedSuperSetterIndexPrefix(
-                node,
-                compoundSemantics.getter,
-                compoundSemantics.setter,
-                node.arguments.single,
-                operator,
-                arg);
-          default:
-            // This is not a valid case.
-            break;
-        }
-        break;
-      default:
-        // This is not a valid case.
-        break;
-    }
-    throw failedAt(node, "Invalid index prefix: ${semantics}");
-  }
-}
-
-/// The structure for a [Send] that is an postfix operation on an index
-/// expression, i.e. of the form `a[b]++`.
-class IndexPostfixStructure<R, A> implements SendStructure<R, A> {
-  /// The target of the left operand.
-  final AccessSemantics semantics;
-
-  /// The `++` or `--` operator used in the operation.
-  final IncDecOperator operator;
-
-  IndexPostfixStructure(this.semantics, this.operator);
-
-  @override
-  SendStructureKind get kind => SendStructureKind.INDEX_POSTFIX;
-
-  R dispatch(SemanticSendVisitor<R, A> visitor, Send node, A arg) {
-    switch (semantics.kind) {
-      case AccessKind.EXPRESSION:
-        return visitor.visitIndexPostfix(
-            node, node.receiver, node.arguments.single, operator, arg);
-      case AccessKind.UNRESOLVED_SUPER:
-        return visitor.visitUnresolvedSuperIndexPostfix(
-            node, semantics.element, node.arguments.single, operator, arg);
-      case AccessKind.INVALID:
-        return visitor.errorInvalidIndexPostfix(
-            node, semantics.element, node.arguments.single, operator, arg);
-      case AccessKind.COMPOUND:
-        CompoundAccessSemantics compoundSemantics = semantics;
-        switch (compoundSemantics.compoundAccessKind) {
-          case CompoundAccessKind.SUPER_GETTER_SETTER:
-            return visitor.visitSuperIndexPostfix(
-                node,
-                compoundSemantics.getter,
-                compoundSemantics.setter,
-                node.arguments.single,
-                operator,
-                arg);
-          case CompoundAccessKind.UNRESOLVED_SUPER_GETTER:
-            return visitor.visitUnresolvedSuperGetterIndexPostfix(
-                node,
-                compoundSemantics.getter,
-                compoundSemantics.setter,
-                node.arguments.single,
-                operator,
-                arg);
-          case CompoundAccessKind.UNRESOLVED_SUPER_SETTER:
-            return visitor.visitUnresolvedSuperSetterIndexPostfix(
-                node,
-                compoundSemantics.getter,
-                compoundSemantics.setter,
-                node.arguments.single,
-                operator,
-                arg);
-          default:
-            // This is not a valid case.
-            break;
-        }
-        break;
-      default:
-        // This is not a valid case.
-        break;
-    }
-    throw failedAt(node, "Invalid index postfix: ${semantics}");
-  }
-}
-
-/// The structure for a [Send] that is a compound assignment. For instance
-/// `a += b`.
-class CompoundStructure<R, A> implements SendStructure<R, A> {
-  /// The target of the compound assignment, i.e. the left-hand side.
-  final AccessSemantics semantics;
-
-  /// The assignment operator used in the compound assignment.
-  final AssignmentOperator operator;
-
-  CompoundStructure(this.semantics, this.operator);
-
-  @override
-  SendStructureKind get kind => SendStructureKind.COMPOUND;
-
-  R dispatch(SemanticSendVisitor<R, A> visitor, Send node, A arg) {
-    switch (semantics.kind) {
-      case AccessKind.CONDITIONAL_DYNAMIC_PROPERTY:
-        return visitor.visitIfNotNullDynamicPropertyCompound(
-            node,
-            node.receiver,
-            semantics.name,
-            operator,
-            node.arguments.single,
-            arg);
-      case AccessKind.DYNAMIC_PROPERTY:
-        return visitor.visitDynamicPropertyCompound(node, node.receiver,
-            semantics.name, operator, node.arguments.single, arg);
-      case AccessKind.LOCAL_FUNCTION:
-        return visitor.visitLocalFunctionCompound(
-            node, semantics.element, operator, node.arguments.single, arg);
-      case AccessKind.LOCAL_VARIABLE:
-        return visitor.visitLocalVariableCompound(
-            node, semantics.element, operator, node.arguments.single, arg);
-      case AccessKind.FINAL_LOCAL_VARIABLE:
-        return visitor.visitFinalLocalVariableCompound(
-            node, semantics.element, operator, node.arguments.single, arg);
-      case AccessKind.PARAMETER:
-        return visitor.visitParameterCompound(
-            node, semantics.element, operator, node.arguments.single, arg);
-      case AccessKind.FINAL_PARAMETER:
-        return visitor.visitFinalParameterCompound(
-            node, semantics.element, operator, node.arguments.single, arg);
-      case AccessKind.STATIC_FIELD:
-        return visitor.visitStaticFieldCompound(
-            node, semantics.element, operator, node.arguments.single, arg);
-      case AccessKind.FINAL_STATIC_FIELD:
-        return visitor.visitFinalStaticFieldCompound(
-            node, semantics.element, operator, node.arguments.single, arg);
-      case AccessKind.STATIC_METHOD:
-        return visitor.visitStaticMethodCompound(
-            node, semantics.element, operator, node.arguments.single, arg);
-      case AccessKind.STATIC_GETTER:
-        // This is not a valid case.
-        break;
-      case AccessKind.STATIC_SETTER:
-        // This is not a valid case.
-        break;
-      case AccessKind.TOPLEVEL_FIELD:
-        return visitor.visitTopLevelFieldCompound(
-            node, semantics.element, operator, node.arguments.single, arg);
-      case AccessKind.FINAL_TOPLEVEL_FIELD:
-        return visitor.visitFinalTopLevelFieldCompound(
-            node, semantics.element, operator, node.arguments.single, arg);
-      case AccessKind.TOPLEVEL_METHOD:
-        return visitor.visitTopLevelMethodCompound(
-            node, semantics.element, operator, node.arguments.single, arg);
-      case AccessKind.TOPLEVEL_GETTER:
-        // This is not a valid case.
-        break;
-      case AccessKind.TOPLEVEL_SETTER:
-        // This is not a valid case.
-        break;
-      case AccessKind.CLASS_TYPE_LITERAL:
-        return visitor.visitClassTypeLiteralCompound(
-            node, semantics.constant, operator, node.arguments.single, arg);
-      case AccessKind.TYPEDEF_TYPE_LITERAL:
-        return visitor.visitTypedefTypeLiteralCompound(
-            node, semantics.constant, operator, node.arguments.single, arg);
-      case AccessKind.DYNAMIC_TYPE_LITERAL:
-        return visitor.visitDynamicTypeLiteralCompound(
-            node, semantics.constant, operator, node.arguments.single, arg);
-      case AccessKind.TYPE_PARAMETER_TYPE_LITERAL:
-        return visitor.visitTypeVariableTypeLiteralCompound(
-            node, semantics.element, operator, node.arguments.single, arg);
-      case AccessKind.EXPRESSION:
-        // This is not a valid case.
-        break;
-      case AccessKind.THIS:
-        // This is not a valid case.
-        break;
-      case AccessKind.THIS_PROPERTY:
-        return visitor.visitThisPropertyCompound(
-            node, semantics.name, operator, node.arguments.single, arg);
-      case AccessKind.SUPER_FIELD:
-        return visitor.visitSuperFieldCompound(
-            node, semantics.element, operator, node.arguments.single, arg);
-      case AccessKind.SUPER_FINAL_FIELD:
-        return visitor.visitFinalSuperFieldCompound(
-            node, semantics.element, operator, node.arguments.single, arg);
-      case AccessKind.SUPER_METHOD:
-        return visitor.visitSuperMethodCompound(
-            node, semantics.element, operator, node.arguments.single, arg);
-      case AccessKind.SUPER_GETTER:
-        // This is not a valid case.
-        break;
-      case AccessKind.SUPER_SETTER:
-        // This is not a valid case.
-        break;
-      case AccessKind.CONSTANT:
-        // TODO(johnniwinther): Should this be a valid case?
-        break;
-      case AccessKind.UNRESOLVED_SUPER:
-        return visitor.visitUnresolvedSuperCompound(
-            node, semantics.element, operator, node.arguments.single, arg);
-      case AccessKind.UNRESOLVED:
-        return visitor.visitUnresolvedCompound(
-            node, semantics.element, operator, node.arguments.single, arg);
-      case AccessKind.INVALID:
-        return visitor.errorInvalidCompound(
-            node, semantics.element, operator, node.arguments.single, arg);
-      case AccessKind.COMPOUND:
-        CompoundAccessSemantics compoundSemantics = semantics;
-        switch (compoundSemantics.compoundAccessKind) {
-          case CompoundAccessKind.STATIC_GETTER_SETTER:
-            return visitor.visitStaticGetterSetterCompound(
-                node,
-                compoundSemantics.getter,
-                compoundSemantics.setter,
-                operator,
-                node.arguments.single,
-                arg);
-          case CompoundAccessKind.STATIC_METHOD_SETTER:
-            return visitor.visitStaticMethodSetterCompound(
-                node,
-                compoundSemantics.getter,
-                compoundSemantics.setter,
-                operator,
-                node.arguments.single,
-                arg);
-          case CompoundAccessKind.UNRESOLVED_STATIC_GETTER:
-            return visitor.visitUnresolvedStaticGetterCompound(
-                node,
-                compoundSemantics.getter,
-                compoundSemantics.setter,
-                operator,
-                node.arguments.single,
-                arg);
-          case CompoundAccessKind.UNRESOLVED_STATIC_SETTER:
-            return visitor.visitUnresolvedStaticSetterCompound(
-                node,
-                compoundSemantics.getter,
-                compoundSemantics.setter,
-                operator,
-                node.arguments.single,
-                arg);
-          case CompoundAccessKind.TOPLEVEL_GETTER_SETTER:
-            return visitor.visitTopLevelGetterSetterCompound(
-                node,
-                compoundSemantics.getter,
-                compoundSemantics.setter,
-                operator,
-                node.arguments.single,
-                arg);
-          case CompoundAccessKind.TOPLEVEL_METHOD_SETTER:
-            return visitor.visitTopLevelMethodSetterCompound(
-                node,
-                compoundSemantics.getter,
-                compoundSemantics.setter,
-                operator,
-                node.arguments.single,
-                arg);
-          case CompoundAccessKind.UNRESOLVED_TOPLEVEL_GETTER:
-            return visitor.visitUnresolvedTopLevelGetterCompound(
-                node,
-                compoundSemantics.getter,
-                compoundSemantics.setter,
-                operator,
-                node.arguments.single,
-                arg);
-          case CompoundAccessKind.UNRESOLVED_TOPLEVEL_SETTER:
-            return visitor.visitUnresolvedTopLevelSetterCompound(
-                node,
-                compoundSemantics.getter,
-                compoundSemantics.setter,
-                operator,
-                node.arguments.single,
-                arg);
-          case CompoundAccessKind.SUPER_FIELD_FIELD:
-            return visitor.visitSuperFieldFieldCompound(
-                node,
-                compoundSemantics.getter,
-                compoundSemantics.setter,
-                operator,
-                node.arguments.single,
-                arg);
-          case CompoundAccessKind.SUPER_GETTER_SETTER:
-            return visitor.visitSuperGetterSetterCompound(
-                node,
-                compoundSemantics.getter,
-                compoundSemantics.setter,
-                operator,
-                node.arguments.single,
-                arg);
-          case CompoundAccessKind.SUPER_GETTER_FIELD:
-            return visitor.visitSuperGetterFieldCompound(
-                node,
-                compoundSemantics.getter,
-                compoundSemantics.setter,
-                operator,
-                node.arguments.single,
-                arg);
-          case CompoundAccessKind.SUPER_METHOD_SETTER:
-            return visitor.visitSuperMethodSetterCompound(
-                node,
-                compoundSemantics.getter,
-                compoundSemantics.setter,
-                operator,
-                node.arguments.single,
-                arg);
-          case CompoundAccessKind.SUPER_FIELD_SETTER:
-            return visitor.visitSuperFieldSetterCompound(
-                node,
-                compoundSemantics.getter,
-                compoundSemantics.setter,
-                operator,
-                node.arguments.single,
-                arg);
-          case CompoundAccessKind.UNRESOLVED_SUPER_GETTER:
-            return visitor.visitUnresolvedSuperGetterCompound(
-                node,
-                compoundSemantics.getter,
-                compoundSemantics.setter,
-                operator,
-                node.arguments.single,
-                arg);
-          case CompoundAccessKind.UNRESOLVED_SUPER_SETTER:
-            return visitor.visitUnresolvedSuperSetterCompound(
-                node,
-                compoundSemantics.getter,
-                compoundSemantics.setter,
-                operator,
-                node.arguments.single,
-                arg);
-        }
-        break;
-    }
-    throw failedAt(node, "Invalid compound assigment: ${semantics}");
-  }
-
-  String toString() => 'compound($operator,$semantics)';
-}
-
-/// The structure for a [Send] that is an if-null assignment. For instance
-/// `a ??= b`.
-class SetIfNullStructure<R, A> implements SendStructure<R, A> {
-  /// The target of the if-null assignment, i.e. the left-hand side.
-  final AccessSemantics semantics;
-
-  SetIfNullStructure(this.semantics);
-
-  @override
-  SendStructureKind get kind => SendStructureKind.SET_IF_NULL;
-
-  R dispatch(SemanticSendVisitor<R, A> visitor, Send node, A arg) {
-    switch (semantics.kind) {
-      case AccessKind.CONDITIONAL_DYNAMIC_PROPERTY:
-        return visitor.visitIfNotNullDynamicPropertySetIfNull(
-            node, node.receiver, semantics.name, node.arguments.single, arg);
-      case AccessKind.DYNAMIC_PROPERTY:
-        return visitor.visitDynamicPropertySetIfNull(
-            node, node.receiver, semantics.name, node.arguments.single, arg);
-      case AccessKind.LOCAL_FUNCTION:
-        return visitor.visitLocalFunctionSetIfNull(
-            node, semantics.element, node.arguments.single, arg);
-      case AccessKind.LOCAL_VARIABLE:
-        return visitor.visitLocalVariableSetIfNull(
-            node, semantics.element, node.arguments.single, arg);
-      case AccessKind.FINAL_LOCAL_VARIABLE:
-        return visitor.visitFinalLocalVariableSetIfNull(
-            node, semantics.element, node.arguments.single, arg);
-      case AccessKind.PARAMETER:
-        return visitor.visitParameterSetIfNull(
-            node, semantics.element, node.arguments.single, arg);
-      case AccessKind.FINAL_PARAMETER:
-        return visitor.visitFinalParameterSetIfNull(
-            node, semantics.element, node.arguments.single, arg);
-      case AccessKind.STATIC_FIELD:
-        return visitor.visitStaticFieldSetIfNull(
-            node, semantics.element, node.arguments.single, arg);
-      case AccessKind.FINAL_STATIC_FIELD:
-        return visitor.visitFinalStaticFieldSetIfNull(
-            node, semantics.element, node.arguments.single, arg);
-      case AccessKind.STATIC_METHOD:
-        return visitor.visitStaticMethodSetIfNull(
-            node, semantics.element, node.arguments.single, arg);
-      case AccessKind.STATIC_GETTER:
-        // This is not a valid case.
-        break;
-      case AccessKind.STATIC_SETTER:
-        // This is not a valid case.
-        break;
-      case AccessKind.TOPLEVEL_FIELD:
-        return visitor.visitTopLevelFieldSetIfNull(
-            node, semantics.element, node.arguments.single, arg);
-      case AccessKind.FINAL_TOPLEVEL_FIELD:
-        return visitor.visitFinalTopLevelFieldSetIfNull(
-            node, semantics.element, node.arguments.single, arg);
-      case AccessKind.TOPLEVEL_METHOD:
-        return visitor.visitTopLevelMethodSetIfNull(
-            node, semantics.element, node.arguments.single, arg);
-      case AccessKind.TOPLEVEL_GETTER:
-        // This is not a valid case.
-        break;
-      case AccessKind.TOPLEVEL_SETTER:
-        // This is not a valid case.
-        break;
-      case AccessKind.CLASS_TYPE_LITERAL:
-        return visitor.visitClassTypeLiteralSetIfNull(
-            node, semantics.constant, node.arguments.single, arg);
-      case AccessKind.TYPEDEF_TYPE_LITERAL:
-        return visitor.visitTypedefTypeLiteralSetIfNull(
-            node, semantics.constant, node.arguments.single, arg);
-      case AccessKind.DYNAMIC_TYPE_LITERAL:
-        return visitor.visitDynamicTypeLiteralSetIfNull(
-            node, semantics.constant, node.arguments.single, arg);
-      case AccessKind.TYPE_PARAMETER_TYPE_LITERAL:
-        return visitor.visitTypeVariableTypeLiteralSetIfNull(
-            node, semantics.element, node.arguments.single, arg);
-      case AccessKind.EXPRESSION:
-        // This is not a valid case.
-        break;
-      case AccessKind.THIS:
-        // This is not a valid case.
-        break;
-      case AccessKind.THIS_PROPERTY:
-        return visitor.visitThisPropertySetIfNull(
-            node, semantics.name, node.arguments.single, arg);
-      case AccessKind.SUPER_FIELD:
-        return visitor.visitSuperFieldSetIfNull(
-            node, semantics.element, node.arguments.single, arg);
-      case AccessKind.SUPER_FINAL_FIELD:
-        return visitor.visitFinalSuperFieldSetIfNull(
-            node, semantics.element, node.arguments.single, arg);
-      case AccessKind.SUPER_METHOD:
-        return visitor.visitSuperMethodSetIfNull(
-            node, semantics.element, node.arguments.single, arg);
-      case AccessKind.SUPER_GETTER:
-        // This is not a valid case.
-        break;
-      case AccessKind.SUPER_SETTER:
-        // This is not a valid case.
-        break;
-      case AccessKind.CONSTANT:
-        // TODO(johnniwinther): Should this be a valid case?
-        break;
-      case AccessKind.UNRESOLVED_SUPER:
-        return visitor.visitUnresolvedSuperSetIfNull(
-            node, semantics.element, node.arguments.single, arg);
-      case AccessKind.UNRESOLVED:
-        return visitor.visitUnresolvedSetIfNull(
-            node, semantics.element, node.arguments.single, arg);
-      case AccessKind.INVALID:
-        return visitor.errorInvalidSetIfNull(
-            node, semantics.element, node.arguments.single, arg);
-      case AccessKind.COMPOUND:
-        CompoundAccessSemantics compoundSemantics = semantics;
-        switch (compoundSemantics.compoundAccessKind) {
-          case CompoundAccessKind.STATIC_GETTER_SETTER:
-            return visitor.visitStaticGetterSetterSetIfNull(
-                node,
-                compoundSemantics.getter,
-                compoundSemantics.setter,
-                node.arguments.single,
-                arg);
-          case CompoundAccessKind.STATIC_METHOD_SETTER:
-            return visitor.visitStaticMethodSetterSetIfNull(
-                node,
-                compoundSemantics.getter,
-                compoundSemantics.setter,
-                node.arguments.single,
-                arg);
-          case CompoundAccessKind.UNRESOLVED_STATIC_GETTER:
-            return visitor.visitUnresolvedStaticGetterSetIfNull(
-                node,
-                compoundSemantics.getter,
-                compoundSemantics.setter,
-                node.arguments.single,
-                arg);
-          case CompoundAccessKind.UNRESOLVED_STATIC_SETTER:
-            return visitor.visitUnresolvedStaticSetterSetIfNull(
-                node,
-                compoundSemantics.getter,
-                compoundSemantics.setter,
-                node.arguments.single,
-                arg);
-          case CompoundAccessKind.TOPLEVEL_GETTER_SETTER:
-            return visitor.visitTopLevelGetterSetterSetIfNull(
-                node,
-                compoundSemantics.getter,
-                compoundSemantics.setter,
-                node.arguments.single,
-                arg);
-          case CompoundAccessKind.TOPLEVEL_METHOD_SETTER:
-            return visitor.visitTopLevelMethodSetterSetIfNull(
-                node,
-                compoundSemantics.getter,
-                compoundSemantics.setter,
-                node.arguments.single,
-                arg);
-          case CompoundAccessKind.UNRESOLVED_TOPLEVEL_GETTER:
-            return visitor.visitUnresolvedTopLevelGetterSetIfNull(
-                node,
-                compoundSemantics.getter,
-                compoundSemantics.setter,
-                node.arguments.single,
-                arg);
-          case CompoundAccessKind.UNRESOLVED_TOPLEVEL_SETTER:
-            return visitor.visitUnresolvedTopLevelSetterSetIfNull(
-                node,
-                compoundSemantics.getter,
-                compoundSemantics.setter,
-                node.arguments.single,
-                arg);
-          case CompoundAccessKind.SUPER_FIELD_FIELD:
-            return visitor.visitSuperFieldFieldSetIfNull(
-                node,
-                compoundSemantics.getter,
-                compoundSemantics.setter,
-                node.arguments.single,
-                arg);
-          case CompoundAccessKind.SUPER_GETTER_SETTER:
-            return visitor.visitSuperGetterSetterSetIfNull(
-                node,
-                compoundSemantics.getter,
-                compoundSemantics.setter,
-                node.arguments.single,
-                arg);
-          case CompoundAccessKind.SUPER_GETTER_FIELD:
-            return visitor.visitSuperGetterFieldSetIfNull(
-                node,
-                compoundSemantics.getter,
-                compoundSemantics.setter,
-                node.arguments.single,
-                arg);
-          case CompoundAccessKind.SUPER_METHOD_SETTER:
-            return visitor.visitSuperMethodSetterSetIfNull(
-                node,
-                compoundSemantics.getter,
-                compoundSemantics.setter,
-                node.arguments.single,
-                arg);
-          case CompoundAccessKind.SUPER_FIELD_SETTER:
-            return visitor.visitSuperFieldSetterSetIfNull(
-                node,
-                compoundSemantics.getter,
-                compoundSemantics.setter,
-                node.arguments.single,
-                arg);
-          case CompoundAccessKind.UNRESOLVED_SUPER_GETTER:
-            return visitor.visitUnresolvedSuperGetterSetIfNull(
-                node,
-                compoundSemantics.getter,
-                compoundSemantics.setter,
-                node.arguments.single,
-                arg);
-          case CompoundAccessKind.UNRESOLVED_SUPER_SETTER:
-            return visitor.visitUnresolvedSuperSetterSetIfNull(
-                node,
-                compoundSemantics.getter,
-                compoundSemantics.setter,
-                node.arguments.single,
-                arg);
-        }
-        break;
-    }
-    throw failedAt(node, "Invalid if-null assigment: ${semantics}");
-  }
-
-  String toString() => 'ifNull($semantics)';
-}
-
-/// The structure for a [Send] that is a compound assignment on the index
-/// operator. For instance `a[b] += c`.
-class CompoundIndexSetStructure<R, A> implements SendStructure<R, A> {
-  /// The target of the index operations.
-  final AccessSemantics semantics;
-
-  /// The assignment operator used in the compound assignment.
-  final AssignmentOperator operator;
-
-  CompoundIndexSetStructure(this.semantics, this.operator);
-
-  @override
-  SendStructureKind get kind => SendStructureKind.COMPOUND_INDEX_SET;
-
-  R dispatch(SemanticSendVisitor<R, A> visitor, Send node, A arg) {
-    switch (semantics.kind) {
-      case AccessKind.EXPRESSION:
-        return visitor.visitCompoundIndexSet(node, node.receiver,
-            node.arguments.first, operator, node.arguments.tail.head, arg);
-      case AccessKind.UNRESOLVED_SUPER:
-        return visitor.visitUnresolvedSuperCompoundIndexSet(
-            node,
-            semantics.element,
-            node.arguments.first,
-            operator,
-            node.arguments.tail.head,
-            arg);
-      case AccessKind.INVALID:
-        return visitor.errorInvalidCompoundIndexSet(node, semantics.element,
-            node.arguments.first, operator, node.arguments.tail.head, arg);
-      case AccessKind.COMPOUND:
-        CompoundAccessSemantics compoundSemantics = semantics;
-        switch (compoundSemantics.compoundAccessKind) {
-          case CompoundAccessKind.SUPER_GETTER_SETTER:
-            return visitor.visitSuperCompoundIndexSet(
-                node,
-                compoundSemantics.getter,
-                compoundSemantics.setter,
-                node.arguments.first,
-                operator,
-                node.arguments.tail.head,
-                arg);
-          case CompoundAccessKind.UNRESOLVED_SUPER_GETTER:
-            return visitor.visitUnresolvedSuperGetterCompoundIndexSet(
-                node,
-                compoundSemantics.getter,
-                compoundSemantics.setter,
-                node.arguments.first,
-                operator,
-                node.arguments.tail.head,
-                arg);
-          case CompoundAccessKind.UNRESOLVED_SUPER_SETTER:
-            return visitor.visitUnresolvedSuperSetterCompoundIndexSet(
-                node,
-                compoundSemantics.getter,
-                compoundSemantics.setter,
-                node.arguments.first,
-                operator,
-                node.arguments.tail.head,
-                arg);
-          default:
-            // This is not a valid case.
-            break;
-        }
-        break;
-      default:
-        // This is not a valid case.
-        break;
-    }
-    throw failedAt(node, "Invalid compound index set: ${semantics}");
-  }
-
-  String toString() => 'compound []=($operator,$semantics)';
-}
-
-/// The structure for a [Send] that is a if-null assignment on the index
-/// operator. For instance `a[b] ??= c`.
-class IndexSetIfNullStructure<R, A> implements SendStructure<R, A> {
-  /// The target of the index operations.
-  final AccessSemantics semantics;
-
-  IndexSetIfNullStructure(this.semantics);
-
-  @override
-  SendStructureKind get kind => SendStructureKind.INDEX_SET_IF_NULL;
-
-  R dispatch(SemanticSendVisitor<R, A> visitor, Send node, A arg) {
-    switch (semantics.kind) {
-      case AccessKind.EXPRESSION:
-        return visitor.visitIndexSetIfNull(node, node.receiver,
-            node.arguments.first, node.arguments.tail.head, arg);
-      case AccessKind.UNRESOLVED_SUPER:
-        return visitor.visitUnresolvedSuperIndexSetIfNull(
-            node,
-            semantics.element,
-            node.arguments.first,
-            node.arguments.tail.head,
-            arg);
-      case AccessKind.INVALID:
-        return visitor.errorInvalidIndexSetIfNull(node, semantics.element,
-            node.arguments.first, node.arguments.tail.head, arg);
-      case AccessKind.COMPOUND:
-        CompoundAccessSemantics compoundSemantics = semantics;
-        switch (compoundSemantics.compoundAccessKind) {
-          case CompoundAccessKind.SUPER_GETTER_SETTER:
-            return visitor.visitSuperIndexSetIfNull(
-                node,
-                compoundSemantics.getter,
-                compoundSemantics.setter,
-                node.arguments.first,
-                node.arguments.tail.head,
-                arg);
-          case CompoundAccessKind.UNRESOLVED_SUPER_GETTER:
-            return visitor.visitUnresolvedSuperGetterIndexSetIfNull(
-                node,
-                compoundSemantics.getter,
-                compoundSemantics.setter,
-                node.arguments.first,
-                node.arguments.tail.head,
-                arg);
-          case CompoundAccessKind.UNRESOLVED_SUPER_SETTER:
-            return visitor.visitUnresolvedSuperSetterIndexSetIfNull(
-                node,
-                compoundSemantics.getter,
-                compoundSemantics.setter,
-                node.arguments.first,
-                node.arguments.tail.head,
-                arg);
-          default:
-            // This is not a valid case.
-            break;
-        }
-        break;
-      default:
-        // This is not a valid case.
-        break;
-    }
-    throw failedAt(node, "Invalid index set if-null: ${semantics}");
-  }
-
-  String toString() => 'index set if-null []??=($semantics)';
-}
-
-/// The structure for a [Send] that is a prefix operations. For instance
-/// `++a`.
-class PrefixStructure<R, A> implements SendStructure<R, A> {
-  /// The target of the prefix operation.
-  final AccessSemantics semantics;
-
-  /// The `++` or `--` operator used in the operation.
-  final IncDecOperator operator;
-
-  PrefixStructure(this.semantics, this.operator);
-
-  @override
-  SendStructureKind get kind => SendStructureKind.PREFIX;
-
-  R dispatch(SemanticSendVisitor<R, A> visitor, Send node, A arg) {
-    switch (semantics.kind) {
-      case AccessKind.CONDITIONAL_DYNAMIC_PROPERTY:
-        return visitor.visitIfNotNullDynamicPropertyPrefix(
-            node, node.receiver, semantics.name, operator, arg);
-      case AccessKind.DYNAMIC_PROPERTY:
-        return visitor.visitDynamicPropertyPrefix(
-            node, node.receiver, semantics.name, operator, arg);
-      case AccessKind.LOCAL_FUNCTION:
-        return visitor.visitLocalFunctionPrefix(
-            node, semantics.element, operator, arg);
-      case AccessKind.LOCAL_VARIABLE:
-        return visitor.visitLocalVariablePrefix(
-            node, semantics.element, operator, arg);
-      case AccessKind.FINAL_LOCAL_VARIABLE:
-        return visitor.visitFinalLocalVariablePrefix(
-            node, semantics.element, operator, arg);
-      case AccessKind.PARAMETER:
-        return visitor.visitParameterPrefix(
-            node, semantics.element, operator, arg);
-      case AccessKind.FINAL_PARAMETER:
-        return visitor.visitFinalParameterPrefix(
-            node, semantics.element, operator, arg);
-      case AccessKind.STATIC_FIELD:
-        return visitor.visitStaticFieldPrefix(
-            node, semantics.element, operator, arg);
-      case AccessKind.FINAL_STATIC_FIELD:
-        return visitor.visitFinalStaticFieldPrefix(
-            node, semantics.element, operator, arg);
-      case AccessKind.STATIC_METHOD:
-        return visitor.visitStaticMethodPrefix(
-            node, semantics.element, operator, arg);
-      case AccessKind.STATIC_GETTER:
-        // This is not a valid case.
-        break;
-      case AccessKind.STATIC_SETTER:
-        // This is not a valid case.
-        break;
-      case AccessKind.TOPLEVEL_FIELD:
-        return visitor.visitTopLevelFieldPrefix(
-            node, semantics.element, operator, arg);
-      case AccessKind.FINAL_TOPLEVEL_FIELD:
-        return visitor.visitFinalTopLevelFieldPrefix(
-            node, semantics.element, operator, arg);
-      case AccessKind.TOPLEVEL_METHOD:
-        return visitor.visitTopLevelMethodPrefix(
-            node, semantics.element, operator, arg);
-      case AccessKind.TOPLEVEL_GETTER:
-        // This is not a valid case.
-        break;
-      case AccessKind.TOPLEVEL_SETTER:
-        // This is not a valid case.
-        break;
-      case AccessKind.CLASS_TYPE_LITERAL:
-        return visitor.visitClassTypeLiteralPrefix(
-            node, semantics.constant, operator, arg);
-      case AccessKind.TYPEDEF_TYPE_LITERAL:
-        return visitor.visitTypedefTypeLiteralPrefix(
-            node, semantics.constant, operator, arg);
-      case AccessKind.DYNAMIC_TYPE_LITERAL:
-        return visitor.visitDynamicTypeLiteralPrefix(
-            node, semantics.constant, operator, arg);
-      case AccessKind.TYPE_PARAMETER_TYPE_LITERAL:
-        return visitor.visitTypeVariableTypeLiteralPrefix(
-            node, semantics.element, operator, arg);
-      case AccessKind.EXPRESSION:
-        // This is not a valid case.
-        break;
-      case AccessKind.THIS:
-        // This is not a valid case.
-        break;
-      case AccessKind.THIS_PROPERTY:
-        return visitor.visitThisPropertyPrefix(
-            node, semantics.name, operator, arg);
-      case AccessKind.SUPER_FIELD:
-        return visitor.visitSuperFieldPrefix(
-            node, semantics.element, operator, arg);
-      case AccessKind.SUPER_FINAL_FIELD:
-        return visitor.visitFinalSuperFieldPrefix(
-            node, semantics.element, operator, arg);
-      case AccessKind.SUPER_METHOD:
-        return visitor.visitSuperMethodPrefix(
-            node, semantics.element, operator, arg);
-      case AccessKind.SUPER_GETTER:
-        // This is not a valid case.
-        break;
-      case AccessKind.SUPER_SETTER:
-        // This is not a valid case.
-        break;
-      case AccessKind.CONSTANT:
-        // TODO(johnniwinther): Should this be a valid case?
-        break;
-      case AccessKind.UNRESOLVED_SUPER:
-        return visitor.visitUnresolvedSuperPrefix(
-            node, semantics.element, operator, arg);
-      case AccessKind.UNRESOLVED:
-        return visitor.visitUnresolvedPrefix(
-            node, semantics.element, operator, arg);
-      case AccessKind.INVALID:
-        return visitor.errorInvalidPrefix(
-            node, semantics.element, operator, arg);
-      case AccessKind.COMPOUND:
-        CompoundAccessSemantics compoundSemantics = semantics;
-        switch (compoundSemantics.compoundAccessKind) {
-          case CompoundAccessKind.STATIC_GETTER_SETTER:
-            return visitor.visitStaticGetterSetterPrefix(
-                node,
-                compoundSemantics.getter,
-                compoundSemantics.setter,
-                operator,
-                arg);
-          case CompoundAccessKind.STATIC_METHOD_SETTER:
-            return visitor.visitStaticMethodSetterPrefix(
-                node,
-                compoundSemantics.getter,
-                compoundSemantics.setter,
-                operator,
-                arg);
-          case CompoundAccessKind.UNRESOLVED_STATIC_GETTER:
-            return visitor.visitUnresolvedStaticGetterPrefix(
-                node,
-                compoundSemantics.getter,
-                compoundSemantics.setter,
-                operator,
-                arg);
-          case CompoundAccessKind.UNRESOLVED_STATIC_SETTER:
-            return visitor.visitUnresolvedStaticSetterPrefix(
-                node,
-                compoundSemantics.getter,
-                compoundSemantics.setter,
-                operator,
-                arg);
-          case CompoundAccessKind.STATIC_METHOD_SETTER:
-            return visitor.visitStaticMethodSetterPrefix(
-                node,
-                compoundSemantics.getter,
-                compoundSemantics.setter,
-                operator,
-                arg);
-          case CompoundAccessKind.TOPLEVEL_GETTER_SETTER:
-            return visitor.visitTopLevelGetterSetterPrefix(
-                node,
-                compoundSemantics.getter,
-                compoundSemantics.setter,
-                operator,
-                arg);
-          case CompoundAccessKind.TOPLEVEL_METHOD_SETTER:
-            return visitor.visitTopLevelMethodSetterPrefix(
-                node,
-                compoundSemantics.getter,
-                compoundSemantics.setter,
-                operator,
-                arg);
-          case CompoundAccessKind.UNRESOLVED_TOPLEVEL_GETTER:
-            return visitor.visitUnresolvedTopLevelGetterPrefix(
-                node,
-                compoundSemantics.getter,
-                compoundSemantics.setter,
-                operator,
-                arg);
-          case CompoundAccessKind.UNRESOLVED_TOPLEVEL_SETTER:
-            return visitor.visitUnresolvedTopLevelSetterPrefix(
-                node,
-                compoundSemantics.getter,
-                compoundSemantics.setter,
-                operator,
-                arg);
-          case CompoundAccessKind.SUPER_FIELD_FIELD:
-            return visitor.visitSuperFieldFieldPrefix(
-                node,
-                compoundSemantics.getter,
-                compoundSemantics.setter,
-                operator,
-                arg);
-          case CompoundAccessKind.SUPER_GETTER_SETTER:
-            return visitor.visitSuperGetterSetterPrefix(
-                node,
-                compoundSemantics.getter,
-                compoundSemantics.setter,
-                operator,
-                arg);
-          case CompoundAccessKind.SUPER_GETTER_FIELD:
-            return visitor.visitSuperGetterFieldPrefix(
-                node,
-                compoundSemantics.getter,
-                compoundSemantics.setter,
-                operator,
-                arg);
-          case CompoundAccessKind.SUPER_METHOD_SETTER:
-            return visitor.visitSuperMethodSetterPrefix(
-                node,
-                compoundSemantics.getter,
-                compoundSemantics.setter,
-                operator,
-                arg);
-          case CompoundAccessKind.SUPER_FIELD_SETTER:
-            return visitor.visitSuperFieldSetterPrefix(
-                node,
-                compoundSemantics.getter,
-                compoundSemantics.setter,
-                operator,
-                arg);
-          case CompoundAccessKind.UNRESOLVED_SUPER_GETTER:
-            return visitor.visitUnresolvedSuperGetterPrefix(
-                node,
-                compoundSemantics.getter,
-                compoundSemantics.setter,
-                operator,
-                arg);
-          case CompoundAccessKind.UNRESOLVED_SUPER_SETTER:
-            return visitor.visitUnresolvedSuperSetterPrefix(
-                node,
-                compoundSemantics.getter,
-                compoundSemantics.setter,
-                operator,
-                arg);
-        }
-    }
-    throw failedAt(node, "Invalid compound assigment: ${semantics}");
-  }
-
-  String toString() => 'prefix($operator,$semantics)';
-}
-
-/// The structure for a [Send] that is a postfix operations. For instance
-/// `a++`.
-class PostfixStructure<R, A> implements SendStructure<R, A> {
-  /// The target of the postfix operation.
-  final AccessSemantics semantics;
-
-  /// The `++` or `--` operator used in the operation.
-  final IncDecOperator operator;
-
-  PostfixStructure(this.semantics, this.operator);
-
-  @override
-  SendStructureKind get kind => SendStructureKind.POSTFIX;
-
-  R dispatch(SemanticSendVisitor<R, A> visitor, Send node, A arg) {
-    switch (semantics.kind) {
-      case AccessKind.CONDITIONAL_DYNAMIC_PROPERTY:
-        return visitor.visitIfNotNullDynamicPropertyPostfix(
-            node, node.receiver, semantics.name, operator, arg);
-      case AccessKind.DYNAMIC_PROPERTY:
-        return visitor.visitDynamicPropertyPostfix(
-            node, node.receiver, semantics.name, operator, arg);
-      case AccessKind.LOCAL_FUNCTION:
-        return visitor.visitLocalFunctionPostfix(
-            node, semantics.element, operator, arg);
-      case AccessKind.LOCAL_VARIABLE:
-        return visitor.visitLocalVariablePostfix(
-            node, semantics.element, operator, arg);
-      case AccessKind.FINAL_LOCAL_VARIABLE:
-        return visitor.visitFinalLocalVariablePostfix(
-            node, semantics.element, operator, arg);
-      case AccessKind.PARAMETER:
-        return visitor.visitParameterPostfix(
-            node, semantics.element, operator, arg);
-      case AccessKind.FINAL_PARAMETER:
-        return visitor.visitFinalParameterPostfix(
-            node, semantics.element, operator, arg);
-      case AccessKind.STATIC_FIELD:
-        return visitor.visitStaticFieldPostfix(
-            node, semantics.element, operator, arg);
-      case AccessKind.FINAL_STATIC_FIELD:
-        return visitor.visitFinalStaticFieldPostfix(
-            node, semantics.element, operator, arg);
-      case AccessKind.STATIC_METHOD:
-        return visitor.visitStaticMethodPostfix(
-            node, semantics.element, operator, arg);
-      case AccessKind.STATIC_GETTER:
-        // This is not a valid case.
-        break;
-      case AccessKind.STATIC_SETTER:
-        // This is not a valid case.
-        break;
-      case AccessKind.TOPLEVEL_FIELD:
-        return visitor.visitTopLevelFieldPostfix(
-            node, semantics.element, operator, arg);
-      case AccessKind.FINAL_TOPLEVEL_FIELD:
-        return visitor.visitFinalTopLevelFieldPostfix(
-            node, semantics.element, operator, arg);
-      case AccessKind.TOPLEVEL_METHOD:
-        return visitor.visitTopLevelMethodPostfix(
-            node, semantics.element, operator, arg);
-      case AccessKind.TOPLEVEL_GETTER:
-        // This is not a valid case.
-        break;
-      case AccessKind.TOPLEVEL_SETTER:
-        // This is not a valid case.
-        break;
-      case AccessKind.CLASS_TYPE_LITERAL:
-        return visitor.visitClassTypeLiteralPostfix(
-            node, semantics.constant, operator, arg);
-      case AccessKind.TYPEDEF_TYPE_LITERAL:
-        return visitor.visitTypedefTypeLiteralPostfix(
-            node, semantics.constant, operator, arg);
-      case AccessKind.DYNAMIC_TYPE_LITERAL:
-        return visitor.visitDynamicTypeLiteralPostfix(
-            node, semantics.constant, operator, arg);
-      case AccessKind.TYPE_PARAMETER_TYPE_LITERAL:
-        return visitor.visitTypeVariableTypeLiteralPostfix(
-            node, semantics.element, operator, arg);
-      case AccessKind.EXPRESSION:
-        // This is not a valid case.
-        break;
-      case AccessKind.THIS:
-        // This is not a valid case.
-        break;
-      case AccessKind.THIS_PROPERTY:
-        return visitor.visitThisPropertyPostfix(
-            node, semantics.name, operator, arg);
-      case AccessKind.SUPER_FIELD:
-        return visitor.visitSuperFieldPostfix(
-            node, semantics.element, operator, arg);
-      case AccessKind.SUPER_FINAL_FIELD:
-        return visitor.visitFinalSuperFieldPostfix(
-            node, semantics.element, operator, arg);
-      case AccessKind.SUPER_METHOD:
-        return visitor.visitSuperMethodPostfix(
-            node, semantics.element, operator, arg);
-      case AccessKind.SUPER_GETTER:
-        // This is not a valid case.
-        break;
-      case AccessKind.SUPER_SETTER:
-        // This is not a valid case.
-        break;
-      case AccessKind.CONSTANT:
-        // TODO(johnniwinther): Should this be a valid case?
-        break;
-      case AccessKind.UNRESOLVED_SUPER:
-        return visitor.visitUnresolvedSuperPostfix(
-            node, semantics.element, operator, arg);
-      case AccessKind.UNRESOLVED:
-        return visitor.visitUnresolvedPostfix(
-            node, semantics.element, operator, arg);
-      case AccessKind.INVALID:
-        return visitor.errorInvalidPostfix(
-            node, semantics.element, operator, arg);
-      case AccessKind.COMPOUND:
-        CompoundAccessSemantics compoundSemantics = semantics;
-        switch (compoundSemantics.compoundAccessKind) {
-          case CompoundAccessKind.STATIC_GETTER_SETTER:
-            return visitor.visitStaticGetterSetterPostfix(
-                node,
-                compoundSemantics.getter,
-                compoundSemantics.setter,
-                operator,
-                arg);
-          case CompoundAccessKind.UNRESOLVED_STATIC_GETTER:
-            return visitor.visitUnresolvedStaticGetterPostfix(
-                node,
-                compoundSemantics.getter,
-                compoundSemantics.setter,
-                operator,
-                arg);
-          case CompoundAccessKind.UNRESOLVED_STATIC_SETTER:
-            return visitor.visitUnresolvedStaticSetterPostfix(
-                node,
-                compoundSemantics.getter,
-                compoundSemantics.setter,
-                operator,
-                arg);
-          case CompoundAccessKind.STATIC_METHOD_SETTER:
-            return visitor.visitStaticMethodSetterPostfix(
-                node,
-                compoundSemantics.getter,
-                compoundSemantics.setter,
-                operator,
-                arg);
-          case CompoundAccessKind.TOPLEVEL_GETTER_SETTER:
-            return visitor.visitTopLevelGetterSetterPostfix(
-                node,
-                compoundSemantics.getter,
-                compoundSemantics.setter,
-                operator,
-                arg);
-          case CompoundAccessKind.TOPLEVEL_METHOD_SETTER:
-            return visitor.visitTopLevelMethodSetterPostfix(
-                node,
-                compoundSemantics.getter,
-                compoundSemantics.setter,
-                operator,
-                arg);
-          case CompoundAccessKind.UNRESOLVED_TOPLEVEL_GETTER:
-            return visitor.visitUnresolvedTopLevelGetterPostfix(
-                node,
-                compoundSemantics.getter,
-                compoundSemantics.setter,
-                operator,
-                arg);
-          case CompoundAccessKind.UNRESOLVED_TOPLEVEL_SETTER:
-            return visitor.visitUnresolvedTopLevelSetterPostfix(
-                node,
-                compoundSemantics.getter,
-                compoundSemantics.setter,
-                operator,
-                arg);
-          case CompoundAccessKind.SUPER_FIELD_FIELD:
-            return visitor.visitSuperFieldFieldPostfix(
-                node,
-                compoundSemantics.getter,
-                compoundSemantics.setter,
-                operator,
-                arg);
-          case CompoundAccessKind.SUPER_GETTER_SETTER:
-            return visitor.visitSuperGetterSetterPostfix(
-                node,
-                compoundSemantics.getter,
-                compoundSemantics.setter,
-                operator,
-                arg);
-          case CompoundAccessKind.SUPER_GETTER_FIELD:
-            return visitor.visitSuperGetterFieldPostfix(
-                node,
-                compoundSemantics.getter,
-                compoundSemantics.setter,
-                operator,
-                arg);
-          case CompoundAccessKind.SUPER_METHOD_SETTER:
-            return visitor.visitSuperMethodSetterPostfix(
-                node,
-                compoundSemantics.getter,
-                compoundSemantics.setter,
-                operator,
-                arg);
-          case CompoundAccessKind.SUPER_FIELD_SETTER:
-            return visitor.visitSuperFieldSetterPostfix(
-                node,
-                compoundSemantics.getter,
-                compoundSemantics.setter,
-                operator,
-                arg);
-          case CompoundAccessKind.UNRESOLVED_SUPER_GETTER:
-            return visitor.visitUnresolvedSuperGetterPostfix(
-                node,
-                compoundSemantics.getter,
-                compoundSemantics.setter,
-                operator,
-                arg);
-          case CompoundAccessKind.UNRESOLVED_SUPER_SETTER:
-            return visitor.visitUnresolvedSuperSetterPostfix(
-                node,
-                compoundSemantics.getter,
-                compoundSemantics.setter,
-                operator,
-                arg);
-        }
-    }
-    throw failedAt(node, "Invalid compound assigment: ${semantics}");
-  }
-
-  String toString() => 'postfix($operator,$semantics)';
-}
-
-/// The structure for a [Send] whose prefix is a prefix for a deferred library.
-/// For instance `deferred.a` where `deferred` is a deferred prefix.
-class DeferredPrefixStructure<R, A> implements SendStructure<R, A> {
-  /// The deferred prefix element.
-  final PrefixElement prefix;
-
-  /// The send structure for the whole [Send] node. For instance a
-  /// [GetStructure] for `deferred.a` where `a` is a top level member of the
-  /// deferred library.
-  final SendStructure sendStructure;
-
-  DeferredPrefixStructure(this.prefix, this.sendStructure) {
-    assert(sendStructure != null);
-  }
-
-  @override
-  SendStructureKind get kind => SendStructureKind.DEFERRED_PREFIX;
-
-  @override
-  R dispatch(SemanticSendVisitor<R, A> visitor, Send send, A arg) {
-    visitor.previsitDeferredAccess(send, prefix, arg);
-    return sendStructure.dispatch(visitor, send, arg);
-  }
-}
-
-enum NewStructureKind {
-  NEW_INVOKE,
-  CONST_INVOKE,
-  LATE_CONST,
-}
-
-/// The structure for a [NewExpression] of a new invocation.
-abstract class NewStructure<R, A> implements SemanticSendStructure<R, A> {
-  /// Calls the matching visit method on [visitor] with [node] and [arg].
-  R dispatch(SemanticSendVisitor<R, A> visitor, NewExpression node, A arg);
-
-  NewStructureKind get kind;
-}
-
-/// The structure for a [NewExpression] of a new invocation. For instance
-/// `new C()`.
-class NewInvokeStructure<R, A> extends NewStructure<R, A> {
-  final ConstructorAccessSemantics semantics;
-  final Selector selector;
-
-  NewInvokeStructure(this.semantics, this.selector);
-
-  @override
-  NewStructureKind get kind => NewStructureKind.NEW_INVOKE;
-
-  CallStructure get callStructure => selector.callStructure;
-
-  R dispatch(SemanticSendVisitor<R, A> visitor, NewExpression node, A arg) {
-    switch (semantics.kind) {
-      case ConstructorAccessKind.GENERATIVE:
-        ConstructorElement constructor = semantics.element;
-        if (constructor.isRedirectingGenerative) {
-          return visitor.visitRedirectingGenerativeConstructorInvoke(
-              node,
-              constructor,
-              semantics.type,
-              node.send.argumentsNode,
-              callStructure,
-              arg);
-        }
-        return visitor.visitGenerativeConstructorInvoke(node, constructor,
-            semantics.type, node.send.argumentsNode, callStructure, arg);
-      case ConstructorAccessKind.FACTORY:
-        ConstructorElement constructor = semantics.element;
-        if (constructor.isRedirectingFactory) {
-          if (constructor.isEffectiveTargetMalformed) {
-            return visitor.visitUnresolvedRedirectingFactoryConstructorInvoke(
-                node,
-                semantics.element,
-                semantics.type,
-                node.send.argumentsNode,
-                callStructure,
-                arg);
-          }
-          ConstructorElement effectiveTarget = constructor.effectiveTarget;
-          ResolutionInterfaceType effectiveTargetType =
-              constructor.computeEffectiveTargetType(semantics.type);
-          if (callStructure
-              .signatureApplies(effectiveTarget.parameterStructure)) {
-            return visitor.visitRedirectingFactoryConstructorInvoke(
-                node,
-                semantics.element,
-                semantics.type,
-                effectiveTarget,
-                effectiveTargetType,
-                node.send.argumentsNode,
-                callStructure,
-                arg);
-          } else {
-            return visitor.visitUnresolvedRedirectingFactoryConstructorInvoke(
-                node,
-                semantics.element,
-                semantics.type,
-                node.send.argumentsNode,
-                callStructure,
-                arg);
-          }
-        }
-        if (callStructure.signatureApplies(constructor.parameterStructure)) {
-          return visitor.visitFactoryConstructorInvoke(node, constructor,
-              semantics.type, node.send.argumentsNode, callStructure, arg);
-        }
-        return visitor.visitConstructorIncompatibleInvoke(node, constructor,
-            semantics.type, node.send.argumentsNode, callStructure, arg);
-      case ConstructorAccessKind.ABSTRACT:
-        return visitor.visitAbstractClassConstructorInvoke(
-            node,
-            semantics.element,
-            semantics.type,
-            node.send.argumentsNode,
-            callStructure,
-            arg);
-      case ConstructorAccessKind.UNRESOLVED_CONSTRUCTOR:
-        return visitor.visitUnresolvedConstructorInvoke(node, semantics.element,
-            semantics.type, node.send.argumentsNode, selector, arg);
-      case ConstructorAccessKind.UNRESOLVED_TYPE:
-        return visitor.visitUnresolvedClassConstructorInvoke(
-            node,
-            semantics.element,
-            semantics.type,
-            node.send.argumentsNode,
-            selector,
-            arg);
-      case ConstructorAccessKind.NON_CONSTANT_CONSTRUCTOR:
-        return visitor.errorNonConstantConstructorInvoke(
-            node,
-            semantics.element,
-            semantics.type,
-            node.send.argumentsNode,
-            callStructure,
-            arg);
-      case ConstructorAccessKind.INCOMPATIBLE:
-        return visitor.visitConstructorIncompatibleInvoke(
-            node,
-            semantics.element,
-            semantics.type,
-            node.send.argumentsNode,
-            callStructure,
-            arg);
-    }
-    throw failedAt(
-        node, "Unhandled constructor invocation kind: ${semantics.kind}");
-  }
-
-  String toString() => 'new($semantics,$selector)';
-}
-
-enum ConstantInvokeKind {
-  CONSTRUCTED,
-  BOOL_FROM_ENVIRONMENT,
-  INT_FROM_ENVIRONMENT,
-  STRING_FROM_ENVIRONMENT,
-}
-
-/// The structure for a [NewExpression] of a constant invocation. For instance
-/// `const C()`.
-class ConstInvokeStructure<R, A> extends NewStructure<R, A> {
-  final ConstantInvokeKind constantInvokeKind;
-  final ConstantExpression constant;
-
-  ConstInvokeStructure(this.constantInvokeKind, this.constant);
-
-  @override
-  NewStructureKind get kind => NewStructureKind.CONST_INVOKE;
-
-  // ignore: MISSING_RETURN
-  R dispatch(SemanticSendVisitor<R, A> visitor, NewExpression node, A arg) {
-    switch (constantInvokeKind) {
-      case ConstantInvokeKind.CONSTRUCTED:
-        return visitor.visitConstConstructorInvoke(node, constant, arg);
-      case ConstantInvokeKind.BOOL_FROM_ENVIRONMENT:
-        return visitor.visitBoolFromEnvironmentConstructorInvoke(
-            node, constant, arg);
-      case ConstantInvokeKind.INT_FROM_ENVIRONMENT:
-        return visitor.visitIntFromEnvironmentConstructorInvoke(
-            node, constant, arg);
-      case ConstantInvokeKind.STRING_FROM_ENVIRONMENT:
-        return visitor.visitStringFromEnvironmentConstructorInvoke(
-            node, constant, arg);
-    }
-  }
-}
-
-/// A constant constructor invocation that couldn't be determined fully during
-/// resolution.
-// TODO(johnniwinther): Remove this when all constants are computed during
-// resolution.
-class LateConstInvokeStructure<R, A> extends NewStructure<R, A> {
-  final TreeElements elements;
-
-  LateConstInvokeStructure(this.elements);
-
-  @override
-  NewStructureKind get kind => NewStructureKind.LATE_CONST;
-
-  /// Convert this new structure into a regular new structure using the data
-  /// available in [elements].
-  NewStructure resolve(NewExpression node) {
-    Element element = elements[node.send];
-    Selector selector = elements.getSelector(node.send);
-    ResolutionDartType type = elements.getType(node);
-    ConstantExpression constant = elements.getConstant(node);
-    if (element.isMalformed ||
-        constant == null ||
-        constant.kind == ConstantExpressionKind.ERRONEOUS) {
-      // This is a non-constant constant constructor invocation, like
-      // `const Const(method())`.
-      return new NewInvokeStructure(
-          new ConstructorAccessSemantics(
-              ConstructorAccessKind.NON_CONSTANT_CONSTRUCTOR, element, type),
-          selector);
-    } else {
-      ConstantInvokeKind kind;
-      switch (constant.kind) {
-        case ConstantExpressionKind.CONSTRUCTED:
-          kind = ConstantInvokeKind.CONSTRUCTED;
-          break;
-        case ConstantExpressionKind.BOOL_FROM_ENVIRONMENT:
-          kind = ConstantInvokeKind.BOOL_FROM_ENVIRONMENT;
-          break;
-        case ConstantExpressionKind.INT_FROM_ENVIRONMENT:
-          kind = ConstantInvokeKind.INT_FROM_ENVIRONMENT;
-          break;
-        case ConstantExpressionKind.STRING_FROM_ENVIRONMENT:
-          kind = ConstantInvokeKind.STRING_FROM_ENVIRONMENT;
-          break;
-        default:
-          throw failedAt(
-              node, "Unexpected constant kind $kind: ${constant.toDartText()}");
-      }
-      return new ConstInvokeStructure(kind, constant);
-    }
-  }
-
-  R dispatch(SemanticSendVisitor<R, A> visitor, NewExpression node, A arg) {
-    Element element = elements[node.send];
-    Selector selector = elements.getSelector(node.send);
-    ResolutionDartType type = elements.getType(node);
-    ConstantExpression constant = elements.getConstant(node);
-    if (element.isMalformed ||
-        constant == null ||
-        constant.kind == ConstantExpressionKind.ERRONEOUS) {
-      // This is a non-constant constant constructor invocation, like
-      // `const Const(method())`.
-      return visitor.errorNonConstantConstructorInvoke(node, element, type,
-          node.send.argumentsNode, selector.callStructure, arg);
-    } else {
-      ConstantInvokeKind kind;
-      switch (constant.kind) {
-        case ConstantExpressionKind.CONSTRUCTED:
-          return visitor.visitConstConstructorInvoke(node, constant, arg);
-        case ConstantExpressionKind.BOOL_FROM_ENVIRONMENT:
-          return visitor.visitBoolFromEnvironmentConstructorInvoke(
-              node, constant, arg);
-        case ConstantExpressionKind.INT_FROM_ENVIRONMENT:
-          return visitor.visitIntFromEnvironmentConstructorInvoke(
-              node, constant, arg);
-        case ConstantExpressionKind.STRING_FROM_ENVIRONMENT:
-          return visitor.visitStringFromEnvironmentConstructorInvoke(
-              node, constant, arg);
-        default:
-          throw failedAt(
-              node, "Unexpected constant kind $kind: ${constant.toDartText()}");
-      }
-    }
-  }
-}
-
-/// The structure of a parameter declaration.
-abstract class ParameterStructure<R, A> {
-  final VariableDefinitions definitions;
-  final Node node;
-  final ParameterElement parameter;
-
-  ParameterStructure(this.definitions, this.node, this.parameter);
-
-  /// Calls the matching visit method on [visitor] with [definitions] and [arg].
-  R dispatch(SemanticDeclarationVisitor<R, A> visitor, A arg);
-}
-
-/// The structure of a required parameter declaration.
-class RequiredParameterStructure<R, A> extends ParameterStructure<R, A> {
-  final int index;
-
-  RequiredParameterStructure(VariableDefinitions definitions, Node node,
-      ParameterElement parameter, this.index)
-      : super(definitions, node, parameter);
-
-  @override
-  R dispatch(SemanticDeclarationVisitor<R, A> visitor, A arg) {
-    if (parameter.isInitializingFormal) {
-      return visitor.visitInitializingFormalDeclaration(
-          definitions, node, parameter, index, arg);
-    } else {
-      return visitor.visitParameterDeclaration(
-          definitions, node, parameter, index, arg);
-    }
-  }
-}
-
-/// The structure of a optional positional parameter declaration.
-class OptionalParameterStructure<R, A> extends ParameterStructure<R, A> {
-  final ConstantExpression defaultValue;
-  final int index;
-
-  OptionalParameterStructure(VariableDefinitions definitions, Node node,
-      ParameterElement parameter, this.defaultValue, this.index)
-      : super(definitions, node, parameter);
-
-  @override
-  R dispatch(SemanticDeclarationVisitor<R, A> visitor, A arg) {
-    if (parameter.isInitializingFormal) {
-      return visitor.visitOptionalInitializingFormalDeclaration(
-          definitions, node, parameter, defaultValue, index, arg);
-    } else {
-      return visitor.visitOptionalParameterDeclaration(
-          definitions, node, parameter, defaultValue, index, arg);
-    }
-  }
-}
-
-/// The structure of a optional named parameter declaration.
-class NamedParameterStructure<R, A> extends ParameterStructure<R, A> {
-  final ConstantExpression defaultValue;
-
-  NamedParameterStructure(VariableDefinitions definitions, Node node,
-      ParameterElement parameter, this.defaultValue)
-      : super(definitions, node, parameter);
-
-  @override
-  R dispatch(SemanticDeclarationVisitor<R, A> visitor, A arg) {
-    if (parameter.isInitializingFormal) {
-      return visitor.visitNamedInitializingFormalDeclaration(
-          definitions, node, parameter, defaultValue, arg);
-    } else {
-      return visitor.visitNamedParameterDeclaration(
-          definitions, node, parameter, defaultValue, arg);
-    }
-  }
-}
-
-enum VariableKind {
-  TOP_LEVEL_FIELD,
-  STATIC_FIELD,
-  INSTANCE_FIELD,
-  LOCAL_VARIABLE,
-}
-
-abstract class VariableStructure<R, A> {
-  final VariableKind kind;
-  final Node node;
-  final VariableElement variable;
-
-  VariableStructure(this.kind, this.node, this.variable);
-
-  R dispatch(SemanticDeclarationVisitor<R, A> visitor,
-      VariableDefinitions definitions, A arg);
-}
-
-class NonConstantVariableStructure<R, A> extends VariableStructure<R, A> {
-  NonConstantVariableStructure(
-      VariableKind kind, Node node, VariableElement variable)
-      : super(kind, node, variable);
-
-  // ignore: MISSING_RETURN
-  R dispatch(SemanticDeclarationVisitor<R, A> visitor,
-      VariableDefinitions definitions, A arg) {
-    switch (kind) {
-      case VariableKind.TOP_LEVEL_FIELD:
-        return visitor.visitTopLevelFieldDeclaration(
-            definitions, node, variable, variable.initializer, arg);
-      case VariableKind.STATIC_FIELD:
-        return visitor.visitStaticFieldDeclaration(
-            definitions, node, variable, variable.initializer, arg);
-      case VariableKind.INSTANCE_FIELD:
-        return visitor.visitInstanceFieldDeclaration(
-            definitions, node, variable, variable.initializer, arg);
-      case VariableKind.LOCAL_VARIABLE:
-        return visitor.visitLocalVariableDeclaration(
-            definitions, node, variable, variable.initializer, arg);
-    }
-  }
-}
-
-class ConstantVariableStructure<R, A> extends VariableStructure<R, A> {
-  final ConstantExpression constant;
-
-  ConstantVariableStructure(
-      VariableKind kind, Node node, VariableElement variable, this.constant)
-      : super(kind, node, variable);
-
-  R dispatch(SemanticDeclarationVisitor<R, A> visitor,
-      VariableDefinitions definitions, A arg) {
-    switch (kind) {
-      case VariableKind.TOP_LEVEL_FIELD:
-        return visitor.visitTopLevelConstantDeclaration(
-            definitions, node, variable, constant, arg);
-      case VariableKind.STATIC_FIELD:
-        return visitor.visitStaticConstantDeclaration(
-            definitions, node, variable, constant, arg);
-      case VariableKind.LOCAL_VARIABLE:
-        return visitor.visitLocalConstantDeclaration(
-            definitions, node, variable, constant, arg);
-      default:
-    }
-    throw failedAt(node, "Invalid constant variable: $variable");
-  }
-}
-
-class InitializersStructure<R, A> {
-  final List<InitializerStructure<R, A>> initializers;
-
-  InitializersStructure(this.initializers);
-}
-
-abstract class InitializerStructure<R, A> {
-  R dispatch(SemanticDeclarationVisitor<R, A> visitor, A arg);
-
-  bool get isConstructorInvoke => false;
-}
-
-class FieldInitializerStructure<R, A> extends InitializerStructure<R, A> {
-  final Send node;
-  final FieldElement field;
-
-  FieldInitializerStructure(this.node, this.field);
-
-  R dispatch(SemanticDeclarationVisitor<R, A> visitor, A arg) {
-    return visitor.visitFieldInitializer(
-        node, field, node.arguments.single, arg);
-  }
-}
-
-class SuperConstructorInvokeStructure<R, A> extends InitializerStructure<R, A> {
-  final Send node;
-  final ConstructorElement constructor;
-  final ResolutionInterfaceType type;
-  final CallStructure callStructure;
-
-  SuperConstructorInvokeStructure(
-      this.node, this.constructor, this.type, this.callStructure);
-
-  R dispatch(SemanticDeclarationVisitor<R, A> visitor, A arg) {
-    return visitor.visitSuperConstructorInvoke(
-        node, constructor, type, node.argumentsNode, callStructure, arg);
-  }
-
-  bool get isConstructorInvoke => true;
-}
-
-class ImplicitSuperConstructorInvokeStructure<R, A>
-    extends InitializerStructure<R, A> {
-  final FunctionExpression node;
-  final ConstructorElement constructor;
-  final ResolutionInterfaceType type;
-
-  ImplicitSuperConstructorInvokeStructure(
-      this.node, this.constructor, this.type);
-
-  R dispatch(SemanticDeclarationVisitor<R, A> visitor, A arg) {
-    return visitor.visitImplicitSuperConstructorInvoke(
-        node, constructor, type, arg);
-  }
-
-  bool get isConstructorInvoke => true;
-}
-
-class ThisConstructorInvokeStructure<R, A> extends InitializerStructure<R, A> {
-  final Send node;
-  final ConstructorElement constructor;
-  final CallStructure callStructure;
-
-  ThisConstructorInvokeStructure(
-      this.node, this.constructor, this.callStructure);
-
-  R dispatch(SemanticDeclarationVisitor<R, A> visitor, A arg) {
-    return visitor.visitThisConstructorInvoke(
-        node, constructor, node.argumentsNode, callStructure, arg);
-  }
-
-  bool get isConstructorInvoke => true;
-}
diff --git a/pkg/compiler/lib/src/resolution/signatures.dart b/pkg/compiler/lib/src/resolution/signatures.dart
deleted file mode 100644
index 36890b2..0000000
--- a/pkg/compiler/lib/src/resolution/signatures.dart
+++ /dev/null
@@ -1,513 +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.
-
-library dart2js.resolution.signatures;
-
-import '../common.dart';
-import '../common/resolution.dart';
-import '../elements/resolution_types.dart';
-import '../elements/elements.dart';
-import '../elements/entities.dart' show AsyncMarker;
-import '../elements/modelx.dart'
-    show
-        ErroneousFieldElementX,
-        ErroneousInitializingFormalElementX,
-        FormalElementX,
-        FunctionSignatureX,
-        InitializingFormalElementX,
-        LocalParameterElementX,
-        TypeVariableElementX;
-import '../elements/names.dart';
-import '../tree/tree.dart';
-import '../util/util.dart' show Link, LinkBuilder;
-import 'members.dart' show ResolverVisitor;
-import 'registry.dart' show ResolutionRegistry;
-import 'resolution_common.dart' show MappingVisitor;
-import 'scope.dart' show Scope, TypeVariablesScope;
-import 'type_resolver.dart' show FunctionTypeParameterScope;
-
-/**
- * [SignatureResolver] resolves function signatures.
- */
-class SignatureResolver extends MappingVisitor<FormalElementX> {
-  final ResolverVisitor resolver;
-  final FunctionTypedElement enclosingElement;
-  final Scope scope;
-  final MessageKind defaultValuesError;
-  final bool createRealParameters;
-  final FunctionTypeParameterScope functionTypeParameters;
-  List<FormalElement> optionalParameters = const <FormalElement>[];
-  int optionalParameterCount = 0;
-  bool isOptionalParameter = false;
-  bool optionalParametersAreNamed = false;
-  VariableDefinitions currentDefinitions;
-
-  SignatureResolver(Resolution resolution, this.enclosingElement, this.scope,
-      this.functionTypeParameters, ResolutionRegistry registry,
-      {this.defaultValuesError, this.createRealParameters})
-      : this.resolver = new ResolverVisitor(
-            resolution, enclosingElement, registry,
-            scope: scope),
-        super(resolution, registry);
-
-  bool get defaultValuesAllowed => defaultValuesError == null;
-
-  visitNodeList(NodeList node) {
-    // This must be a list of optional arguments.
-    String value = node.beginToken.stringValue;
-    if ((!identical(value, '[')) && (!identical(value, '{'))) {
-      reporter.internalError(node, "expected optional parameters");
-    }
-    optionalParametersAreNamed = (identical(value, '{'));
-    isOptionalParameter = true;
-    LinkBuilder<FormalElement> elements = analyzeNodes(node.nodes);
-    optionalParameterCount = elements.length;
-    optionalParameters = elements.toList();
-  }
-
-  FormalElementX visitVariableDefinitions(VariableDefinitions node) {
-    Link<Node> definitions = node.definitions.nodes;
-    if (definitions.isEmpty) {
-      reporter.internalError(node, 'no parameter definition');
-      return null;
-    }
-    if (!definitions.tail.isEmpty) {
-      reporter.internalError(definitions.tail.head, 'extra definition');
-      return null;
-    }
-    Node definition = definitions.head;
-    if (definition is NodeList) {
-      reporter.internalError(node, 'optional parameters are not implemented');
-    }
-    if (node.modifiers.isConst) {
-      reporter.reportErrorMessage(node, MessageKind.FORMAL_DECLARED_CONST);
-    }
-    if (node.modifiers.isStatic) {
-      reporter.reportErrorMessage(node, MessageKind.FORMAL_DECLARED_STATIC);
-    }
-
-    if (currentDefinitions != null) {
-      reporter.internalError(node, 'function type parameters not supported');
-    }
-    currentDefinitions = node;
-    FormalElementX element = definition == null
-        ? createUnnamedParameter() // This happens in function types.
-        : definition.accept(this);
-    if (currentDefinitions.metadata != null) {
-      element.metadataInternal =
-          resolution.resolver.resolveMetadata(element, node);
-    }
-    currentDefinitions = null;
-    return element;
-  }
-
-  void validateName(Identifier node) {
-    if (isOptionalParameter &&
-        optionalParametersAreNamed &&
-        Name.isPrivateName(node.source)) {
-      reporter.reportErrorMessage(node, MessageKind.PRIVATE_NAMED_PARAMETER);
-    }
-  }
-
-  void computeParameterType(FormalElementX element,
-      [VariableElement fieldElement]) {
-    // Function-type as in `foo(int bar(String x))`
-    void computeInlineFunctionType(FunctionExpression functionExpression) {
-      FunctionSignature functionSignature = SignatureResolver.analyze(
-          resolution,
-          scope,
-          functionTypeParameters.expand(functionExpression.typeVariables),
-          null, // Don't create type variable types for the type parameters.
-          functionExpression.parameters,
-          functionExpression.returnType,
-          element,
-          registry,
-          defaultValuesError: MessageKind.FUNCTION_TYPE_FORMAL_WITH_DEFAULT);
-      element.functionSignature = functionSignature;
-    }
-
-    if (currentDefinitions.type != null) {
-      element.typeCache = resolveTypeAnnotation(currentDefinitions.type);
-    } else {
-      // Is node.definitions exactly one FunctionExpression?
-      Link<Node> link = currentDefinitions.definitions.nodes;
-      assert(!link.isEmpty, failedAt(currentDefinitions));
-      assert(link.tail.isEmpty, failedAt(currentDefinitions));
-      if (link.head.asFunctionExpression() != null) {
-        // Inline function typed parameter, like `void m(int f(String s))`.
-        computeInlineFunctionType(link.head);
-      } else if (link.head.asSend() != null &&
-          link.head.asSend().selector.asFunctionExpression() != null) {
-        // Inline function typed initializing formal or
-        // parameter with default value, like `C(int this.f(String s))` or
-        // `void m([int f(String s) = null])`.
-        computeInlineFunctionType(
-            link.head.asSend().selector.asFunctionExpression());
-      } else {
-        assert(link.head.asIdentifier() != null || link.head.asSend() != null,
-            failedAt(currentDefinitions));
-        if (fieldElement != null) {
-          element.typeCache = fieldElement.computeType(resolution);
-        } else {
-          element.typeCache = const ResolutionDynamicType();
-        }
-      }
-    }
-  }
-
-  FormalElementX visitIdentifier(Identifier node) {
-    return createParameter(node, null);
-  }
-
-  Identifier getParameterName(Send node) {
-    var identifier = node.selector.asIdentifier();
-    if (identifier != null) {
-      // Normal parameter: [:Type name:].
-      return identifier;
-    } else {
-      // Function type parameter: [:void name(DartType arg):].
-      var functionExpression = node.selector.asFunctionExpression();
-      if (functionExpression != null &&
-          functionExpression.name.asIdentifier() != null) {
-        return functionExpression.name.asIdentifier();
-      } else {
-        reporter.internalError(
-            node, 'internal error: unimplemented receiver on parameter send');
-        return null;
-      }
-    }
-  }
-
-  // The only valid [Send] can be in constructors and must be of the form
-  // [:this.x:] (where [:x:] represents an instance field).
-  InitializingFormalElementX visitSend(Send node) {
-    return createFieldParameter(node, null);
-  }
-
-  FormalElementX createParameter(Identifier name, Expression initializer) {
-    validateName(name);
-    FormalElementX parameter;
-    if (createRealParameters) {
-      parameter = new LocalParameterElementX(
-          enclosingElement, currentDefinitions, name, initializer,
-          isOptional: isOptionalParameter, isNamed: optionalParametersAreNamed);
-    } else {
-      parameter = new FormalElementX(
-          ElementKind.PARAMETER, enclosingElement, currentDefinitions, name);
-    }
-    computeParameterType(parameter);
-    return parameter;
-  }
-
-  FormalElementX createUnnamedParameter() {
-    FormalElementX parameter;
-    assert(!createRealParameters);
-    parameter = new FormalElementX.unnamed(
-        ElementKind.PARAMETER, enclosingElement, currentDefinitions);
-    computeParameterType(parameter);
-    return parameter;
-  }
-
-  InitializingFormalElementX createFieldParameter(
-      Send node, Expression initializer) {
-    InitializingFormalElementX element;
-    Identifier receiver = node.receiver.asIdentifier();
-    if (receiver == null || !receiver.isThis()) {
-      reporter.reportErrorMessage(node, MessageKind.INVALID_PARAMETER);
-      return new ErroneousInitializingFormalElementX(
-          getParameterName(node), enclosingElement);
-    } else {
-      if (!enclosingElement.isGenerativeConstructor) {
-        reporter.reportErrorMessage(
-            node, MessageKind.INITIALIZING_FORMAL_NOT_ALLOWED);
-        return new ErroneousInitializingFormalElementX(
-            getParameterName(node), enclosingElement);
-      }
-      Identifier name = getParameterName(node);
-      validateName(name);
-      Element fieldElement =
-          enclosingElement.enclosingClass.lookupLocalMember(name.source);
-      if (fieldElement == null ||
-          !identical(fieldElement.kind, ElementKind.FIELD)) {
-        reporter.reportErrorMessage(
-            node, MessageKind.NOT_A_FIELD, {'fieldName': name});
-        fieldElement =
-            new ErroneousFieldElementX(name, enclosingElement.enclosingClass);
-      } else if (!fieldElement.isInstanceMember) {
-        reporter.reportErrorMessage(
-            node, MessageKind.NOT_INSTANCE_FIELD, {'fieldName': name});
-        fieldElement =
-            new ErroneousFieldElementX(name, enclosingElement.enclosingClass);
-      }
-      element = new InitializingFormalElementX(
-          enclosingElement, currentDefinitions, name, initializer, fieldElement,
-          isOptional: isOptionalParameter, isNamed: optionalParametersAreNamed);
-      computeParameterType(element, fieldElement);
-    }
-    return element;
-  }
-
-  /// A [SendSet] node is an optional parameter with a default value.
-  FormalElementX visitSendSet(SendSet node) {
-    FormalElementX element;
-    if (node.receiver != null) {
-      element = createFieldParameter(node, node.arguments.first);
-    } else if (node.selector.asIdentifier() != null ||
-        node.selector.asFunctionExpression() != null) {
-      element = createParameter(getParameterName(node), node.arguments.first);
-    }
-    Node defaultValue = node.arguments.head;
-    if (!defaultValuesAllowed) {
-      reporter.reportErrorMessage(defaultValue, defaultValuesError);
-    }
-    return element;
-  }
-
-  FormalElementX visitFunctionExpression(FunctionExpression node) {
-    // This is a function typed parameter.
-    Modifiers modifiers = currentDefinitions.modifiers;
-    if (modifiers.isFinal) {
-      reporter.reportErrorMessage(
-          modifiers, MessageKind.FINAL_FUNCTION_TYPE_PARAMETER);
-    }
-    if (modifiers.isVar) {
-      reporter.reportErrorMessage(
-          modifiers, MessageKind.VAR_FUNCTION_TYPE_PARAMETER);
-    }
-
-    return createParameter(node.name, null);
-  }
-
-  LinkBuilder<FormalElement> analyzeNodes(Link<Node> link) {
-    LinkBuilder<FormalElement> elements = new LinkBuilder<FormalElement>();
-    for (; !link.isEmpty; link = link.tail) {
-      Element element = link.head.accept(this);
-      if (element != null) {
-        elements.addLast(element);
-      } else {
-        // If parameter is null, the current node should be the last,
-        // and a list of optional named parameters.
-        if (!link.tail.isEmpty || (link.head is! NodeList)) {
-          reporter.internalError(link.head, "expected optional parameters");
-        }
-      }
-    }
-    return elements;
-  }
-
-  /**
-   * Resolves formal parameters and return type of a [FunctionExpression]
-   * to a [FunctionSignature].
-   *
-   * If [createRealParameters] is `true`, the parameters will be
-   * real parameters implementing the [ParameterElement] interface. Otherwise,
-   * the parameters will only implement [FormalElement].
-   */
-  static FunctionSignature analyze(
-      Resolution resolution,
-      Scope scope,
-      FunctionTypeParameterScope functionTypeParameters,
-      NodeList typeVariables,
-      NodeList formalParameters,
-      Node returnNode,
-      FunctionTypedElement element,
-      ResolutionRegistry registry,
-      {MessageKind defaultValuesError,
-      bool createRealParameters: false,
-      bool isFunctionExpression: false}) {
-    DiagnosticReporter reporter = resolution.reporter;
-
-    List<ResolutionDartType> createTypeVariables(NodeList typeVariableNodes) {
-      if (element.isPatch) {
-        FunctionTypedElement origin = element.origin;
-        origin.computeType(resolution);
-        return origin.typeVariables;
-      }
-      if (typeVariableNodes == null) return const <ResolutionDartType>[];
-
-      // Create the types and elements corresponding to [typeVariableNodes].
-      Link<Node> nodes = typeVariableNodes.nodes;
-      List<ResolutionDartType> arguments =
-          new List.generate(nodes.slowLength(), (int index) {
-        TypeVariable node = nodes.head;
-        String variableName = node.name.source;
-        nodes = nodes.tail;
-        TypeVariableElementX variableElement =
-            new TypeVariableElementX(variableName, element, index, node);
-        // GENERIC_METHODS: When method type variables are implemented fully we
-        // must resolve the actual bounds; currently we just claim that
-        // every method type variable has upper bound [dynamic].
-        variableElement.boundCache = const ResolutionDynamicType();
-        ResolutionTypeVariableType variableType =
-            new MethodTypeVariableType(variableElement);
-        variableElement.typeCache = variableType;
-        return variableType;
-      }, growable: false);
-      return arguments;
-    }
-
-    List<ResolutionDartType> typeVariableTypes =
-        createTypeVariables(typeVariables);
-    scope = new FunctionSignatureBuildingScope(scope, typeVariableTypes);
-    SignatureResolver visitor = new SignatureResolver(
-        resolution, element, scope, functionTypeParameters, registry,
-        defaultValuesError: defaultValuesError,
-        createRealParameters: createRealParameters);
-    List<FormalElement> parameters = const <FormalElement>[];
-    int requiredParameterCount = 0;
-    if (formalParameters == null) {
-      if (!element.isGetter) {
-        if (element.isMalformed) {
-          // If the element is erroneous, an error should already have been
-          // reported. In the case of parse errors, it is possible that there
-          // are formal parameters, but something else in the method failed to
-          // parse. So we suppress the message about missing formals.
-          assert(reporter.hasReportedError, failedAt(element));
-        } else {
-          reporter.reportErrorMessage(element, MessageKind.MISSING_FORMALS);
-        }
-      }
-    } else {
-      if (element.isGetter) {
-        if (!identical(
-            formalParameters.endToken.next.stringValue,
-            // TODO(ahe): Remove the check for native keyword.
-            'native')) {
-          reporter.reportErrorMessage(
-              formalParameters, MessageKind.EXTRA_FORMALS);
-        }
-      }
-      LinkBuilder<FormalElement> parametersBuilder =
-          visitor.analyzeNodes(formalParameters.nodes);
-      requiredParameterCount = parametersBuilder.length;
-      parameters = parametersBuilder.toList();
-    }
-    ResolutionDartType returnType;
-    if (element.isFactoryConstructor) {
-      returnType = element.enclosingClass.thisType;
-      // Because there is no type annotation for the return type of
-      // this element, we explicitly add one.
-      registry.registerCheckedModeCheck(returnType);
-    } else {
-      AsyncMarker asyncMarker = AsyncMarker.SYNC;
-      if (isFunctionExpression) {
-        // Use async marker to determine the return type of function
-        // expressions.
-        FunctionElement function = element;
-        asyncMarker = function.asyncMarker;
-      }
-      switch (asyncMarker) {
-        case AsyncMarker.SYNC:
-          returnType = visitor.resolveReturnType(returnNode);
-          break;
-        case AsyncMarker.SYNC_STAR:
-          ResolutionInterfaceType iterableType =
-              resolution.commonElements.iterableType();
-          returnType = iterableType;
-          break;
-        case AsyncMarker.ASYNC:
-          ResolutionInterfaceType futureType =
-              resolution.commonElements.futureType();
-          returnType = futureType;
-          break;
-        case AsyncMarker.ASYNC_STAR:
-          ResolutionInterfaceType streamType =
-              resolution.commonElements.streamType();
-          returnType = streamType;
-          break;
-      }
-    }
-
-    if (element.isSetter &&
-        (requiredParameterCount != 1 || visitor.optionalParameterCount != 0)) {
-      // If there are no formal parameters, we already reported an error above.
-      if (formalParameters != null) {
-        reporter.reportErrorMessage(
-            formalParameters, MessageKind.ILLEGAL_SETTER_FORMALS);
-      }
-    }
-    LinkBuilder<ResolutionDartType> parameterTypes =
-        new LinkBuilder<ResolutionDartType>();
-    for (FormalElement parameter in parameters) {
-      parameterTypes.addLast(parameter.type);
-    }
-    List<ResolutionDartType> optionalParameterTypes =
-        const <ResolutionDartType>[];
-    List<String> namedParameters = const <String>[];
-    List<ResolutionDartType> namedParameterTypes = const <ResolutionDartType>[];
-    List<FormalElement> orderedOptionalParameters =
-        visitor.optionalParameters.toList();
-    if (visitor.optionalParametersAreNamed) {
-      // TODO(karlklose); replace when [visitor.optionalParameters] is a [List].
-      orderedOptionalParameters.sort((Element a, Element b) {
-        return a.name.compareTo(b.name);
-      });
-      LinkBuilder<String> namedParametersBuilder = new LinkBuilder<String>();
-      LinkBuilder<ResolutionDartType> namedParameterTypesBuilder =
-          new LinkBuilder<ResolutionDartType>();
-      for (FormalElement parameter in orderedOptionalParameters) {
-        namedParametersBuilder.addLast(parameter.name);
-        namedParameterTypesBuilder.addLast(parameter.type);
-      }
-      namedParameters = namedParametersBuilder.toLink().toList(growable: false);
-      namedParameterTypes =
-          namedParameterTypesBuilder.toLink().toList(growable: false);
-    } else {
-      // TODO(karlklose); replace when [visitor.optionalParameters] is a [List].
-      LinkBuilder<ResolutionDartType> optionalParameterTypesBuilder =
-          new LinkBuilder<ResolutionDartType>();
-      for (FormalElement parameter in visitor.optionalParameters) {
-        optionalParameterTypesBuilder.addLast(parameter.type);
-      }
-      optionalParameterTypes =
-          optionalParameterTypesBuilder.toLink().toList(growable: false);
-    }
-    ResolutionFunctionType type = new ResolutionFunctionType(
-        element.declaration,
-        returnType,
-        parameterTypes.toLink().toList(growable: false),
-        optionalParameterTypes,
-        namedParameters,
-        namedParameterTypes);
-    return new FunctionSignatureX(
-        typeVariables: typeVariableTypes,
-        requiredParameters: parameters,
-        optionalParameters: visitor.optionalParameters,
-        requiredParameterCount: requiredParameterCount,
-        optionalParameterCount: visitor.optionalParameterCount,
-        optionalParametersAreNamed: visitor.optionalParametersAreNamed,
-        orderedOptionalParameters: orderedOptionalParameters,
-        type: type);
-  }
-
-  ResolutionDartType resolveTypeAnnotation(TypeAnnotation annotation) {
-    ResolutionDartType type = resolveReturnType(annotation);
-    if (type.isVoid) {
-      reporter.reportErrorMessage(annotation, MessageKind.VOID_NOT_ALLOWED);
-    }
-    return type;
-  }
-
-  ResolutionDartType resolveReturnType(TypeAnnotation annotation) {
-    if (annotation == null) return const ResolutionDynamicType();
-    ResolutionDartType result = resolver.resolveTypeAnnotation(annotation,
-        functionTypeParameters: functionTypeParameters);
-    if (result == null) {
-      return const ResolutionDynamicType();
-    }
-    return result;
-  }
-}
-
-/// Used during `SignatureResolver.analyze` to provide access to the type
-/// variables of the function signature itself when its signature is analyzed.
-class FunctionSignatureBuildingScope extends TypeVariablesScope {
-  @override
-  final List<ResolutionDartType> typeVariables;
-
-  FunctionSignatureBuildingScope(Scope parent, this.typeVariables)
-      : super(parent);
-
-  String toString() => 'FunctionSignatureBuildingScope($typeVariables)';
-}
diff --git a/pkg/compiler/lib/src/resolution/tree_elements.dart b/pkg/compiler/lib/src/resolution/tree_elements.dart
deleted file mode 100644
index f2f43be..0000000
--- a/pkg/compiler/lib/src/resolution/tree_elements.dart
+++ /dev/null
@@ -1,439 +0,0 @@
-// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library dart2js.resolution.tree_elements;
-
-import '../common.dart';
-import '../constants/expressions.dart';
-import '../elements/resolution_types.dart';
-import '../diagnostics/source_span.dart';
-import '../elements/elements.dart';
-import '../elements/jumps.dart';
-import '../tree/tree.dart';
-import '../universe/selector.dart' show Selector;
-import '../util/util.dart';
-import 'secret_tree_element.dart' show getTreeElement, setTreeElement;
-import 'send_structure.dart';
-
-abstract class TreeElements {
-  AnalyzableElement get analyzedElement;
-  Iterable<SourceSpan> get superUses;
-
-  void forEachConstantNode(f(Node n, ConstantExpression c));
-
-  Element operator [](Node node);
-  Map<Node, ResolutionDartType> get typesCache;
-
-  /// Returns the [SendStructure] that describes the semantics of [node].
-  SendStructure getSendStructure(Send node);
-
-  /// Returns the [NewStructure] that describes the semantics of [node].
-  NewStructure getNewStructure(NewExpression node);
-
-  // TODO(johnniwinther): Investigate whether [Node] could be a [Send].
-  Selector getSelector(Node node);
-  Selector getGetterSelectorInComplexSendSet(SendSet node);
-  Selector getOperatorSelectorInComplexSendSet(SendSet node);
-  ResolutionDartType getType(Node node);
-
-  /// Returns the for-in loop variable for [node].
-  Element getForInVariable(ForIn node);
-  void setConstant(Node node, ConstantExpression constant);
-  ConstantExpression getConstant(Node node);
-
-  /// Returns the [FunctionElement] defined by [node].
-  FunctionElement getFunctionDefinition(FunctionExpression node);
-
-  /// Returns target constructor for the redirecting factory body [node].
-  ConstructorElement getRedirectingTargetConstructor(
-      RedirectingFactoryBody node);
-
-  /**
-   * Returns [:true:] if [node] is a type literal.
-   *
-   * Resolution marks this by setting the type on the node to be the
-   * type that the literal refers to.
-   */
-  bool isTypeLiteral(Send node);
-
-  /// Returns the type that the type literal [node] refers to.
-  ResolutionDartType getTypeLiteralType(Send node);
-
-  /// Returns a list of nodes that potentially mutate [element] anywhere in its
-  /// scope.
-  List<Node> getPotentialMutations(VariableElement element);
-
-  /// Returns a list of nodes that potentially mutate [element] in [node].
-  List<Node> getPotentialMutationsIn(Node node, VariableElement element);
-
-  /// Returns a list of nodes that potentially mutate [element] in a closure.
-  List<Node> getPotentialMutationsInClosure(VariableElement element);
-
-  /// Returns a list of nodes that access [element] within a closure in [node].
-  List<Node> getAccessesByClosureIn(Node node, VariableElement element);
-
-  /// Returns the jump target defined by [node].
-  JumpTarget getTargetDefinition(Node node);
-
-  /// Returns the jump target of the [node].
-  JumpTarget getTargetOf(GotoStatement node);
-
-  /// Returns the label defined by [node].
-  LabelDefinition getLabelDefinition(Label node);
-
-  /// Returns the label that [node] targets.
-  LabelDefinition getTargetLabel(GotoStatement node);
-
-  /// `true` if the [analyzedElement]'s source code contains a [TryStatement].
-  bool get containsTryStatement;
-
-  /// Returns native data stored with [node].
-  getNativeData(Node node);
-}
-
-class TreeElementMapping extends TreeElements {
-  final AnalyzableElement analyzedElement;
-  Map<Spannable, Selector> _selectors;
-  Map<Node, ResolutionDartType> _types;
-
-  Map<Node, ResolutionDartType> _typesCache;
-  Map<Node, ResolutionDartType> get typesCache =>
-      _typesCache ??= <Node, ResolutionDartType>{};
-
-  Setlet<SourceSpan> _superUses;
-  Map<Node, ConstantExpression> _constants;
-  Map<VariableElement, List<Node>> _potentiallyMutated;
-  Map<Node, Map<VariableElement, List<Node>>> _potentiallyMutatedIn;
-  Map<VariableElement, List<Node>> _potentiallyMutatedInClosure;
-  Map<Node, Map<VariableElement, List<Node>>> _accessedByClosureIn;
-  Maplet<Send, SendStructure> _sendStructureMap;
-  Maplet<NewExpression, NewStructure> _newStructureMap;
-  bool containsTryStatement = false;
-
-  /// Map from nodes to the targets they define.
-  Map<Node, JumpTarget> _definedTargets;
-
-  /// Map from goto statements to their targets.
-  Map<GotoStatement, JumpTarget> _usedTargets;
-
-  /// Map from labels to their label definition.
-  Map<Label, LabelDefinition> _definedLabels;
-
-  /// Map from labeled goto statements to the labels they target.
-  Map<GotoStatement, LabelDefinition> _targetLabels;
-
-  /// Map from nodes to native data.
-  Map<Node, dynamic> _nativeData;
-
-  final int hashCode = _hashCodeCounter = (_hashCodeCounter + 1).toUnsigned(30);
-  static int _hashCodeCounter = 0;
-
-  TreeElementMapping(this.analyzedElement);
-
-  operator []=(Node node, Element element) {
-    // TODO(johnniwinther): Simplify this invariant to use only declarations in
-    // [TreeElements].
-    assert(() {
-      if (!element.isMalformed && analyzedElement != null && element.isPatch) {
-        return analyzedElement.implementationLibrary.isPatch;
-      }
-      return true;
-    }(), failedAt(node));
-    // TODO(ahe): Investigate why the invariant below doesn't hold.
-    // assert(
-    //     getTreeElement(node) == element ||
-    //     getTreeElement(node) == null,
-    //     failedAt(node, '${getTreeElement(node)}; $element'));
-
-    setTreeElement(node, element);
-  }
-
-  @override
-  operator [](Node node) => getTreeElement(node);
-
-  @override
-  SendStructure getSendStructure(Send node) {
-    if (_sendStructureMap == null) return null;
-    return _sendStructureMap[node];
-  }
-
-  void setSendStructure(Send node, SendStructure sendStructure) {
-    if (_sendStructureMap == null) {
-      _sendStructureMap = new Maplet<Send, SendStructure>();
-    }
-    _sendStructureMap[node] = sendStructure;
-  }
-
-  @override
-  NewStructure getNewStructure(NewExpression node) {
-    if (_newStructureMap == null) return null;
-    return _newStructureMap[node];
-  }
-
-  void setNewStructure(NewExpression node, NewStructure newStructure) {
-    if (_newStructureMap == null) {
-      _newStructureMap = new Maplet<NewExpression, NewStructure>();
-    }
-    _newStructureMap[node] = newStructure;
-  }
-
-  void setType(Node node, ResolutionDartType type) {
-    if (_types == null) {
-      _types = new Maplet<Node, ResolutionDartType>();
-    }
-    _types[node] = type;
-  }
-
-  @override
-  ResolutionDartType getType(Node node) => _types != null ? _types[node] : null;
-
-  @override
-  Iterable<SourceSpan> get superUses {
-    return _superUses != null ? _superUses : const <SourceSpan>[];
-  }
-
-  void addSuperUse(SourceSpan span) {
-    if (_superUses == null) {
-      _superUses = new Setlet<SourceSpan>();
-    }
-    _superUses.add(span);
-  }
-
-  Selector _getSelector(Spannable node) {
-    return _selectors != null ? _selectors[node] : null;
-  }
-
-  void _setSelector(Spannable node, Selector selector) {
-    if (_selectors == null) {
-      _selectors = new Maplet<Spannable, Selector>();
-    }
-    _selectors[node] = selector;
-  }
-
-  void setSelector(Node node, Selector selector) {
-    _setSelector(node, selector);
-  }
-
-  @override
-  Selector getSelector(Node node) => _getSelector(node);
-
-  int getSelectorCount() => _selectors == null ? 0 : _selectors.length;
-
-  void setGetterSelectorInComplexSendSet(SendSet node, Selector selector) {
-    _setSelector(node.selector, selector);
-  }
-
-  @override
-  Selector getGetterSelectorInComplexSendSet(SendSet node) {
-    return _getSelector(node.selector);
-  }
-
-  void setOperatorSelectorInComplexSendSet(SendSet node, Selector selector) {
-    _setSelector(node.assignmentOperator, selector);
-  }
-
-  @override
-  Selector getOperatorSelectorInComplexSendSet(SendSet node) {
-    return _getSelector(node.assignmentOperator);
-  }
-
-  @override
-  Element getForInVariable(ForIn node) {
-    return this[node];
-  }
-
-  @override
-  void setConstant(Node node, ConstantExpression constant) {
-    if (_constants == null) {
-      _constants = new Maplet<Node, ConstantExpression>();
-    }
-    _constants[node] = constant;
-  }
-
-  @override
-  ConstantExpression getConstant(Node node) {
-    return _constants != null ? _constants[node] : null;
-  }
-
-  @override
-  bool isTypeLiteral(Send node) {
-    return getType(node) != null;
-  }
-
-  @override
-  ResolutionDartType getTypeLiteralType(Send node) {
-    return getType(node);
-  }
-
-  @override
-  List<Node> getPotentialMutations(VariableElement element) {
-    if (_potentiallyMutated == null) return const <Node>[];
-    List<Node> mutations = _potentiallyMutated[element];
-    if (mutations == null) return const <Node>[];
-    return mutations;
-  }
-
-  void registerPotentialMutation(VariableElement element, Node mutationNode) {
-    if (_potentiallyMutated == null) {
-      _potentiallyMutated = new Maplet<VariableElement, List<Node>>();
-    }
-    _potentiallyMutated.putIfAbsent(element, () => <Node>[]).add(mutationNode);
-  }
-
-  @override
-  List<Node> getPotentialMutationsIn(Node node, VariableElement element) {
-    if (_potentiallyMutatedIn == null) return const <Node>[];
-    Map<VariableElement, List<Node>> mutationsIn = _potentiallyMutatedIn[node];
-    if (mutationsIn == null) return const <Node>[];
-    List<Node> mutations = mutationsIn[element];
-    if (mutations == null) return const <Node>[];
-    return mutations;
-  }
-
-  void registerPotentialMutationIn(
-      Node contextNode, VariableElement element, Node mutationNode) {
-    if (_potentiallyMutatedIn == null) {
-      _potentiallyMutatedIn =
-          new Maplet<Node, Map<VariableElement, List<Node>>>();
-    }
-    Map<VariableElement, List<Node>> mutationMap =
-        _potentiallyMutatedIn.putIfAbsent(
-            contextNode, () => new Maplet<VariableElement, List<Node>>());
-    mutationMap.putIfAbsent(element, () => <Node>[]).add(mutationNode);
-  }
-
-  @override
-  List<Node> getPotentialMutationsInClosure(VariableElement element) {
-    if (_potentiallyMutatedInClosure == null) return const <Node>[];
-    List<Node> mutations = _potentiallyMutatedInClosure[element];
-    if (mutations == null) return const <Node>[];
-    return mutations;
-  }
-
-  void registerPotentialMutationInClosure(
-      VariableElement element, Node mutationNode) {
-    if (_potentiallyMutatedInClosure == null) {
-      _potentiallyMutatedInClosure = new Maplet<VariableElement, List<Node>>();
-    }
-    _potentiallyMutatedInClosure
-        .putIfAbsent(element, () => <Node>[])
-        .add(mutationNode);
-  }
-
-  @override
-  List<Node> getAccessesByClosureIn(Node node, VariableElement element) {
-    if (_accessedByClosureIn == null) return const <Node>[];
-    Map<VariableElement, List<Node>> accessesIn = _accessedByClosureIn[node];
-    if (accessesIn == null) return const <Node>[];
-    List<Node> accesses = accessesIn[element];
-    if (accesses == null) return const <Node>[];
-    return accesses;
-  }
-
-  void setAccessedByClosureIn(
-      Node contextNode, VariableElement element, Node accessNode) {
-    if (_accessedByClosureIn == null) {
-      _accessedByClosureIn = new Map<Node, Map<VariableElement, List<Node>>>();
-    }
-    Map<VariableElement, List<Node>> accessMap =
-        _accessedByClosureIn.putIfAbsent(
-            contextNode, () => new Maplet<VariableElement, List<Node>>());
-    accessMap.putIfAbsent(element, () => <Node>[]).add(accessNode);
-  }
-
-  String toString() => 'TreeElementMapping($analyzedElement)';
-
-  @override
-  void forEachConstantNode(f(Node n, ConstantExpression c)) {
-    if (_constants != null) {
-      _constants.forEach(f);
-    }
-  }
-
-  @override
-  FunctionElement getFunctionDefinition(FunctionExpression node) {
-    Element e = this[node];
-    return e is FunctionElement ? e : null;
-  }
-
-  @override
-  ConstructorElement getRedirectingTargetConstructor(
-      RedirectingFactoryBody node) {
-    return this[node];
-  }
-
-  void defineTarget(Node node, JumpTarget target) {
-    _definedTargets ??= new Maplet<Node, JumpTarget>();
-    _definedTargets[node] = target;
-  }
-
-  void undefineTarget(Node node) {
-    if (_definedTargets != null) {
-      _definedTargets.remove(node);
-      if (_definedTargets.isEmpty) {
-        _definedTargets = null;
-      }
-    }
-  }
-
-  @override
-  JumpTarget getTargetDefinition(Node node) {
-    return _definedTargets != null ? _definedTargets[node] : null;
-  }
-
-  void registerTargetOf(GotoStatement node, JumpTarget target) {
-    _usedTargets ??= new Maplet<GotoStatement, JumpTarget>();
-    _usedTargets[node] = target;
-  }
-
-  @override
-  JumpTarget getTargetOf(GotoStatement node) {
-    return _usedTargets != null ? _usedTargets[node] : null;
-  }
-
-  void defineLabel(Label label, LabelDefinition target) {
-    _definedLabels ??= new Maplet<Label, LabelDefinition>();
-    _definedLabels[label] = target;
-  }
-
-  void undefineLabel(Label label) {
-    if (_definedLabels != null) {
-      _definedLabels.remove(label);
-      if (_definedLabels.isEmpty) {
-        _definedLabels = null;
-      }
-    }
-  }
-
-  @override
-  LabelDefinition getLabelDefinition(Label label) {
-    return _definedLabels != null ? _definedLabels[label] : null;
-  }
-
-  void registerTargetLabel(GotoStatement node, LabelDefinition label) {
-    assert(node.target != null);
-    if (_targetLabels == null) {
-      _targetLabels = new Maplet<GotoStatement, LabelDefinition>();
-    }
-    _targetLabels[node] = label;
-  }
-
-  @override
-  LabelDefinition getTargetLabel(GotoStatement node) {
-    assert(node.target != null);
-    return _targetLabels != null ? _targetLabels[node] : null;
-  }
-
-  void registerNativeData(Node node, dynamic nativeData) {
-    if (_nativeData == null) {
-      _nativeData = <Node, dynamic>{};
-    }
-    _nativeData[node] = nativeData;
-  }
-
-  @override
-  dynamic getNativeData(Node node) {
-    return _nativeData != null ? _nativeData[node] : null;
-  }
-}
diff --git a/pkg/compiler/lib/src/resolution/type_resolver.dart b/pkg/compiler/lib/src/resolution/type_resolver.dart
deleted file mode 100644
index 47b9ef0..0000000
--- a/pkg/compiler/lib/src/resolution/type_resolver.dart
+++ /dev/null
@@ -1,497 +0,0 @@
-// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library dart2js.resolution.types;
-
-import '../common.dart';
-import '../common/resolution.dart' show Resolution;
-import '../elements/resolution_types.dart';
-import '../elements/elements.dart'
-    show
-        AmbiguousElement,
-        ClassElement,
-        Element,
-        Elements,
-        ErroneousElement,
-        PrefixElement,
-        TypedefElement,
-        TypeVariableElement;
-import '../elements/modelx.dart' show ErroneousElementX;
-import '../elements/types.dart' show DartType, TypeVariableType;
-import '../resolution/resolution.dart';
-import '../tree/tree.dart';
-import '../universe/feature.dart' show Feature;
-import '../util/util.dart' show Link;
-import 'members.dart' show lookupInScope;
-import 'registry.dart' show ResolutionRegistry;
-import 'resolution_common.dart' show MappingVisitor;
-import 'scope.dart' show Scope;
-
-class _FormalsTypeResolutionResult {
-  final List<ResolutionDartType> requiredTypes;
-  final List<ResolutionDartType> orderedTypes;
-  final List<String> names;
-  final List<ResolutionDartType> nameTypes;
-
-  _FormalsTypeResolutionResult(
-      this.requiredTypes, this.orderedTypes, this.names, this.nameTypes);
-}
-
-class TypeResolver {
-  final Resolution resolution;
-
-  TypeResolver(this.resolution);
-
-  ResolverTask get resolver => resolution.resolver;
-  DiagnosticReporter get reporter => resolution.reporter;
-  Types get types => resolution.types;
-
-  /// Tries to resolve the type name as an element.
-  Element resolveTypeName(
-      Identifier prefixName, Identifier typeName, Scope scope,
-      {bool deferredIsMalformed: true}) {
-    Element element;
-    if (prefixName != null) {
-      Element prefixElement =
-          lookupInScope(reporter, prefixName, scope, prefixName.source);
-      if (prefixElement != null && prefixElement.isPrefix) {
-        // The receiver is a prefix. Lookup in the imported members.
-        PrefixElement prefix = prefixElement;
-        element = prefix.lookupLocalMember(typeName.source);
-        if (element != null && prefix.isDeferred && deferredIsMalformed) {
-          element = new ErroneousElementX(MessageKind.DEFERRED_TYPE_ANNOTATION,
-              {'node': typeName}, element.name, element);
-        }
-      } else {
-        // The caller of this method will create the ErroneousElement for
-        // the MalformedType.
-        element = null;
-      }
-    } else {
-      element = lookupInScope(reporter, typeName, scope, typeName.source);
-    }
-    return element;
-  }
-
-  ResolutionDartType resolveTypeAnnotation(MappingVisitor visitor,
-      TypeAnnotation node, FunctionTypeParameterScope functionTypeParameters,
-      {bool malformedIsError: false, bool deferredIsMalformed: true}) {
-    return _resolveTypeAnnotation(visitor, node, functionTypeParameters,
-        malformedIsError: malformedIsError,
-        deferredIsMalformed: deferredIsMalformed);
-  }
-
-  ResolutionDartType _resolveTypeAnnotation(MappingVisitor visitor,
-      TypeAnnotation node, FunctionTypeParameterScope functionTypeParameters,
-      {bool malformedIsError: false, bool deferredIsMalformed: true}) {
-    if (node.asNominalTypeAnnotation() != null) {
-      return resolveNominalTypeAnnotation(visitor, node, functionTypeParameters,
-          malformedIsError: malformedIsError,
-          deferredIsMalformed: deferredIsMalformed);
-    }
-    assert(node.asFunctionTypeAnnotation() != null);
-    return _resolveFunctionTypeAnnotation(visitor, node, functionTypeParameters,
-        malformedIsError: malformedIsError,
-        deferredIsMalformed: deferredIsMalformed);
-  }
-
-  /// Resolves the types of a parameter list.
-  ///
-  /// This function does not accept "inline" function types. For example
-  /// `foo(int bar(String x))` is not accepted.
-  ///
-  /// However, it does work with nested generalized function types:
-  ///   `foo(int Function(String) x)`.
-  _FormalsTypeResolutionResult _resolveFormalTypes(MappingVisitor visitor,
-      NodeList formals, FunctionTypeParameterScope functionTypeParameters) {
-    ResolutionDartType resolvePositionalType(VariableDefinitions node) {
-      return _resolveTypeAnnotation(visitor, node.type, functionTypeParameters);
-    }
-
-    void fillNamedTypes(NodeList namedFormals, List<String> names,
-        List<ResolutionDartType> types) {
-      List<Node> nodes = namedFormals.nodes.toList(growable: false);
-
-      // Sort the named arguments first.
-      nodes.sort((node1, node2) {
-        VariableDefinitions a = node1;
-        VariableDefinitions b = node2;
-        assert(a.definitions.nodes.tail.isEmpty);
-        assert(b.definitions.nodes.tail.isEmpty);
-        return a.definitions.nodes.head
-            .asIdentifier()
-            .source
-            .compareTo(b.definitions.nodes.head.asIdentifier().source);
-      });
-
-      for (VariableDefinitions node in nodes) {
-        String name = node.definitions.nodes.head.asIdentifier().source;
-        ResolutionDartType type = node.type == null
-            ? const ResolutionDynamicType()
-            : _resolveTypeAnnotation(
-                visitor, node.type, functionTypeParameters);
-        names.add(name);
-        types.add(type);
-      }
-    }
-
-    List<ResolutionDartType> requiredTypes = <ResolutionDartType>[];
-    NodeList optionalFormals = null;
-    for (Link<Node> link = formals.nodes; !link.isEmpty; link = link.tail) {
-      if (link.tail.isEmpty && link.head is NodeList) {
-        optionalFormals = link.head;
-        break;
-      }
-      requiredTypes.add(resolvePositionalType(link.head));
-    }
-
-    List<ResolutionDartType> orderedTypes = const <ResolutionDartType>[];
-    List<String> names = const <String>[];
-    List<ResolutionDartType> namedTypes = const <ResolutionDartType>[];
-
-    if (optionalFormals != null) {
-      // This must be a list of optional arguments.
-      String value = optionalFormals.beginToken.stringValue;
-      if ((!identical(value, '[')) && (!identical(value, '{'))) {
-        reporter.internalError(optionalFormals, "expected optional parameters");
-      }
-      bool optionalParametersAreNamed = (identical(value, '{'));
-
-      if (optionalParametersAreNamed) {
-        names = <String>[];
-        namedTypes = <ResolutionDartType>[];
-        fillNamedTypes(optionalFormals, names, namedTypes);
-      } else {
-        orderedTypes = <ResolutionDartType>[];
-        for (Link<Node> link = optionalFormals.nodes;
-            !link.isEmpty;
-            link = link.tail) {
-          orderedTypes.add(resolvePositionalType(link.head));
-        }
-      }
-    }
-    return new _FormalsTypeResolutionResult(
-        requiredTypes, orderedTypes, names, namedTypes);
-  }
-
-  ResolutionFunctionType _resolveFunctionTypeAnnotation(
-      MappingVisitor visitor,
-      FunctionTypeAnnotation node,
-      FunctionTypeParameterScope functionTypeParameters,
-      {bool malformedIsError: false,
-      bool deferredIsMalformed: true}) {
-    assert(functionTypeParameters != null);
-
-    functionTypeParameters = functionTypeParameters.expand(node.typeParameters);
-
-    ResolutionDartType returnType = node.returnType == null
-        ? const ResolutionDynamicType()
-        : _resolveTypeAnnotation(
-            visitor, node.returnType, functionTypeParameters);
-    var formalTypes =
-        _resolveFormalTypes(visitor, node.formals, functionTypeParameters);
-    var result = new ResolutionFunctionType.generalized(
-        returnType,
-        formalTypes.requiredTypes,
-        formalTypes.orderedTypes,
-        formalTypes.names,
-        formalTypes.nameTypes);
-    visitor.registry.useType(node, result);
-
-    functionTypeParameters = functionTypeParameters.parent;
-
-    return result;
-  }
-
-  ResolutionDartType resolveNominalTypeAnnotation(
-      MappingVisitor visitor,
-      NominalTypeAnnotation node,
-      FunctionTypeParameterScope functionTypeParameters,
-      {bool malformedIsError: false,
-      bool deferredIsMalformed: true}) {
-    ResolutionRegistry registry = visitor.registry;
-
-    Identifier typeName;
-    ResolutionDartType type;
-
-    ResolutionDartType checkNoTypeArguments(ResolutionDartType type) {
-      List<ResolutionDartType> arguments = new List<ResolutionDartType>();
-      bool hasTypeArgumentMismatch = resolveTypeArguments(visitor, node,
-          const <ResolutionDartType>[], arguments, functionTypeParameters);
-      if (hasTypeArgumentMismatch) {
-        return new MalformedType(
-            new ErroneousElementX(MessageKind.TYPE_ARGUMENT_COUNT_MISMATCH,
-                {'type': node}, typeName.source, visitor.enclosingElement),
-            type,
-            arguments);
-      }
-      return type;
-    }
-
-    Identifier prefixName;
-    Send send = node.typeName.asSend();
-    if (send != null) {
-      // The type name is of the form [: prefix . identifier :].
-      prefixName = send.receiver.asIdentifier();
-      typeName = send.selector.asIdentifier();
-    } else {
-      typeName = node.typeName.asIdentifier();
-      if (identical(typeName.source, 'void')) {
-        type = const ResolutionVoidType();
-        checkNoTypeArguments(type);
-        registry.useType(node, type);
-        return type;
-      } else if (identical(typeName.source, 'dynamic')) {
-        type = const ResolutionDynamicType();
-        checkNoTypeArguments(type);
-        registry.useType(node, type);
-        return type;
-      }
-    }
-
-    ResolutionDartType reportFailureAndCreateType(
-        MessageKind messageKind, Map messageArguments,
-        {ResolutionDartType userProvidedBadType,
-        Element erroneousElement,
-        List<DiagnosticMessage> infos: const <DiagnosticMessage>[]}) {
-      if (malformedIsError) {
-        reporter.reportError(
-            reporter.createMessage(node, messageKind, messageArguments), infos);
-      } else {
-        registry.registerFeature(Feature.THROW_RUNTIME_ERROR);
-        reporter.reportWarning(
-            reporter.createMessage(node, messageKind, messageArguments), infos);
-      }
-      if (erroneousElement == null) {
-        registry.registerFeature(Feature.THROW_RUNTIME_ERROR);
-        erroneousElement = new ErroneousElementX(messageKind, messageArguments,
-            typeName.source, visitor.enclosingElement);
-      }
-      List<ResolutionDartType> arguments = <ResolutionDartType>[];
-      resolveTypeArguments(visitor, node, const <ResolutionDartType>[],
-          arguments, functionTypeParameters);
-      return new MalformedType(
-          erroneousElement, userProvidedBadType, arguments);
-    }
-
-    Element element;
-    if (prefixName == null) {
-      type = functionTypeParameters.lookup(typeName.source);
-    }
-    if (type == null) {
-      element = resolveTypeName(prefixName, typeName, visitor.scope,
-          deferredIsMalformed: deferredIsMalformed);
-    }
-
-    // Try to construct the type from the element.
-    if (type != null) {
-      // Already assigned to through the visibleTypeParameterNames.
-      // Just make sure that it doesn't have type arguments.
-      if (node.typeArguments != null) {
-        reporter.reportWarningMessage(node.typeArguments.nodes.head,
-            MessageKind.ADDITIONAL_TYPE_ARGUMENT);
-      }
-    } else if (element == null) {
-      type = reportFailureAndCreateType(
-          MessageKind.CANNOT_RESOLVE_TYPE, {'typeName': node.typeName});
-    } else if (element.isAmbiguous) {
-      AmbiguousElement ambiguous = element;
-      type = reportFailureAndCreateType(
-          ambiguous.messageKind, ambiguous.messageArguments,
-          infos: ambiguous.computeInfos(
-              registry.mapping.analyzedElement, reporter));
-      ;
-    } else if (element.isMalformed) {
-      if (element is ErroneousElement) {
-        type = reportFailureAndCreateType(
-            element.messageKind, element.messageArguments,
-            erroneousElement: element);
-      } else {
-        type = const ResolutionDynamicType();
-      }
-    } else if (!element.impliesType) {
-      type = reportFailureAndCreateType(
-          MessageKind.NOT_A_TYPE, {'node': node.typeName});
-    } else if (element.library.isPlatformLibrary &&
-        element.name == 'FutureOr') {
-      type = const ResolutionDynamicType();
-      registry.useType(node, type);
-      return type;
-    } else {
-      bool addTypeVariableBoundsCheck = false;
-      if (element.isClass) {
-        ClassElement cls = element;
-        // TODO(johnniwinther): [ensureClassWillBeResolvedInternal] should imply
-        // [computeType].
-        resolver.ensureClassWillBeResolvedInternal(cls);
-        cls.computeType(resolution);
-        List<ResolutionDartType> arguments = <ResolutionDartType>[];
-        bool hasTypeArgumentMismatch = resolveTypeArguments(visitor, node,
-            cls.typeVariables, arguments, functionTypeParameters);
-        if (hasTypeArgumentMismatch) {
-          type = new BadInterfaceType(
-              cls.declaration,
-              new ResolutionInterfaceType.forUserProvidedBadType(
-                  cls.declaration, arguments));
-        } else {
-          if (arguments.isEmpty) {
-            type = cls.rawType;
-          } else {
-            type = new ResolutionInterfaceType(
-                cls.declaration, arguments.toList(growable: false));
-            addTypeVariableBoundsCheck =
-                arguments.any((ResolutionDartType type) => !type.isDynamic);
-          }
-        }
-      } else if (element.isTypedef) {
-        TypedefElement typdef = element;
-        // TODO(johnniwinther): [ensureResolved] should imply [computeType].
-        typdef.ensureResolved(resolution);
-        typdef.computeType(resolution);
-        List<ResolutionDartType> arguments = <ResolutionDartType>[];
-        bool hasTypeArgumentMismatch = resolveTypeArguments(visitor, node,
-            typdef.typeVariables, arguments, functionTypeParameters);
-        if (hasTypeArgumentMismatch) {
-          type = new BadTypedefType(
-              typdef,
-              new ResolutionTypedefType.forUserProvidedBadType(
-                  typdef, arguments));
-        } else {
-          if (arguments.isEmpty) {
-            type = typdef.rawType;
-          } else {
-            type = new ResolutionTypedefType(
-                typdef, arguments.toList(growable: false));
-            addTypeVariableBoundsCheck =
-                arguments.any((ResolutionDartType type) => !type.isDynamic);
-          }
-        }
-      } else if (element.isTypeVariable) {
-        TypeVariableElement typeVariable = element;
-        Element outer =
-            visitor.enclosingElement.outermostEnclosingMemberOrTopLevel;
-        if (!outer.isClass &&
-            !outer.isTypedef &&
-            !Elements.hasAccessToTypeVariable(
-                visitor.enclosingElement, typeVariable)) {
-          registry.registerFeature(Feature.THROW_RUNTIME_ERROR);
-          type = reportFailureAndCreateType(
-              MessageKind.TYPE_VARIABLE_WITHIN_STATIC_MEMBER,
-              {'typeVariableName': node},
-              userProvidedBadType: typeVariable.type);
-        } else {
-          type = typeVariable.type;
-        }
-        type = checkNoTypeArguments(type);
-      } else {
-        reporter.internalError(
-            node, "Unexpected element kind ${element.kind}.");
-      }
-      if (addTypeVariableBoundsCheck) {
-        visitor.addDeferredAction(visitor.enclosingElement,
-            () => checkTypeVariableBounds(node, type));
-      }
-    }
-    registry.useType(node, type);
-    return type;
-  }
-
-  /// Checks the type arguments of [type] against the type variable bounds.
-  void checkTypeVariableBounds(NominalTypeAnnotation node, GenericType type) {
-    void checkTypeVariableBound(_, DartType _typeArgument,
-        TypeVariableType _typeVariable, DartType _bound) {
-      ResolutionDartType typeArgument = _typeArgument;
-      ResolutionTypeVariableType typeVariable = _typeVariable;
-      ResolutionDartType bound = _bound;
-      if (!types.isSubtype(typeArgument, bound)) {
-        reporter.reportWarningMessage(
-            node, MessageKind.INVALID_TYPE_VARIABLE_BOUND, {
-          'typeVariable': typeVariable,
-          'bound': bound,
-          'typeArgument': typeArgument,
-          'thisType': type.element.thisType
-        });
-      }
-    }
-
-    types.genericCheckTypeVariableBounds(type, type.typeArguments,
-        type.element.typeVariables, checkTypeVariableBound);
-  }
-
-  /**
-   * Resolves the type arguments of [node] and adds these to [arguments].
-   *
-   * Returns [: true :] if the number of type arguments did not match the
-   * number of type variables.
-   */
-  bool resolveTypeArguments(
-      MappingVisitor visitor,
-      NominalTypeAnnotation node,
-      List<ResolutionDartType> typeVariables,
-      List<ResolutionDartType> arguments,
-      FunctionTypeParameterScope functionTypeParameters) {
-    if (node.typeArguments == null) {
-      return false;
-    }
-    int expectedVariables = typeVariables.length;
-    int index = 0;
-    bool typeArgumentCountMismatch = false;
-    for (Link<Node> typeArguments = node.typeArguments.nodes;
-        !typeArguments.isEmpty;
-        typeArguments = typeArguments.tail, index++) {
-      if (index > expectedVariables - 1) {
-        reporter.reportWarningMessage(
-            typeArguments.head, MessageKind.ADDITIONAL_TYPE_ARGUMENT);
-        typeArgumentCountMismatch = true;
-      }
-      ResolutionDartType argType = _resolveTypeAnnotation(
-          visitor, typeArguments.head, functionTypeParameters);
-      // TODO(karlklose): rewrite to not modify [arguments].
-      arguments.add(argType);
-    }
-    if (index < expectedVariables) {
-      reporter.reportWarningMessage(
-          node.typeArguments, MessageKind.MISSING_TYPE_ARGUMENT);
-      typeArgumentCountMismatch = true;
-    }
-    return typeArgumentCountMismatch;
-  }
-}
-
-/// [FunctionTypeParameterScope] put type parameters in scope for the nested
-/// types.
-///
-/// For example, in the following examples, the generic types `A` would be stored
-/// in a [FunctionTypeParameterScope].
-///
-///     typedef F = List<A> Function<A>(A x)
-///     typedef F = Function(List<A> Function<A>(A x))
-///
-/// They are resolved to `dynamic` until dart2js supports generic methods.
-class FunctionTypeParameterScope {
-  final FunctionTypeParameterScope parent;
-  final Map<String, ResolutionDartType> _map;
-
-  const FunctionTypeParameterScope()
-      : parent = null,
-        _map = const {};
-
-  FunctionTypeParameterScope._(this.parent, this._map);
-
-  FunctionTypeParameterScope expand(NodeList typeParameters) {
-    if (typeParameters == null)
-      return new FunctionTypeParameterScope._(this, const {});
-    Map<String, ResolutionDartType> map = <String, ResolutionDartType>{};
-    for (TypeVariable node in typeParameters) {
-      /// TODO(johnniwinther): Create a special [FunctionTypeVariableType]
-      /// instead of [ResolutionDynamicType].
-      map[node.name.source] = const ResolutionDynamicType();
-    }
-    return new FunctionTypeParameterScope._(this, map);
-  }
-
-  ResolutionDartType lookup(String name) {
-    return _map[name] ?? parent?.lookup(name);
-  }
-}
diff --git a/pkg/compiler/lib/src/resolution/typedefs.dart b/pkg/compiler/lib/src/resolution/typedefs.dart
deleted file mode 100644
index e3e58ec..0000000
--- a/pkg/compiler/lib/src/resolution/typedefs.dart
+++ /dev/null
@@ -1,150 +0,0 @@
-// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library dart2js.resolution.typedefs;
-
-import '../common.dart';
-import '../common/resolution.dart';
-import '../elements/resolution_types.dart';
-import '../elements/elements.dart'
-    show FunctionSignature, TypedefElement, TypeVariableElement;
-import '../elements/modelx.dart' show ErroneousElementX, TypedefElementX;
-import '../tree/tree.dart';
-import '../util/util.dart' show Link;
-import 'class_hierarchy.dart' show TypeDefinitionVisitor;
-import 'registry.dart' show ResolutionRegistry;
-import 'scope.dart' show MethodScope, TypeDeclarationScope;
-import 'signatures.dart' show SignatureResolver;
-import 'type_resolver.dart' show FunctionTypeParameterScope;
-
-class TypedefResolverVisitor extends TypeDefinitionVisitor {
-  TypedefElementX get element => enclosingElement;
-
-  TypedefResolverVisitor(Resolution resolution, TypedefElement typedefElement,
-      ResolutionRegistry registry)
-      : super(resolution, typedefElement, registry);
-
-  visitTypedef(Typedef node) {
-    element.computeType(resolution);
-    scope = new TypeDeclarationScope(scope, element);
-    resolveTypeVariableBounds(node.templateParameters);
-
-    FunctionTypeParameterScope functionTypeParameters =
-        const FunctionTypeParameterScope().expand(node.typeParameters);
-
-    FunctionSignature signature = SignatureResolver.analyze(
-        resolution,
-        scope,
-        functionTypeParameters,
-        null, // Don't create type variable types for the type parameters.
-        node.formals,
-        node.returnType,
-        element,
-        registry,
-        defaultValuesError: MessageKind.TYPEDEF_FORMAL_WITH_DEFAULT);
-    element.functionSignature = signature;
-
-    scope = new MethodScope(scope, element);
-    signature.forEachParameter(addToScope);
-
-    element.aliasCache = signature.type;
-
-    void checkCyclicReference() {
-      element.checkCyclicReference(resolution);
-    }
-
-    addDeferredAction(element, checkCyclicReference);
-  }
-}
-
-// TODO(johnniwinther): Replace with a traversal on the AST when the type
-// annotations in typedef alias are stored in a [TreeElements] mapping.
-class TypedefCyclicVisitor extends BaseResolutionDartTypeVisitor {
-  final DiagnosticReporter reporter;
-  final TypedefElementX element;
-  bool hasCyclicReference = false;
-
-  Link<TypedefElement> seenTypedefs = const Link<TypedefElement>();
-
-  int seenTypedefsCount = 0;
-
-  Link<TypeVariableElement> seenTypeVariables =
-      const Link<TypeVariableElement>();
-
-  TypedefCyclicVisitor(this.reporter, this.element);
-
-  visitType(ResolutionDartType type, _) {
-    // Do nothing.
-  }
-
-  visitTypedefType(ResolutionTypedefType type, _) {
-    TypedefElementX typedefElement = type.element;
-    if (seenTypedefs.contains(typedefElement)) {
-      if (!hasCyclicReference && identical(element, typedefElement)) {
-        // Only report an error on the checked typedef to avoid generating
-        // multiple errors for the same cyclicity.
-        hasCyclicReference = true;
-        if (seenTypedefsCount == 1) {
-          // Direct cyclicity.
-          reporter.reportErrorMessage(element, MessageKind.CYCLIC_TYPEDEF,
-              {'typedefName': element.name});
-        } else if (seenTypedefsCount == 2) {
-          // Cyclicity through one other typedef.
-          reporter.reportErrorMessage(element, MessageKind.CYCLIC_TYPEDEF_ONE, {
-            'typedefName': element.name,
-            'otherTypedefName': seenTypedefs.head.name
-          });
-        } else {
-          // Cyclicity through more than one other typedef.
-          for (TypedefElement cycle in seenTypedefs) {
-            if (!identical(typedefElement, cycle)) {
-              reporter.reportErrorMessage(
-                  element, MessageKind.CYCLIC_TYPEDEF_ONE, {
-                'typedefName': element.name,
-                'otherTypedefName': cycle.name
-              });
-            }
-          }
-        }
-        ErroneousElementX erroneousElement = new ErroneousElementX(
-            MessageKind.CYCLIC_TYPEDEF,
-            {'typedefName': element.name},
-            element.name,
-            element);
-        element.aliasCache =
-            new MalformedType(erroneousElement, typedefElement.aliasCache);
-        element.hasBeenCheckedForCycles = true;
-      }
-    } else {
-      seenTypedefs = seenTypedefs.prepend(typedefElement);
-      seenTypedefsCount++;
-      type.visitChildren(this, null);
-      if (!typedefElement.isMalformed) {
-        typedefElement.aliasCache.accept(this, null);
-      }
-      seenTypedefs = seenTypedefs.tail;
-      seenTypedefsCount--;
-    }
-  }
-
-  visitFunctionType(ResolutionFunctionType type, _) {
-    type.visitChildren(this, null);
-  }
-
-  visitInterfaceType(ResolutionInterfaceType type, _) {
-    type.visitChildren(this, null);
-  }
-
-  visitTypeVariableType(ResolutionTypeVariableType type, _) {
-    TypeVariableElement typeVariableElement = type.element;
-    if (seenTypeVariables.contains(typeVariableElement)) {
-      // Avoid running in cycles on cyclic type variable bounds.
-      // Cyclicity is reported elsewhere.
-      return;
-    }
-    seenTypeVariables = seenTypeVariables.prepend(typeVariableElement);
-    typeVariableElement.bound.accept(this, null);
-    seenTypeVariables = seenTypeVariables.tail;
-  }
-}
diff --git a/pkg/compiler/lib/src/resolution/variables.dart b/pkg/compiler/lib/src/resolution/variables.dart
deleted file mode 100644
index 60541a5..0000000
--- a/pkg/compiler/lib/src/resolution/variables.dart
+++ /dev/null
@@ -1,77 +0,0 @@
-// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library dart2js.resolution.variables;
-
-import '../common.dart';
-import '../common/resolution.dart';
-import '../elements/modelx.dart' show LocalVariableElementX, VariableList;
-import '../tree/tree.dart';
-import '../universe/feature.dart';
-import '../util/util.dart' show Link;
-import 'members.dart' show ResolverVisitor;
-import 'registry.dart' show ResolutionRegistry;
-import 'resolution_common.dart' show CommonResolverVisitor;
-import 'scope.dart' show VariableDefinitionScope;
-
-class VariableDefinitionsVisitor extends CommonResolverVisitor<Identifier> {
-  VariableDefinitions definitions;
-  ResolverVisitor resolver;
-  VariableList variables;
-
-  VariableDefinitionsVisitor(
-      Resolution resolution, this.definitions, this.resolver, this.variables)
-      : super(resolution);
-
-  ResolutionRegistry get registry => resolver.registry;
-
-  Identifier visitSendSet(SendSet node) {
-    assert(node.arguments.tail.isEmpty); // Sanity check
-    Identifier identifier = node.selector;
-    String name = identifier.source;
-    VariableDefinitionScope scope =
-        new VariableDefinitionScope(resolver.scope, name);
-    resolver.visitIn(node.arguments.head, scope);
-    if (scope.variableReferencedInInitializer) {
-      reporter.reportErrorMessage(identifier,
-          MessageKind.REFERENCE_IN_INITIALIZATION, {'variableName': name});
-    }
-    return identifier;
-  }
-
-  Identifier visitIdentifier(Identifier node) {
-    if (!resolver.inCatchParameters) {
-      // The variable is initialized to null.
-      registry.registerFeature(Feature.LOCAL_WITHOUT_INITIALIZER);
-    }
-    if (definitions.modifiers.isConst) {
-      if (resolver.inLoopVariable) {
-        reporter.reportErrorMessage(node, MessageKind.CONST_LOOP_VARIABLE);
-      } else {
-        reporter.reportErrorMessage(
-            node, MessageKind.CONST_WITHOUT_INITIALIZER);
-      }
-    }
-    if (definitions.modifiers.isFinal && !resolver.inLoopVariable) {
-      reporter.reportErrorMessage(node, MessageKind.FINAL_WITHOUT_INITIALIZER);
-    }
-    return node;
-  }
-
-  visitNodeList(NodeList node) {
-    for (Link<Node> link = node.nodes; !link.isEmpty; link = link.tail) {
-      Identifier name = visit(link.head);
-      LocalVariableElementX element = new LocalVariableElementX(
-          name.source, resolver.enclosingElement, variables, name.token);
-      resolver.defineLocalVariable(link.head, element);
-      resolver.addToScope(element);
-      if (definitions.modifiers.isConst) {
-        addDeferredAction(element, () {
-          element.constant =
-              resolution.resolver.constantCompiler.compileConstant(element);
-        });
-      }
-    }
-  }
-}
diff --git a/pkg/compiler/lib/src/resolved_uri_translator.dart b/pkg/compiler/lib/src/resolved_uri_translator.dart
index f40aeb3..ded9161 100644
--- a/pkg/compiler/lib/src/resolved_uri_translator.dart
+++ b/pkg/compiler/lib/src/resolved_uri_translator.dart
@@ -2,41 +2,14 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-import 'common.dart';
-import 'elements/elements.dart' show LibraryElement;
-import 'util/emptyset.dart';
-
 /// API used by the library loader to translate internal SDK URIs into file
 /// system readable URIs.
 abstract class ResolvedUriTranslator {
-  factory ResolvedUriTranslator(
-      Map<String, Uri> sdkLibraries,
-      DiagnosticReporter reporter,
-      Uri platformConfigUri) = _ResolvedUriTranslator;
-
-  /// The set of platform libraries reported as unsupported.
-  ///
-  /// For instance when importing 'dart:io' without '--categories=Server'.
-  Set<Uri> get disallowedLibraryUris;
-
-  /// Whether or not a mockable library has been translated.
-  bool get mockableLibraryUsed;
+  factory ResolvedUriTranslator(Map<String, Uri> sdkLibraries) =
+      _ResolvedUriTranslator;
 
   /// A mapping from dart: library names to their location.
   Map<String, Uri> get sdkLibraries;
-
-  /// Translates the resolved [uri] into a readable URI.
-  ///
-  /// The [importingLibrary] holds the library importing [uri] or `null` if
-  /// [uri] is loaded as the main library. The [importingLibrary] is used to
-  /// grant access to internal libraries from platform libraries and patch
-  /// libraries.
-  ///
-  /// If the [uri] is not accessible from [importingLibrary], this method is
-  /// responsible for reporting errors.
-  ///
-  /// See [LibraryLoader] for terminology on URIs.
-  Uri translate(LibraryElement importingLibrary, Uri uri, Spannable spannable);
 }
 
 /// A translator that forwards all methods to an internal
@@ -58,129 +31,13 @@
   bool get isNotSet => resolvedUriTranslator == null;
 
   @override
-  Uri translate(LibraryElement importingLibrary, Uri resolvedUri,
-          Spannable spannable) =>
-      resolvedUriTranslator.translate(importingLibrary, resolvedUri, spannable);
-
-  @override
-  Set<Uri> get disallowedLibraryUris =>
-      resolvedUriTranslator?.disallowedLibraryUris ??
-      const ImmutableEmptySet<Uri>();
-
-  @override
-  bool get mockableLibraryUsed => resolvedUriTranslator.mockableLibraryUsed;
-
-  @override
   Map<String, Uri> get sdkLibraries => resolvedUriTranslator.sdkLibraries;
 }
 
 class _ResolvedUriTranslator implements ResolvedUriTranslator {
   final Map<String, Uri> _sdkLibraries;
-  final DiagnosticReporter _reporter;
-  final Uri _platformConfigUri;
 
-  Set<Uri> disallowedLibraryUris = new Set<Uri>();
-  bool mockableLibraryUsed = false;
-
-  _ResolvedUriTranslator(
-      this._sdkLibraries, this._reporter, this._platformConfigUri);
+  _ResolvedUriTranslator(this._sdkLibraries);
 
   Map<String, Uri> get sdkLibraries => _sdkLibraries;
-
-  @override
-  Uri translate(LibraryElement importingLibrary, Uri uri, Spannable spannable) {
-    if (uri.scheme == 'dart') {
-      return translateDartUri(importingLibrary, uri, spannable);
-    }
-    return uri;
-  }
-
-  /// Translates "resolvedUri" with scheme "dart" to a [uri] resolved relative
-  /// to `options.platformConfigUri` according to the information in the file at
-  /// `options.platformConfigUri`.
-  ///
-  /// Returns `null` and emits an error if the library could not be found or
-  /// imported into [importingLibrary].
-  ///
-  /// Internal libraries (whose name starts with '_') can be only resolved if
-  /// [importingLibrary] is a platform or patch library.
-  Uri translateDartUri(
-      LibraryElement importingLibrary, Uri resolvedUri, Spannable spannable) {
-    Uri location = lookupLibraryUri(resolvedUri.path);
-
-    if (location == null) {
-      _reporter.reportErrorMessage(spannable, MessageKind.LIBRARY_NOT_FOUND,
-          {'resolvedUri': resolvedUri});
-      return null;
-    }
-
-    if (resolvedUri.path.startsWith('_')) {
-      bool allowInternalLibraryAccess = importingLibrary != null &&
-          (importingLibrary.isPlatformLibrary ||
-              importingLibrary.isPatch ||
-              importingLibrary.canonicalUri.scheme == 'memory' ||
-              importingLibrary.canonicalUri.path
-                  .contains('tests/compiler/dart2js_native') ||
-              importingLibrary.canonicalUri.path
-                  .contains('tests/compiler/dart2js_extra') ||
-              (importingLibrary.canonicalUri.scheme == 'package' &&
-                  importingLibrary.canonicalUri.path
-                      .startsWith('dart_internal/')));
-
-      if (!allowInternalLibraryAccess) {
-        if (importingLibrary != null) {
-          _reporter.reportErrorMessage(
-              spannable, MessageKind.INTERNAL_LIBRARY_FROM, {
-            'resolvedUri': resolvedUri,
-            'importingUri': importingLibrary.canonicalUri
-          });
-        } else {
-          _reporter.reportErrorMessage(spannable, MessageKind.INTERNAL_LIBRARY,
-              {'resolvedUri': resolvedUri});
-          registerDisallowedLibraryUse(resolvedUri);
-        }
-        return null;
-      }
-    }
-
-    if (location.scheme == "unsupported") {
-      if (location.path == "") {
-        _reporter.reportErrorMessage(spannable,
-            MessageKind.LIBRARY_NOT_SUPPORTED, {'resolvedUri': resolvedUri});
-        registerDisallowedLibraryUse(resolvedUri);
-      } else {
-        // If the specification includes a path, we treat it as "partially"
-        // unsupported: it is allowed to be imported unconditionally, but we
-        // will not expose it as being supported in the const variable
-        // `dart.library.name`.
-        //
-        // This is a stopgap measure to support packages like `http` that need
-        // to import `dart:io` conditionally. Once config-imports are supported
-        // in the language, we can make it an error again to import it
-        // unconditionally.
-        //
-        // The plaform configuration files contain a URI of the form
-        // `unsupported:path/to/library.dart` to indicate this partially
-        // supported mode. We resolve the path with respect to the configuration
-        // file.
-        return _platformConfigUri.resolve(location.path);
-      }
-      return null;
-    }
-
-    if (resolvedUri.path == 'html' || resolvedUri.path == 'io') {
-      // TODO(ahe): Get rid of mockableLibraryUsed when test.dart
-      // supports this use case better.
-      mockableLibraryUsed = true;
-    }
-    return location;
-  }
-
-  void registerDisallowedLibraryUse(Uri uri) {
-    disallowedLibraryUris.add(uri);
-  }
-
-  Uri lookupLibraryUri(String libraryName) {
-    return _sdkLibraries[libraryName];
-  }
 }
diff --git a/pkg/compiler/lib/src/scanner/scanner_task.dart b/pkg/compiler/lib/src/scanner/scanner_task.dart
deleted file mode 100644
index 6e3b3e9..0000000
--- a/pkg/compiler/lib/src/scanner/scanner_task.dart
+++ /dev/null
@@ -1,69 +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.
-
-library dart2js.scanner.task;
-
-import '../common/tasks.dart' show CompilerTask, Measurer;
-import '../diagnostics/diagnostic_listener.dart' show DiagnosticReporter;
-import '../elements/elements.dart' show CompilationUnitElement, LibraryElement;
-import '../parser/diet_parser_task.dart' show DietParserTask;
-import '../script.dart' show Script;
-import 'package:front_end/src/fasta/scanner.dart'
-    show Scanner, StringScanner, Token, Utf8BytesScanner;
-import '../io/source_file.dart';
-
-class ScannerTask extends CompilerTask {
-  final DietParserTask _dietParser;
-  final DiagnosticReporter reporter;
-
-  ScannerTask(this._dietParser, this.reporter, Measurer measurer)
-      : super(measurer);
-
-  String get name => 'Scanner';
-
-  void scanLibrary(LibraryElement library) {
-    CompilationUnitElement compilationUnit = library.entryCompilationUnit;
-    String canonicalUri = library.canonicalUri.toString();
-    String resolvedUri = compilationUnit.script.resourceUri.toString();
-    if (canonicalUri == resolvedUri) {
-      reporter.log("Scanning library $canonicalUri");
-    } else {
-      reporter.log("Scanning library $canonicalUri ($resolvedUri)");
-    }
-    scan(compilationUnit);
-  }
-
-  void scan(CompilationUnitElement compilationUnit) {
-    measure(() {
-      scanElements(compilationUnit);
-    });
-  }
-
-  Token scanFile(SourceFile file, {bool includeComments: false}) {
-    Scanner scanner = file is Utf8BytesSourceFile
-        ? new Utf8BytesScanner(file.slowUtf8ZeroTerminatedBytes(),
-            includeComments: includeComments)
-        : new StringScanner(file.slowText(), includeComments: includeComments);
-    return measure(scanner.tokenize);
-  }
-
-  void scanElements(CompilationUnitElement compilationUnit) {
-    Script script = compilationUnit.script;
-    Token tokens = scanFile(script.file);
-    _dietParser.dietParse(compilationUnit, tokens);
-  }
-
-  /**
-   * Returns the tokens for the [source].
-   *
-   * The [StringScanner] implementation works on strings that end with a '0'
-   * value ('\x00'). If [source] does not end with '0', the string is copied
-   * before scanning.
-   */
-  Token tokenize(String source) {
-    return measure(() {
-      return new StringScanner(source, includeComments: false).tokenize();
-    });
-  }
-}
diff --git a/pkg/compiler/lib/src/ssa/builder.dart b/pkg/compiler/lib/src/ssa/builder.dart
deleted file mode 100644
index 2616b59..0000000
--- a/pkg/compiler/lib/src/ssa/builder.dart
+++ /dev/null
@@ -1,7089 +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.
-
-import 'dart:collection';
-
-import 'package:js_runtime/shared/embedded_names.dart';
-
-import '../closure.dart';
-import '../common.dart';
-import '../common/codegen.dart' show CodegenRegistry;
-import '../common/names.dart' show Identifiers, Selectors;
-import '../common/tasks.dart' show CompilerTask;
-import '../compiler.dart';
-import '../constants/constant_system.dart';
-import '../constants/expressions.dart';
-import '../constants/values.dart';
-import '../deferred_load.dart' show OutputUnit;
-import '../diagnostics/messages.dart' show Message, MessageTemplate;
-import '../dump_info.dart' show InfoReporter;
-import '../elements/elements.dart';
-import '../elements/entities.dart';
-import '../elements/jumps.dart';
-import '../elements/modelx.dart' show ConstructorBodyElementX;
-import '../elements/names.dart';
-import '../elements/operators.dart';
-import '../elements/resolution_types.dart';
-import '../elements/types.dart';
-import '../io/source_information.dart';
-import '../js/js.dart' as js;
-import '../js_backend/backend.dart' show JavaScriptBackend;
-import '../js_backend/element_strategy.dart' show ElementCodegenWorkItem;
-import '../js_backend/runtime_types.dart';
-import '../js_emitter/js_emitter.dart' show CodeEmitterTask, NativeEmitter;
-import '../native/native.dart' as native;
-import '../resolution/deferred_load.dart' show AstDeferredLoadTask;
-import '../resolution/semantic_visitor.dart';
-import '../resolution/tree_elements.dart' show TreeElements;
-import '../tree/tree.dart' as ast;
-import '../types/types.dart';
-import '../universe/call_structure.dart' show CallStructure;
-import '../universe/selector.dart' show Selector;
-import '../universe/side_effects.dart' show SideEffects;
-import '../universe/use.dart'
-    show ConstantUse, ConstrainedDynamicUse, StaticUse;
-import '../util/util.dart';
-import '../world.dart' show ClosedWorld;
-
-import 'graph_builder.dart';
-import 'jump_handler.dart';
-import 'locals_handler.dart';
-import 'loop_handler.dart';
-import 'nodes.dart';
-import 'optimize.dart';
-import 'ssa.dart';
-import 'ssa_branch_builder.dart';
-import 'type_builder.dart';
-import 'types.dart';
-
-abstract class SsaAstBuilderBase extends SsaBuilderFieldMixin
-    implements SsaBuilder {
-  final CompilerTask task;
-  final JavaScriptBackend backend;
-
-  SsaAstBuilderBase(this.task, this.backend);
-
-  ConstantValue getFieldInitialConstantValue(FieldElement field) {
-    ConstantExpression constant = field.constant;
-    if (constant != null) {
-      ConstantValue initialValue = backend.constants.getConstantValue(constant);
-      if (initialValue == null) {
-        assert(
-            field.isInstanceMember ||
-                constant.isImplicit ||
-                constant.isPotential,
-            failedAt(
-                field,
-                "Constant expression without value: "
-                "${constant.toStructuredText()}."));
-      }
-      return initialValue;
-    }
-    return null;
-  }
-}
-
-class SsaAstBuilder extends SsaAstBuilderBase {
-  final CodeEmitterTask emitter;
-  final SourceInformationStrategy sourceInformationFactory;
-
-  SsaAstBuilder(CompilerTask task, JavaScriptBackend backend,
-      this.sourceInformationFactory)
-      : emitter = backend.emitter,
-        super(task, backend);
-
-  DiagnosticReporter get reporter => backend.reporter;
-
-  HGraph build(covariant ElementCodegenWorkItem work, ClosedWorld closedWorld) {
-    return task.measure(() {
-      if (handleConstantField(work.element, work.registry, closedWorld)) {
-        // No code is generated for `work.element`.
-        return null;
-      }
-      MemberElement element = work.element.implementation;
-      return reporter.withCurrentElement(element, () {
-        SsaAstGraphBuilder builder = new SsaAstGraphBuilder(
-            work.element.implementation,
-            work.resolvedAst,
-            work.registry,
-            backend,
-            closedWorld,
-            emitter.nativeEmitter,
-            sourceInformationFactory);
-        HGraph graph = builder.build();
-
-        // Default arguments are handled elsewhere, but we must ensure
-        // that the default values are computed during codegen.
-        if (!identical(element.kind, ElementKind.FIELD)) {
-          MethodElement function = element;
-          FunctionSignature signature = function.functionSignature;
-          signature.forEachOptionalParameter((_parameter) {
-            ParameterElement parameter = _parameter;
-            // This ensures the default value will be computed.
-            ConstantValue constant =
-                backend.constants.getConstantValue(parameter.constant);
-            work.registry.registerConstantUse(new ConstantUse.init(constant));
-          });
-        }
-        if (backend.tracer.isEnabled) {
-          String name;
-          if (element.isClassMember) {
-            String className = element.enclosingClass.name;
-            String memberName = element.name;
-            name = "$className.$memberName";
-            if (element.isGenerativeConstructorBody) {
-              name = "$name (body)";
-            }
-          } else {
-            name = "${element.name}";
-          }
-          backend.tracer.traceCompilation(name);
-          backend.tracer.traceGraph('builder', graph);
-        }
-        return graph;
-      });
-    });
-  }
-}
-
-/**
- * This class builds SSA nodes for functions represented in AST.
- */
-class SsaAstGraphBuilder extends ast.Visitor
-    with
-        BaseImplementationOfCompoundsMixin,
-        BaseImplementationOfSetIfNullsMixin,
-        BaseImplementationOfSuperIndexSetIfNullMixin,
-        SemanticSendResolvedMixin,
-        NewBulkMixin,
-        ErrorBulkMixin,
-        GraphBuilder
-    implements SemanticSendVisitor {
-  /// The element for which this SSA builder is being used.
-  final MemberElement target;
-  final ClosedWorld closedWorld;
-
-  ResolvedAst resolvedAst;
-
-  /// Used to report information about inlining (which occurs while building the
-  /// SSA graph), when dump-info is enabled.
-  final InfoReporter infoReporter;
-
-  /// Registry used to enqueue work during codegen, may be null to avoid
-  /// enqueing any work.
-  // TODO(sigmund,johnniwinther): get rid of registry entirely. We should be
-  // able to return the impact as a result after building and avoid enqueing
-  // things here. Later the codegen task can decide whether to enqueue
-  // something. In the past this didn't matter as much because the SSA graph was
-  // used only for codegen, but currently we want to experiment using it for
-  // code-analysis too.
-  final CodegenRegistry registry;
-
-  /// Results from the global type-inference analysis corresponding to the
-  /// current element being visited.
-  ///
-  /// Invariant: this property is updated together with [resolvedAst].
-  GlobalTypeInferenceElementResult elementInferenceResults;
-
-  final JavaScriptBackend backend;
-
-  Compiler get compiler => backend.compiler;
-
-  AstDeferredLoadTask get deferredLoadTask => super.deferredLoadTask;
-
-  final ConstantSystem constantSystem;
-  final RuntimeTypesSubstitutions rtiSubstitutions;
-
-  SourceInformationBuilder sourceInformationBuilder;
-
-  bool inLazyInitializerExpression = false;
-
-  // TODO(sigmund): make all comments /// instead of /* */
-  /* This field is used by the native handler. */
-  final NativeEmitter nativeEmitter;
-
-  /**
-   * True if we are visiting the expression of a throw statement; we assume this
-   * is a slow path.
-   */
-  bool inExpressionOfThrow = false;
-
-  /**
-   * This stack contains declaration elements of the functions being built
-   * or inlined by this builder.
-   */
-  final List<MemberElement> sourceElementStack = <MemberElement>[];
-
-  HInstruction rethrowableException;
-
-  /// Returns `true` if the current element is an `async` function.
-  bool get isBuildingAsyncFunction {
-    Element element = sourceElement;
-    return (element is FunctionElement &&
-        element.asyncMarker == AsyncMarker.ASYNC);
-  }
-
-  /// Handles the building of loops.
-  LoopHandler<ast.Node> loopHandler;
-
-  /// Handles type check building.
-  TypeBuilder typeBuilder;
-
-  // TODO(sigmund): make most args optional
-  SsaAstGraphBuilder(
-      this.target,
-      this.resolvedAst,
-      this.registry,
-      JavaScriptBackend backend,
-      this.closedWorld,
-      this.nativeEmitter,
-      SourceInformationStrategy sourceInformationFactory)
-      : this.infoReporter = backend.compiler.dumpInfoTask,
-        this.backend = backend,
-        this.constantSystem = backend.constantSystem,
-        this.rtiSubstitutions = backend.rtiSubstitutions {
-    assert(target.isImplementation);
-    elementInferenceResults = _resultOf(target.declaration);
-    assert(elementInferenceResults != null);
-    graph.element = target;
-    sourceElementStack.add(target.declaration);
-    sourceInformationBuilder =
-        sourceInformationFactory.createBuilderForContext(target);
-    graph.sourceInformation =
-        sourceInformationBuilder.buildVariableDeclaration();
-    localsHandler = new LocalsHandler(
-        this,
-        target,
-        target.memberContext,
-        target.contextClass?.thisType,
-        closedWorld.nativeData,
-        closedWorld.interceptorData);
-    loopHandler = new SsaLoopHandler(this);
-    typeBuilder = new AstTypeBuilder(this);
-  }
-
-  MemberElement get targetElement => target;
-
-  /// Reference to resolved elements in [target]'s AST.
-  TreeElements get elements => resolvedAst.elements;
-
-  @override
-  SemanticSendVisitor get sendVisitor => this;
-
-  @override
-  void visitNode(ast.Node node) {
-    internalError(node, "Unhandled node: $node");
-  }
-
-  @override
-  void apply(ast.Node node, [_]) {
-    node.accept(this);
-  }
-
-  /// Returns the current source element.
-  ///
-  /// The returned element is a declaration element.
-  // TODO(johnniwinther): Check that all usages of sourceElement agree on
-  // implementation/declaration distinction.
-  @override
-  MemberElement get sourceElement => sourceElementStack.last;
-
-  /// Helper to retrieve global inference results for [element] with special
-  /// care for `ConstructorBodyElement`s which don't exist at the time the
-  /// global analysis run.
-  ///
-  /// Note: this helper is used selectively. When we know that we are in a
-  /// context were we don't expect to see a constructor body element, we
-  /// directly fetch the data from the global inference results.
-  GlobalTypeInferenceElementResult _resultOf(MemberElement element) {
-    assert(element.isDeclaration);
-    return globalInferenceResults.resultOfMember(
-        element is ConstructorBodyElementX ? element.constructor : element);
-  }
-
-  /// Build the graph for [target].
-  HGraph build() {
-    assert(target.isImplementation, failedAt(target));
-    HInstruction.idCounter = 0;
-    // TODO(sigmund): remove `result` and return graph directly, need to ensure
-    // that it can never be null (see result in buildFactory for instance).
-    var result;
-    if (target.isGenerativeConstructor) {
-      result = buildFactory(resolvedAst);
-    } else if (target.isGenerativeConstructorBody ||
-        target.isFactoryConstructor ||
-        target.isFunction ||
-        target.isGetter ||
-        target.isSetter) {
-      result = buildMethod(target);
-    } else if (target.isField) {
-      if (target.isInstanceMember) {
-        assert(options.enableTypeAssertions);
-        result = buildCheckedSetter(target);
-      } else {
-        result = buildLazyInitializer(target);
-      }
-    } else {
-      reporter.internalError(target, 'Unexpected element kind $target.');
-    }
-    assert(result.isValid());
-    return result;
-  }
-
-  void addWithPosition(HInstruction instruction, ast.Node node) {
-    add(attachPosition(instruction, node));
-  }
-
-  /**
-   * Returns a complete argument list for a call of [function].
-   */
-  List<HInstruction> completeSendArgumentsList(
-      FunctionElement function,
-      Selector selector,
-      List<HInstruction> providedArguments,
-      ast.Node currentNode) {
-    assert(function.isImplementation, failedAt(function));
-    assert(providedArguments != null);
-
-    bool isInstanceMember = function.isInstanceMember;
-    // For static calls, [providedArguments] is complete, default arguments
-    // have been included if necessary, see [makeStaticArgumentList].
-    if (!isInstanceMember ||
-        currentNode == null || // In erroneous code, currentNode can be null.
-        providedArgumentsKnownToBeComplete(currentNode) ||
-        function.isGenerativeConstructorBody ||
-        selector.isGetter) {
-      // For these cases, the provided argument list is known to be complete.
-      return providedArguments;
-    } else {
-      return completeDynamicSendArgumentsList(
-          selector, function, providedArguments);
-    }
-  }
-
-  /**
-   * Returns a complete argument list for a dynamic call of [function]. The
-   * initial argument list [providedArguments], created by
-   * [addDynamicSendArgumentsToList], does not include values for default
-   * arguments used in the call. The reason is that the target function (which
-   * defines the defaults) is not known.
-   *
-   * However, inlining can only be performed when the target function can be
-   * resolved statically. The defaults can therefore be included at this point.
-   *
-   * The [providedArguments] list contains first all positional arguments, then
-   * the provided named arguments (the named arguments that are defined in the
-   * [selector]) in a specific order (see [addDynamicSendArgumentsToList]).
-   */
-  List<HInstruction> completeDynamicSendArgumentsList(Selector selector,
-      MethodElement function, List<HInstruction> providedArguments) {
-    assert(selector.applies(function));
-    FunctionSignature signature = function.functionSignature;
-    List<HInstruction> compiledArguments = new List<HInstruction>(
-        signature.parameterCount + 1); // Plus one for receiver.
-
-    compiledArguments[0] = providedArguments[0]; // Receiver.
-    int index = 1;
-    for (; index <= signature.requiredParameterCount; index++) {
-      compiledArguments[index] = providedArguments[index];
-    }
-    if (!signature.optionalParametersAreNamed) {
-      signature.forEachOptionalParameter((element) {
-        if (index < providedArguments.length) {
-          compiledArguments[index] = providedArguments[index];
-        } else {
-          compiledArguments[index] =
-              handleConstantForOptionalParameter(element);
-        }
-        index++;
-      });
-    } else {
-      /* Example:
-       *   void foo(a, {b, d, c})
-       *   foo(0, d = 1, b = 2)
-       *
-       * providedArguments = [0, 2, 1]
-       * selectorArgumentNames = [b, d]
-       * signature.orderedOptionalParameters = [b, c, d]
-       *
-       * For each parameter name in the signature, if the argument name matches
-       * we use the next provided argument, otherwise we get the default.
-       */
-      List<String> selectorArgumentNames =
-          selector.callStructure.getOrderedNamedArguments();
-      int namedArgumentIndex = 0;
-      int firstProvidedNamedArgument = index;
-      signature.orderedOptionalParameters.forEach((element) {
-        if (namedArgumentIndex < selectorArgumentNames.length &&
-            element.name == selectorArgumentNames[namedArgumentIndex]) {
-          // The named argument was provided in the function invocation.
-          compiledArguments[index] = providedArguments[
-              firstProvidedNamedArgument + namedArgumentIndex++];
-        } else {
-          compiledArguments[index] =
-              handleConstantForOptionalParameter(element);
-        }
-        index++;
-      });
-    }
-    return compiledArguments;
-  }
-
-  /**
-   * Try to inline [element] within the correct context of the builder. The
-   * insertion point is the state of the builder.
-   */
-  bool tryInlineMethod(MethodElement element, Selector selector, TypeMask mask,
-      List<HInstruction> providedArguments, ast.Node currentNode,
-      {ResolutionInterfaceType instanceType}) {
-    if (nativeData.isJsInteropMember(element) &&
-        !element.isFactoryConstructor) {
-      // We only inline factory JavaScript interop constructors.
-      return false;
-    }
-
-    // Ensure that [element] is an implementation element.
-    element = element.implementation;
-
-    if (compiler.elementHasCompileTimeError(element)) return false;
-
-    MethodElement function = element;
-    MethodElement declaration = function.declaration;
-    ResolvedAst functionResolvedAst = function.resolvedAst;
-    bool insideLoop = loopDepth > 0 || graph.calledInLoop;
-
-    // Bail out early if the inlining decision is in the cache and we can't
-    // inline (no need to check the hard constraints).
-    bool cachedCanBeInlined =
-        inlineCache.canInline(declaration, insideLoop: insideLoop);
-    if (cachedCanBeInlined == false) return false;
-
-    bool meetsHardConstraints() {
-      if (options.disableInlining) return false;
-
-      assert(
-          selector != null ||
-              Elements.isStaticOrTopLevel(function) ||
-              function.isGenerativeConstructorBody,
-          failedAt(currentNode ?? function,
-              "Missing selector for inlining of $function."));
-      if (selector != null) {
-        if (!selector.applies(function)) return false;
-        if (mask != null && !mask.canHit(function, selector, closedWorld)) {
-          return false;
-        }
-      }
-
-      if (nativeData.isJsInteropMember(function)) return false;
-
-      // Don't inline operator== methods if the parameter can be null.
-      if (function.name == '==') {
-        if (function.enclosingClass != commonElements.objectClass &&
-            providedArguments[1].canBeNull(abstractValueDomain)) {
-          return false;
-        }
-      }
-
-      // Generative constructors of native classes should not be called directly
-      // and have an extra argument that causes problems with inlining.
-      if (function.isGenerativeConstructor &&
-          nativeData.isNativeOrExtendsNative(function.enclosingClass)) {
-        return false;
-      }
-
-      // A generative constructor body is not seen by global analysis,
-      // so we should not query for its type.
-      if (!function.isGenerativeConstructorBody) {
-        if (globalInferenceResults.resultOfMember(declaration).throwsAlways) {
-          isReachable = false;
-          return false;
-        }
-      }
-
-      return true;
-    }
-
-    bool doesNotContainCode() {
-      // A function with size 1 does not contain any code.
-      return InlineWeeder.canBeInlined(functionResolvedAst, 1,
-          enableUserAssertions: options.enableUserAssertions);
-    }
-
-    bool reductiveHeuristic() {
-      // The call is on a path which is executed rarely, so inline only if it
-      // does not make the program larger.
-      if (isCalledOnce(declaration)) {
-        return InlineWeeder.canBeInlined(functionResolvedAst, null,
-            enableUserAssertions: options.enableUserAssertions);
-      }
-      // TODO(sra): Measure if inlining would 'reduce' the size.  One desirable
-      // case we miss by doing nothing is inlining very simple constructors
-      // where all fields are initialized with values from the arguments at this
-      // call site.  The code is slightly larger (`new Foo(1)` vs `Foo$(1)`) but
-      // that usually means the factory constructor is left unused and not
-      // emitted.
-      // We at least inline bodies that are empty (and thus have a size of 1).
-      return doesNotContainCode();
-    }
-
-    bool heuristicSayGoodToGo() {
-      // Don't inline recursively
-      if (inliningStack.any((entry) => entry.function == function)) {
-        return false;
-      }
-
-      if (function.isSynthesized) return true;
-
-      // Don't inline across deferred import to prevent leaking code. The only
-      // exception is an empty function (which does not contain code).
-      bool hasOnlyNonDeferredImportPaths = backend.outputUnitData
-          .hasOnlyNonDeferredImportPaths(compiler.currentElement, function);
-
-      if (!hasOnlyNonDeferredImportPaths) {
-        return doesNotContainCode();
-      }
-
-      // Do not inline code that is rarely executed unless it reduces size.
-      if (inExpressionOfThrow || inLazyInitializerExpression) {
-        return reductiveHeuristic();
-      }
-
-      if (cachedCanBeInlined == true) {
-        // We may have forced the inlining of some methods. Therefore check
-        // if we can inline this method regardless of size.
-        assert(InlineWeeder.canBeInlined(functionResolvedAst, null,
-            allowLoops: true,
-            enableUserAssertions: options.enableUserAssertions));
-        return true;
-      }
-
-      int numParameters = function.functionSignature.parameterCount;
-      int maxInliningNodes;
-      if (insideLoop) {
-        maxInliningNodes = InlineWeeder.INLINING_NODES_INSIDE_LOOP +
-            InlineWeeder.INLINING_NODES_INSIDE_LOOP_ARG_FACTOR * numParameters;
-      } else {
-        maxInliningNodes = InlineWeeder.INLINING_NODES_OUTSIDE_LOOP +
-            InlineWeeder.INLINING_NODES_OUTSIDE_LOOP_ARG_FACTOR * numParameters;
-      }
-
-      // If a method is called only once, and all the methods in the
-      // inlining stack are called only once as well, we know we will
-      // save on output size by inlining this method.
-      if (isCalledOnce(declaration)) {
-        maxInliningNodes = null;
-      }
-      bool canInline = InlineWeeder.canBeInlined(
-          functionResolvedAst, maxInliningNodes,
-          enableUserAssertions: options.enableUserAssertions);
-      if (canInline) {
-        inlineCache.markAsInlinable(declaration, insideLoop: insideLoop);
-      } else {
-        inlineCache.markAsNonInlinable(declaration, insideLoop: insideLoop);
-      }
-      return canInline;
-    }
-
-    void doInlining() {
-      registry
-          .registerStaticUse(new StaticUse.inlining(declaration, instanceType));
-
-      // Add an explicit null check on the receiver before doing the
-      // inlining. We use [element] to get the same name in the
-      // NoSuchMethodError message as if we had called it.
-      if (function.isInstanceMember &&
-          !function.isGenerativeConstructorBody &&
-          (mask == null || mask.isNullable)) {
-        addWithPosition(
-            new HFieldGet(null, providedArguments[0], commonMasks.dynamicType,
-                isAssignable: false),
-            currentNode);
-      }
-      List<HInstruction> compiledArguments = completeSendArgumentsList(
-          function, selector, providedArguments, currentNode);
-      enterInlinedMethod(
-          function, functionResolvedAst, compiledArguments, instanceType);
-      inlinedFrom(functionResolvedAst, () {
-        if (!isReachable) {
-          emitReturn(graph.addConstantNull(closedWorld), null);
-        } else {
-          doInline(functionResolvedAst);
-        }
-      });
-      leaveInlinedMethod();
-    }
-
-    if (meetsHardConstraints() && heuristicSayGoodToGo()) {
-      doInlining();
-      MemberElement inlinedFrom = inliningStack.isEmpty
-          ? target.declaration
-          : inliningStack.last.function.declaration;
-      infoReporter?.reportInlined(declaration, inlinedFrom);
-      return true;
-    }
-
-    return false;
-  }
-
-  bool get allInlinedFunctionsCalledOnce {
-    return inliningStack.isEmpty || inliningStack.last.allFunctionsCalledOnce;
-  }
-
-  bool isFunctionCalledOnce(MethodElement element) {
-    // ConstructorBodyElements are not in the type inference graph.
-    if (element is ConstructorBodyEntity) return false;
-    return globalInferenceResults.resultOfMember(element).isCalledOnce;
-  }
-
-  bool isCalledOnce(MethodElement element) {
-    assert(element.isDeclaration);
-    return allInlinedFunctionsCalledOnce && isFunctionCalledOnce(element);
-  }
-
-  inlinedFrom(ResolvedAst resolvedAst, f()) {
-    MemberElement element = resolvedAst.element;
-    assert(element is FunctionElement || element is VariableElement);
-    return reporter.withCurrentElement(element.implementation, () {
-      // The [sourceElementStack] contains declaration elements.
-      SourceInformationBuilder oldSourceInformationBuilder =
-          sourceInformationBuilder;
-      sourceInformationBuilder = sourceInformationBuilder.forContext(element);
-      sourceElementStack.add(element);
-      var result = f();
-      sourceInformationBuilder = oldSourceInformationBuilder;
-      sourceElementStack.removeLast();
-      return result;
-    });
-  }
-
-  /**
-   * Return null so it is simple to remove the optional parameters completely
-   * from interop methods to match JavaScript semantics for omitted arguments.
-   */
-  HInstruction handleConstantForOptionalParameterJsInterop(Element parameter) =>
-      null;
-
-  HInstruction handleConstantForOptionalParameter(ParameterElement parameter) {
-    ConstantValue constantValue =
-        constants.getConstantValue(parameter.constant);
-    assert(constantValue != null,
-        failedAt(parameter, 'No constant computed for $parameter'));
-    return graph.addConstant(constantValue, closedWorld);
-  }
-
-  ClassElement get currentNonClosureClass {
-    ClassElement cls = sourceElement.enclosingClass;
-    if (cls != null && cls.isClosure) {
-      dynamic closureClass = cls;
-      // ignore: UNDEFINED_GETTER
-      return closureClass.methodElement.enclosingClass;
-    } else {
-      return cls;
-    }
-  }
-
-  /// A stack of [ResolutionDartType]s that have been seen during inlining of
-  /// factory constructors.  These types are preserved in [HInvokeStatic]s and
-  /// [HCreate]s inside the inline code and registered during code generation
-  /// for these nodes.
-  // TODO(karlklose): consider removing this and keeping the (substituted) types
-  // of the type variables in an environment (like the [LocalsHandler]).
-  final List<ResolutionDartType> currentInlinedInstantiations =
-      <ResolutionDartType>[];
-
-  final List<AstInliningState> inliningStack = <AstInliningState>[];
-
-  Local returnLocal;
-  ResolutionDartType returnType;
-
-  ConstantValue getConstantForNode(ast.Node node) {
-    ConstantValue constantValue =
-        constants.getConstantValueForNode(node, elements);
-    assert(constantValue != null,
-        failedAt(node, 'No constant computed for $node'));
-    return constantValue;
-  }
-
-  HInstruction addConstant(ast.Node node) {
-    return graph.addConstant(getConstantForNode(node), closedWorld);
-  }
-
-  /**
-   * Documentation wanted -- johnniwinther
-   *
-   * Invariant: [functionElement] must be an implementation element.
-   */
-  HGraph buildMethod(MethodElement functionElement) {
-    assert(functionElement.isImplementation, failedAt(functionElement));
-    MethodElement declaration = functionElement.declaration;
-    graph.calledInLoop = closedWorld.isCalledInLoop(declaration);
-    ast.FunctionExpression function = resolvedAst.node;
-    assert(function != null);
-    assert(elements.getFunctionDefinition(function) != null);
-    openFunction(functionElement, function);
-    String name = functionElement.name;
-    if (nativeData.isJsInteropMember(functionElement)) {
-      push(invokeJsInteropFunction(functionElement, parameters.values.toList(),
-          sourceInformationBuilder.buildGeneric(function)));
-      var value = pop();
-      closeAndGotoExit(new HReturn(abstractValueDomain, value,
-          sourceInformationBuilder.buildReturn(functionElement.node)));
-      return closeFunction();
-    }
-    assert(!function.modifiers.isExternal, failedAt(functionElement));
-
-    // If [functionElement] is `operator==` we explicitly add a null check at
-    // the beginning of the method. This is to avoid having call sites do the
-    // null check.
-    if (name == '==') {
-      if (!commonElements.operatorEqHandlesNullArgument(functionElement)) {
-        handleIf(
-            node: function,
-            visitCondition: () {
-              HParameterValue parameter = parameters.values.first;
-              push(new HIdentity(parameter, graph.addConstantNull(closedWorld),
-                  null, commonMasks.boolType));
-            },
-            visitThen: () {
-              closeAndGotoExit(new HReturn(
-                  abstractValueDomain,
-                  graph.addConstantBool(false, closedWorld),
-                  sourceInformationBuilder
-                      .buildImplicitReturn(functionElement)));
-            },
-            visitElse: null,
-            sourceInformation: sourceInformationBuilder.buildIf(function.body));
-      }
-    }
-    if (const bool.fromEnvironment('unreachable-throw')) {
-      var emptyParameters = parameters.values
-          .where((p) => abstractValueDomain.isEmpty(p.instructionType));
-      if (emptyParameters.length > 0) {
-        addComment('${emptyParameters} inferred as [empty]');
-        pushInvokeStatic(
-            function.body, commonElements.assertUnreachableMethod, []);
-        pop();
-        return closeFunction();
-      }
-    }
-    function.body.accept(this);
-    return closeFunction();
-  }
-
-  /// Adds a JavaScript comment to the output. The comment will be omitted in
-  /// minified mode.  Each line in [text] is preceded with `//` and indented.
-  /// Use sparingly. In order for the comment to be retained it is modeled as
-  /// having side effects which will inhibit code motion.
-  // TODO(sra): Figure out how to keep comment anchored without effects.
-  void addComment(String text) {
-    add(new HForeignCode(js.js.statementTemplateYielding(new js.Comment(text)),
-        commonMasks.dynamicType, <HInstruction>[],
-        isStatement: true));
-  }
-
-  HGraph buildCheckedSetter(FieldElement field) {
-    ResolvedAst resolvedAst = field.resolvedAst;
-    openFunction(field, resolvedAst.node);
-    HInstruction thisInstruction = localsHandler.readThis(
-        sourceInformation: sourceInformationBuilder.buildDeclaration(field));
-    // Use dynamic type because the type computed by the inferrer is
-    // narrowed to the type annotation.
-    HInstruction parameter =
-        new HParameterValue(field, commonMasks.dynamicType);
-    // Add the parameter as the last instruction of the entry block.
-    // If the method is intercepted, we want the actual receiver
-    // to be the first parameter.
-    graph.entry.addBefore(graph.entry.last, parameter);
-    HInstruction value = typeBuilder.potentiallyCheckOrTrustTypeOfParameter(
-        parameter, field.type);
-    add(new HFieldSet(abstractValueDomain, field, thisInstruction, value));
-    return closeFunction();
-  }
-
-  HGraph buildLazyInitializer(FieldElement variable) {
-    assert(resolvedAst.element == variable,
-        failedAt(variable, "Unexpected variable $variable for $resolvedAst."));
-    inLazyInitializerExpression = true;
-    ast.VariableDefinitions node = resolvedAst.node;
-    ast.Node initializer = resolvedAst.body;
-    assert(
-        initializer != null,
-        failedAt(
-            variable, "Non-constant variable $variable has no initializer."));
-    openFunction(variable, node);
-    visit(initializer);
-    HInstruction value = pop();
-    value = typeBuilder.potentiallyCheckOrTrustTypeOfAssignment(
-        value, variable.type);
-    // In the case of multiple declarations (and some definitions) on the same
-    // line, the source pointer needs to point to the right initialized
-    // variable. So find the specific initialized variable we are referring to.
-    ast.Node sourceInfoNode = initializer;
-    for (var definition in node.definitions) {
-      if (definition is ast.SendSet &&
-          definition.selector.asIdentifier().source == variable.name) {
-        sourceInfoNode = definition.assignmentOperator;
-        break;
-      }
-    }
-
-    closeAndGotoExit(new HReturn(abstractValueDomain, value,
-        sourceInformationBuilder.buildReturn(sourceInfoNode)));
-    return closeFunction();
-  }
-
-  /**
-   * This method sets up the local state of the builder for inlining [function].
-   * The arguments of the function are inserted into the [localsHandler].
-   *
-   * When inlining a function, [:return:] statements are not emitted as
-   * [HReturn] instructions. Instead, the value of a synthetic element is
-   * updated in the [localsHandler]. This function creates such an element and
-   * stores it in the [returnLocal] field.
-   */
-  void setupStateForInlining(
-      MethodElement function, List<HInstruction> compiledArguments,
-      {ResolutionInterfaceType instanceType}) {
-    ResolvedAst resolvedAst = function.resolvedAst;
-    assert(resolvedAst != null);
-    localsHandler = new LocalsHandler(
-        this,
-        function,
-        function.memberContext,
-        instanceType ?? function.contextClass?.thisType,
-        nativeData,
-        interceptorData);
-    localsHandler.scopeInfo = closureDataLookup.getScopeInfo(function);
-    returnLocal =
-        new SyntheticLocal("result", function, function.memberContext);
-    localsHandler.updateLocal(returnLocal, graph.addConstantNull(closedWorld));
-
-    inTryStatement = false; // TODO(lry): why? Document.
-
-    int argumentIndex = 0;
-    if (function.isInstanceMember) {
-      localsHandler.updateLocal(localsHandler.scopeInfo.thisLocal,
-          compiledArguments[argumentIndex++]);
-    }
-
-    FunctionSignature signature = function.functionSignature;
-    signature.orderedForEachParameter((_parameter) {
-      ParameterElement parameter = _parameter;
-      HInstruction argument = compiledArguments[argumentIndex++];
-      localsHandler.updateLocal(parameter, argument);
-    });
-
-    ClassElement enclosing = function.enclosingClass;
-    if ((function.isConstructor || function.isGenerativeConstructorBody) &&
-        rtiNeed.classNeedsTypeArguments(enclosing)) {
-      enclosing.typeVariables.forEach((_typeVariable) {
-        ResolutionTypeVariableType typeVariable = _typeVariable;
-        HInstruction argument = compiledArguments[argumentIndex++];
-        localsHandler.updateLocal(
-            localsHandler.getTypeVariableAsLocal(typeVariable), argument);
-      });
-    }
-    assert(argumentIndex == compiledArguments.length);
-
-    returnType = signature.type.returnType;
-    stack = <HInstruction>[];
-
-    insertTraceCall(function);
-    insertCoverageCall(function);
-  }
-
-  void restoreState(AstInliningState state) {
-    localsHandler = state.oldLocalsHandler;
-    returnLocal = state.oldReturnLocal;
-    inTryStatement = state.inTryStatement;
-    resolvedAst = state.oldResolvedAst;
-    elementInferenceResults = state.oldElementInferenceResults;
-    returnType = state.oldReturnType;
-    assert(stack.isEmpty);
-    stack = state.oldStack;
-  }
-
-  /**
-   * Run this builder on the body of the [function] to be inlined.
-   */
-  void visitInlinedFunction(ResolvedAst resolvedAst) {
-    MethodElement function = resolvedAst.element.implementation;
-    typeBuilder.potentiallyCheckInlinedParameterTypes(function);
-
-    if (resolvedAst.element.isGenerativeConstructor) {
-      buildFactory(resolvedAst);
-    } else {
-      ast.FunctionExpression functionNode = resolvedAst.node;
-      functionNode.body.accept(this);
-    }
-  }
-
-  addInlinedInstantiation(ResolutionDartType type) {
-    if (type != null) {
-      currentInlinedInstantiations.add(type);
-    }
-  }
-
-  removeInlinedInstantiation(ResolutionDartType type) {
-    if (type != null) {
-      currentInlinedInstantiations.removeLast();
-    }
-  }
-
-  bool providedArgumentsKnownToBeComplete(ast.Node currentNode) {
-    /* When inlining the iterator methods generated for a [:for-in:] loop, the
-     * [currentNode] is the [ForIn] tree. The compiler-generated iterator
-     * invocations are known to have fully specified argument lists, no default
-     * arguments are used. See invocations of [pushInvokeDynamic] in
-     * [visitForIn].
-     */
-    return currentNode.asForIn() != null;
-  }
-
-  /**
-   * Documentation wanted -- johnniwinther
-   *
-   * Invariant: [constructors] must contain only implementation elements.
-   */
-  void inlineSuperOrRedirect(
-      ResolvedAst constructorResolvedAst,
-      List<HInstruction> compiledArguments,
-      List<ResolvedAst> constructorResolvedAsts,
-      Map<FieldElement, HInstruction> fieldValues,
-      FunctionElement caller) {
-    ConstructorElement callee = constructorResolvedAst.element.implementation;
-
-    reporter.withCurrentElement(callee, () {
-      Set<ClassElement> includedClasses = new Set<ClassElement>();
-      constructorResolvedAsts.add(constructorResolvedAst);
-      ClassElement currentClass = caller.enclosingClass;
-
-      /// Include locals for type variable used in [member].
-      void includeTypeVariables(MemberElement member) {
-        ClassElement enclosingClass = member.enclosingClass;
-        if (!includedClasses.add(enclosingClass)) return;
-
-        if (rtiNeed.classNeedsTypeArguments(enclosingClass)) {
-          // If [enclosingClass] needs RTI, we have to give a value to its
-          // type parameters.
-          // For a super constructor call, the type is the supertype of
-          // [currentClass]. For a redirecting constructor, the type is
-          // the current type. [InterfaceType.asInstanceOf] takes care
-          // of both.
-          ResolutionInterfaceType type =
-              currentClass.thisType.asInstanceOf(enclosingClass);
-          type = localsHandler.substInContext(type);
-          List<ResolutionDartType> arguments = type.typeArguments;
-          List<ResolutionDartType> typeVariables = enclosingClass.typeVariables;
-          if (!type.isRaw) {
-            assert(arguments.length == typeVariables.length);
-            Iterator<ResolutionDartType> variables = typeVariables.iterator;
-            type.typeArguments.forEach((ResolutionDartType argument) {
-              variables.moveNext();
-              ResolutionTypeVariableType typeVariable = variables.current;
-              localsHandler.updateLocal(
-                  localsHandler.getTypeVariableAsLocal(typeVariable),
-                  typeBuilder.analyzeTypeArgument(argument, sourceElement));
-            });
-          } else {
-            // If the supertype is a raw type, we need to set to null the
-            // type variables.
-            for (ResolutionTypeVariableType variable in typeVariables) {
-              localsHandler.updateLocal(
-                  localsHandler.getTypeVariableAsLocal(variable),
-                  graph.addConstantNull(closedWorld));
-            }
-          }
-        }
-      }
-
-      includeTypeVariables(callee);
-
-      // For redirecting constructors, the fields will be initialized later
-      // by the effective target.
-      if (!callee.isRedirectingGenerative) {
-        callee.enclosingClass.implementation.forEachInstanceField(
-            (ClassElement enclosingClass, FieldElement member) {
-          includeTypeVariables(member);
-        });
-        inlinedFrom(constructorResolvedAst, () {
-          buildFieldInitializers(
-              callee.enclosingClass.implementation, fieldValues);
-        });
-      }
-
-      int index = 0;
-      FunctionSignature params = callee.functionSignature;
-      params.orderedForEachParameter((_parameter) {
-        ParameterElement parameter = _parameter;
-        HInstruction argument = compiledArguments[index++];
-        // Because we are inlining the initializer, we must update
-        // what was given as parameter. This will be used in case
-        // there is a parameter check expression in the initializer.
-        parameters[parameter] = argument;
-        localsHandler.updateLocal(parameter, argument);
-        // Don't forget to update the field, if the parameter is of the
-        // form [:this.x:].
-        if (parameter.isInitializingFormal) {
-          InitializingFormalElement fieldParameterElement = parameter;
-          fieldValues[fieldParameterElement.fieldElement] = argument;
-        }
-      });
-
-      // Build the initializers in the context of the new constructor.
-      ResolvedAst oldResolvedAst = resolvedAst;
-      resolvedAst = callee.resolvedAst;
-      final oldElementInferenceResults = elementInferenceResults;
-      elementInferenceResults = globalInferenceResults.resultOfMember(callee);
-      ScopeInfo oldScopeInfo = localsHandler.scopeInfo;
-      ScopeInfo newScopeInfo = closureDataLookup.getScopeInfo(callee);
-      localsHandler.scopeInfo = newScopeInfo;
-      if (resolvedAst.kind == ResolvedAstKind.PARSED) {
-        localsHandler.enterScope(closureDataLookup.getCapturedScope(callee),
-            sourceInformationBuilder.buildDeclaration(callee),
-            forGenerativeConstructorBody: callee.isGenerativeConstructorBody);
-      }
-      buildInitializers(callee, constructorResolvedAsts, fieldValues);
-      localsHandler.scopeInfo = oldScopeInfo;
-      resolvedAst = oldResolvedAst;
-      elementInferenceResults = oldElementInferenceResults;
-    });
-  }
-
-  void buildInitializers(
-      ConstructorElement constructor,
-      List<ResolvedAst> constructorResolvedAsts,
-      Map<FieldElement, HInstruction> fieldValues) {
-    assert(
-        resolvedAst.element == constructor.declaration,
-        failedAt(constructor,
-            "Expected ResolvedAst for $constructor, found $resolvedAst"));
-    if (resolvedAst.kind == ResolvedAstKind.PARSED) {
-      buildParsedInitializers(
-          constructor, constructorResolvedAsts, fieldValues);
-    } else {
-      buildSynthesizedConstructorInitializers(
-          constructor, constructorResolvedAsts, fieldValues);
-    }
-  }
-
-  void buildSynthesizedConstructorInitializers(
-      ConstructorElement constructor,
-      List<ResolvedAst> constructorResolvedAsts,
-      Map<FieldElement, HInstruction> fieldValues) {
-    assert(
-        constructor.isSynthesized,
-        failedAt(
-            constructor, "Unexpected unsynthesized constructor: $constructor"));
-    List<HInstruction> arguments = <HInstruction>[];
-    HInstruction compileArgument(ParameterElement parameter) {
-      return localsHandler.readLocal(parameter);
-    }
-
-    ConstructorElement target = constructor.definingConstructor.implementation;
-    bool match = !target.isMalformed &&
-        Elements.addForwardingElementArgumentsToList<HInstruction>(
-            constructor,
-            arguments,
-            target,
-            compileArgument,
-            handleConstantForOptionalParameter);
-    if (!match) {
-      if (compiler.elementHasCompileTimeError(constructor)) {
-        return;
-      }
-      // If this fails, the selector we constructed for the call to a
-      // forwarding constructor in a mixin application did not match the
-      // constructor (which, for example, may happen when the libraries are
-      // not compatible for private names, see issue 20394).
-      reporter.internalError(
-          constructor, 'forwarding constructor call does not match');
-    }
-    inlineSuperOrRedirect(target.resolvedAst, arguments,
-        constructorResolvedAsts, fieldValues, constructor);
-  }
-
-  /**
-   * Run through the initializers and inline all field initializers. Recursively
-   * inlines super initializers.
-   *
-   * The constructors of the inlined initializers is added to [constructors]
-   * with sub constructors having a lower index than super constructors.
-   *
-   * Invariant: The [constructor] and elements in [constructors] must all be
-   * implementation elements.
-   */
-  void buildParsedInitializers(
-      ConstructorElement constructor,
-      List<ResolvedAst> constructorResolvedAsts,
-      Map<FieldElement, HInstruction> fieldValues) {
-    assert(
-        resolvedAst.element == constructor.declaration, failedAt(constructor));
-    assert(constructor.isImplementation, failedAt(constructor));
-    assert(
-        !constructor.isSynthesized,
-        failedAt(
-            constructor, "Unexpected synthesized constructor: $constructor"));
-    ast.FunctionExpression functionNode = resolvedAst.node;
-
-    bool foundSuperOrRedirect = false;
-    if (functionNode.initializers != null) {
-      Link<ast.Node> initializers = functionNode.initializers.nodes;
-      for (Link<ast.Node> link = initializers;
-          !link.isEmpty;
-          link = link.tail) {
-        assert(link.head is ast.Send);
-        if (link.head is! ast.SendSet) {
-          // A super initializer or constructor redirection.
-          foundSuperOrRedirect = true;
-          ast.Send call = link.head;
-          assert(ast.Initializers.isSuperConstructorCall(call) ||
-              ast.Initializers.isConstructorRedirect(call));
-          ConstructorElement target = elements[call];
-          CallStructure callStructure =
-              elements.getSelector(call).callStructure;
-          Link<ast.Node> arguments = call.arguments;
-          List<HInstruction> compiledArguments;
-          inlinedFrom(resolvedAst, () {
-            compiledArguments =
-                makeStaticArgumentList(callStructure, arguments, target);
-          });
-          inlineSuperOrRedirect(target.resolvedAst, compiledArguments,
-              constructorResolvedAsts, fieldValues, constructor);
-        } else {
-          // A field initializer.
-          ast.SendSet init = link.head;
-          Link<ast.Node> arguments = init.arguments;
-          assert(!arguments.isEmpty && arguments.tail.isEmpty);
-          inlinedFrom(resolvedAst, () {
-            visit(arguments.head);
-          });
-          fieldValues[elements[init]] = pop();
-        }
-      }
-    }
-
-    if (!foundSuperOrRedirect) {
-      // No super initializer found. Try to find the default constructor if
-      // the class is not Object.
-      ClassElement enclosingClass = constructor.enclosingClass;
-      ClassElement superClass = enclosingClass.superclass;
-      if (!enclosingClass.isObject) {
-        assert(superClass != null);
-        assert(superClass.isResolved);
-        // TODO(johnniwinther): Should we find injected constructors as well?
-        FunctionElement target = superClass.lookupDefaultConstructor();
-        if (target == null) {
-          reporter.internalError(
-              superClass, "No default constructor available.");
-        }
-        List<HInstruction> arguments = Elements.makeArgumentsList<HInstruction>(
-            CallStructure.NO_ARGS,
-            const Link<ast.Node>(),
-            target.implementation,
-            null,
-            handleConstantForOptionalParameter);
-        inlineSuperOrRedirect(target.resolvedAst, arguments,
-            constructorResolvedAsts, fieldValues, constructor);
-      }
-    }
-  }
-
-  /**
-   * Run through the fields of [cls] and add their potential
-   * initializers.
-   *
-   * Invariant: [classElement] must be an implementation element.
-   */
-  void buildFieldInitializers(
-      ClassElement classElement, Map<Element, HInstruction> fieldValues) {
-    assert(classElement.isImplementation, failedAt(classElement));
-    classElement.forEachInstanceField(
-        (ClassElement enclosingClass, FieldElement member) {
-      if (compiler.elementHasCompileTimeError(member)) return;
-      reporter.withCurrentElement(member, () {
-        ResolvedAst fieldResolvedAst = member.resolvedAst;
-        ast.Expression initializer = fieldResolvedAst.body;
-        if (initializer == null) {
-          // Unassigned fields of native classes are not initialized to
-          // prevent overwriting pre-initialized native properties.
-          if (!nativeData.isNativeOrExtendsNative(classElement)) {
-            fieldValues[member] = graph.addConstantNull(closedWorld);
-          }
-        } else {
-          ast.Node right = initializer;
-          ResolvedAst savedResolvedAst = resolvedAst;
-          resolvedAst = fieldResolvedAst;
-          final oldElementInferenceResults = elementInferenceResults;
-          elementInferenceResults =
-              globalInferenceResults.resultOfMember(member);
-          inlinedFrom(fieldResolvedAst, () => right.accept(this));
-          resolvedAst = savedResolvedAst;
-          elementInferenceResults = oldElementInferenceResults;
-          fieldValues[member] = pop();
-        }
-      });
-    });
-  }
-
-  /**
-   * Build the factory function corresponding to the constructor
-   * [functionElement]:
-   *  - Initialize fields with the values of the field initializers of the
-   *    current constructor and super constructors or constructors redirected
-   *    to, starting from the current constructor.
-   *  - Call the constructor bodies, starting from the constructor(s) in the
-   *    super class(es).
-   */
-  HGraph buildFactory(ResolvedAst resolvedAst) {
-    ConstructorElement functionElement = resolvedAst.element;
-    functionElement = functionElement.implementation;
-    ClassElement classElement = functionElement.enclosingClass.implementation;
-    bool isNativeUpgradeFactory =
-        nativeData.isNativeOrExtendsNative(classElement) &&
-            !nativeData.isJsInteropClass(classElement);
-    ast.FunctionExpression function;
-    if (resolvedAst.kind == ResolvedAstKind.PARSED) {
-      function = resolvedAst.node;
-    }
-
-    // Note that constructors (like any other static function) do not need
-    // to deal with optional arguments. It is the callers job to provide all
-    // arguments as if they were positional.
-
-    if (inliningStack.isEmpty) {
-      // The initializer list could contain closures.
-      openFunction(functionElement, function);
-    }
-
-    Map<FieldElement, HInstruction> fieldValues =
-        new Map<FieldElement, HInstruction>();
-
-    // Compile the possible initialization code for local fields and
-    // super fields, unless this is a redirecting constructor, in which case
-    // the effective target will initialize these.
-    if (!functionElement.isRedirectingGenerative) {
-      buildFieldInitializers(classElement, fieldValues);
-    }
-
-    // Compile field-parameters such as [:this.x:].
-    FunctionSignature params = functionElement.functionSignature;
-    params.orderedForEachParameter((_parameter) {
-      ParameterElement parameter = _parameter;
-      if (parameter.isInitializingFormal) {
-        // If the [element] is a field-parameter then
-        // initialize the field element with its value.
-        InitializingFormalElement fieldParameter = parameter;
-        HInstruction parameterValue = localsHandler.readLocal(fieldParameter);
-        fieldValues[fieldParameter.fieldElement] = parameterValue;
-      }
-    });
-
-    // Analyze the constructor and all referenced constructors and collect
-    // initializers and constructor bodies.
-    List<ResolvedAst> constructorResolvedAsts = <ResolvedAst>[resolvedAst];
-    buildInitializers(functionElement, constructorResolvedAsts, fieldValues);
-
-    // Call the JavaScript constructor with the fields as argument.
-    List<HInstruction> constructorArguments = <HInstruction>[];
-    List<FieldEntity> fields = <FieldEntity>[];
-
-    classElement.forEachInstanceField(
-        (ClassElement enclosingClass, FieldElement member) {
-      HInstruction value = fieldValues[member];
-      if (value == null) {
-        // Uninitialized native fields are pre-initialized by the native
-        // implementation.
-        assert(isNativeUpgradeFactory || reporter.hasReportedError,
-            failedAt(member));
-      } else {
-        fields.add(member);
-        ResolutionDartType type = localsHandler.substInContext(member.type);
-        constructorArguments.add(
-            typeBuilder.potentiallyCheckOrTrustTypeOfAssignment(value, type));
-      }
-    }, includeSuperAndInjectedMembers: true);
-
-    ResolutionInterfaceType type = classElement.thisType;
-    TypeMask ssaType =
-        new TypeMask.nonNullExact(classElement.declaration, closedWorld);
-    List<DartType> instantiatedTypes;
-    addInlinedInstantiation(type);
-    if (!currentInlinedInstantiations.isEmpty) {
-      instantiatedTypes =
-          new List<ResolutionInterfaceType>.from(currentInlinedInstantiations);
-    }
-
-    HInstruction newObject;
-    if (!isNativeUpgradeFactory) {
-      // Create the runtime type information, if needed.
-      bool hasRtiInput = false;
-      if (rtiNeed.classNeedsTypeArguments(classElement.declaration)) {
-        // Read the values of the type arguments and create a
-        // HTypeInfoExpression to set on the newly create object.
-        hasRtiInput = true;
-        List<HInstruction> typeArguments = <HInstruction>[];
-        classElement.typeVariables.forEach((_typeVariable) {
-          ResolutionTypeVariableType typeVariable = _typeVariable;
-          HInstruction argument = localsHandler
-              .readLocal(localsHandler.getTypeVariableAsLocal(typeVariable));
-          typeArguments.add(argument);
-        });
-
-        HInstruction typeInfo = new HTypeInfoExpression(
-            TypeInfoExpressionKind.INSTANCE,
-            classElement.thisType,
-            typeArguments,
-            commonMasks.dynamicType);
-        add(typeInfo);
-        constructorArguments.add(typeInfo);
-      }
-
-      newObject = new HCreate(
-          classElement,
-          constructorArguments,
-          ssaType,
-          function != null
-              ? sourceInformationBuilder.buildCreate(function)
-              : sourceInformationBuilder.buildDeclaration(functionElement),
-          instantiatedTypes: instantiatedTypes,
-          hasRtiInput: hasRtiInput);
-      add(newObject);
-    } else {
-      // Bulk assign to the initialized fields.
-      newObject = graph.explicitReceiverParameter;
-      // Null guard ensures an error if we are being called from an explicit
-      // 'new' of the constructor instead of via an upgrade. It is optimized out
-      // if there are field initializers.
-      add(new HFieldGet(null, newObject, commonMasks.dynamicType,
-          isAssignable: false));
-      for (int i = 0; i < fields.length; i++) {
-        add(new HFieldSet(abstractValueDomain, fields[i], newObject,
-            constructorArguments[i]));
-      }
-    }
-    removeInlinedInstantiation(type);
-
-    // Generate calls to the constructor bodies.
-    HInstruction interceptor = null;
-    for (int index = constructorResolvedAsts.length - 1; index >= 0; index--) {
-      ResolvedAst constructorResolvedAst = constructorResolvedAsts[index];
-      ConstructorElement constructor =
-          constructorResolvedAst.element.implementation;
-      ConstructorBodyElement body =
-          ConstructorBodyElementX.createFromResolvedAst(constructorResolvedAst);
-      if (body == null) continue;
-
-      List bodyCallInputs = <HInstruction>[];
-      if (isNativeUpgradeFactory) {
-        if (interceptor == null) {
-          ConstantValue constant = new InterceptorConstantValue(classElement);
-          interceptor = graph.addConstant(constant, closedWorld);
-        }
-        bodyCallInputs.add(interceptor);
-      }
-      bodyCallInputs.add(newObject);
-
-      FunctionSignature functionSignature = body.functionSignature;
-      // Provide the parameters to the generative constructor body.
-      functionSignature.orderedForEachParameter((_parameter) {
-        ParameterElement parameter = _parameter;
-        // If [parameter] is boxed, it will be a field in the box passed as the
-        // last parameter. So no need to directly pass it.
-        if (!localsHandler.isBoxed(parameter)) {
-          bodyCallInputs.add(localsHandler.readLocal(parameter));
-        }
-      });
-
-      // If there are locals that escape (ie mutated in closures), we
-      // pass the box to the constructor.
-      // The box must be passed before any type variable.
-      CapturedScope scopeData = closureDataLookup.getCapturedScope(constructor);
-      if (scopeData.requiresContextBox) {
-        bodyCallInputs.add(localsHandler.readLocal(scopeData.context));
-      }
-
-      // Type variables arguments must come after the box (if there is one).
-      ClassElement currentClass = constructor.enclosingClass;
-      if (rtiNeed.classNeedsTypeArguments(currentClass)) {
-        // If [currentClass] needs RTI, we add the type variables as
-        // parameters of the generative constructor body.
-        currentClass.typeVariables.forEach((_argument) {
-          ResolutionTypeVariableType argument = _argument;
-          // TODO(johnniwinther): Substitute [argument] with
-          // `localsHandler.substInContext(argument)`.
-          bodyCallInputs.add(localsHandler
-              .readLocal(localsHandler.getTypeVariableAsLocal(argument)));
-        });
-      }
-
-      if (!isNativeUpgradeFactory && // TODO(13836): Fix inlining.
-          tryInlineMethod(body, null, null, bodyCallInputs, function)) {
-        pop();
-      } else {
-        ConstructorBodyElement declaration = body.declaration;
-        HInvokeConstructorBody invoke = new HInvokeConstructorBody(
-            declaration,
-            bodyCallInputs,
-            commonMasks.nonNullType,
-            sourceInformationBuilder.buildDeclaration(constructor));
-        invoke.sideEffects = closedWorld.getSideEffectsOfElement(constructor);
-        add(invoke);
-      }
-    }
-    if (inliningStack.isEmpty) {
-      closeAndGotoExit(new HReturn(abstractValueDomain, newObject,
-          sourceInformationBuilder.buildImplicitReturn(functionElement)));
-      return closeFunction();
-    } else {
-      localsHandler.updateLocal(returnLocal, newObject);
-      return null;
-    }
-  }
-
-  /**
-   * Documentation wanted -- johnniwinther
-   *
-   * Invariant: [functionElement] must be the implementation element.
-   */
-  void openFunction(MemberElement element, ast.Node node) {
-    assert(element.isImplementation, failedAt(element));
-    HBasicBlock block = graph.addNewBlock();
-    open(graph.entry);
-
-    Map<Local, TypeMask> parameters = <Local, TypeMask>{};
-    if (element is MethodElement) {
-      element.functionSignature.orderedForEachParameter((_parameter) {
-        ParameterElement parameter = _parameter;
-        parameters[parameter] = TypeMaskFactory.inferredTypeForParameter(
-            parameter, globalInferenceResults);
-      });
-    }
-
-    localsHandler.startFunction(
-        element,
-        closureDataLookup.getScopeInfo(element),
-        closureDataLookup.getCapturedScope(element),
-        parameters,
-        sourceInformationBuilder.buildDeclaration(element),
-        isGenerativeConstructorBody: element.isGenerativeConstructorBody);
-    close(new HGoto(abstractValueDomain)).addSuccessor(block);
-
-    open(block);
-
-    // Add the type parameters of the class as parameters of this method.  This
-    // must be done before adding the normal parameters, because their types
-    // may contain references to type variables.
-    ClassElement cls = element.enclosingClass;
-    if ((element.isConstructor || element.isGenerativeConstructorBody) &&
-        rtiNeed.classNeedsTypeArguments(cls)) {
-      cls.typeVariables.forEach((_typeVariable) {
-        ResolutionTypeVariableType typeVariable = _typeVariable;
-        HParameterValue param =
-            addParameter(typeVariable.element, commonMasks.nonNullType);
-        localsHandler.directLocals[
-            localsHandler.getTypeVariableAsLocal(typeVariable)] = param;
-      });
-    }
-
-    if (element is MethodElement) {
-      MethodElement functionElement = element;
-      FunctionSignature signature = functionElement.functionSignature;
-
-      // Put the type checks in the first successor of the entry,
-      // because that is where the type guards will also be inserted.
-      // This way we ensure that a type guard will dominate the type
-      // check.
-      signature.forEachParameter((_parameterElement) {
-        ParameterElement parameterElement = _parameterElement;
-        if (element.isGenerativeConstructorBody) {
-          if (closureDataLookup
-              .getCapturedScope(element)
-              .isBoxed(parameterElement)) {
-            // The parameter will be a field in the box passed as the
-            // last parameter. So no need to have it.
-            return;
-          }
-        }
-        HInstruction newParameter =
-            localsHandler.directLocals[parameterElement];
-        if (!element.isConstructor ||
-            !(element as ConstructorElement).isRedirectingFactory) {
-          // Redirection factories must not check their argument types.
-          // Example:
-          //
-          //     class A {
-          //       A(String foo) = A.b;
-          //       A.b(int foo) { print(foo); }
-          //     }
-          //     main() {
-          //       new A(499);    // valid even in checked mode.
-          //       new A("foo");  // invalid in checked mode.
-          //
-          // Only the final target is allowed to check for the argument types.
-          newParameter = typeBuilder.potentiallyCheckOrTrustTypeOfAssignment(
-              newParameter, parameterElement.type);
-        }
-        localsHandler.directLocals[parameterElement] = newParameter;
-      });
-
-      returnType = signature.type.returnType;
-    } else {
-      // Otherwise it is a lazy initializer which does not have parameters.
-      assert(element is VariableElement);
-    }
-
-    insertTraceCall(element);
-    insertCoverageCall(element);
-  }
-
-  insertTraceCall(Element element) {
-    if (JavaScriptBackend.TRACE_METHOD == 'console') {
-      if (element == commonElements.traceHelper) return;
-      n(e) => e == null ? '' : e.name;
-      String name = "${n(element.library)}:${n(element.enclosingClass)}."
-          "${n(element)}";
-      HConstant nameConstant = addConstantString(name);
-      add(new HInvokeStatic(
-          commonElements.traceHelper,
-          <HInstruction>[nameConstant],
-          commonMasks.dynamicType,
-          const <DartType>[]));
-    }
-  }
-
-  insertCoverageCall(Element element) {
-    if (JavaScriptBackend.TRACE_METHOD == 'post') {
-      if (element == commonElements.traceHelper) return;
-      // TODO(sigmund): create a better uuid for elements.
-      HConstant idConstant =
-          graph.addConstantInt(element.hashCode, closedWorld);
-      HConstant nameConstant = addConstantString(element.name);
-      add(new HInvokeStatic(
-          commonElements.traceHelper,
-          <HInstruction>[idConstant, nameConstant],
-          commonMasks.dynamicType,
-          const <DartType>[]));
-    }
-  }
-
-  void assertIsSubtype(
-      ast.Node node,
-      ResolutionDartType subtype,
-      ResolutionDartType supertype,
-      String prefix,
-      String infix,
-      String suffix) {
-    HInstruction subtypeInstruction = typeBuilder.analyzeTypeArgument(
-        localsHandler.substInContext(subtype), sourceElement);
-    HInstruction supertypeInstruction = typeBuilder.analyzeTypeArgument(
-        localsHandler.substInContext(supertype), sourceElement);
-    HInstruction prefixInstruction =
-        graph.addConstantString(prefix, closedWorld);
-    HInstruction infixInstruction = graph.addConstantString(infix, closedWorld);
-    HInstruction suffixInstruction =
-        graph.addConstantString(suffix, closedWorld);
-    MethodElement element = commonElements.assertIsSubtype;
-    var inputs = <HInstruction>[
-      subtypeInstruction,
-      supertypeInstruction,
-      prefixInstruction,
-      infixInstruction,
-      suffixInstruction,
-    ];
-    HInstruction assertIsSubtype = new HInvokeStatic(element, inputs,
-        subtypeInstruction.instructionType, const <DartType>[]);
-    registry?.registerTypeVariableBoundsSubtypeCheck(subtype, supertype);
-    add(assertIsSubtype);
-  }
-
-  HGraph closeFunction() {
-    // TODO(kasperl): Make this goto an implicit return.
-    if (!isAborted()) closeAndGotoExit(new HGoto(abstractValueDomain));
-    graph.finalize(abstractValueDomain);
-    return graph;
-  }
-
-  void pushWithPosition(HInstruction instruction, ast.Node node) {
-    push(attachPosition(instruction, node));
-  }
-
-  /// Pops the most recent instruction from the stack and 'boolifies' it.
-  ///
-  /// Boolification is checking if the value is '=== true'.
-  @override
-  HInstruction popBoolified() {
-    HInstruction value = pop();
-    if (typeBuilder.checkOrTrustTypes) {
-      ResolutionInterfaceType boolType = commonElements.boolType;
-      return typeBuilder.potentiallyCheckOrTrustTypeOfAssignment(
-          value, boolType,
-          kind: HTypeConversion.BOOLEAN_CONVERSION_CHECK);
-    }
-    HInstruction result = new HBoolify(value, commonMasks.boolType)
-      ..sourceInformation = value.sourceInformation;
-    add(result);
-    return result;
-  }
-
-  HInstruction attachPosition(HInstruction target, ast.Node node) {
-    if (node != null) {
-      target.sourceInformation = sourceInformationBuilder.buildGeneric(node);
-    }
-    return target;
-  }
-
-  void visit(ast.Node node) {
-    if (node != null) node.accept(this);
-  }
-
-  /// Visit [node] and pop the resulting [HInstruction].
-  HInstruction visitAndPop(ast.Node node) {
-    node.accept(this);
-    return pop();
-  }
-
-  visitAssert(ast.Assert node) {
-    if (!options.enableUserAssertions) return;
-
-    if (!node.hasMessage) {
-      // Generate:
-      //
-      //     assertHelper(condition);
-      //
-      visit(node.condition);
-      pushInvokeStatic(node, commonElements.assertHelper, [pop()]);
-      pop();
-      return;
-    }
-    // Assert has message. Generate:
-    //
-    //     if (assertTest(condition)) assertThrow(message);
-    //
-    void buildCondition() {
-      visit(node.condition);
-      pushInvokeStatic(node, commonElements.assertTest, [pop()]);
-    }
-
-    void fail() {
-      visit(node.message);
-      pushInvokeStatic(node, commonElements.assertThrow, [pop()]);
-      pop();
-    }
-
-    handleIf(node: node, visitCondition: buildCondition, visitThen: fail);
-  }
-
-  visitBlock(ast.Block node) {
-    assert(!isAborted());
-    if (!isReachable) return; // This can only happen when inlining.
-    for (Link<ast.Node> link = node.statements.nodes;
-        !link.isEmpty;
-        link = link.tail) {
-      visit(link.head);
-      if (!isReachable) {
-        // The block has been aborted by a return or a throw.
-        if (!stack.isEmpty) {
-          reporter.internalError(node, 'Non-empty instruction stack.');
-        }
-        return;
-      }
-    }
-    assert(!current.isClosed());
-    if (!stack.isEmpty) {
-      reporter.internalError(node, 'Non-empty instruction stack.');
-    }
-  }
-
-  visitClassNode(ast.ClassNode node) {
-    reporter.internalError(
-        node, 'SsaBuilder.visitClassNode should not be called.');
-  }
-
-  visitThrowExpression(ast.Expression expression) {
-    bool old = inExpressionOfThrow;
-    try {
-      inExpressionOfThrow = true;
-      visit(expression);
-    } finally {
-      inExpressionOfThrow = old;
-    }
-  }
-
-  visitExpressionStatement(ast.ExpressionStatement node) {
-    if (!isReachable) return;
-    ast.Throw throwExpression = node.expression.asThrow();
-    if (throwExpression != null && inliningStack.isEmpty) {
-      visitThrowExpression(throwExpression.expression);
-      handleInTryStatement();
-      closeAndGotoExit(new HThrow(abstractValueDomain, pop(),
-          sourceInformationBuilder.buildThrow(node)));
-    } else {
-      visit(node.expression);
-      pop();
-    }
-  }
-
-  visitFor(ast.For node) {
-    assert(isReachable);
-    assert(node.body != null);
-    void buildInitializer() {
-      ast.Node initializer = node.initializer;
-      if (initializer == null) return;
-      visit(initializer);
-      if (initializer.asExpression() != null) {
-        pop();
-      }
-    }
-
-    HInstruction buildCondition() {
-      if (node.condition == null) {
-        return graph.addConstantBool(true, closedWorld);
-      }
-      visit(node.condition);
-      return popBoolified();
-    }
-
-    void buildUpdate() {
-      for (ast.Expression expression in node.update) {
-        visit(expression);
-        assert(!isAborted());
-        // The result of the update instruction isn't used, and can just
-        // be dropped.
-        pop();
-      }
-    }
-
-    void buildBody() {
-      visit(node.body);
-    }
-
-    loopHandler.handleLoop(
-        node,
-        closureDataLookup.getCapturedLoopScope(node),
-        elements.getTargetDefinition(node),
-        buildInitializer,
-        buildCondition,
-        buildUpdate,
-        buildBody,
-        sourceInformationBuilder.buildLoop(node));
-  }
-
-  visitWhile(ast.While node) {
-    assert(isReachable);
-    HInstruction buildCondition() {
-      visit(node.condition);
-      return popBoolified();
-    }
-
-    loopHandler.handleLoop(node, closureDataLookup.getCapturedLoopScope(node),
-        elements.getTargetDefinition(node), () {}, buildCondition, () {}, () {
-      visit(node.body);
-    }, sourceInformationBuilder.buildLoop(node));
-  }
-
-  visitDoWhile(ast.DoWhile node) {
-    assert(isReachable);
-    SourceInformation sourceInformation =
-        sourceInformationBuilder.buildLoop(node);
-    LocalsHandler savedLocals = new LocalsHandler.from(localsHandler);
-    var loopClosureInfo = closureDataLookup.getCapturedLoopScope(node);
-    localsHandler.startLoop(loopClosureInfo, sourceInformation);
-    loopDepth++;
-    JumpTarget target = elements.getTargetDefinition(node);
-    JumpHandler jumpHandler = loopHandler.beginLoopHeader(node, target);
-    HLoopInformation loopInfo = current.loopInformation;
-    HBasicBlock loopEntryBlock = current;
-    HBasicBlock bodyEntryBlock = current;
-    bool hasContinues = target != null && target.isContinueTarget;
-    if (hasContinues) {
-      // Add extra block to hang labels on.
-      // It doesn't currently work if they are on the same block as the
-      // HLoopInfo. The handling of HLabeledBlockInformation will visit a
-      // SubGraph that starts at the same block again, so the HLoopInfo is
-      // either handled twice, or it's handled after the labeled block info,
-      // both of which generate the wrong code.
-      // Using a separate block is just a simple workaround.
-      bodyEntryBlock = openNewBlock();
-    }
-    localsHandler.enterLoopBody(loopClosureInfo, sourceInformation);
-    visit(node.body);
-
-    // If there are no continues we could avoid the creation of the condition
-    // block. This could also lead to a block having multiple entries and exits.
-    HBasicBlock bodyExitBlock;
-    bool isAbortingBody = false;
-    if (current != null) {
-      bodyExitBlock = close(new HGoto(abstractValueDomain));
-    } else {
-      isAbortingBody = true;
-      bodyExitBlock = lastOpenedBlock;
-    }
-
-    SubExpression conditionExpression;
-    bool loopIsDegenerate = isAbortingBody && !hasContinues;
-    if (!loopIsDegenerate) {
-      HBasicBlock conditionBlock = addNewBlock();
-
-      List<LocalsHandler> continueHandlers = <LocalsHandler>[];
-      jumpHandler
-          .forEachContinue((HContinue instruction, LocalsHandler locals) {
-        instruction.block.addSuccessor(conditionBlock);
-        continueHandlers.add(locals);
-      });
-
-      if (!isAbortingBody) {
-        bodyExitBlock.addSuccessor(conditionBlock);
-      }
-
-      if (!continueHandlers.isEmpty) {
-        if (!isAbortingBody) continueHandlers.add(localsHandler);
-        localsHandler =
-            savedLocals.mergeMultiple(continueHandlers, conditionBlock);
-        SubGraph bodyGraph = new SubGraph(bodyEntryBlock, bodyExitBlock);
-        List<LabelDefinition> labels = jumpHandler.labels;
-        HSubGraphBlockInformation bodyInfo =
-            new HSubGraphBlockInformation(bodyGraph);
-        HLabeledBlockInformation info;
-        if (!labels.isEmpty) {
-          info =
-              new HLabeledBlockInformation(bodyInfo, labels, isContinue: true);
-        } else {
-          info = new HLabeledBlockInformation.implicit(bodyInfo, target,
-              isContinue: true);
-        }
-        bodyEntryBlock.setBlockFlow(info, conditionBlock);
-      }
-      open(conditionBlock);
-
-      visit(node.condition);
-      assert(!isAborted());
-      HInstruction conditionInstruction = popBoolified();
-      HBasicBlock conditionEndBlock = close(new HLoopBranch(abstractValueDomain,
-          conditionInstruction, HLoopBranch.DO_WHILE_LOOP));
-
-      HBasicBlock avoidCriticalEdge = addNewBlock();
-      conditionEndBlock.addSuccessor(avoidCriticalEdge);
-      open(avoidCriticalEdge);
-      close(new HGoto(abstractValueDomain));
-      avoidCriticalEdge.addSuccessor(loopEntryBlock); // The back-edge.
-
-      conditionExpression =
-          new SubExpression(conditionBlock, conditionEndBlock);
-
-      // Avoid a critical edge from the condition to the loop-exit body.
-      HBasicBlock conditionExitBlock = addNewBlock();
-      open(conditionExitBlock);
-      close(new HGoto(abstractValueDomain));
-      conditionEndBlock.addSuccessor(conditionExitBlock);
-
-      loopHandler.endLoop(
-          loopEntryBlock, conditionExitBlock, jumpHandler, localsHandler);
-
-      loopEntryBlock.postProcessLoopHeader();
-      SubGraph bodyGraph = new SubGraph(loopEntryBlock, bodyExitBlock);
-      HLoopBlockInformation loopBlockInfo = new HLoopBlockInformation(
-          HLoopBlockInformation.DO_WHILE_LOOP,
-          null,
-          wrapExpressionGraph(conditionExpression),
-          wrapStatementGraph(bodyGraph),
-          null,
-          loopEntryBlock.loopInformation.target,
-          loopEntryBlock.loopInformation.labels,
-          sourceInformation);
-      loopEntryBlock.setBlockFlow(loopBlockInfo, current);
-      loopInfo.loopBlockInformation = loopBlockInfo;
-    } else {
-      // Since the loop has no back edge, we remove the loop information on the
-      // header.
-      loopEntryBlock.loopInformation = null;
-
-      if (jumpHandler.hasAnyBreak()) {
-        // Null branchBlock because the body of the do-while loop always aborts,
-        // so we never get to the condition.
-        loopHandler.endLoop(loopEntryBlock, null, jumpHandler, localsHandler);
-
-        // Since the body of the loop has a break, we attach a synthesized label
-        // to the body.
-        SubGraph bodyGraph = new SubGraph(bodyEntryBlock, bodyExitBlock);
-        JumpTarget target = elements.getTargetDefinition(node);
-        LabelDefinition label =
-            target.addLabel(null, 'loop', isBreakTarget: true);
-        HLabeledBlockInformation info = new HLabeledBlockInformation(
-            new HSubGraphBlockInformation(bodyGraph), <LabelDefinition>[label]);
-        loopEntryBlock.setBlockFlow(info, current);
-        jumpHandler.forEachBreak((HBreak breakInstruction, _) {
-          HBasicBlock block = breakInstruction.block;
-          block.addAtExit(new HBreak.toLabel(
-              abstractValueDomain, label, sourceInformation));
-          block.remove(breakInstruction);
-        });
-      }
-    }
-    jumpHandler.close();
-    loopDepth--;
-  }
-
-  visitFunctionExpression(ast.FunctionExpression node) {
-    ClosureRepresentationInfo closureInfo =
-        closureDataLookup.getClosureInfo(node);
-    ClassEntity closureClassEntity = closureInfo.closureClassEntity;
-
-    List<HInstruction> capturedVariables = <HInstruction>[];
-    compiler.codegenWorldBuilder.forEachInstanceField(closureClassEntity,
-        (_, FieldEntity field) {
-      capturedVariables
-          .add(localsHandler.readLocal(closureInfo.getLocalForField(field)));
-    });
-
-    TypeMask type = new TypeMask.nonNullExact(closureClassEntity, closedWorld);
-    push(new HCreate(closureClassEntity, capturedVariables, type,
-        sourceInformationBuilder.buildCreate(node),
-        callMethod: closureInfo.callMethod));
-  }
-
-  visitFunctionDeclaration(ast.FunctionDeclaration node) {
-    assert(isReachable);
-    visit(node.function);
-    LocalFunctionElement localFunction =
-        elements.getFunctionDefinition(node.function);
-    localsHandler.updateLocal(localFunction, pop());
-  }
-
-  @override
-  void visitThisGet(ast.Identifier node, [_]) {
-    stack.add(localsHandler.readThis(
-        sourceInformation: sourceInformationBuilder.buildGet(node)));
-  }
-
-  visitIdentifier(ast.Identifier node) {
-    if (node.isThis()) {
-      visitThisGet(node);
-    } else {
-      reporter.internalError(
-          node, "SsaFromAstMixin.visitIdentifier on non-this.");
-    }
-  }
-
-  void handleIf(
-      {ast.Node node,
-      void visitCondition(),
-      void visitThen(),
-      void visitElse(),
-      SourceInformation sourceInformation}) {
-    SsaBranchBuilder branchBuilder = new SsaBranchBuilder(this, node);
-    branchBuilder.handleIf(visitCondition, visitThen, visitElse,
-        sourceInformation: sourceInformation);
-  }
-
-  visitIf(ast.If node) {
-    assert(isReachable);
-    handleIf(
-        node: node,
-        visitCondition: () => visit(node.condition),
-        visitThen: () => visit(node.thenPart),
-        visitElse: node.elsePart != null ? () => visit(node.elsePart) : null,
-        sourceInformation: sourceInformationBuilder.buildIf(node));
-  }
-
-  @override
-  void visitIfNull(ast.Send node, ast.Node left, ast.Node right, _) {
-    SsaBranchBuilder brancher = new SsaBranchBuilder(this, node);
-    brancher.handleIfNull(() => visit(left), () => visit(right));
-  }
-
-  /// Optimizes logical binary where the left is also a logical binary.
-  ///
-  /// This method transforms the operator by optimizing the case where [left] is
-  /// a logical "and" or logical "or". Then it uses [branchBuilder] to build the
-  /// graph for the optimized expression.
-  ///
-  /// For example, `(x && y) && z` is transformed into `x && (y && z)`:
-  ///
-  ///     t0 = boolify(x);
-  ///     if (t0) {
-  ///       t1 = boolify(y);
-  ///       if (t1) {
-  ///         t2 = boolify(z);
-  ///       }
-  ///       t3 = phi(t2, false);
-  ///     }
-  ///     result = phi(t3, false);
-  void handleLogicalBinaryWithLeftNode(ast.Node left, void visitRight(),
-      SsaBranchBuilder branchBuilder, SourceInformation sourceInformation,
-      {bool isAnd}) {
-    ast.Send send = left.asSend();
-    if (send != null && (isAnd ? send.isLogicalAnd : send.isLogicalOr)) {
-      ast.Node newLeft = send.receiver;
-      Link<ast.Node> link = send.argumentsNode.nodes;
-      assert(link.tail.isEmpty);
-      ast.Node middle = link.head;
-      handleLogicalBinaryWithLeftNode(
-          newLeft,
-          () => handleLogicalBinaryWithLeftNode(middle, visitRight,
-              branchBuilder, sourceInformationBuilder.buildBinary(middle),
-              isAnd: isAnd),
-          branchBuilder,
-          sourceInformation,
-          isAnd: isAnd);
-    } else {
-      branchBuilder.handleLogicalBinary(
-          () => visit(left), visitRight, sourceInformation,
-          isAnd: isAnd);
-    }
-  }
-
-  @override
-  void visitLogicalAnd(ast.Send node, ast.Node left, ast.Node right, _) {
-    SsaBranchBuilder branchBuilder = new SsaBranchBuilder(this, node);
-    handleLogicalBinaryWithLeftNode(left, () => visit(right), branchBuilder,
-        sourceInformationBuilder.buildBinary(node),
-        isAnd: true);
-  }
-
-  @override
-  void visitLogicalOr(ast.Send node, ast.Node left, ast.Node right, _) {
-    SsaBranchBuilder branchBuilder = new SsaBranchBuilder(this, node);
-    handleLogicalBinaryWithLeftNode(left, () => visit(right), branchBuilder,
-        sourceInformationBuilder.buildBinary(node),
-        isAnd: false);
-  }
-
-  @override
-  void visitNot(ast.Send node, ast.Node expression, _) {
-    assert(node.argumentsNode is ast.Prefix);
-    visit(expression);
-    SourceInformation sourceInformation =
-        sourceInformationBuilder.buildGeneric(node);
-    push(new HNot(popBoolified(), commonMasks.boolType)
-      ..sourceInformation = sourceInformation);
-  }
-
-  @override
-  void visitUnary(
-      ast.Send node, UnaryOperator operator, ast.Node expression, _) {
-    assert(node.argumentsNode is ast.Prefix);
-    HInstruction operand = visitAndPop(expression);
-
-    // See if we can constant-fold right away. This avoids rewrites later on.
-    if (operand is HConstant) {
-      UnaryOperation operation = constantSystem.lookupUnary(operator);
-      HConstant constant = operand;
-      ConstantValue folded = operation.fold(constant.constant);
-      if (folded != null) {
-        stack.add(graph.addConstant(folded, closedWorld));
-        return;
-      }
-    }
-
-    pushInvokeDynamic(node, elements.getSelector(node),
-        elementInferenceResults.typeOfSend(node), [operand],
-        sourceInformation: sourceInformationBuilder.buildGeneric(node));
-  }
-
-  @override
-  void visitBinary(ast.Send node, ast.Node left, BinaryOperator operator,
-      ast.Node right, _) {
-    handleBinary(node, left, right);
-  }
-
-  @override
-  void visitIndex(ast.Send node, ast.Node receiver, ast.Node index, _) {
-    generateDynamicSend(node);
-  }
-
-  @override
-  void visitEquals(ast.Send node, ast.Node left, ast.Node right, _) {
-    handleBinary(node, left, right);
-  }
-
-  @override
-  void visitNotEquals(ast.Send node, ast.Node left, ast.Node right, _) {
-    handleBinary(node, left, right);
-    pushWithPosition(
-        new HNot(popBoolified(), commonMasks.boolType), node.selector);
-  }
-
-  void handleBinary(ast.Send node, ast.Node left, ast.Node right) {
-    visitBinarySend(
-        visitAndPop(left),
-        visitAndPop(right),
-        elements.getSelector(node),
-        elementInferenceResults.typeOfSend(node),
-        node,
-        sourceInformation:
-            sourceInformationBuilder.buildGeneric(node.selector));
-  }
-
-  /// TODO(johnniwinther): Merge [visitBinarySend] with [handleBinary] and
-  /// remove use of [location] for source information.
-  void visitBinarySend(HInstruction left, HInstruction right, Selector selector,
-      TypeMask mask, ast.Send send,
-      {SourceInformation sourceInformation}) {
-    pushInvokeDynamic(send, selector, mask, [left, right],
-        sourceInformation: sourceInformation);
-  }
-
-  HInstruction generateInstanceSendReceiver(ast.Send send) {
-    assert(Elements.isInstanceSend(send, elements));
-    if (send.receiver == null) {
-      return localsHandler.readThis(
-          sourceInformation: sourceInformationBuilder.buildGet(send));
-    }
-    visit(send.receiver);
-    return pop();
-  }
-
-  String noSuchMethodTargetSymbolString(Element error, [String prefix]) {
-    String result = error.name;
-    if (prefix == "set") return "$result=";
-    return result;
-  }
-
-  /**
-   * Returns a set of interceptor classes that contain the given
-   * [selector].
-   */
-  void generateInstanceGetterWithCompiledReceiver(
-      ast.Send send, Selector selector, TypeMask mask, HInstruction receiver) {
-    assert(Elements.isInstanceSend(send, elements));
-    assert(selector.isGetter);
-    pushInvokeDynamic(send, selector, mask, [receiver],
-        sourceInformation: sourceInformationBuilder.buildGet(send));
-  }
-
-  /// Inserts a call to checkDeferredIsLoaded for a deferred [import].
-  /// If [import] is [null], do nothing.
-  void generateIsDeferredLoadedCheckIfNeeded(
-      ImportElement import, ast.Node location) {
-    if (import == null) return;
-    String loadId = deferredLoadTask.getImportDeferName(location, import);
-    HInstruction loadIdConstant = addConstantString(loadId);
-    String uri = import.uri.toString();
-    HInstruction uriConstant = addConstantString(uri);
-    MethodElement helper = commonElements.checkDeferredIsLoaded;
-    pushInvokeStatic(location, helper, [loadIdConstant, uriConstant]);
-    pop();
-  }
-
-  /// Inserts a call to checkDeferredIsLoaded if the send has a prefix that
-  /// resolves to a deferred library.
-  void generateIsDeferredLoadedCheckOfSend(ast.Send node) {
-    generateIsDeferredLoadedCheckIfNeeded(
-        deferredLoadTask.deferredImportElement(node, elements), node);
-  }
-
-  void handleInvalidStaticGet(ast.Send node, Element element) {
-    SourceInformation sourceInformation =
-        sourceInformationBuilder.buildGet(node);
-    generateThrowNoSuchMethod(
-        node, noSuchMethodTargetSymbolString(element, 'get'),
-        argumentNodes: const Link<ast.Node>(),
-        sourceInformation: sourceInformation);
-  }
-
-  /// Generate read access of an unresolved static or top level entity.
-  void generateStaticUnresolvedGet(ast.Send node, Element element) {
-    if (element is ErroneousElement) {
-      // An erroneous element indicates an unresolved static getter.
-      handleInvalidStaticGet(node, element);
-    } else {
-      // This happens when [element] has parse errors.
-      assert(element == null || element.isMalformed, failedAt(node));
-      // TODO(ahe): Do something like the above, that is, emit a runtime
-      // error.
-      stack.add(graph.addConstantNull(closedWorld));
-    }
-  }
-
-  /// Read a static or top level [field] of constant value.
-  void generateStaticConstGet(ast.Send node, FieldElement field,
-      ConstantExpression constant, SourceInformation sourceInformation) {
-    ConstantValue value = constants.getConstantValue(constant);
-    HConstant instruction;
-    // Constants that are referred via a deferred prefix should be referred
-    // by reference.
-    ImportElement deferredImport =
-        deferredLoadTask.deferredImportElement(node, elements);
-    if (deferredImport != null) {
-      OutputUnit unit =
-          compiler.backend.outputUnitData.outputUnitForMember(field);
-      instruction = graph.addDeferredConstant(
-          value, unit, sourceInformation, compiler, closedWorld);
-    } else {
-      instruction = graph.addConstant(value, closedWorld,
-          sourceInformation: sourceInformation);
-    }
-    stack.add(instruction);
-    // The inferrer may have found a better type than the constant
-    // handler in the case of lists, because the constant handler
-    // does not look at elements in the list.
-    TypeMask type =
-        TypeMaskFactory.inferredTypeForMember(field, globalInferenceResults);
-    if (!type.containsAll(closedWorld) && !instruction.isConstantNull()) {
-      // TODO(13429): The inferrer should know that an element
-      // cannot be null.
-      instruction.instructionType = type.nonNullable();
-    }
-  }
-
-  @override
-  void previsitDeferredAccess(ast.Send node, PrefixElement prefix, _) {
-    generateIsDeferredLoadedCheckIfNeeded(prefix.deferredImport, node);
-  }
-
-  /// Read a static or top level [field].
-  void generateStaticFieldGet(ast.Send node, FieldElement field) {
-    ConstantExpression constant = field.constant;
-    SourceInformation sourceInformation =
-        sourceInformationBuilder.buildGet(node.selector);
-    if (constant != null) {
-      if (!field.isAssignable) {
-        // A static final or const. Get its constant value and inline it if
-        // the value can be compiled eagerly.
-        generateStaticConstGet(node, field, constant, sourceInformation);
-      } else {
-        // TODO(5346): Try to avoid the need for calling [declaration] before
-        // creating an [HStatic].
-        HInstruction instruction = new HStatic(
-            field,
-            TypeMaskFactory.inferredTypeForMember(
-                field, globalInferenceResults),
-            sourceInformation);
-        push(instruction);
-      }
-    } else {
-      HInstruction instruction = new HLazyStatic(
-          field,
-          TypeMaskFactory.inferredTypeForMember(field, globalInferenceResults),
-          sourceInformation);
-      push(instruction);
-    }
-  }
-
-  /// Generate a getter invocation of the static or top level [getter].
-  void generateStaticGetterGet(ast.Send node, MethodElement getter) {
-    SourceInformation sourceInformation =
-        sourceInformationBuilder.buildGet(node.selector);
-    if (getter.isDeferredLoaderGetter) {
-      generateDeferredLoaderGet(node, getter, sourceInformation);
-    } else {
-      pushInvokeStatic(node, getter, <HInstruction>[],
-          sourceInformation: sourceInformation);
-    }
-  }
-
-  /// Generate a dynamic getter invocation.
-  void generateDynamicGet(ast.Send node) {
-    HInstruction receiver = generateInstanceSendReceiver(node);
-    generateInstanceGetterWithCompiledReceiver(node, elements.getSelector(node),
-        elementInferenceResults.typeOfSend(node), receiver);
-  }
-
-  /// Generate a closurization of the static or top level [method].
-  void generateStaticFunctionGet(ast.Send node, MethodElement method) {
-    assert(method.isDeclaration);
-    // TODO(5346): Try to avoid the need for calling [declaration] before
-    // creating an [HStatic].
-    SourceInformation sourceInformation =
-        sourceInformationBuilder.buildGet(node.selector);
-    push(new HStatic(method, commonMasks.nonNullType, sourceInformation));
-  }
-
-  /// Read a local variable, function or parameter.
-  void buildLocalGet(LocalElement local, SourceInformation sourceInformation) {
-    stack.add(
-        localsHandler.readLocal(local, sourceInformation: sourceInformation));
-  }
-
-  void handleLocalGet(ast.Send node, LocalElement local) {
-    buildLocalGet(local, sourceInformationBuilder.buildGet(node));
-  }
-
-  @override
-  void visitDynamicPropertyGet(ast.Send node, ast.Node receiver, Name name, _) {
-    generateDynamicGet(node);
-  }
-
-  @override
-  void visitIfNotNullDynamicPropertyGet(
-      ast.Send node, ast.Node receiver, Name name, _) {
-    // exp?.x compiled as:
-    //   t1 = exp;
-    //   result = t1 == null ? t1 : t1.x;
-    // This is equivalent to t1 == null ? null : t1.x, but in the current form
-    // we will be able to later compress it as:
-    //   t1 || t1.x
-    HInstruction expression;
-    SsaBranchBuilder brancher = new SsaBranchBuilder(this, node);
-    brancher.handleConditional(
-        () {
-          expression = visitAndPop(receiver);
-          pushCheckNull(expression);
-        },
-        () => stack.add(expression),
-        () {
-          generateInstanceGetterWithCompiledReceiver(
-              node,
-              elements.getSelector(node),
-              elementInferenceResults.typeOfSend(node),
-              expression);
-        });
-  }
-
-  @override
-  void visitLocalVariableGet(ast.Send node, LocalVariableElement variable, _) {
-    handleLocalGet(node, variable);
-  }
-
-  @override
-  void visitParameterGet(ast.Send node, ParameterElement parameter, _) {
-    handleLocalGet(node, parameter);
-  }
-
-  @override
-  void visitLocalFunctionGet(ast.Send node, LocalFunctionElement function, _) {
-    handleLocalGet(node, function);
-  }
-
-  @override
-  void visitStaticFieldGet(ast.Send node, FieldElement field, _) {
-    generateStaticFieldGet(node, field);
-  }
-
-  @override
-  void visitStaticFunctionGet(ast.Send node, MethodElement function, _) {
-    generateStaticFunctionGet(node, function);
-  }
-
-  @override
-  void visitStaticGetterGet(ast.Send node, FunctionElement getter, _) {
-    generateStaticGetterGet(node, getter);
-  }
-
-  @override
-  void visitThisPropertyGet(ast.Send node, Name name, _) {
-    generateDynamicGet(node);
-  }
-
-  @override
-  void visitTopLevelFieldGet(ast.Send node, FieldElement field, _) {
-    generateStaticFieldGet(node, field);
-  }
-
-  @override
-  void visitTopLevelFunctionGet(ast.Send node, MethodElement function, _) {
-    generateStaticFunctionGet(node, function);
-  }
-
-  @override
-  void visitTopLevelGetterGet(ast.Send node, FunctionElement getter, _) {
-    generateStaticGetterGet(node, getter);
-  }
-
-  void generateInstanceSetterWithCompiledReceiver(
-      ast.Send send, HInstruction receiver, HInstruction value,
-      {Selector selector, TypeMask mask, ast.Node location}) {
-    assert(
-        send == null || Elements.isInstanceSend(send, elements),
-        failedAt(
-            send ?? location,
-            "Unexpected instance setter"
-            "${send != null ? " element: ${elements[send]}" : ""}"));
-    if (selector == null) {
-      assert(send != null);
-      selector = elements.getSelector(send);
-      mask ??= elementInferenceResults.typeOfSend(send);
-    }
-    if (location == null) {
-      assert(send != null);
-      location = send;
-    }
-    assert(selector.isSetter);
-    pushInvokeDynamic(location, selector, mask, [receiver, value],
-        sourceInformation: sourceInformationBuilder.buildAssignment(location));
-    pop();
-    stack.add(value);
-  }
-
-  void generateNoSuchSetter(
-      ast.Node location, Element element, HInstruction value) {
-    List<HInstruction> arguments =
-        value == null ? const <HInstruction>[] : <HInstruction>[value];
-    // An erroneous element indicates an unresolved static setter.
-    generateThrowNoSuchMethod(
-        location, noSuchMethodTargetSymbolString(element, 'set'),
-        argumentValues: arguments);
-  }
-
-  void generateNonInstanceSetter(
-      ast.SendSet send, Element element, HInstruction value,
-      {ast.Node location}) {
-    if (location == null) {
-      assert(send != null);
-      location = send;
-    }
-    assert(send == null || !Elements.isInstanceSend(send, elements),
-        failedAt(location, "Unexpected non instance setter: $element."));
-    if (Elements.isStaticOrTopLevelField(element)) {
-      if (element.isSetter) {
-        pushInvokeStatic(location, element, <HInstruction>[value]);
-        pop();
-      } else {
-        FieldElement field = element;
-        value = typeBuilder.potentiallyCheckOrTrustTypeOfAssignment(
-            value, field.type);
-        addWithPosition(
-            new HStaticStore(abstractValueDomain, field, value), location);
-      }
-      stack.add(value);
-    } else if (Elements.isError(element)) {
-      generateNoSuchSetter(location, element, send == null ? null : value);
-    } else if (Elements.isMalformed(element)) {
-      // TODO(ahe): Do something like [generateWrongArgumentCountError].
-      stack.add(graph.addConstantNull(closedWorld));
-    } else {
-      stack.add(value);
-      LocalElement local = element;
-      // If the value does not already have a name, give it here.
-      if (value.sourceElement == null) {
-        value.sourceElement = local;
-      }
-      HInstruction checkedOrTrusted = typeBuilder
-          .potentiallyCheckOrTrustTypeOfAssignment(value, local.type);
-      if (!identical(checkedOrTrusted, value)) {
-        pop();
-        stack.add(checkedOrTrusted);
-      }
-
-      localsHandler.updateLocal(local, checkedOrTrusted,
-          sourceInformation:
-              sourceInformationBuilder.buildAssignment(location));
-    }
-  }
-
-  HInstruction invokeInterceptor(HInstruction receiver) {
-    HInterceptor interceptor =
-        new HInterceptor(receiver, commonMasks.nonNullType);
-    add(interceptor);
-    return interceptor;
-  }
-
-  @override
-  void visitAs(ast.Send node, ast.Node expression, ResolutionDartType type, _) {
-    HInstruction expressionInstruction = visitAndPop(expression);
-    if (type.isMalformed) {
-      if (type is MalformedType) {
-        ErroneousElement element = type.element;
-        generateTypeError(node, element.message);
-      } else {
-        assert(type is MethodTypeVariableType);
-        stack.add(expressionInstruction);
-      }
-    } else {
-      HInstruction converted = typeBuilder.buildTypeConversion(
-          expressionInstruction,
-          localsHandler.substInContext(type),
-          HTypeConversion.CAST_TYPE_CHECK,
-          sourceInformation: sourceInformationBuilder.buildAs(node));
-      if (converted != expressionInstruction) add(converted);
-      stack.add(converted);
-    }
-  }
-
-  @override
-  void visitIs(ast.Send node, ast.Node expression, ResolutionDartType type, _) {
-    HInstruction expressionInstruction = visitAndPop(expression);
-    push(buildIsNode(node, type, expressionInstruction,
-        sourceInformationBuilder.buildIs(node)));
-  }
-
-  @override
-  void visitIsNot(
-      ast.Send node, ast.Node expression, ResolutionDartType type, _) {
-    HInstruction expressionInstruction = visitAndPop(expression);
-    HInstruction instruction = buildIsNode(node, type, expressionInstruction,
-        sourceInformationBuilder.buildIs(node));
-    add(instruction);
-    push(new HNot(instruction, commonMasks.boolType));
-  }
-
-  HInstruction buildIsNode(ast.Node node, ResolutionDartType type,
-      HInstruction expression, SourceInformation sourceInformation) {
-    type = localsHandler.substInContext(type).unaliased;
-    if (type.isMalformed) {
-      String message;
-      if (type is MethodTypeVariableType) {
-        message = "Method type variables are not reified, "
-            "so they cannot be tested with an `is` expression.";
-      } else {
-        assert(type is MalformedType);
-        ErroneousElement element = type.element;
-        message = element.message;
-      }
-      generateTypeError(node, message);
-      HInstruction call = pop();
-      return new HIs.compound(
-          type, expression, call, commonMasks.boolType, sourceInformation);
-    } else if (type.isFunctionType) {
-      HInstruction representation =
-          typeBuilder.analyzeTypeArgument(type, sourceElement);
-      List<HInstruction> inputs = <HInstruction>[
-        expression,
-        representation,
-      ];
-      pushInvokeStatic(node, commonElements.functionTypeTest, inputs,
-          typeMask: commonMasks.boolType, sourceInformation: sourceInformation);
-      HInstruction call = pop();
-      return new HIs.compound(
-          type, expression, call, commonMasks.boolType, sourceInformation);
-    } else if (type.isTypeVariable) {
-      ResolutionTypeVariableType typeVariable = type;
-      HInstruction runtimeType =
-          typeBuilder.addTypeVariableReference(typeVariable, sourceElement);
-      MethodElement helper = commonElements.checkSubtypeOfRuntimeType;
-      List<HInstruction> inputs = <HInstruction>[expression, runtimeType];
-      pushInvokeStatic(null, helper, inputs,
-          typeMask: commonMasks.boolType, sourceInformation: sourceInformation);
-      HInstruction call = pop();
-      return new HIs.variable(
-          type, expression, call, commonMasks.boolType, sourceInformation);
-    } else if (RuntimeTypesSubstitutions.hasTypeArguments(type)) {
-      ClassElement element = type.element;
-      MethodElement helper = commonElements.checkSubtype;
-      HInstruction representations =
-          typeBuilder.buildTypeArgumentRepresentations(type, sourceElement);
-      add(representations);
-      js.Name operator = namer.operatorIs(element);
-      HInstruction isFieldName = addConstantStringFromName(operator);
-      HInstruction asFieldName = closedWorld.hasAnyStrictSubtype(element)
-          ? addConstantStringFromName(namer.substitutionName(element))
-          : graph.addConstantNull(closedWorld);
-      List<HInstruction> inputs = <HInstruction>[
-        expression,
-        isFieldName,
-        representations,
-        asFieldName
-      ];
-      pushInvokeStatic(node, helper, inputs,
-          typeMask: commonMasks.boolType, sourceInformation: sourceInformation);
-      HInstruction call = pop();
-      return new HIs.compound(
-          type, expression, call, commonMasks.boolType, sourceInformation);
-    } else {
-      if (backend.hasDirectCheckFor(closedWorld.commonElements, type)) {
-        return new HIs.direct(
-            type, expression, commonMasks.boolType, sourceInformation);
-      }
-      // The interceptor is not always needed.  It is removed by optimization
-      // when the receiver type or tested type permit.
-      return new HIs.raw(type, expression, invokeInterceptor(expression),
-          commonMasks.boolType, sourceInformation);
-    }
-  }
-
-  void addDynamicSendArgumentsToList(ast.Send node, List<HInstruction> list) {
-    CallStructure callStructure = elements.getSelector(node).callStructure;
-    if (callStructure.namedArgumentCount == 0) {
-      addGenericSendArgumentsToList(node.arguments, list);
-    } else {
-      // Visit positional arguments and add them to the list.
-      Link<ast.Node> arguments = node.arguments;
-      int positionalArgumentCount = callStructure.positionalArgumentCount;
-      for (int i = 0;
-          i < positionalArgumentCount;
-          arguments = arguments.tail, i++) {
-        visit(arguments.head);
-        list.add(pop());
-      }
-
-      // Visit named arguments and add them into a temporary map.
-      Map<String, HInstruction> instructions = new Map<String, HInstruction>();
-      List<String> namedArguments = callStructure.namedArguments;
-      int nameIndex = 0;
-      for (; !arguments.isEmpty; arguments = arguments.tail) {
-        visit(arguments.head);
-        instructions[namedArguments[nameIndex++]] = pop();
-      }
-
-      // Iterate through the named arguments to add them to the list
-      // of instructions, in an order that can be shared with
-      // selectors with the same named arguments.
-      List<String> orderedNames = callStructure.getOrderedNamedArguments();
-      for (String name in orderedNames) {
-        list.add(instructions[name]);
-      }
-    }
-  }
-
-  /**
-   * Returns a list with the evaluated [arguments] in the normalized order.
-   *
-   * Precondition: `this.applies(element, world)`.
-   * Invariant: [element] must be an implementation element.
-   */
-  List<HInstruction> makeStaticArgumentList(CallStructure callStructure,
-      Link<ast.Node> arguments, MethodElement element) {
-    assert(element.isDeclaration, failedAt(element));
-
-    HInstruction compileArgument(ast.Node argument) {
-      visit(argument);
-      return pop();
-    }
-
-    return Elements.makeArgumentsList<HInstruction>(
-        callStructure,
-        arguments,
-        element.implementation,
-        compileArgument,
-        nativeData.isJsInteropMember(element)
-            ? handleConstantForOptionalParameterJsInterop
-            : handleConstantForOptionalParameter);
-  }
-
-  void addGenericSendArgumentsToList(
-      Link<ast.Node> link, List<HInstruction> list) {
-    for (; !link.isEmpty; link = link.tail) {
-      visit(link.head);
-      list.add(pop());
-    }
-  }
-
-  /// Generate a dynamic method, getter or setter invocation.
-  void generateDynamicSend(ast.Send node) {
-    HInstruction receiver = generateInstanceSendReceiver(node);
-    _generateDynamicSend(node, receiver);
-  }
-
-  void _generateDynamicSend(ast.Send node, HInstruction receiver) {
-    Selector selector = elements.getSelector(node);
-    TypeMask mask = elementInferenceResults.typeOfSend(node);
-    SourceInformation sourceInformation =
-        sourceInformationBuilder.buildCall(node, node.selector);
-
-    List<HInstruction> inputs = <HInstruction>[];
-    inputs.add(receiver);
-    addDynamicSendArgumentsToList(node, inputs);
-
-    pushInvokeDynamic(node, selector, mask, inputs,
-        sourceInformation: sourceInformation);
-    if (selector.isSetter || selector.isIndexSet) {
-      pop();
-      stack.add(inputs.last);
-    }
-  }
-
-  @override
-  visitDynamicPropertyInvoke(ast.Send node, ast.Node receiver,
-      ast.NodeList arguments, Selector selector, _) {
-    generateDynamicSend(node);
-  }
-
-  @override
-  visitIfNotNullDynamicPropertyInvoke(ast.Send node, ast.Node receiver,
-      ast.NodeList arguments, Selector selector, _) {
-    /// Desugar `exp?.m()` to `(t1 = exp) == null ? t1 : t1.m()`
-    HInstruction receiver;
-    SsaBranchBuilder brancher = new SsaBranchBuilder(this, node);
-    brancher.handleConditional(() {
-      receiver = generateInstanceSendReceiver(node);
-      pushCheckNull(receiver);
-    }, () => stack.add(receiver), () => _generateDynamicSend(node, receiver));
-  }
-
-  @override
-  visitThisPropertyInvoke(
-      ast.Send node, ast.NodeList arguments, Selector selector, _) {
-    generateDynamicSend(node);
-  }
-
-  @override
-  visitExpressionInvoke(ast.Send node, ast.Node expression,
-      ast.NodeList arguments, CallStructure callStructure, _) {
-    generateCallInvoke(node, visitAndPop(expression),
-        sourceInformationBuilder.buildCall(node, node.argumentsNode));
-  }
-
-  @override
-  visitThisInvoke(
-      ast.Send node, ast.NodeList arguments, CallStructure callStructure, _) {
-    generateCallInvoke(
-        node,
-        localsHandler.readThis(
-            sourceInformation: sourceInformationBuilder.buildGet(node)),
-        sourceInformationBuilder.buildCall(node, node.argumentsNode));
-  }
-
-  @override
-  visitParameterInvoke(ast.Send node, ParameterElement parameter,
-      ast.NodeList arguments, CallStructure callStructure, _) {
-    generateCallInvoke(node, localsHandler.readLocal(parameter),
-        sourceInformationBuilder.buildCall(node, node.argumentsNode));
-  }
-
-  @override
-  visitLocalVariableInvoke(ast.Send node, LocalVariableElement variable,
-      ast.NodeList arguments, CallStructure callStructure, _) {
-    generateCallInvoke(node, localsHandler.readLocal(variable),
-        sourceInformationBuilder.buildCall(node, node.argumentsNode));
-  }
-
-  @override
-  visitLocalFunctionInvoke(ast.Send node, LocalFunctionElement function,
-      ast.NodeList arguments, CallStructure callStructure, _) {
-    generateCallInvoke(node, localsHandler.readLocal(function),
-        sourceInformationBuilder.buildCall(node, node.argumentsNode));
-  }
-
-  @override
-  visitLocalFunctionIncompatibleInvoke(
-      ast.Send node,
-      LocalFunctionElement function,
-      ast.NodeList arguments,
-      CallStructure callStructure,
-      _) {
-    generateCallInvoke(node, localsHandler.readLocal(function),
-        sourceInformationBuilder.buildCall(node, node.argumentsNode));
-  }
-
-  void handleForeignJs(ast.Send node) {
-    Link<ast.Node> link = node.arguments;
-    // Don't visit the first argument, which is the type, and the second
-    // argument, which is the foreign code.
-    if (link.isEmpty || link.tail.isEmpty) {
-      // We should not get here because the call should be compiled to NSM.
-      reporter.internalError(
-          node.argumentsNode, 'At least two arguments expected.');
-    }
-    native.NativeBehavior nativeBehavior = elements.getNativeData(node);
-    assert(
-        nativeBehavior != null, failedAt(node, "No NativeBehavior for $node"));
-
-    List<HInstruction> inputs = <HInstruction>[];
-    addGenericSendArgumentsToList(link.tail.tail, inputs);
-
-    if (nativeBehavior.codeTemplate.positionalArgumentCount != inputs.length) {
-      reporter.reportErrorMessage(node, MessageKind.GENERIC, {
-        'text': 'Mismatch between number of placeholders'
-            ' and number of arguments.'
-      });
-      // Result expected on stack.
-      stack.add(graph.addConstantNull(closedWorld));
-      return;
-    }
-
-    if (native.HasCapturedPlaceholders.check(nativeBehavior.codeTemplate.ast)) {
-      reporter.reportErrorMessage(node, MessageKind.JS_PLACEHOLDER_CAPTURE);
-    }
-
-    TypeMask ssaType =
-        TypeMaskFactory.fromNativeBehavior(nativeBehavior, closedWorld);
-
-    DartType typeArgument;
-    ast.NodeList typeArgumentsNode = node.typeArgumentsNode;
-    if (typeArgumentsNode != null) {
-      if (typeArgumentsNode.slowLength() == 1) {
-        ast.Node typeNode = typeArgumentsNode.single;
-        typeArgument = elements.getType(typeNode);
-      } else {
-        reporter.reportErrorMessage(typeArgumentsNode, MessageKind.GENERIC,
-            {'text': 'JS takes one type argument'});
-      }
-    }
-
-    SourceInformation sourceInformation =
-        sourceInformationBuilder.buildCall(node, node.argumentsNode);
-    push(new HForeignCode(nativeBehavior.codeTemplate, ssaType, inputs,
-        isStatement: !nativeBehavior.codeTemplate.isExpression,
-        effects: nativeBehavior.sideEffects,
-        nativeBehavior: nativeBehavior)
-      ..sourceInformation = sourceInformation);
-
-    HInstruction code = stack.last;
-    TypeMask trustedMask = typeBuilder.trustTypeMask(typeArgument);
-
-    if (trustedMask != null) {
-      // We only allow the type argument to narrow `dynamic`, which probably
-      // comes from an unspecified return type in the NativeBehavior.
-      if (abstractValueDomain.containsAll(code.instructionType)) {
-        // Overwrite the type with the narrower type.
-        code.instructionType = trustedMask;
-      } else if (trustedMask.containsMask(code.instructionType, closedWorld)) {
-        // It is acceptable for the type parameter to be broader than the
-        // specified type.
-      } else {
-        reporter.reportErrorMessage(typeArgumentsNode, MessageKind.GENERIC, {
-          'text': 'Type argument too narrow for specified behavior type '
-              '(${trustedMask} does not allow '
-              'all values in ${code.instructionType})'
-        });
-      }
-    }
-  }
-
-  void handleJsStringConcat(ast.Send node) {
-    List<HInstruction> inputs = <HInstruction>[];
-    addGenericSendArgumentsToList(node.arguments, inputs);
-    if (inputs.length != 2) {
-      reporter.internalError(node.argumentsNode, 'Two arguments expected.');
-    }
-    push(new HStringConcat(inputs[0], inputs[1], commonMasks.stringType));
-  }
-
-  void handleForeignJsCurrentIsolateContext(ast.Send node) {
-    if (!node.arguments.isEmpty) {
-      reporter.internalError(
-          node, 'Too many arguments to JS_CURRENT_ISOLATE_CONTEXT.');
-    }
-
-    String name = namer.staticStateHolder;
-    push(new HForeignCode(
-        js.js.parseForeignJS(name), commonMasks.dynamicType, <HInstruction>[],
-        nativeBehavior: native.NativeBehavior.DEPENDS_OTHER));
-  }
-
-  void handleForeignJsGetFlag(ast.Send node) {
-    List<ast.Node> arguments = node.arguments.toList();
-    ast.Node argument;
-    switch (arguments.length) {
-      case 0:
-        reporter.reportErrorMessage(node, MessageKind.GENERIC,
-            {'text': 'Error: Expected one argument to JS_GET_FLAG.'});
-        return;
-      case 1:
-        argument = arguments[0];
-        break;
-      default:
-        for (int i = 1; i < arguments.length; i++) {
-          reporter.reportErrorMessage(arguments[i], MessageKind.GENERIC,
-              {'text': 'Error: Extra argument to JS_GET_FLAG.'});
-        }
-        return;
-    }
-    ast.LiteralString string = argument.asLiteralString();
-    if (string == null) {
-      reporter.reportErrorMessage(argument, MessageKind.GENERIC,
-          {'text': 'Error: Expected a literal string.'});
-    }
-    String name = string.dartString.slowToString();
-    bool value = getFlagValue(name);
-    if (value == null) {
-      reporter.reportErrorMessage(node, MessageKind.GENERIC,
-          {'text': 'Error: Unknown internal flag "$name".'});
-    } else {
-      stack.add(graph.addConstantBool(value, closedWorld));
-    }
-  }
-
-  void handleForeignJsGetName(ast.Send node) {
-    List<ast.Node> arguments = node.arguments.toList();
-    ast.Node argument;
-    switch (arguments.length) {
-      case 0:
-        reporter.reportErrorMessage(node, MessageKind.GENERIC,
-            {'text': 'Error: Expected one argument to JS_GET_NAME.'});
-        return;
-      case 1:
-        argument = arguments[0];
-        break;
-      default:
-        for (int i = 1; i < arguments.length; i++) {
-          reporter.reportErrorMessage(arguments[i], MessageKind.GENERIC,
-              {'text': 'Error: Extra argument to JS_GET_NAME.'});
-        }
-        return;
-    }
-    Element element = elements[argument];
-    if (element == null ||
-        element is! EnumConstantElement ||
-        element.enclosingClass != commonElements.jsGetNameEnum) {
-      reporter.reportErrorMessage(argument, MessageKind.GENERIC,
-          {'text': 'Error: Expected a JsGetName enum value.'});
-    }
-    EnumConstantElement enumConstant = element;
-    int index = enumConstant.index;
-    stack.add(addConstantStringFromName(
-        namer.getNameForJsGetName(argument, JsGetName.values[index])));
-  }
-
-  void handleForeignJsBuiltin(ast.Send node) {
-    List<ast.Node> arguments = node.arguments.toList();
-    ast.Node argument;
-    if (arguments.length < 2) {
-      reporter.reportErrorMessage(node, MessageKind.GENERIC,
-          {'text': 'Error: Expected at least two arguments to JS_BUILTIN.'});
-    }
-
-    Element builtinElement = elements[arguments[1]];
-    if (builtinElement == null ||
-        (builtinElement is! EnumConstantElement) ||
-        builtinElement.enclosingClass != commonElements.jsBuiltinEnum) {
-      reporter.reportErrorMessage(argument, MessageKind.GENERIC,
-          {'text': 'Error: Expected a JsBuiltin enum value.'});
-    }
-    EnumConstantElement enumConstant = builtinElement;
-    int index = enumConstant.index;
-
-    js.Template template = emitter.builtinTemplateFor(JsBuiltin.values[index]);
-
-    List<HInstruction> compiledArguments = <HInstruction>[];
-    for (int i = 2; i < arguments.length; i++) {
-      visit(arguments[i]);
-      compiledArguments.add(pop());
-    }
-
-    native.NativeBehavior nativeBehavior = elements.getNativeData(node);
-    assert(
-        nativeBehavior != null, failedAt(node, "No NativeBehavior for $node"));
-
-    TypeMask ssaType =
-        TypeMaskFactory.fromNativeBehavior(nativeBehavior, closedWorld);
-
-    push(new HForeignCode(template, ssaType, compiledArguments,
-        nativeBehavior: nativeBehavior));
-  }
-
-  void handleForeignJsEmbeddedGlobal(ast.Send node) {
-    List<ast.Node> arguments = node.arguments.toList();
-    ast.Node globalNameNode;
-    switch (arguments.length) {
-      case 0:
-      case 1:
-        reporter.reportErrorMessage(node, MessageKind.GENERIC,
-            {'text': 'Error: Expected two arguments to JS_EMBEDDED_GLOBAL.'});
-        return;
-      case 2:
-        // The type has been extracted earlier. We are only interested in the
-        // name in this function.
-        globalNameNode = arguments[1];
-        break;
-      default:
-        for (int i = 2; i < arguments.length; i++) {
-          reporter.reportErrorMessage(arguments[i], MessageKind.GENERIC,
-              {'text': 'Error: Extra argument to JS_EMBEDDED_GLOBAL.'});
-        }
-        return;
-    }
-    visit(globalNameNode);
-    HInstruction globalNameHNode = pop();
-    if (!globalNameHNode.isConstantString()) {
-      reporter.reportErrorMessage(arguments[1], MessageKind.GENERIC, {
-        'text': 'Error: Expected String as second argument '
-            'to JS_EMBEDDED_GLOBAL.'
-      });
-      return;
-    }
-    HConstant hConstant = globalNameHNode;
-    StringConstantValue constant = hConstant.constant;
-    String globalName = constant.stringValue;
-    js.Template expr = js.js.expressionTemplateYielding(
-        emitter.generateEmbeddedGlobalAccess(globalName));
-    native.NativeBehavior nativeBehavior = elements.getNativeData(node);
-    assert(
-        nativeBehavior != null, failedAt(node, "No NativeBehavior for $node"));
-    TypeMask ssaType =
-        TypeMaskFactory.fromNativeBehavior(nativeBehavior, closedWorld);
-    push(new HForeignCode(expr, ssaType, const [],
-        nativeBehavior: nativeBehavior));
-  }
-
-  void handleJsInterceptorConstant(ast.Send node) {
-    // Single argument must be a TypeConstant which is converted into a
-    // InterceptorConstant.
-    if (!node.arguments.isEmpty && node.arguments.tail.isEmpty) {
-      ast.Node argument = node.arguments.head;
-      visit(argument);
-      HInstruction argumentInstruction = pop();
-      if (argumentInstruction is HConstant) {
-        ConstantValue argumentConstant = argumentInstruction.constant;
-        if (argumentConstant is TypeConstantValue &&
-            argumentConstant.representedType is ResolutionInterfaceType) {
-          ResolutionInterfaceType type = argumentConstant.representedType;
-          ConstantValue constant = new InterceptorConstantValue(type.element);
-          HInstruction instruction = graph.addConstant(constant, closedWorld);
-          stack.add(instruction);
-          return;
-        }
-      }
-    }
-    reporter.reportErrorMessage(
-        node, MessageKind.WRONG_ARGUMENT_FOR_JS_INTERCEPTOR_CONSTANT);
-    stack.add(graph.addConstantNull(closedWorld));
-  }
-
-  FunctionSignature handleForeignRawFunctionRef(ast.Send node, String name) {
-    if (node.arguments.isEmpty || !node.arguments.tail.isEmpty) {
-      reporter.internalError(
-          node.argumentsNode, '"$name" requires exactly one argument.');
-    }
-    ast.Node closure = node.arguments.head;
-    Element element = elements[closure];
-    if (!Elements.isStaticOrTopLevelFunction(element)) {
-      reporter.internalError(
-          closure, '"$name" requires a static or top-level method.');
-    }
-    MethodElement function = element;
-    // TODO(johnniwinther): Try to eliminate the need to distinguish declaration
-    // and implementation signatures. Currently it is need because the
-    // signatures have different elements for parameters.
-    FunctionElement implementation = function.implementation;
-    FunctionSignature params = implementation.functionSignature;
-    if (params.optionalParameterCount != 0) {
-      reporter.internalError(
-          closure, '"$name" does not handle closure with optional parameters.');
-    }
-
-    push(new HForeignCode(
-        js.js
-            .expressionTemplateYielding(emitter.staticFunctionAccess(function)),
-        commonMasks.dynamicType,
-        <HInstruction>[],
-        nativeBehavior: native.NativeBehavior.PURE,
-        foreignFunction: function));
-    return params;
-  }
-
-  void handleForeignDartClosureToJs(ast.Send node, String name) {
-    // TODO(ahe): This implements DART_CLOSURE_TO_JS and should probably take
-    // care to wrap the closure in another closure that saves the current
-    // isolate.
-    handleForeignRawFunctionRef(node, name);
-  }
-
-  void handleForeignJsSetStaticState(ast.Send node) {
-    if (node.arguments.isEmpty || !node.arguments.tail.isEmpty) {
-      reporter.internalError(
-          node.argumentsNode, 'Exactly one argument required.');
-    }
-    visit(node.arguments.head);
-    String isolateName = namer.staticStateHolder;
-    SideEffects sideEffects = new SideEffects.empty();
-    sideEffects.setAllSideEffects();
-    push(new HForeignCode(js.js.parseForeignJS("$isolateName = #"),
-        commonMasks.dynamicType, <HInstruction>[pop()],
-        nativeBehavior: native.NativeBehavior.CHANGES_OTHER,
-        effects: sideEffects));
-  }
-
-  void handleForeignJsGetStaticState(ast.Send node) {
-    if (!node.arguments.isEmpty) {
-      reporter.internalError(node.argumentsNode, 'Too many arguments.');
-    }
-    push(new HForeignCode(js.js.parseForeignJS(namer.staticStateHolder),
-        commonMasks.dynamicType, <HInstruction>[],
-        nativeBehavior: native.NativeBehavior.DEPENDS_OTHER));
-  }
-
-  void handleForeignSend(ast.Send node, FunctionElement element) {
-    String name = element.name;
-    if (name == JavaScriptBackend.JS) {
-      handleForeignJs(node);
-    } else if (name == 'JS_CURRENT_ISOLATE_CONTEXT') {
-      handleForeignJsCurrentIsolateContext(node);
-    } else if (name == 'DART_CLOSURE_TO_JS') {
-      handleForeignDartClosureToJs(node, 'DART_CLOSURE_TO_JS');
-    } else if (name == 'RAW_DART_FUNCTION_REF') {
-      handleForeignRawFunctionRef(node, 'RAW_DART_FUNCTION_REF');
-    } else if (name == 'JS_SET_STATIC_STATE') {
-      handleForeignJsSetStaticState(node);
-    } else if (name == 'JS_GET_STATIC_STATE') {
-      handleForeignJsGetStaticState(node);
-    } else if (name == 'JS_GET_NAME') {
-      handleForeignJsGetName(node);
-    } else if (name == JavaScriptBackend.JS_EMBEDDED_GLOBAL) {
-      handleForeignJsEmbeddedGlobal(node);
-    } else if (name == JavaScriptBackend.JS_BUILTIN) {
-      handleForeignJsBuiltin(node);
-    } else if (name == 'JS_GET_FLAG') {
-      handleForeignJsGetFlag(node);
-    } else if (name == 'JS_EFFECT') {
-      stack.add(graph.addConstantNull(closedWorld));
-    } else if (name == JavaScriptBackend.JS_INTERCEPTOR_CONSTANT) {
-      handleJsInterceptorConstant(node);
-    } else if (name == 'JS_STRING_CONCAT') {
-      handleJsStringConcat(node);
-    } else {
-      reporter.internalError(node, "Unknown foreign: ${element}");
-    }
-  }
-
-  generateDeferredLoaderGet(ast.Send node, FunctionElement deferredLoader,
-      SourceInformation sourceInformation) {
-    // Until now we only handle these as getters.
-    if (!deferredLoader.isDeferredLoaderGetter) {
-      failedAt(node);
-    }
-    FunctionEntity loadFunction = commonElements.loadLibraryWrapper;
-    PrefixElement prefixElement = deferredLoader.enclosingElement;
-    String loadId =
-        deferredLoadTask.getImportDeferName(node, prefixElement.deferredImport);
-    var inputs = [graph.addConstantString(loadId, closedWorld)];
-    push(new HInvokeStatic(
-        loadFunction, inputs, commonMasks.nonNullType, const <DartType>[],
-        targetCanThrow: false)
-      ..sourceInformation = sourceInformation);
-  }
-
-  generateSuperNoSuchMethodSend(
-      ast.Send node, Selector selector, List<HInstruction> arguments) {
-    String name = selector.name;
-
-    ClassElement cls = currentNonClosureClass;
-    MethodElement element = cls.lookupSuperMember(Identifiers.noSuchMethod_);
-    if (!Selectors.noSuchMethod_.signatureApplies(element)) {
-      ClassElement objectClass = commonElements.objectClass;
-      element = objectClass.lookupMember(Identifiers.noSuchMethod_);
-    }
-    if (backendUsage.isInvokeOnUsed && !element.enclosingClass.isObject) {
-      // Register the call as dynamic if [noSuchMethod] on the super
-      // class is _not_ the default implementation from [Object], in
-      // case the [noSuchMethod] implementation calls
-      // [JSInvocationMirror._invokeOn].
-      // TODO(johnniwinther): Register this more precisely.
-      registry
-          ?.registerDynamicUse(new ConstrainedDynamicUse(selector, null, null));
-    }
-    String publicName = name;
-    if (selector.isSetter) publicName += '=';
-
-    ConstantValue nameConstant = constantSystem.createString(publicName);
-
-    js.Name internalName = namer.invocationName(selector);
-
-    MethodElement createInvocationMirror =
-        commonElements.createInvocationMirror;
-    var argumentsInstruction = buildLiteralList(arguments);
-    add(argumentsInstruction);
-
-    var argumentNames = new List<HInstruction>();
-    for (String argumentName in selector.namedArguments) {
-      ConstantValue argumentNameConstant =
-          constantSystem.createString(argumentName);
-      argumentNames.add(graph.addConstant(argumentNameConstant, closedWorld));
-    }
-    var argumentNamesInstruction = buildLiteralList(argumentNames);
-    add(argumentNamesInstruction);
-
-    ConstantValue kindConstant =
-        constantSystem.createInt(selector.invocationMirrorKind);
-
-    pushInvokeStatic(
-        null,
-        createInvocationMirror,
-        [
-          graph.addConstant(nameConstant, closedWorld),
-          graph.addConstantStringFromName(internalName, closedWorld),
-          graph.addConstant(kindConstant, closedWorld),
-          argumentsInstruction,
-          argumentNamesInstruction,
-          graph.addConstantInt(0, closedWorld), // type argument count.
-        ],
-        typeMask: commonMasks.dynamicType);
-
-    var inputs = <HInstruction>[pop()];
-    push(buildInvokeSuper(Selectors.noSuchMethod_, element, inputs,
-        sourceInformationBuilder.buildGeneric(node)));
-  }
-
-  /// Generate a call to a super method or constructor.
-  void generateSuperInvoke(ast.Send node, MethodElement method,
-      SourceInformation sourceInformation) {
-    // TODO(5347): Try to avoid the need for calling [implementation] before
-    // calling [makeStaticArgumentList].
-    Selector selector = elements.getSelector(node);
-    MethodElement implementation = method.implementation;
-    assert(selector.applies(implementation),
-        failedAt(node, "$selector does not apply to ${implementation}"));
-    List<HInstruction> inputs =
-        makeStaticArgumentList(selector.callStructure, node.arguments, method);
-    push(buildInvokeSuper(selector, method, inputs, sourceInformation));
-  }
-
-  /// Access the value from the super [element].
-  void handleSuperGet(ast.Send node, Element element) {
-    Selector selector = elements.getSelector(node);
-    SourceInformation sourceInformation =
-        sourceInformationBuilder.buildGet(node.selector);
-    push(buildInvokeSuper(
-        selector, element, const <HInstruction>[], sourceInformation));
-  }
-
-  /// Invoke .call on the value retrieved from the super [element].
-  void handleSuperCallInvoke(ast.Send node, Element element) {
-    Selector selector = elements.getSelector(node);
-    HInstruction target = buildInvokeSuper(
-        selector,
-        element,
-        const <HInstruction>[],
-        sourceInformationBuilder.buildGet(node.selector));
-    add(target);
-    generateCallInvoke(
-        node,
-        target,
-        sourceInformationBuilder.buildCall(
-            node.argumentsNode, node.argumentsNode));
-  }
-
-  /// Invoke super [method].
-  void handleSuperMethodInvoke(ast.Send node, MethodElement method) {
-    generateSuperInvoke(node, method,
-        sourceInformationBuilder.buildCall(node.selector, node.selector));
-  }
-
-  /// Access an unresolved super property.
-  void handleUnresolvedSuperInvoke(ast.Send node) {
-    Selector selector = elements.getSelector(node);
-    List<HInstruction> arguments = <HInstruction>[];
-    if (!node.isPropertyAccess) {
-      addGenericSendArgumentsToList(node.arguments, arguments);
-    }
-    generateSuperNoSuchMethodSend(node, selector, arguments);
-  }
-
-  @override
-  void visitUnresolvedSuperIndex(
-      ast.Send node, Element element, ast.Node index, _) {
-    handleUnresolvedSuperInvoke(node);
-  }
-
-  @override
-  void visitUnresolvedSuperUnary(
-      ast.Send node, UnaryOperator operator, Element element, _) {
-    handleUnresolvedSuperInvoke(node);
-  }
-
-  @override
-  void visitUnresolvedSuperBinary(ast.Send node, Element element,
-      BinaryOperator operator, ast.Node argument, _) {
-    handleUnresolvedSuperInvoke(node);
-  }
-
-  @override
-  void visitUnresolvedSuperGet(ast.Send node, Element element, _) {
-    handleUnresolvedSuperInvoke(node);
-  }
-
-  @override
-  void visitUnresolvedSuperSet(
-      ast.Send node, Element element, ast.Node rhs, _) {
-    handleSuperSendSet(node);
-  }
-
-  @override
-  void visitSuperSetterGet(ast.Send node, MethodElement setter, _) {
-    handleUnresolvedSuperInvoke(node);
-  }
-
-  @override
-  void visitUnresolvedSuperInvoke(
-      ast.Send node, Element element, ast.Node argument, Selector selector, _) {
-    handleUnresolvedSuperInvoke(node);
-  }
-
-  @override
-  void visitSuperFieldGet(ast.Send node, FieldElement field, _) {
-    handleSuperGet(node, field);
-  }
-
-  @override
-  void visitSuperGetterGet(ast.Send node, MethodElement method, _) {
-    handleSuperGet(node, method);
-  }
-
-  @override
-  void visitSuperMethodGet(ast.Send node, MethodElement method, _) {
-    handleSuperGet(node, method);
-  }
-
-  @override
-  void visitSuperFieldInvoke(ast.Send node, FieldElement field,
-      ast.NodeList arguments, CallStructure callStructure, _) {
-    handleSuperCallInvoke(node, field);
-  }
-
-  @override
-  void visitSuperGetterInvoke(ast.Send node, MethodElement getter,
-      ast.NodeList arguments, CallStructure callStructure, _) {
-    handleSuperCallInvoke(node, getter);
-  }
-
-  @override
-  void visitSuperMethodInvoke(ast.Send node, MethodElement method,
-      ast.NodeList arguments, CallStructure callStructure, _) {
-    handleSuperMethodInvoke(node, method);
-  }
-
-  @override
-  void visitSuperIndex(ast.Send node, MethodElement method, ast.Node index, _) {
-    handleSuperMethodInvoke(node, method);
-  }
-
-  @override
-  void visitSuperEquals(
-      ast.Send node, MethodElement method, ast.Node argument, _) {
-    handleSuperMethodInvoke(node, method);
-  }
-
-  @override
-  void visitSuperBinary(ast.Send node, MethodElement method,
-      BinaryOperator operator, ast.Node argument, _) {
-    handleSuperMethodInvoke(node, method);
-  }
-
-  @override
-  void visitSuperNotEquals(
-      ast.Send node, MethodElement method, ast.Node argument, _) {
-    handleSuperMethodInvoke(node, method);
-    pushWithPosition(
-        new HNot(popBoolified(), commonMasks.boolType), node.selector);
-  }
-
-  @override
-  void visitSuperUnary(
-      ast.Send node, UnaryOperator operator, MethodElement method, _) {
-    handleSuperMethodInvoke(node, method);
-  }
-
-  @override
-  void visitSuperMethodIncompatibleInvoke(ast.Send node, MethodElement method,
-      ast.NodeList arguments, CallStructure callStructure, _) {
-    handleInvalidSuperInvoke(node, arguments);
-  }
-
-  @override
-  void visitSuperSetterInvoke(ast.Send node, SetterElement setter,
-      ast.NodeList arguments, CallStructure callStructure, _) {
-    handleInvalidSuperInvoke(node, arguments);
-  }
-
-  void handleInvalidSuperInvoke(ast.Send node, ast.NodeList arguments) {
-    Selector selector = elements.getSelector(node);
-    List<HInstruction> inputs = <HInstruction>[];
-    addGenericSendArgumentsToList(arguments.nodes, inputs);
-    generateSuperNoSuchMethodSend(node, selector, inputs);
-  }
-
-  bool needsSubstitutionForTypeVariableAccess(ClassElement cls) {
-    if (closedWorld.isUsedAsMixin(cls)) return true;
-
-    return closedWorld.anyStrictSubclassOf(cls, (ClassEntity subclass) {
-      return !rtiSubstitutions.isTrivialSubstitution(subclass, cls);
-    });
-  }
-
-  HInstruction handleListConstructor(ResolutionInterfaceType type,
-      HInstruction newObject, SourceInformation sourceInformation) {
-    if (!rtiNeed.classNeedsTypeArguments(type.element) || type.treatAsRaw) {
-      return newObject;
-    }
-    List<HInstruction> inputs = <HInstruction>[];
-    type = localsHandler.substInContext(type);
-    type.typeArguments.forEach((ResolutionDartType argument) {
-      inputs.add(typeBuilder.analyzeTypeArgument(argument, sourceElement,
-          sourceInformation: sourceInformation));
-    });
-    // TODO(15489): Register at codegen.
-    registry?.registerInstantiation(type);
-    return callSetRuntimeTypeInfoWithTypeArguments(
-        type, inputs, newObject, sourceInformation);
-  }
-
-  HInstruction callSetRuntimeTypeInfo(HInstruction typeInfo,
-      HInstruction newObject, SourceInformation sourceInformation) {
-    // Set the runtime type information on the object.
-    MethodElement typeInfoSetterElement = commonElements.setRuntimeTypeInfo;
-    pushInvokeStatic(
-        null, typeInfoSetterElement, <HInstruction>[newObject, typeInfo],
-        typeMask: commonMasks.dynamicType,
-        sourceInformation: sourceInformation);
-
-    // The new object will now be referenced through the
-    // `setRuntimeTypeInfo` call. We therefore set the type of that
-    // instruction to be of the object's type.
-    assert(
-        stack.last is HInvokeStatic || stack.last == newObject,
-        failedAt(
-            CURRENT_ELEMENT_SPANNABLE,
-            "Unexpected `stack.last`: Found ${stack.last}, "
-            "expected ${newObject} or an HInvokeStatic. "
-            "State: typeInfo=$typeInfo, stack=$stack."));
-    stack.last.instructionType = newObject.instructionType;
-    return pop();
-  }
-
-  void handleNewSend(ast.NewExpression node) {
-    ast.Send send = node.send;
-    SourceInformation sourceInformation =
-        sourceInformationBuilder.buildNew(send);
-
-    generateIsDeferredLoadedCheckOfSend(send);
-
-    ConstructorElement constructor = elements[send];
-    bool isFixedList = false;
-    bool isFixedListConstructorCall = Elements.isFixedListConstructorCall(
-        constructor, send, closedWorld.commonElements);
-    bool isGrowableListConstructorCall = Elements.isGrowableListConstructorCall(
-        constructor, send, closedWorld.commonElements);
-
-    TypeMask computeType(element) {
-      ConstructorElement originalElement = elements[send];
-      if (isFixedListConstructorCall ||
-          Elements.isFilledListConstructorCall(
-              originalElement, send, closedWorld.commonElements)) {
-        isFixedList = true;
-        TypeMask inferred = _inferredTypeOfNewList(send);
-        return inferred.containsAll(closedWorld)
-            ? commonMasks.fixedArrayType
-            : inferred;
-      } else if (isGrowableListConstructorCall) {
-        TypeMask inferred = _inferredTypeOfNewList(send);
-        return inferred.containsAll(closedWorld)
-            ? commonMasks.growableListType
-            : inferred;
-      } else if (Elements.isConstructorOfTypedArraySubclass(
-          originalElement, closedWorld)) {
-        isFixedList = true;
-        TypeMask inferred = _inferredTypeOfNewList(send);
-        ClassElement cls = element.enclosingClass;
-        assert(nativeData.isNativeClass(cls));
-        return inferred.containsAll(closedWorld)
-            ? new TypeMask.nonNullExact(cls, closedWorld)
-            : inferred;
-      } else if (element.isGenerativeConstructor) {
-        ClassElement cls = element.enclosingClass;
-        if (cls.isAbstract) {
-          // An error will be thrown.
-          return new TypeMask.nonNullEmpty();
-        } else {
-          return new TypeMask.nonNullExact(cls, closedWorld);
-        }
-      } else {
-        return TypeMaskFactory.inferredReturnTypeForElement(
-            originalElement, globalInferenceResults);
-      }
-    }
-
-    CallStructure callStructure = elements.getSelector(send).callStructure;
-    ConstructorElement constructorDeclaration = constructor;
-    ConstructorElement constructorImplementation = constructor.implementation;
-    constructor = constructorImplementation.effectiveTarget;
-
-    final bool isSymbolConstructor =
-        closedWorld.commonElements.isSymbolConstructor(constructorDeclaration);
-    final bool isJSArrayTypedConstructor = constructorDeclaration ==
-        closedWorld.commonElements.jsArrayTypedConstructor;
-
-    if (isSymbolConstructor) {
-      constructor = commonElements.symbolValidatedConstructor;
-      assert(constructor != null,
-          failedAt(send, 'Constructor Symbol.validated is missing'));
-      callStructure =
-          commonElements.symbolValidatedConstructorSelector.callStructure;
-      assert(callStructure != null,
-          failedAt(send, 'Constructor Symbol.validated is missing'));
-    }
-
-    bool isRedirected = constructorDeclaration.isRedirectingFactory;
-    if (!constructorDeclaration.isCyclicRedirection) {
-      // Insert a check for every deferred redirection on the path to the
-      // final target.
-      ConstructorElement target = constructorDeclaration;
-      while (target.isRedirectingFactory) {
-        if (constructorDeclaration.redirectionDeferredPrefix != null) {
-          generateIsDeferredLoadedCheckIfNeeded(
-              target.redirectionDeferredPrefix.deferredImport, node);
-        }
-        target = target.immediateRedirectionTarget;
-      }
-    }
-    ResolutionInterfaceType type = elements.getType(node);
-    ResolutionDartType expectedType =
-        constructorDeclaration.computeEffectiveTargetType(type);
-    expectedType = localsHandler.substInContext(expectedType);
-
-    if (compiler.elementHasCompileTimeError(constructor) ||
-        compiler.elementHasCompileTimeError(constructor.enclosingClass)) {
-      // TODO(ahe): Do something like [generateWrongArgumentCountError].
-      stack.add(graph.addConstantNull(closedWorld));
-      return;
-    }
-
-    if (checkTypeVariableBounds(node, type)) return;
-
-    // Abstract class instantiation error takes precedence over argument
-    // mismatch.
-    ClassElement cls = constructor.enclosingClass;
-    if (cls.isAbstract && constructor.isGenerativeConstructor) {
-      // However, we need to ensure that all arguments are evaluated before we
-      // throw the ACIE exception.
-      send.arguments.forEach((arg) {
-        visit(arg);
-        pop();
-      });
-      generateAbstractClassInstantiationError(send, cls.name);
-      return;
-    }
-
-    // TODO(5347): Try to avoid the need for calling [implementation] before
-    // calling [makeStaticArgumentList].
-    constructorImplementation = constructor.implementation;
-    if (constructorImplementation.isMalformed ||
-        !callStructure
-            .signatureApplies(constructorImplementation.parameterStructure)) {
-      generateWrongArgumentCountError(send, constructor, send.arguments);
-      return;
-    }
-
-    List<HInstruction> inputs = <HInstruction>[];
-    if (constructor.isGenerativeConstructor &&
-        nativeData.isNativeOrExtendsNative(constructor.enclosingClass) &&
-        !nativeData.isJsInteropMember(constructor)) {
-      // Native class generative constructors take a pre-constructed object.
-      inputs.add(graph.addConstantNull(closedWorld));
-    }
-    inputs.addAll(makeStaticArgumentList(
-        callStructure, send.arguments, constructorImplementation.declaration));
-
-    TypeMask elementType = computeType(constructor);
-    if (isFixedListConstructorCall) {
-      if (!inputs[0].isNumber(abstractValueDomain)) {
-        HTypeConversion conversion = new HTypeConversion(
-            null,
-            HTypeConversion.ARGUMENT_TYPE_CHECK,
-            commonMasks.numType,
-            inputs[0],
-            sourceInformation);
-        add(conversion);
-        inputs[0] = conversion;
-      }
-      js.Template code = js.js.parseForeignJS('new Array(#)');
-      var behavior = new native.NativeBehavior();
-      behavior.typesInstantiated.add(expectedType);
-      behavior.typesReturned.add(expectedType);
-      // The allocation can throw only if the given length is a double or
-      // outside the unsigned 32 bit range.
-      // TODO(sra): Array allocation should be an instruction so that canThrow
-      // can depend on a length type discovered in optimization.
-      bool canThrow = true;
-      if (inputs[0].isInteger(abstractValueDomain) && inputs[0] is HConstant) {
-        dynamic constant = inputs[0];
-        IntConstantValue intConstant = constant.constant;
-        int value = intConstant.intValue;
-        if (0 <= value && value < 0x100000000) canThrow = false;
-      }
-      HForeignCode foreign = new HForeignCode(code, elementType, inputs,
-          nativeBehavior: behavior,
-          throwBehavior: canThrow
-              ? native.NativeThrowBehavior.MAY
-              : native.NativeThrowBehavior.NEVER);
-      push(foreign);
-      if (globalInferenceResults.isFixedArrayCheckedForGrowable(send)) {
-        js.Template code = js.js.parseForeignJS(r'#.fixed$length = Array');
-        // We set the instruction as [canThrow] to avoid it being dead code.
-        // We need a finer grained side effect.
-        add(new HForeignCode(code, commonMasks.nullType, [stack.last],
-            throwBehavior: native.NativeThrowBehavior.MAY));
-      }
-    } else if (isGrowableListConstructorCall) {
-      push(buildLiteralList(<HInstruction>[]));
-      stack.last.instructionType = elementType;
-    } else if (constructor.isExternal &&
-        constructor.isFromEnvironmentConstructor) {
-      generateUnsupportedError(
-          node,
-          '${cls.name}.${constructor.name} '
-          'can only be used as a const constructor');
-    } else {
-      potentiallyAddTypeArguments(inputs, cls, expectedType);
-      addInlinedInstantiation(expectedType);
-      pushInvokeStatic(node, constructor.declaration, inputs,
-          typeMask: elementType,
-          instanceType: expectedType,
-          sourceInformation: sourceInformation);
-      removeInlinedInstantiation(expectedType);
-    }
-    HInstruction newInstance = stack.last;
-    if (isFixedList) {
-      // Overwrite the element type, in case the allocation site has
-      // been inlined.
-      newInstance.instructionType = elementType;
-      graph.allocatedFixedLists?.add(newInstance);
-    }
-
-    // The List constructor forwards to a Dart static method that does
-    // not know about the type argument. Therefore we special case
-    // this constructor to have the setRuntimeTypeInfo called where
-    // the 'new' is done.
-    if (rtiNeed.classNeedsTypeArguments(commonElements.listClass) &&
-        (isFixedListConstructorCall ||
-            isGrowableListConstructorCall ||
-            isJSArrayTypedConstructor)) {
-      newInstance = handleListConstructor(type, pop(), sourceInformation);
-      stack.add(newInstance);
-    }
-
-    // Finally, if we called a redirecting factory constructor, check the type.
-    if (isRedirected) {
-      HInstruction checked = typeBuilder
-          .potentiallyCheckOrTrustTypeOfAssignment(newInstance, type);
-      if (checked != newInstance) {
-        pop();
-        stack.add(checked);
-      }
-    }
-  }
-
-  void potentiallyAddTypeArguments(List<HInstruction> inputs, ClassElement cls,
-      ResolutionInterfaceType expectedType,
-      {SourceInformation sourceInformation}) {
-    if (!rtiNeed.classNeedsTypeArguments(cls)) return;
-    assert(cls.typeVariables.length == expectedType.typeArguments.length);
-    expectedType.typeArguments.forEach((ResolutionDartType argument) {
-      inputs.add(typeBuilder.analyzeTypeArgument(argument, sourceElement,
-          sourceInformation: sourceInformation));
-    });
-  }
-
-  /// In checked mode checks the [type] of [node] to be well-bounded. The method
-  /// returns [:true:] if an error can be statically determined.
-  bool checkTypeVariableBounds(
-      ast.NewExpression node, ResolutionInterfaceType type) {
-    if (!options.enableTypeAssertions) return false;
-
-    Map<ResolutionDartType, Set<ResolutionDartType>> seenChecksMap =
-        new Map<ResolutionDartType, Set<ResolutionDartType>>();
-    bool definitelyFails = false;
-
-    void addTypeVariableBoundCheck(
-        InterfaceType _instance,
-        DartType _typeArgument,
-        TypeVariableType _typeVariable,
-        DartType _bound) {
-      if (definitelyFails) return;
-      ResolutionInterfaceType instance = _instance;
-      ResolutionDartType typeArgument = _typeArgument;
-      ResolutionTypeVariableType typeVariable = _typeVariable;
-      ResolutionDartType bound = _bound;
-
-      int subtypeRelation = types.computeSubtypeRelation(typeArgument, bound);
-      if (subtypeRelation == DartTypes.IS_SUBTYPE) return;
-
-      String prefix = "Can't create an instance of malbounded type '$type': '";
-      String infix = "' is not a subtype of bound '";
-      String suffix;
-
-      if (type == instance) {
-        suffix = "' of type variable '${typeVariable}' of type "
-            "'${type.element.thisType}'.";
-      } else {
-        suffix = "' of type variable '${typeVariable}' of type "
-            "'${instance.element.thisType}' on the supertype "
-            "'${instance}' of '${type}'.";
-      }
-
-      if (subtypeRelation == DartTypes.NOT_SUBTYPE) {
-        String message = "TypeError: $prefix$typeArgument$infix$bound$suffix";
-        generateTypeError(node, message);
-        definitelyFails = true;
-        return;
-      } else if (subtypeRelation == DartTypes.MAYBE_SUBTYPE) {
-        Set<ResolutionDartType> seenChecks = seenChecksMap.putIfAbsent(
-            typeArgument, () => new Set<ResolutionDartType>());
-        if (!seenChecks.contains(bound)) {
-          seenChecks.add(bound);
-          assertIsSubtype(node, typeArgument, bound, prefix, infix, suffix);
-        }
-      }
-    }
-
-    types.checkTypeVariableBounds(type, type.typeArguments,
-        type.element.typeVariables, addTypeVariableBoundCheck);
-    if (definitelyFails) {
-      return true;
-    }
-    for (ResolutionInterfaceType supertype in type.element.allSupertypes) {
-      ResolutionInterfaceType instance = type.asInstanceOf(supertype.element);
-      types.checkTypeVariableBounds(instance, instance.typeArguments,
-          instance.element.typeVariables, addTypeVariableBoundCheck);
-      if (definitelyFails) {
-        return true;
-      }
-    }
-    return false;
-  }
-
-  visitStaticSend(ast.Send node) {
-    internalError(node, "Unexpected visitStaticSend");
-  }
-
-  /// Generate an invocation to the static or top level [function].
-  void generateStaticFunctionInvoke(
-      ast.Send node, MethodElement function, CallStructure callStructure) {
-    List<HInstruction> inputs =
-        makeStaticArgumentList(callStructure, node.arguments, function);
-    pushInvokeStatic(node, function, inputs,
-        sourceInformation:
-            sourceInformationBuilder.buildCall(node.selector, node.selector));
-  }
-
-  /// Generate an invocation to a static or top level function with the wrong
-  /// number of arguments.
-  void generateStaticFunctionIncompatibleInvoke(
-      ast.Send node, Element element) {
-    generateWrongArgumentCountError(node, element, node.arguments);
-  }
-
-  @override
-  void visitStaticFieldInvoke(ast.Send node, FieldElement field,
-      ast.NodeList arguments, CallStructure callStructure, _) {
-    generateStaticFieldGet(node, field);
-    generateCallInvoke(
-        node,
-        pop(),
-        sourceInformationBuilder.buildCall(
-            node.argumentsNode, node.argumentsNode));
-  }
-
-  @override
-  void visitStaticFunctionInvoke(ast.Send node, MethodElement function,
-      ast.NodeList arguments, CallStructure callStructure, _) {
-    generateStaticFunctionInvoke(node, function, callStructure);
-  }
-
-  @override
-  void visitStaticFunctionIncompatibleInvoke(
-      ast.Send node,
-      MethodElement function,
-      ast.NodeList arguments,
-      CallStructure callStructure,
-      _) {
-    generateStaticFunctionIncompatibleInvoke(node, function);
-  }
-
-  @override
-  void visitStaticGetterInvoke(ast.Send node, FunctionElement getter,
-      ast.NodeList arguments, CallStructure callStructure, _) {
-    generateStaticGetterGet(node, getter);
-    generateCallInvoke(node, pop(),
-        sourceInformationBuilder.buildCall(node, node.argumentsNode));
-  }
-
-  @override
-  void visitTopLevelFieldInvoke(ast.Send node, FieldElement field,
-      ast.NodeList arguments, CallStructure callStructure, _) {
-    generateStaticFieldGet(node, field);
-    generateCallInvoke(node, pop(),
-        sourceInformationBuilder.buildCall(node, node.argumentsNode));
-  }
-
-  @override
-  void visitTopLevelFunctionInvoke(ast.Send node, MethodElement function,
-      ast.NodeList arguments, CallStructure callStructure, _) {
-    if (closedWorld.commonElements.isForeign(function)) {
-      handleForeignSend(node, function);
-    } else {
-      generateStaticFunctionInvoke(node, function, callStructure);
-    }
-  }
-
-  @override
-  void visitTopLevelFunctionIncompatibleInvoke(
-      ast.Send node,
-      MethodElement function,
-      ast.NodeList arguments,
-      CallStructure callStructure,
-      _) {
-    generateStaticFunctionIncompatibleInvoke(node, function);
-  }
-
-  @override
-  void visitTopLevelGetterInvoke(ast.Send node, FunctionElement getter,
-      ast.NodeList arguments, CallStructure callStructure, _) {
-    generateStaticGetterGet(node, getter);
-    generateCallInvoke(node, pop(),
-        sourceInformationBuilder.buildCall(node, node.argumentsNode));
-  }
-
-  @override
-  void visitTopLevelSetterGet(ast.Send node, MethodElement setter, _) {
-    handleInvalidStaticGet(node, setter);
-  }
-
-  @override
-  void visitStaticSetterGet(ast.Send node, MethodElement setter, _) {
-    handleInvalidStaticGet(node, setter);
-  }
-
-  @override
-  void visitUnresolvedGet(ast.Send node, Element element, _) {
-    generateStaticUnresolvedGet(node, element);
-  }
-
-  void handleInvalidStaticInvoke(ast.Send node, Element element) {
-    generateThrowNoSuchMethod(node, noSuchMethodTargetSymbolString(element),
-        argumentNodes: node.arguments);
-  }
-
-  @override
-  void visitStaticSetterInvoke(ast.Send node, MethodElement setter,
-      ast.NodeList arguments, CallStructure callStructure, _) {
-    handleInvalidStaticInvoke(node, setter);
-  }
-
-  @override
-  void visitTopLevelSetterInvoke(ast.Send node, MethodElement setter,
-      ast.NodeList arguments, CallStructure callStructure, _) {
-    handleInvalidStaticInvoke(node, setter);
-  }
-
-  @override
-  void visitUnresolvedInvoke(ast.Send node, Element element,
-      ast.NodeList arguments, Selector selector, _) {
-    if (element is ErroneousElement) {
-      // An erroneous element indicates that the function could not be
-      // resolved (a warning has been issued).
-      handleInvalidStaticInvoke(node, element);
-    } else {
-      // TODO(ahe): Do something like [generateWrongArgumentCountError].
-      stack.add(graph.addConstantNull(closedWorld));
-    }
-    return;
-  }
-
-  HConstant addConstantString(String string) {
-    return graph.addConstantString(string, closedWorld);
-  }
-
-  HConstant addConstantStringFromName(js.Name name) {
-    return graph.addConstantStringFromName(name, closedWorld);
-  }
-
-  visitClassTypeLiteralGet(ast.Send node, ConstantExpression constant, _) {
-    generateConstantTypeLiteral(node);
-  }
-
-  visitClassTypeLiteralInvoke(ast.Send node, ConstantExpression constant,
-      ast.NodeList arguments, CallStructure callStructure, _) {
-    generateConstantTypeLiteral(node);
-    generateTypeLiteralCall(node);
-  }
-
-  visitTypedefTypeLiteralGet(ast.Send node, ConstantExpression constant, _) {
-    generateConstantTypeLiteral(node);
-  }
-
-  visitTypedefTypeLiteralInvoke(ast.Send node, ConstantExpression constant,
-      ast.NodeList arguments, CallStructure callStructure, _) {
-    generateConstantTypeLiteral(node);
-    generateTypeLiteralCall(node);
-  }
-
-  visitTypeVariableTypeLiteralGet(
-      ast.Send node, TypeVariableElement element, _) {
-    generateTypeVariableLiteral(node, element.type);
-  }
-
-  visitTypeVariableTypeLiteralInvoke(ast.Send node, TypeVariableElement element,
-      ast.NodeList arguments, CallStructure callStructure, _) {
-    generateTypeVariableLiteral(node, element.type);
-    generateTypeLiteralCall(node);
-  }
-
-  visitDynamicTypeLiteralGet(ast.Send node, ConstantExpression constant, _) {
-    generateConstantTypeLiteral(node);
-  }
-
-  visitDynamicTypeLiteralInvoke(ast.Send node, ConstantExpression constant,
-      ast.NodeList arguments, CallStructure callStructure, _) {
-    generateConstantTypeLiteral(node);
-    generateTypeLiteralCall(node);
-  }
-
-  /// Generate the constant value for a constant type literal.
-  void generateConstantTypeLiteral(ast.Send node) {
-    // TODO(karlklose): add type representation
-    if (node.isCall) {
-      // The node itself is not a constant but we register the selector (the
-      // identifier that refers to the class/typedef) as a constant.
-      stack.add(addConstant(node.selector));
-    } else {
-      stack.add(addConstant(node));
-    }
-  }
-
-  /// Generate the literal for [typeVariable] in the current context.
-  void generateTypeVariableLiteral(
-      ast.Send node, ResolutionTypeVariableType typeVariable) {
-    // GENERIC_METHODS: This provides thin support for method type variables
-    // by treating them as malformed when evaluated as a literal. For full
-    // support of generic methods this must be revised.
-    if (typeVariable is MethodTypeVariableType) {
-      generateTypeError(node, "Method type variables are not reified");
-    } else {
-      ResolutionDartType type = localsHandler.substInContext(typeVariable);
-      HInstruction value = typeBuilder.analyzeTypeArgument(type, sourceElement,
-          sourceInformation: sourceInformationBuilder.buildGet(node));
-      pushInvokeStatic(node, commonElements.runtimeTypeToString, [value],
-          typeMask: commonMasks.stringType);
-      pushInvokeStatic(node, commonElements.createRuntimeType, [pop()]);
-    }
-  }
-
-  /// Generate a call to a type literal.
-  void generateTypeLiteralCall(ast.Send node) {
-    // This send is of the form 'e(...)', where e is resolved to a type
-    // reference. We create a regular closure call on the result of the type
-    // reference instead of creating a NoSuchMethodError to avoid pulling it
-    // in if it is not used (e.g., in a try/catch).
-    HInstruction target = pop();
-    generateCallInvoke(node, target,
-        sourceInformationBuilder.buildCall(node, node.argumentsNode));
-  }
-
-  /// Generate a '.call' invocation on [target].
-  void generateCallInvoke(
-      ast.Send node, HInstruction target, SourceInformation sourceInformation) {
-    Selector selector = elements.getSelector(node);
-    List<HInstruction> inputs = <HInstruction>[target];
-    addDynamicSendArgumentsToList(node, inputs);
-    push(new HInvokeClosure(new Selector.callClosureFrom(selector), inputs,
-        commonMasks.dynamicType, const <DartType>[])
-      ..sourceInformation = sourceInformation);
-  }
-
-  visitGetterSend(ast.Send node) {
-    internalError(node, "Unexpected visitGetterSend");
-  }
-
-  // TODO(antonm): migrate rest of SsaFromAstMixin to internalError.
-  internalError(Spannable node, String reason) {
-    reporter.internalError(node, reason);
-  }
-
-  void generateError(ast.Node node, String message, Element helper) {
-    HInstruction errorMessage = addConstantString(message);
-    pushInvokeStatic(node, helper, [errorMessage]);
-  }
-
-  void generateRuntimeError(ast.Node node, String message) {
-    MethodElement helper = commonElements.throwRuntimeError;
-    generateError(node, message, helper);
-  }
-
-  void generateUnsupportedError(ast.Node node, String message) {
-    MethodElement helper = commonElements.throwUnsupportedError;
-    generateError(node, message, helper);
-  }
-
-  void generateTypeError(ast.Node node, String message) {
-    MethodElement helper = commonElements.throwTypeError;
-    generateError(node, message, helper);
-  }
-
-  void generateAbstractClassInstantiationError(ast.Node node, String message) {
-    MethodElement helper = commonElements.throwAbstractClassInstantiationError;
-    generateError(node, message, helper);
-  }
-
-  void generateThrowNoSuchMethod(ast.Node diagnosticNode, String methodName,
-      {Link<ast.Node> argumentNodes,
-      List<HInstruction> argumentValues,
-      List<String> existingArguments,
-      SourceInformation sourceInformation}) {
-    MethodElement helper = commonElements.throwNoSuchMethod;
-    ConstantValue receiverConstant = constantSystem.createString('');
-    HInstruction receiver = graph.addConstant(receiverConstant, closedWorld);
-    ConstantValue nameConstant = constantSystem.createString(methodName);
-    HInstruction name = graph.addConstant(nameConstant, closedWorld);
-    if (argumentValues == null) {
-      argumentValues = <HInstruction>[];
-      argumentNodes.forEach((argumentNode) {
-        visit(argumentNode);
-        HInstruction value = pop();
-        argumentValues.add(value);
-      });
-    }
-    HInstruction arguments = buildLiteralList(argumentValues);
-    add(arguments);
-    HInstruction existingNamesList;
-    if (existingArguments != null) {
-      List<HInstruction> existingNames = <HInstruction>[];
-      for (String name in existingArguments) {
-        HInstruction nameConstant = graph.addConstantString(name, closedWorld);
-        existingNames.add(nameConstant);
-      }
-      existingNamesList = buildLiteralList(existingNames);
-      add(existingNamesList);
-    } else {
-      existingNamesList = graph.addConstantNull(closedWorld);
-    }
-    pushInvokeStatic(
-        diagnosticNode, helper, [receiver, name, arguments, existingNamesList],
-        sourceInformation: sourceInformation);
-  }
-
-  /**
-   * Generate code to throw a [NoSuchMethodError] exception for calling a
-   * method with a wrong number of arguments or mismatching named optional
-   * arguments.
-   */
-  void generateWrongArgumentCountError(ast.Node diagnosticNode,
-      FunctionElement function, Link<ast.Node> argumentNodes) {
-    List<String> existingArguments = <String>[];
-    FunctionSignature signature = function.functionSignature;
-    signature.forEachParameter((Element parameter) {
-      existingArguments.add(parameter.name);
-    });
-    generateThrowNoSuchMethod(diagnosticNode, function.name,
-        argumentNodes: argumentNodes, existingArguments: existingArguments);
-  }
-
-  @override
-  void bulkHandleNode(ast.Node node, String message, _) {
-    internalError(node, "Unexpected bulk handled node: $node");
-  }
-
-  @override
-  void bulkHandleNew(ast.NewExpression node, [_]) {
-    Element element = elements[node.send];
-    if (!Elements.isMalformed(element)) {
-      ConstructorElement function = element;
-      element = function.effectiveTarget;
-    }
-    final bool isSymbolConstructor =
-        element == commonElements.symbolConstructorTarget;
-    if (Elements.isError(element)) {
-      ErroneousElement error = element;
-      if (error.messageKind == MessageKind.CANNOT_FIND_CONSTRUCTOR ||
-          error.messageKind == MessageKind.CANNOT_FIND_UNNAMED_CONSTRUCTOR) {
-        generateThrowNoSuchMethod(
-            node.send, noSuchMethodTargetSymbolString(error, 'constructor'),
-            argumentNodes: node.send.arguments);
-      } else {
-        MessageTemplate template = MessageTemplate.TEMPLATES[error.messageKind];
-        Message message = template.message(error.messageArguments);
-        generateRuntimeError(node.send, message.toString());
-      }
-    } else if (Elements.isMalformed(element)) {
-      // TODO(ahe): Do something like [generateWrongArgumentCountError].
-      stack.add(graph.addConstantNull(closedWorld));
-    } else if (node.isConst) {
-      stack.add(addConstant(node));
-      if (isSymbolConstructor) {
-        ConstructedConstantValue symbol = getConstantForNode(node);
-        StringConstantValue stringConstant = symbol.fields.values.single;
-        String nameString = stringConstant.stringValue;
-        registry?.registerConstSymbol(nameString);
-      }
-    } else {
-      handleNewSend(node);
-    }
-  }
-
-  @override
-  void errorNonConstantConstructorInvoke(
-      ast.NewExpression node,
-      Element element,
-      ResolutionDartType type,
-      ast.NodeList arguments,
-      CallStructure callStructure,
-      _) {
-    bulkHandleNew(node);
-  }
-
-  void pushInvokeDynamic(ast.Node node, Selector selector, TypeMask mask,
-      List<HInstruction> arguments,
-      {SourceInformation sourceInformation}) {
-    // We prefer to not inline certain operations on indexables,
-    // because the constant folder will handle them better and turn
-    // them into simpler instructions that allow further
-    // optimizations.
-    bool isOptimizableOperationOnIndexable(Selector selector, Element element) {
-      bool isLength = selector.isGetter && selector.name == "length";
-      if (isLength || selector.isIndex) {
-        return closedWorld.isSubtypeOf(
-            element.enclosingClass, commonElements.jsIndexableClass);
-      } else if (selector.isIndexSet) {
-        return closedWorld.isSubtypeOf(
-            element.enclosingClass, commonElements.jsMutableIndexableClass);
-      } else {
-        return false;
-      }
-    }
-
-    bool isOptimizableOperation(Selector selector, MemberElement element) {
-      ClassElement cls = element.enclosingClass;
-      if (isOptimizableOperationOnIndexable(selector, element)) return true;
-      if (!interceptorData.interceptedClasses.contains(cls)) return false;
-      if (selector.isOperator) return true;
-      if (selector.isSetter) return true;
-      if (selector.isIndex) return true;
-      if (selector.isIndexSet) return true;
-      if (element == commonElements.jsArrayAdd ||
-          element == commonElements.jsArrayRemoveLast ||
-          commonElements.isJsStringSplit(element)) {
-        return true;
-      }
-      return false;
-    }
-
-    MemberElement element = closedWorld.locateSingleMember(selector, mask);
-    if (element != null &&
-        !element.isField &&
-        !(element.isGetter && selector.isCall) &&
-        !(element.isFunction && selector.isGetter) &&
-        !isOptimizableOperation(selector, element)) {
-      if (tryInlineMethod(element, selector, mask, arguments, node)) {
-        return;
-      }
-    }
-
-    HInstruction receiver = arguments[0];
-    List<HInstruction> inputs = <HInstruction>[];
-    bool isIntercepted = interceptorData.isInterceptedSelector(selector);
-    if (isIntercepted) {
-      inputs.add(invokeInterceptor(receiver));
-    }
-    inputs.addAll(arguments);
-    TypeMask type = TypeMaskFactory.inferredTypeForSelector(
-        selector, mask, globalInferenceResults);
-    if (selector.isGetter) {
-      push(new HInvokeDynamicGetter(selector, mask, null, inputs, isIntercepted,
-          type, sourceInformation));
-    } else if (selector.isSetter) {
-      push(new HInvokeDynamicSetter(selector, mask, null, inputs, isIntercepted,
-          type, sourceInformation));
-    } else {
-      push(new HInvokeDynamicMethod(
-          selector, mask, inputs, type, const <DartType>[], sourceInformation,
-          isIntercepted: isIntercepted));
-    }
-  }
-
-  HForeignCode invokeJsInteropFunction(MethodElement element,
-      List<HInstruction> arguments, SourceInformation sourceInformation) {
-    assert(nativeData.isJsInteropMember(element));
-    nativeEmitter.nativeMethods.add(element);
-
-    if (element.isFactoryConstructor &&
-        nativeData.isAnonymousJsInteropClass(element.contextClass)) {
-      // Factory constructor that is syntactic sugar for creating a JavaScript
-      // object literal.
-      ConstructorElement constructor = element;
-      FunctionSignature params = constructor.functionSignature;
-      int i = 0;
-      int positions = 0;
-      var filteredArguments = <HInstruction>[];
-      var parameterNameMap = new Map<String, js.Expression>();
-      params.orderedForEachParameter((_parameter) {
-        ParameterElement parameter = _parameter;
-        // TODO(jacobr): consider throwing if parameter names do not match
-        // names of properties in the class.
-        assert(parameter.isNamed);
-        HInstruction argument = arguments[i];
-        if (argument != null) {
-          filteredArguments.add(argument);
-          var jsName = nativeData.computeUnescapedJSInteropName(parameter.name);
-          parameterNameMap[jsName] = new js.InterpolatedExpression(positions++);
-        }
-        i++;
-      });
-      var codeTemplate =
-          new js.Template(null, js.objectLiteral(parameterNameMap));
-
-      var nativeBehavior = new native.NativeBehavior()
-        ..codeTemplate = codeTemplate;
-      if (options.trustJSInteropTypeAnnotations) {
-        nativeBehavior.typesReturned.add(constructor.enclosingClass.thisType);
-      }
-      return new HForeignCode(
-          codeTemplate, commonMasks.dynamicType, filteredArguments,
-          nativeBehavior: nativeBehavior)
-        ..sourceInformation = sourceInformation;
-    }
-    var target = new HForeignCode(
-        js.js.parseForeignJS("${nativeData.getFixedBackendMethodPath(element)}."
-            "${nativeData.getFixedBackendName(element)}"),
-        commonMasks.dynamicType,
-        <HInstruction>[]);
-    add(target);
-    // Strip off trailing arguments that were not specified.
-    // we could assert that the trailing arguments are all null.
-    // TODO(jacobr): rewrite named arguments to an object literal matching
-    // the factory constructor case.
-    arguments = arguments.where((arg) => arg != null).toList();
-    var inputs = <HInstruction>[target]..addAll(arguments);
-
-    var nativeBehavior = new native.NativeBehavior()
-      ..sideEffects.setAllSideEffects();
-
-    ResolutionDartType type = element.isConstructor
-        ? element.enclosingClass.thisType
-        : element.type.returnType;
-    // Native behavior effects here are similar to native/behavior.dart.
-    // The return type is dynamic if we don't trust js-interop type
-    // declarations.
-    nativeBehavior.typesReturned.add(options.trustJSInteropTypeAnnotations
-        ? type
-        : const ResolutionDynamicType());
-
-    // The allocation effects include the declared type if it is native (which
-    // includes js interop types).
-    if (type is ResolutionInterfaceType &&
-        nativeData.isNativeClass(type.element)) {
-      nativeBehavior.typesInstantiated.add(type);
-    }
-
-    // It also includes any other JS interop type if we don't trust the
-    // annotation or if is declared too broad.
-    if (!options.trustJSInteropTypeAnnotations ||
-        type.isObject ||
-        type.isDynamic) {
-      ClassElement cls = commonElements.jsJavaScriptObjectClass;
-      nativeBehavior.typesInstantiated.add(cls.thisType);
-    }
-
-    String code;
-    if (element.isGetter) {
-      code = "#";
-    } else if (element.isSetter) {
-      code = "# = #";
-    } else {
-      var args = new List.filled(arguments.length, '#').join(',');
-      code = element.isConstructor ? "new #($args)" : "#($args)";
-    }
-    js.Template codeTemplate = js.js.parseForeignJS(code);
-    nativeBehavior.codeTemplate = codeTemplate;
-
-    return new HForeignCode(codeTemplate, commonMasks.dynamicType, inputs,
-        nativeBehavior: nativeBehavior)
-      ..sourceInformation = sourceInformation;
-  }
-
-  void pushInvokeStatic(
-      ast.Node location, MethodElement element, List<HInstruction> arguments,
-      {TypeMask typeMask,
-      ResolutionInterfaceType instanceType,
-      SourceInformation sourceInformation}) {
-    assert(element.isDeclaration);
-    // TODO(johnniwinther): Use [sourceInformation] instead of [location].
-    if (tryInlineMethod(element, null, null, arguments, location,
-        instanceType: instanceType)) {
-      return;
-    }
-
-    if (typeMask == null) {
-      typeMask = TypeMaskFactory.inferredReturnTypeForElement(
-          element, globalInferenceResults);
-    }
-    bool targetCanThrow = !closedWorld.getCannotThrow(element);
-    // TODO(5346): Try to avoid the need for calling [declaration] before
-    var instruction;
-    if (nativeData.isJsInteropMember(element)) {
-      instruction =
-          invokeJsInteropFunction(element, arguments, sourceInformation);
-    } else {
-      // creating an [HInvokeStatic].
-      instruction = new HInvokeStatic(
-          element, arguments, typeMask, const <DartType>[],
-          targetCanThrow: targetCanThrow)
-        ..sourceInformation = sourceInformation;
-      if (currentInlinedInstantiations.isNotEmpty) {
-        instruction.instantiatedTypes = new List<ResolutionInterfaceType>.from(
-            currentInlinedInstantiations);
-      }
-      instruction.sideEffects = closedWorld.getSideEffectsOfElement(element);
-    }
-    if (sourceInformation != null || location == null) {
-      push(instruction);
-    } else {
-      pushWithPosition(instruction, location);
-    }
-  }
-
-  HInstruction buildInvokeSuper(Selector selector, MemberElement element,
-      List<HInstruction> arguments, SourceInformation sourceInformation) {
-    HInstruction receiver =
-        localsHandler.readThis(sourceInformation: sourceInformation);
-    // TODO(5346): Try to avoid the need for calling [declaration] before
-    // creating an [HStatic].
-    List<HInstruction> inputs = <HInstruction>[];
-    // Fields don't need an interceptor; consider generating HFieldGet/Set instead.
-
-    bool isIntercepted = interceptorData.isInterceptedSelector(selector) &&
-        element.kind != ElementKind.FIELD;
-    if (isIntercepted) {
-      inputs.add(invokeInterceptor(receiver));
-    }
-    inputs.add(receiver);
-    inputs.addAll(arguments);
-    TypeMask type;
-    if (!element.isGetter && selector.isGetter) {
-      type = TypeMaskFactory.inferredTypeForMember(
-          element, globalInferenceResults);
-    } else if (element.isFunction) {
-      MethodElement method = element;
-      type = TypeMaskFactory.inferredReturnTypeForElement(
-          method, globalInferenceResults);
-    } else {
-      type = closedWorld.abstractValueDomain.dynamicType;
-    }
-    HInstruction instruction = new HInvokeSuper(
-        element,
-        currentNonClosureClass,
-        selector,
-        inputs,
-        isIntercepted,
-        type,
-        const <DartType>[],
-        sourceInformation,
-        isSetter: selector.isSetter || selector.isIndexSet);
-    instruction.sideEffects =
-        closedWorld.getSideEffectsOfSelector(selector, null);
-    return instruction;
-  }
-
-  void handleComplexOperatorSend(
-      ast.SendSet node, HInstruction receiver, Link<ast.Node> arguments) {
-    HInstruction rhs;
-    if (node.isPrefix || node.isPostfix) {
-      rhs = graph.addConstantInt(1, closedWorld);
-    } else {
-      visit(arguments.head);
-      assert(arguments.tail.isEmpty);
-      rhs = pop();
-    }
-    visitBinarySend(
-        receiver,
-        rhs,
-        elements.getOperatorSelectorInComplexSendSet(node),
-        elementInferenceResults.typeOfOperator(node),
-        node,
-        sourceInformation:
-            sourceInformationBuilder.buildGeneric(node.assignmentOperator));
-  }
-
-  void handleSuperSendSet(ast.SendSet node) {
-    MemberElement element = elements[node];
-    List<HInstruction> setterInputs = <HInstruction>[];
-    void generateSuperSendSet() {
-      Selector setterSelector = elements.getSelector(node);
-      if (Elements.isUnresolved(element) || !setterSelector.applies(element)) {
-        generateSuperNoSuchMethodSend(node, setterSelector, setterInputs);
-        pop();
-      } else {
-        add(buildInvokeSuper(setterSelector, element, setterInputs,
-            sourceInformationBuilder.buildAssignment(node)));
-      }
-    }
-
-    if (identical(node.assignmentOperator.source, '=')) {
-      addDynamicSendArgumentsToList(node, setterInputs);
-      generateSuperSendSet();
-      stack.add(setterInputs.last);
-    } else {
-      Element getter = elements[node.selector];
-      List<HInstruction> getterInputs = <HInstruction>[];
-      Link<ast.Node> arguments = node.arguments;
-      if (node.isIndex) {
-        // If node is of the form [:super.foo[0] += 2:], the send has
-        // two arguments: the index and the left hand side. We get
-        // the index and add it as input of the getter and the
-        // setter.
-        visit(arguments.head);
-        arguments = arguments.tail;
-        HInstruction index = pop();
-        getterInputs.add(index);
-        setterInputs.add(index);
-      }
-      HInstruction getterInstruction;
-      Selector getterSelector =
-          elements.getGetterSelectorInComplexSendSet(node);
-      if (Elements.isUnresolved(getter)) {
-        generateSuperNoSuchMethodSend(node, getterSelector, getterInputs);
-        getterInstruction = pop();
-      } else {
-        getterInstruction = buildInvokeSuper(getterSelector, getter,
-            getterInputs, sourceInformationBuilder.buildGet(node));
-        add(getterInstruction);
-      }
-
-      if (node.isIfNullAssignment) {
-        SsaBranchBuilder brancher = new SsaBranchBuilder(this, node);
-        brancher.handleIfNull(() => stack.add(getterInstruction), () {
-          addDynamicSendArgumentsToList(node, setterInputs);
-          generateSuperSendSet();
-          stack.add(setterInputs.last);
-        });
-      } else {
-        handleComplexOperatorSend(node, getterInstruction, arguments);
-        setterInputs.add(pop());
-        generateSuperSendSet();
-        stack.add(node.isPostfix ? getterInstruction : setterInputs.last);
-      }
-    }
-  }
-
-  @override
-  void handleSuperCompounds(
-      ast.SendSet node,
-      Element getter,
-      CompoundGetter getterKind,
-      Element setter,
-      CompoundSetter setterKind,
-      CompoundRhs rhs,
-      _) {
-    handleSuperSendSet(node);
-  }
-
-  @override
-  void visitFinalSuperFieldSet(
-      ast.SendSet node, FieldElement field, ast.Node rhs, _) {
-    handleSuperSendSet(node);
-  }
-
-  @override
-  void visitSuperFieldSet(
-      ast.SendSet node, FieldElement field, ast.Node rhs, _) {
-    handleSuperSendSet(node);
-  }
-
-  @override
-  void visitSuperGetterSet(
-      ast.SendSet node, FunctionElement getter, ast.Node rhs, _) {
-    handleSuperSendSet(node);
-  }
-
-  @override
-  void visitSuperIndexSet(ast.SendSet node, FunctionElement function,
-      ast.Node index, ast.Node rhs, _) {
-    handleSuperSendSet(node);
-  }
-
-  @override
-  void visitSuperMethodSet(
-      ast.SendSet node, MethodElement method, ast.Node rhs, _) {
-    handleSuperSendSet(node);
-  }
-
-  @override
-  void visitSuperSetterSet(
-      ast.SendSet node, FunctionElement setter, ast.Node rhs, _) {
-    handleSuperSendSet(node);
-  }
-
-  @override
-  void visitUnresolvedSuperIndexSet(ast.SendSet node, ErroneousElement element,
-      ast.Node index, ast.Node rhs, _) {
-    handleSuperSendSet(node);
-  }
-
-  @override
-  void visitSuperIndexPrefix(
-      ast.Send node,
-      MethodElement indexFunction,
-      MethodElement indexSetFunction,
-      ast.Node index,
-      IncDecOperator operator,
-      _) {
-    handleSuperSendSet(node);
-  }
-
-  @override
-  void visitSuperIndexPostfix(
-      ast.Send node,
-      MethodElement indexFunction,
-      MethodElement indexSetFunction,
-      ast.Node index,
-      IncDecOperator operator,
-      _) {
-    handleSuperSendSet(node);
-  }
-
-  @override
-  void visitUnresolvedSuperGetterIndexPrefix(ast.SendSet node, Element element,
-      MethodElement setter, ast.Node index, IncDecOperator operator, _) {
-    handleSuperSendSet(node);
-  }
-
-  @override
-  void visitUnresolvedSuperGetterIndexPostfix(ast.SendSet node, Element element,
-      MethodElement setter, ast.Node index, IncDecOperator operator, _) {
-    handleSuperSendSet(node);
-  }
-
-  @override
-  void visitUnresolvedSuperSetterIndexPrefix(
-      ast.SendSet node,
-      MethodElement indexFunction,
-      Element element,
-      ast.Node index,
-      IncDecOperator operator,
-      _) {
-    handleSuperSendSet(node);
-  }
-
-  @override
-  void visitUnresolvedSuperSetterIndexPostfix(
-      ast.SendSet node,
-      MethodElement indexFunction,
-      Element element,
-      ast.Node index,
-      IncDecOperator operator,
-      _) {
-    handleSuperSendSet(node);
-  }
-
-  @override
-  void visitUnresolvedSuperIndexPrefix(ast.Send node, Element element,
-      ast.Node index, IncDecOperator operator, _) {
-    handleSuperSendSet(node);
-  }
-
-  @override
-  void visitUnresolvedSuperIndexPostfix(ast.Send node, Element element,
-      ast.Node index, IncDecOperator operator, _) {
-    handleSuperSendSet(node);
-  }
-
-  @override
-  void visitSuperCompoundIndexSet(
-      ast.SendSet node,
-      MethodElement getter,
-      MethodElement setter,
-      ast.Node index,
-      AssignmentOperator operator,
-      ast.Node rhs,
-      _) {
-    handleSuperSendSet(node);
-  }
-
-  @override
-  void visitUnresolvedSuperGetterCompoundIndexSet(
-      ast.SendSet node,
-      Element element,
-      MethodElement setter,
-      ast.Node index,
-      AssignmentOperator operator,
-      ast.Node rhs,
-      _) {
-    handleSuperSendSet(node);
-  }
-
-  @override
-  void visitUnresolvedSuperSetterCompoundIndexSet(
-      ast.SendSet node,
-      MethodElement getter,
-      Element element,
-      ast.Node index,
-      AssignmentOperator operator,
-      ast.Node rhs,
-      _) {
-    handleSuperSendSet(node);
-  }
-
-  @override
-  void visitUnresolvedSuperCompoundIndexSet(ast.SendSet node, Element element,
-      ast.Node index, AssignmentOperator operator, ast.Node rhs, _) {
-    handleSuperSendSet(node);
-  }
-
-  @override
-  void visitSuperFieldCompound(ast.Send node, FieldElement field,
-      AssignmentOperator operator, ast.Node rhs, _) {
-    handleSuperSendSet(node);
-  }
-
-  @override
-  void visitFinalSuperFieldCompound(ast.Send node, FieldElement field,
-      AssignmentOperator operator, ast.Node rhs, _) {
-    handleSuperSendSet(node);
-  }
-
-  @override
-  void visitFinalSuperFieldPrefix(
-      ast.Send node, FieldElement field, IncDecOperator operator, _) {
-    handleSuperSendSet(node);
-  }
-
-  @override
-  void visitUnresolvedSuperPrefix(
-      ast.SendSet node, Element element, IncDecOperator operator, _) {
-    handleSuperSendSet(node);
-  }
-
-  @override
-  void visitUnresolvedSuperPostfix(
-      ast.SendSet node, Element element, IncDecOperator operator, _) {
-    handleSuperSendSet(node);
-  }
-
-  @override
-  void visitUnresolvedSuperCompound(ast.Send node, Element element,
-      AssignmentOperator operator, ast.Node rhs, _) {
-    handleSuperSendSet(node);
-  }
-
-  @override
-  void visitFinalSuperFieldPostfix(
-      ast.Send node, FieldElement field, IncDecOperator operator, _) {
-    handleSuperSendSet(node);
-  }
-
-  @override
-  void visitSuperFieldFieldCompound(ast.Send node, FieldElement readField,
-      FieldElement writtenField, AssignmentOperator operator, ast.Node rhs, _) {
-    handleSuperSendSet(node);
-  }
-
-  @override
-  void visitSuperGetterSetterCompound(ast.Send node, FunctionElement getter,
-      FunctionElement setter, AssignmentOperator operator, ast.Node rhs, _) {
-    handleSuperSendSet(node);
-  }
-
-  @override
-  void visitSuperMethodSetterCompound(ast.Send node, FunctionElement method,
-      FunctionElement setter, AssignmentOperator operator, ast.Node rhs, _) {
-    handleSuperSendSet(node);
-  }
-
-  @override
-  void visitSuperMethodCompound(ast.Send node, MethodElement method,
-      AssignmentOperator operator, ast.Node rhs, _) {
-    handleSuperSendSet(node);
-  }
-
-  @override
-  void visitUnresolvedSuperGetterCompound(ast.SendSet node, Element element,
-      SetterElement setter, AssignmentOperator operator, ast.Node rhs, _) {
-    handleSuperSendSet(node);
-  }
-
-  @override
-  void visitUnresolvedSuperSetterCompound(ast.Send node, GetterElement getter,
-      Element element, AssignmentOperator operator, ast.Node rhs, _) {
-    handleSuperSendSet(node);
-  }
-
-  @override
-  void visitSuperFieldSetterCompound(ast.Send node, FieldElement field,
-      FunctionElement setter, AssignmentOperator operator, ast.Node rhs, _) {
-    handleSuperSendSet(node);
-  }
-
-  @override
-  void visitSuperGetterFieldCompound(ast.Send node, FunctionElement getter,
-      FieldElement field, AssignmentOperator operator, ast.Node rhs, _) {
-    handleSuperSendSet(node);
-  }
-
-  @override
-  void visitIndexSet(
-      ast.SendSet node, ast.Node receiver, ast.Node index, ast.Node rhs, _) {
-    generateDynamicSend(node);
-  }
-
-  @override
-  void visitCompoundIndexSet(ast.SendSet node, ast.Node receiver,
-      ast.Node index, AssignmentOperator operator, ast.Node rhs, _) {
-    generateIsDeferredLoadedCheckOfSend(node);
-    handleIndexSendSet(node);
-  }
-
-  @override
-  void visitIndexPrefix(ast.Send node, ast.Node receiver, ast.Node index,
-      IncDecOperator operator, _) {
-    generateIsDeferredLoadedCheckOfSend(node);
-    handleIndexSendSet(node);
-  }
-
-  @override
-  void visitIndexPostfix(ast.Send node, ast.Node receiver, ast.Node index,
-      IncDecOperator operator, _) {
-    generateIsDeferredLoadedCheckOfSend(node);
-    handleIndexSendSet(node);
-  }
-
-  void handleIndexSendSet(ast.SendSet node) {
-    ast.Operator op = node.assignmentOperator;
-    if ("=" == op.source) {
-      internalError(node, "Unexpected index set.");
-    } else {
-      visit(node.receiver);
-      HInstruction receiver = pop();
-      Link<ast.Node> arguments = node.arguments;
-      HInstruction index;
-      if (node.isIndex) {
-        visit(arguments.head);
-        arguments = arguments.tail;
-        index = pop();
-      }
-
-      pushInvokeDynamic(node, elements.getGetterSelectorInComplexSendSet(node),
-          elementInferenceResults.typeOfGetter(node), [receiver, index]);
-      HInstruction getterInstruction = pop();
-      if (node.isIfNullAssignment) {
-        // Compile x[i] ??= e as:
-        //   t1 = x[i]
-        //   if (t1 == null)
-        //      t1 = x[i] = e;
-        //   result = t1
-        SsaBranchBuilder brancher = new SsaBranchBuilder(this, node);
-        brancher.handleIfNull(() => stack.add(getterInstruction), () {
-          visit(arguments.head);
-          HInstruction value = pop();
-          pushInvokeDynamic(
-              node,
-              elements.getSelector(node),
-              elementInferenceResults.typeOfSend(node),
-              [receiver, index, value]);
-          pop();
-          stack.add(value);
-        });
-      } else {
-        handleComplexOperatorSend(node, getterInstruction, arguments);
-        HInstruction value = pop();
-        pushInvokeDynamic(node, elements.getSelector(node),
-            elementInferenceResults.typeOfSend(node), [receiver, index, value]);
-        pop();
-        if (node.isPostfix) {
-          stack.add(getterInstruction);
-        } else {
-          stack.add(value);
-        }
-      }
-    }
-  }
-
-  @override
-  void visitThisPropertySet(ast.SendSet node, Name name, ast.Node rhs, _) {
-    generateInstanceSetterWithCompiledReceiver(
-        node,
-        localsHandler.readThis(
-            sourceInformation: sourceInformationBuilder.buildGet(node)),
-        visitAndPop(rhs));
-  }
-
-  @override
-  void visitDynamicPropertySet(
-      ast.SendSet node, ast.Node receiver, Name name, ast.Node rhs, _) {
-    generateInstanceSetterWithCompiledReceiver(
-        node, generateInstanceSendReceiver(node), visitAndPop(rhs));
-  }
-
-  @override
-  void visitIfNotNullDynamicPropertySet(
-      ast.SendSet node, ast.Node receiver, Name name, ast.Node rhs, _) {
-    // compile e?.x = e2 to:
-    //
-    // t1 = e
-    // if (t1 == null)
-    //   result = t1 // same as result = null
-    // else
-    //   result = e.x = e2
-    HInstruction receiverInstruction;
-    SsaBranchBuilder brancher = new SsaBranchBuilder(this, node);
-    brancher.handleConditional(
-        () {
-          receiverInstruction = generateInstanceSendReceiver(node);
-          pushCheckNull(receiverInstruction);
-        },
-        () => stack.add(receiverInstruction),
-        () {
-          generateInstanceSetterWithCompiledReceiver(
-              node, receiverInstruction, visitAndPop(rhs));
-        });
-  }
-
-  @override
-  void visitParameterSet(
-      ast.SendSet node, ParameterElement parameter, ast.Node rhs, _) {
-    generateNonInstanceSetter(node, parameter, visitAndPop(rhs));
-  }
-
-  @override
-  void visitFinalParameterSet(
-      ast.SendSet node, ParameterElement parameter, ast.Node rhs, _) {
-    generateNoSuchSetter(node, parameter, visitAndPop(rhs));
-  }
-
-  @override
-  void visitLocalVariableSet(
-      ast.SendSet node, LocalVariableElement variable, ast.Node rhs, _) {
-    generateNonInstanceSetter(node, variable, visitAndPop(rhs));
-  }
-
-  @override
-  void visitFinalLocalVariableSet(
-      ast.SendSet node, LocalVariableElement variable, ast.Node rhs, _) {
-    generateNoSuchSetter(node, variable, visitAndPop(rhs));
-  }
-
-  @override
-  void visitLocalFunctionSet(
-      ast.SendSet node, LocalFunctionElement function, ast.Node rhs, _) {
-    generateNoSuchSetter(node, function, visitAndPop(rhs));
-  }
-
-  @override
-  void visitTopLevelFieldSet(
-      ast.SendSet node, FieldElement field, ast.Node rhs, _) {
-    generateIsDeferredLoadedCheckOfSend(node);
-    generateNonInstanceSetter(node, field, visitAndPop(rhs));
-  }
-
-  @override
-  void visitFinalTopLevelFieldSet(
-      ast.SendSet node, FieldElement field, ast.Node rhs, _) {
-    generateIsDeferredLoadedCheckOfSend(node);
-    generateNoSuchSetter(node, field, visitAndPop(rhs));
-  }
-
-  @override
-  void visitTopLevelGetterSet(
-      ast.SendSet node, GetterElement getter, ast.Node rhs, _) {
-    generateIsDeferredLoadedCheckOfSend(node);
-    generateNoSuchSetter(node, getter, visitAndPop(rhs));
-  }
-
-  @override
-  void visitTopLevelSetterSet(
-      ast.SendSet node, SetterElement setter, ast.Node rhs, _) {
-    generateIsDeferredLoadedCheckOfSend(node);
-    generateNonInstanceSetter(node, setter, visitAndPop(rhs));
-  }
-
-  @override
-  void visitTopLevelFunctionSet(
-      ast.SendSet node, MethodElement function, ast.Node rhs, _) {
-    generateIsDeferredLoadedCheckOfSend(node);
-    generateNoSuchSetter(node, function, visitAndPop(rhs));
-  }
-
-  @override
-  void visitStaticFieldSet(
-      ast.SendSet node, FieldElement field, ast.Node rhs, _) {
-    generateIsDeferredLoadedCheckOfSend(node);
-    generateNonInstanceSetter(node, field, visitAndPop(rhs));
-  }
-
-  @override
-  void visitFinalStaticFieldSet(
-      ast.SendSet node, FieldElement field, ast.Node rhs, _) {
-    generateIsDeferredLoadedCheckOfSend(node);
-    generateNoSuchSetter(node, field, visitAndPop(rhs));
-  }
-
-  @override
-  void visitStaticGetterSet(
-      ast.SendSet node, GetterElement getter, ast.Node rhs, _) {
-    generateIsDeferredLoadedCheckOfSend(node);
-    generateNoSuchSetter(node, getter, visitAndPop(rhs));
-  }
-
-  @override
-  void visitStaticSetterSet(
-      ast.SendSet node, SetterElement setter, ast.Node rhs, _) {
-    generateIsDeferredLoadedCheckOfSend(node);
-    generateNonInstanceSetter(node, setter, visitAndPop(rhs));
-  }
-
-  @override
-  void visitStaticFunctionSet(
-      ast.SendSet node, MethodElement function, ast.Node rhs, _) {
-    generateIsDeferredLoadedCheckOfSend(node);
-    generateNoSuchSetter(node, function, visitAndPop(rhs));
-  }
-
-  @override
-  void visitUnresolvedSet(ast.SendSet node, Element element, ast.Node rhs, _) {
-    generateIsDeferredLoadedCheckOfSend(node);
-    generateNonInstanceSetter(node, element, visitAndPop(rhs));
-  }
-
-  @override
-  void visitClassTypeLiteralSet(
-      ast.SendSet node, TypeConstantExpression constant, ast.Node rhs, _) {
-    generateThrowNoSuchMethod(node, constant.name,
-        argumentNodes: node.arguments);
-  }
-
-  @override
-  void visitTypedefTypeLiteralSet(
-      ast.SendSet node, TypeConstantExpression constant, ast.Node rhs, _) {
-    generateThrowNoSuchMethod(node, constant.name,
-        argumentNodes: node.arguments);
-  }
-
-  @override
-  void visitDynamicTypeLiteralSet(
-      ast.SendSet node, TypeConstantExpression constant, ast.Node rhs, _) {
-    generateThrowNoSuchMethod(node, constant.name,
-        argumentNodes: node.arguments);
-  }
-
-  @override
-  void visitTypeVariableTypeLiteralSet(
-      ast.SendSet node, TypeVariableElement element, ast.Node rhs, _) {
-    generateThrowNoSuchMethod(node, element.name,
-        argumentNodes: node.arguments);
-  }
-
-  void handleCompoundSendSet(ast.SendSet node) {
-    Element element = elements[node];
-    Element getter = elements[node.selector];
-
-    if (!Elements.isUnresolved(getter) && getter.impliesType) {
-      if (node.isIfNullAssignment) {
-        // C ??= x is compiled just as C.
-        stack.add(addConstant(node.selector));
-      } else {
-        ast.Identifier selector = node.selector;
-        generateThrowNoSuchMethod(node, selector.source,
-            argumentNodes: node.arguments);
-      }
-      return;
-    }
-
-    if (Elements.isInstanceSend(node, elements)) {
-      void generateAssignment(HInstruction receiver) {
-        // desugars `e.x op= e2` to `e.x = e.x op e2`
-        generateInstanceGetterWithCompiledReceiver(
-            node,
-            elements.getGetterSelectorInComplexSendSet(node),
-            elementInferenceResults.typeOfGetter(node),
-            receiver);
-        HInstruction getterInstruction = pop();
-        if (node.isIfNullAssignment) {
-          SsaBranchBuilder brancher = new SsaBranchBuilder(this, node);
-          brancher.handleIfNull(() => stack.add(getterInstruction), () {
-            visit(node.arguments.head);
-            generateInstanceSetterWithCompiledReceiver(node, receiver, pop());
-          });
-        } else {
-          handleComplexOperatorSend(node, getterInstruction, node.arguments);
-          HInstruction value = pop();
-          generateInstanceSetterWithCompiledReceiver(node, receiver, value);
-        }
-        if (node.isPostfix) {
-          pop();
-          stack.add(getterInstruction);
-        }
-      }
-
-      if (node.isConditional) {
-        // generate `e?.x op= e2` as:
-        //   t1 = e
-        //   t1 == null ? t1 : (t1.x = t1.x op e2);
-        HInstruction receiver;
-        SsaBranchBuilder brancher = new SsaBranchBuilder(this, node);
-        brancher.handleConditional(() {
-          receiver = generateInstanceSendReceiver(node);
-          pushCheckNull(receiver);
-        }, () => stack.add(receiver), () => generateAssignment(receiver));
-      } else {
-        generateAssignment(generateInstanceSendReceiver(node));
-      }
-      return;
-    }
-
-    if (getter.isMalformed) {
-      generateStaticUnresolvedGet(node, getter);
-    } else if (getter.isField) {
-      generateStaticFieldGet(node, getter);
-    } else if (getter.isGetter) {
-      generateStaticGetterGet(node, getter);
-    } else if (getter.isFunction) {
-      generateStaticFunctionGet(node, getter);
-    } else if (getter.isLocal) {
-      handleLocalGet(node, getter);
-    } else {
-      internalError(node, "Unexpected getter: $getter");
-    }
-    HInstruction getterInstruction = pop();
-    if (node.isIfNullAssignment) {
-      SsaBranchBuilder brancher = new SsaBranchBuilder(this, node);
-      brancher.handleIfNull(() => stack.add(getterInstruction), () {
-        visit(node.arguments.head);
-        generateNonInstanceSetter(node, element, pop());
-      });
-    } else {
-      handleComplexOperatorSend(node, getterInstruction, node.arguments);
-      HInstruction value = pop();
-      generateNonInstanceSetter(node, element, value);
-    }
-    if (node.isPostfix) {
-      pop();
-      stack.add(getterInstruction);
-    }
-  }
-
-  @override
-  void handleDynamicCompounds(
-      ast.Send node, ast.Node receiver, Name name, CompoundRhs rhs, _) {
-    handleCompoundSendSet(node);
-  }
-
-  @override
-  void handleLocalCompounds(
-      ast.SendSet node, LocalElement local, CompoundRhs rhs, _,
-      {bool isSetterValid}) {
-    handleCompoundSendSet(node);
-  }
-
-  @override
-  void handleStaticCompounds(
-      ast.SendSet node,
-      Element getter,
-      CompoundGetter getterKind,
-      Element setter,
-      CompoundSetter setterKind,
-      CompoundRhs rhs,
-      _) {
-    handleCompoundSendSet(node);
-  }
-
-  @override
-  handleDynamicSetIfNulls(
-      ast.Send node, ast.Node receiver, Name name, ast.Node rhs, arg) {
-    handleCompoundSendSet(node);
-  }
-
-  @override
-  handleLocalSetIfNulls(ast.SendSet node, LocalElement local, ast.Node rhs, arg,
-      {bool isSetterValid}) {
-    handleCompoundSendSet(node);
-  }
-
-  @override
-  handleStaticSetIfNulls(
-      ast.SendSet node,
-      Element getter,
-      CompoundGetter getterKind,
-      Element setter,
-      CompoundSetter setterKind,
-      ast.Node rhs,
-      arg) {
-    handleCompoundSendSet(node);
-  }
-
-  @override
-  handleSuperSetIfNulls(
-      ast.SendSet node,
-      Element getter,
-      CompoundGetter getterKind,
-      Element setter,
-      CompoundSetter setterKind,
-      ast.Node rhs,
-      arg) {
-    handleSuperSendSet(node);
-  }
-
-  @override
-  handleSuperIndexSetIfNull(ast.SendSet node, Element indexFunction,
-      Element indexSetFunction, ast.Node index, ast.Node rhs, arg,
-      {bool isGetterValid, bool isSetterValid}) {
-    handleCompoundSendSet(node);
-  }
-
-  @override
-  visitIndexSetIfNull(
-      ast.SendSet node, ast.Node receiver, ast.Node index, ast.Node rhs, arg,
-      {bool isGetterValid, bool isSetterValid}) {
-    generateIsDeferredLoadedCheckOfSend(node);
-    handleIndexSendSet(node);
-  }
-
-  @override
-  handleTypeLiteralConstantSetIfNulls(
-      ast.SendSet node, ConstantExpression constant, ast.Node rhs, arg) {
-    // The type variable is never `null`.
-    generateConstantTypeLiteral(node);
-  }
-
-  @override
-  visitTypeVariableTypeLiteralSetIfNull(
-      ast.Send node, TypeVariableElement element, ast.Node rhs, arg) {
-    // The type variable is never `null`.
-    generateTypeVariableLiteral(node, element.type);
-  }
-
-  void visitLiteralInt(ast.LiteralInt node) {
-    stack.add(graph.addConstantInt(node.value, closedWorld));
-  }
-
-  void visitLiteralDouble(ast.LiteralDouble node) {
-    stack.add(graph.addConstantDouble(node.value, closedWorld));
-  }
-
-  void visitLiteralBool(ast.LiteralBool node) {
-    stack.add(graph.addConstantBool(node.value, closedWorld));
-  }
-
-  void visitLiteralString(ast.LiteralString node) {
-    stack.add(
-        graph.addConstantString(node.dartString.slowToString(), closedWorld));
-  }
-
-  void visitLiteralSymbol(ast.LiteralSymbol node) {
-    stack.add(addConstant(node));
-    registry?.registerConstSymbol(node.slowNameString);
-  }
-
-  void visitStringJuxtaposition(ast.StringJuxtaposition node) {
-    if (!node.isInterpolation) {
-      // This is a simple string with no interpolations.
-      stack.add(
-          graph.addConstantString(node.dartString.slowToString(), closedWorld));
-      return;
-    }
-    StringBuilderVisitor stringBuilder = new StringBuilderVisitor(this, node);
-    stringBuilder.visit(node);
-    stack.add(stringBuilder.result);
-  }
-
-  void visitLiteralNull(ast.LiteralNull node) {
-    stack.add(graph.addConstantNull(closedWorld));
-  }
-
-  visitNodeList(ast.NodeList node) {
-    for (Link<ast.Node> link = node.nodes; !link.isEmpty; link = link.tail) {
-      if (isAborted()) {
-        reporter.reportHintMessage(
-            link.head, MessageKind.GENERIC, {'text': 'dead code'});
-      } else {
-        visit(link.head);
-      }
-    }
-  }
-
-  void visitParenthesizedExpression(ast.ParenthesizedExpression node) {
-    visit(node.expression);
-  }
-
-  visitOperator(ast.Operator node) {
-    // Operators are intercepted in their surrounding Send nodes.
-    reporter.internalError(
-        node, 'SsaBuilder.visitOperator should not be called.');
-  }
-
-  visitCascade(ast.Cascade node) {
-    visit(node.expression);
-    // Remove the result and reveal the duplicated receiver on the stack.
-    pop();
-  }
-
-  visitCascadeReceiver(ast.CascadeReceiver node) {
-    visit(node.expression);
-    dup();
-  }
-
-  visitRethrow(ast.Rethrow node) {
-    HInstruction exception = rethrowableException;
-    if (exception == null) {
-      exception = graph.addConstantNull(closedWorld);
-      reporter.internalError(node, 'rethrowableException should not be null.');
-    }
-    handleInTryStatement();
-    closeAndGotoExit(new HThrow(abstractValueDomain, exception,
-        sourceInformationBuilder.buildThrow(node),
-        isRethrow: true));
-  }
-
-  visitRedirectingFactoryBody(ast.RedirectingFactoryBody node) {
-    ConstructorElement targetConstructor =
-        elements.getRedirectingTargetConstructor(node).implementation;
-    ConstructorElement redirectingConstructor = sourceElement.implementation;
-    List<HInstruction> inputs = <HInstruction>[];
-    FunctionSignature targetSignature = targetConstructor.functionSignature;
-    FunctionSignature redirectingSignature =
-        redirectingConstructor.functionSignature;
-
-    List<Element> targetRequireds = targetSignature.requiredParameters;
-    List<Element> redirectingRequireds =
-        redirectingSignature.requiredParameters;
-
-    List<Element> targetOptionals = targetSignature.orderedOptionalParameters;
-    List<Element> redirectingOptionals =
-        redirectingSignature.orderedOptionalParameters;
-
-    // TODO(25579): This code can do the wrong thing redirecting constructor and
-    // the target do not correspond. It is correct if there is no
-    // warning. Ideally the redirecting constructor and the target would be the
-    // same function.
-
-    void loadLocal(ParameterElement parameter) {
-      inputs.add(localsHandler.readLocal(parameter));
-    }
-
-    void loadPosition(int position, ParameterElement optionalParameter) {
-      if (position < redirectingRequireds.length) {
-        loadLocal(redirectingRequireds[position]);
-      } else if (position < redirectingSignature.parameterCount &&
-          !redirectingSignature.optionalParametersAreNamed) {
-        loadLocal(redirectingOptionals[position - redirectingRequireds.length]);
-      } else if (optionalParameter != null) {
-        inputs.add(handleConstantForOptionalParameter(optionalParameter));
-      } else {
-        // Wrong.
-        inputs.add(graph.addConstantNull(closedWorld));
-      }
-    }
-
-    int position = 0;
-
-    for (ParameterElement _ in targetRequireds) {
-      loadPosition(position++, null);
-    }
-
-    if (targetOptionals.isNotEmpty) {
-      if (targetSignature.optionalParametersAreNamed) {
-        for (ParameterElement parameter in targetOptionals) {
-          ParameterElement redirectingParameter = redirectingOptionals
-              .firstWhere((p) => p.name == parameter.name, orElse: () => null);
-          if (redirectingParameter == null) {
-            inputs.add(handleConstantForOptionalParameter(parameter));
-          } else {
-            inputs.add(localsHandler.readLocal(redirectingParameter));
-          }
-        }
-      } else {
-        for (ParameterElement parameter in targetOptionals) {
-          loadPosition(position++, parameter);
-        }
-      }
-    }
-
-    ClassElement targetClass = targetConstructor.enclosingClass;
-    if (rtiNeed.classNeedsTypeArguments(targetClass)) {
-      ClassElement cls = redirectingConstructor.enclosingClass;
-      ResolutionDartType targetType =
-          redirectingConstructor.computeEffectiveTargetType(cls.thisType);
-      targetType = localsHandler.substInContext(targetType);
-      if (targetType is ResolutionInterfaceType) {
-        targetType.typeArguments.forEach((ResolutionDartType argument) {
-          inputs.add(typeBuilder.analyzeTypeArgument(argument, sourceElement));
-        });
-      }
-    }
-    pushInvokeStatic(node, targetConstructor.declaration, inputs);
-    HInstruction value = pop();
-    emitReturn(value, node);
-  }
-
-  /// Returns true if the [type] is a valid return type for an asynchronous
-  /// function.
-  ///
-  /// Asynchronous functions return a `Future`, and a valid return is thus
-  /// either dynamic, Object, or Future.
-  ///
-  /// We do not accept the internal Future implementation class.
-  bool isValidAsyncReturnType(ResolutionDartType type) {
-    assert(isBuildingAsyncFunction);
-    // TODO(sigurdm): In an internal library a function could be declared:
-    //
-    // _FutureImpl foo async => 1;
-    //
-    // This should be valid (because the actual value returned from an async
-    // function is a `_FutureImpl`), but currently false is returned in this
-    // case.
-    return type.isDynamic ||
-        type.isObject ||
-        (type is ResolutionInterfaceType &&
-            type.element == commonElements.futureClass);
-  }
-
-  visitReturn(ast.Return node) {
-    if (identical(node.beginToken.stringValue, 'native')) {
-      native.handleSsaNative(this, node.expression);
-      return;
-    }
-    HInstruction value;
-    if (node.expression == null) {
-      value = graph.addConstantNull(closedWorld);
-    } else {
-      visit(node.expression);
-      value = pop();
-      if (isBuildingAsyncFunction) {
-        if (options.enableTypeAssertions &&
-            !isValidAsyncReturnType(returnType)) {
-          String message = "Async function returned a Future, "
-              "was declared to return a $returnType.";
-          generateTypeError(node, message);
-          pop();
-          return;
-        }
-      } else {
-        value = typeBuilder.potentiallyCheckOrTrustTypeOfAssignment(
-            value, returnType);
-      }
-    }
-
-    handleInTryStatement();
-    emitReturn(value, node);
-  }
-
-  visitThrow(ast.Throw node) {
-    visitThrowExpression(node.expression);
-    if (isReachable) {
-      handleInTryStatement();
-      push(new HThrowExpression(abstractValueDomain, pop(),
-          sourceInformationBuilder.buildThrow(node)));
-      isReachable = false;
-    }
-  }
-
-  visitYield(ast.Yield node) {
-    visit(node.expression);
-    HInstruction yielded = pop();
-    add(new HYield(abstractValueDomain, yielded, node.hasStar,
-        sourceInformationBuilder.buildYield(node)));
-  }
-
-  visitAwait(ast.Await node) {
-    visit(node.expression);
-    HInstruction awaited = pop();
-    // TODO(herhut): Improve this type.
-    push(new HAwait(
-        awaited, new TypeMask.subclass(commonElements.objectClass, closedWorld))
-      ..sourceInformation = sourceInformationBuilder.buildAwait(node));
-  }
-
-  visitTypeAnnotation(ast.TypeAnnotation node) {
-    reporter.internalError(node, 'Visiting type annotation in SSA builder.');
-  }
-
-  visitVariableDefinitions(ast.VariableDefinitions node) {
-    assert(isReachable);
-    for (Link<ast.Node> link = node.definitions.nodes;
-        !link.isEmpty;
-        link = link.tail) {
-      ast.Node definition = link.head;
-      LocalElement local = elements[definition];
-      if (definition is ast.Identifier) {
-        HInstruction initialValue = graph.addConstantNull(closedWorld);
-        localsHandler.updateLocal(local, initialValue);
-      } else {
-        ast.SendSet node = definition;
-        generateNonInstanceSetter(
-            node, local, visitAndPop(node.arguments.first));
-        pop(); // Discard value.
-      }
-    }
-  }
-
-  HInstruction setRtiIfNeeded(
-      HInstruction object, ast.Node node, SourceInformation sourceInformation) {
-    ResolutionInterfaceType type =
-        localsHandler.substInContext(elements.getType(node));
-    if (!rtiNeed.classNeedsTypeArguments(type.element) || type.treatAsRaw) {
-      return object;
-    }
-    List<HInstruction> arguments = <HInstruction>[];
-    for (ResolutionDartType argument in type.typeArguments) {
-      arguments.add(typeBuilder.analyzeTypeArgument(argument, sourceElement,
-          sourceInformation: sourceInformation));
-    }
-    // TODO(15489): Register at codegen.
-    registry?.registerInstantiation(type);
-    return callSetRuntimeTypeInfoWithTypeArguments(
-        type, arguments, object, sourceInformation);
-  }
-
-  visitLiteralList(ast.LiteralList node) {
-    HInstruction instruction;
-
-    if (node.isConst) {
-      instruction = addConstant(node);
-    } else {
-      List<HInstruction> inputs = <HInstruction>[];
-      for (Link<ast.Node> link = node.elements.nodes;
-          !link.isEmpty;
-          link = link.tail) {
-        visit(link.head);
-        inputs.add(pop());
-      }
-      instruction = buildLiteralList(inputs);
-      add(instruction);
-      instruction = setRtiIfNeeded(
-          instruction, node, sourceInformationBuilder.buildListLiteral(node));
-    }
-
-    TypeMask type = _inferredTypeOfListLiteral(node);
-    if (!type.containsAll(closedWorld)) {
-      instruction.instructionType = type;
-    }
-    stack.add(instruction);
-  }
-
-  _inferredTypeOfNewList(ast.Send node) =>
-      _resultOf(sourceElement).typeOfNewList(node) ?? commonMasks.dynamicType;
-
-  _inferredTypeOfListLiteral(ast.LiteralList node) =>
-      _resultOf(sourceElement).typeOfListLiteral(node) ??
-      commonMasks.dynamicType;
-
-  visitConditional(ast.Conditional node) {
-    SsaBranchBuilder brancher = new SsaBranchBuilder(this, node);
-    brancher.handleConditional(() => visit(node.condition),
-        () => visit(node.thenExpression), () => visit(node.elseExpression));
-  }
-
-  visitStringInterpolation(ast.StringInterpolation node) {
-    StringBuilderVisitor stringBuilder = new StringBuilderVisitor(this, node);
-    stringBuilder.visit(node);
-    stack.add(stringBuilder.result);
-  }
-
-  visitStringInterpolationPart(ast.StringInterpolationPart node) {
-    // The parts are iterated in visitStringInterpolation.
-    reporter.internalError(
-        node, 'SsaBuilder.visitStringInterpolation should not be called.');
-  }
-
-  visitEmptyStatement(ast.EmptyStatement node) {
-    // Do nothing, empty statement.
-  }
-
-  visitModifiers(ast.Modifiers node) {
-    failedAt(node, 'SsaFromAstMixin.visitModifiers not implemented.');
-  }
-
-  visitBreakStatement(ast.BreakStatement node) {
-    assert(!isAborted());
-    handleInTryStatement();
-    JumpTarget target = elements.getTargetOf(node);
-    assert(target != null);
-    JumpHandler handler = jumpTargets[target];
-    assert(handler != null);
-    if (node.target == null) {
-      handler.generateBreak(sourceInformationBuilder.buildGoto(node));
-    } else {
-      LabelDefinition label = elements.getTargetLabel(node);
-      handler.generateBreak(sourceInformationBuilder.buildGoto(node), label);
-    }
-  }
-
-  visitContinueStatement(ast.ContinueStatement node) {
-    handleInTryStatement();
-    JumpTarget target = elements.getTargetOf(node);
-    assert(target != null);
-    JumpHandler handler = jumpTargets[target];
-    assert(handler != null);
-    if (node.target == null) {
-      handler.generateContinue(sourceInformationBuilder.buildGoto(node));
-    } else {
-      LabelDefinition label = elements.getTargetLabel(node);
-      assert(label != null);
-      handler.generateContinue(sourceInformationBuilder.buildGoto(node), label);
-    }
-  }
-
-  /**
-   * Creates a [JumpHandler] for a statement. The node must be a jump
-   * target. If there are no breaks or continues targeting the statement,
-   * a special "null handler" is returned.
-   *
-   * [isLoopJump] is [:true:] when the jump handler is for a loop. This is used
-   * to distinguish the synthesized loop created for a switch statement with
-   * continue statements from simple switch statements.
-   */
-  JumpHandler createJumpHandler(ast.Statement node, JumpTarget jumpTarget,
-      {bool isLoopJump}) {
-    if (jumpTarget == null || !identical(jumpTarget.statement, node)) {
-      // No breaks or continues to this node.
-      return new NullJumpHandler(reporter);
-    }
-    if (isLoopJump && node is ast.SwitchStatement) {
-      // Create a special jump handler for loops created for switch statements
-      // with continue statements.
-      return new AstSwitchCaseJumpHandler(this, jumpTarget, node);
-    }
-    return new JumpHandler(this, jumpTarget);
-  }
-
-  visitAsyncForIn(ast.AsyncForIn node) {
-    // The async-for is implemented with a StreamIterator.
-    HInstruction streamIterator;
-
-    visit(node.expression);
-    HInstruction expression = pop();
-    ConstructorElement constructor = commonElements.streamIteratorConstructor;
-    pushInvokeStatic(
-        node, constructor, [expression, graph.addConstantNull(closedWorld)]);
-    streamIterator = pop();
-
-    void buildInitializer() {}
-
-    HInstruction buildCondition() {
-      Selector selector = Selectors.moveNext;
-      TypeMask mask = elementInferenceResults.typeOfIteratorMoveNext(node);
-      pushInvokeDynamic(node, selector, mask, [streamIterator]);
-      HInstruction future = pop();
-      push(new HAwait(future,
-          new TypeMask.subclass(commonElements.objectClass, closedWorld)));
-      return popBoolified();
-    }
-
-    void buildBody() {
-      Selector call = Selectors.current;
-      TypeMask callMask = elementInferenceResults.typeOfIteratorCurrent(node);
-      pushInvokeDynamic(node, call, callMask, [streamIterator]);
-
-      ast.Node identifier = node.declaredIdentifier;
-      Element variable = elements.getForInVariable(node);
-      Selector selector = elements.getSelector(identifier);
-      HInstruction value = pop();
-      if (identifier.asSend() != null &&
-          Elements.isInstanceSend(identifier, elements)) {
-        TypeMask mask = elementInferenceResults.typeOfSend(identifier);
-        HInstruction receiver = generateInstanceSendReceiver(identifier);
-        assert(receiver != null);
-        generateInstanceSetterWithCompiledReceiver(null, receiver, value,
-            selector: selector, mask: mask, location: identifier);
-      } else {
-        generateNonInstanceSetter(null, variable, value, location: identifier);
-      }
-      pop(); // Pop the value pushed by the setter call.
-
-      visit(node.body);
-    }
-
-    void buildUpdate() {}
-
-    buildProtectedByFinally(() {
-      loopHandler.handleLoop(
-          node,
-          closureDataLookup.getCapturedLoopScope(node),
-          elements.getTargetDefinition(node),
-          buildInitializer,
-          buildCondition,
-          buildUpdate,
-          buildBody,
-          sourceInformationBuilder.buildLoop(node));
-    }, () {
-      pushInvokeDynamic(node, Selectors.cancel, null, [streamIterator]);
-      add(new HAwait(pop(),
-          new TypeMask.subclass(commonElements.objectClass, closedWorld)));
-    });
-  }
-
-  visitSyncForIn(ast.SyncForIn node) {
-    // The 'get iterator' selector for this node has the inferred receiver type.
-    // If the receiver supports JavaScript indexing we generate an indexing loop
-    // instead of allocating an iterator object.
-
-    // This scheme recognizes for-in on direct lists.  It does not recognize all
-    // uses of ArrayIterator.  They still occur when the receiver is an Iterable
-    // with a `get iterator` method that delegates to another Iterable and the
-    // method is inlined.  We would require full scalar replacement in that
-    // case.
-
-    TypeMask mask = elementInferenceResults.typeOfIterator(node);
-
-    if (mask != null &&
-        mask.satisfies(commonElements.jsIndexableClass, closedWorld) &&
-        // String is indexable but not iterable.
-        !mask.satisfies(commonElements.jsStringClass, closedWorld)) {
-      return buildSyncForInIndexable(node, mask);
-    }
-    buildSyncForInIterator(node);
-  }
-
-  buildSyncForInIterator(ast.SyncForIn node) {
-    // Generate a structure equivalent to:
-    //   Iterator<E> $iter = <iterable>.iterator;
-    //   while ($iter.moveNext()) {
-    //     <declaredIdentifier> = $iter.current;
-    //     <body>
-    //   }
-
-    // The iterator is shared between initializer, condition and body.
-    HInstruction iterator;
-
-    void buildInitializer() {
-      Selector selector = Selectors.iterator;
-      TypeMask mask = elementInferenceResults.typeOfIterator(node);
-      visit(node.expression);
-      HInstruction receiver = pop();
-      pushInvokeDynamic(node, selector, mask, [receiver],
-          sourceInformation: sourceInformationBuilder.buildForInIterator(node));
-      iterator = pop();
-    }
-
-    HInstruction buildCondition() {
-      Selector selector = Selectors.moveNext;
-      TypeMask mask = elementInferenceResults.typeOfIteratorMoveNext(node);
-      pushInvokeDynamic(node, selector, mask, [iterator],
-          sourceInformation: sourceInformationBuilder.buildForInMoveNext(node));
-      return popBoolified();
-    }
-
-    void buildBody() {
-      Selector call = Selectors.current;
-      TypeMask mask = elementInferenceResults.typeOfIteratorCurrent(node);
-      pushInvokeDynamic(node, call, mask, [iterator],
-          sourceInformation: sourceInformationBuilder.buildForInCurrent(node));
-      buildAssignLoopVariable(node, pop());
-      visit(node.body);
-    }
-
-    loopHandler.handleLoop(
-        node,
-        closureDataLookup.getCapturedLoopScope(node),
-        elements.getTargetDefinition(node),
-        buildInitializer,
-        buildCondition,
-        () {},
-        buildBody,
-        sourceInformationBuilder.buildLoop(node));
-  }
-
-  buildAssignLoopVariable(ast.ForIn node, HInstruction value) {
-    ast.Node identifier = node.declaredIdentifier;
-    Element variable = elements.getForInVariable(node);
-    Selector selector = elements.getSelector(identifier);
-
-    if (identifier.asSend() != null &&
-        Elements.isInstanceSend(identifier, elements)) {
-      TypeMask mask = elementInferenceResults.typeOfSend(identifier);
-      HInstruction receiver = generateInstanceSendReceiver(identifier);
-      assert(receiver != null);
-      generateInstanceSetterWithCompiledReceiver(null, receiver, value,
-          selector: selector, mask: mask, location: identifier);
-    } else {
-      generateNonInstanceSetter(null, variable, value, location: identifier);
-    }
-    pop(); // Discard the value pushed by the setter call.
-  }
-
-  buildSyncForInIndexable(ast.ForIn node, TypeMask arrayType) {
-    // Generate a structure equivalent to:
-    //
-    //     int end = a.length;
-    //     for (int i = 0;
-    //          i < a.length;
-    //          checkConcurrentModificationError(a.length == end, a), ++i) {
-    //       <declaredIdentifier> = a[i];
-    //       <body>
-    //     }
-    ExecutableElement loopVariable = elements.getForInVariable(node);
-    SyntheticLocal indexVariable =
-        new SyntheticLocal('_i', loopVariable, target);
-    TypeMask boolType = commonMasks.boolType;
-
-    // These variables are shared by initializer, condition, body and update.
-    HInstruction array; // Set in buildInitializer.
-    bool isFixed; // Set in buildInitializer.
-    HInstruction originalLength = null; // Set for growable lists.
-
-    HInstruction buildGetLength() {
-      HInstruction result = new HGetLength(array, commonMasks.positiveIntType,
-          isAssignable: !isFixed);
-      add(result);
-      return result;
-    }
-
-    void buildConcurrentModificationErrorCheck() {
-      if (originalLength == null) return;
-      // The static call checkConcurrentModificationError() is expanded in
-      // codegen to:
-      //
-      //     array.length == _end || throwConcurrentModificationError(array)
-      //
-      HInstruction length = buildGetLength();
-      push(new HIdentity(length, originalLength, null, boolType));
-      pushInvokeStatic(node, commonElements.checkConcurrentModificationError,
-          [pop(), array]);
-      pop();
-    }
-
-    void buildInitializer() {
-      visit(node.expression);
-      array = pop();
-      isFixed = isFixedLength(array.instructionType, closedWorld);
-      localsHandler.updateLocal(
-          indexVariable, graph.addConstantInt(0, closedWorld));
-      originalLength = buildGetLength();
-    }
-
-    HInstruction buildCondition() {
-      HInstruction index = localsHandler.readLocal(indexVariable);
-      HInstruction length = buildGetLength();
-      HInstruction compare = new HLess(index, length, null, boolType);
-      add(compare);
-      return compare;
-    }
-
-    void buildBody() {
-      // If we had mechanically inlined ArrayIterator.moveNext(), it would have
-      // inserted the ConcurrentModificationError check as part of the
-      // condition.  It is not necessary on the first iteration since there is
-      // no code between calls to `get iterator` and `moveNext`, so the test is
-      // moved to the loop update.
-
-      // Find a type for the element. Use the element type of the indexer of the
-      // array, as this is stronger than the iterator's `get current` type, for
-      // example, `get current` includes null.
-      // TODO(sra): The element type of a container type mask might be better.
-      Selector selector = new Selector.index();
-      TypeMask type = TypeMaskFactory.inferredTypeForSelector(
-          selector, arrayType, globalInferenceResults);
-
-      HInstruction index = localsHandler.readLocal(indexVariable);
-      HInstruction value = new HIndex(array, index, null, type);
-      add(value);
-
-      buildAssignLoopVariable(node, value);
-      visit(node.body);
-    }
-
-    void buildUpdate() {
-      // See buildBody as to why we check here.
-      buildConcurrentModificationErrorCheck();
-
-      // TODO(sra): It would be slightly shorter to generate `a[i++]` in the
-      // body (and that more closely follows what an inlined iterator would do)
-      // but the code is horrible as `i+1` is carried around the loop in an
-      // additional variable.
-      HInstruction index = localsHandler.readLocal(indexVariable);
-      HInstruction one = graph.addConstantInt(1, closedWorld);
-      HInstruction addInstruction =
-          new HAdd(index, one, null, commonMasks.positiveIntType);
-      add(addInstruction);
-      localsHandler.updateLocal(indexVariable, addInstruction);
-    }
-
-    loopHandler.handleLoop(
-        node,
-        closureDataLookup.getCapturedLoopScope(node),
-        elements.getTargetDefinition(node),
-        buildInitializer,
-        buildCondition,
-        buildUpdate,
-        buildBody,
-        sourceInformationBuilder.buildLoop(node));
-  }
-
-  visitLabel(ast.Label node) {
-    reporter.internalError(node, 'SsaFromAstMixin.visitLabel.');
-  }
-
-  visitLabeledStatement(ast.LabeledStatement node) {
-    ast.Statement body = node.statement;
-    if (body is ast.Loop ||
-        body is ast.SwitchStatement ||
-        Elements.isUnusedLabel(node, elements)) {
-      // Loops and switches handle their own labels.
-      visit(body);
-      return;
-    }
-    JumpTarget targetElement = elements.getTargetDefinition(body);
-    LocalsHandler beforeLocals = new LocalsHandler.from(localsHandler);
-    assert(targetElement.isBreakTarget);
-    JumpHandler handler = new JumpHandler(this, targetElement);
-    // Introduce a new basic block.
-    HBasicBlock entryBlock = openNewBlock();
-    visit(body);
-    SubGraph bodyGraph = new SubGraph(entryBlock, lastOpenedBlock);
-
-    HBasicBlock joinBlock = graph.addNewBlock();
-    List<LocalsHandler> breakHandlers = <LocalsHandler>[];
-    handler.forEachBreak((HBreak breakInstruction, LocalsHandler locals) {
-      breakInstruction.block.addSuccessor(joinBlock);
-      breakHandlers.add(locals);
-    });
-    bool hasBreak = breakHandlers.length > 0;
-    if (!isAborted()) {
-      goto(current, joinBlock);
-      breakHandlers.add(localsHandler);
-    }
-    open(joinBlock);
-    localsHandler = beforeLocals.mergeMultiple(breakHandlers, joinBlock);
-
-    if (hasBreak) {
-      // There was at least one reachable break, so the label is needed.
-      entryBlock.setBlockFlow(
-          new HLabeledBlockInformation(
-              new HSubGraphBlockInformation(bodyGraph), handler.labels),
-          joinBlock);
-    }
-    handler.close();
-  }
-
-  visitLiteralMap(ast.LiteralMap node) {
-    if (node.isConst) {
-      stack.add(addConstant(node));
-      return;
-    }
-    List<HInstruction> listInputs = <HInstruction>[];
-    for (Link<ast.Node> link = node.entries.nodes;
-        !link.isEmpty;
-        link = link.tail) {
-      visit(link.head);
-      listInputs.add(pop());
-      listInputs.add(pop());
-    }
-
-    ConstructorElement listConstructor;
-    List<HInstruction> inputs = <HInstruction>[];
-
-    if (listInputs.isEmpty) {
-      listConstructor = commonElements.mapLiteralConstructorEmpty;
-    } else {
-      listConstructor = commonElements.mapLiteralConstructor;
-      HLiteralList keyValuePairs = buildLiteralList(listInputs);
-      add(keyValuePairs);
-      inputs.add(keyValuePairs);
-    }
-
-    assert(listConstructor.isFactoryConstructor);
-
-    ConstructorElement constructorElement = listConstructor;
-    listConstructor = constructorElement.effectiveTarget;
-
-    ResolutionInterfaceType type = elements.getType(node);
-    ResolutionDartType expectedType =
-        constructorElement.computeEffectiveTargetType(type);
-    expectedType = localsHandler.substInContext(expectedType);
-
-    ClassElement cls = listConstructor.enclosingClass;
-
-    MethodElement createFunction = listConstructor;
-    if (expectedType is ResolutionInterfaceType &&
-        rtiNeed.classNeedsTypeArguments(cls)) {
-      List<HInstruction> typeInputs = <HInstruction>[];
-      expectedType.typeArguments.forEach((ResolutionDartType argument) {
-        typeInputs
-            .add(typeBuilder.analyzeTypeArgument(argument, sourceElement));
-      });
-
-      // We lift this common call pattern into a helper function to save space
-      // in the output.
-      if (typeInputs
-          .every((HInstruction input) => input.isNull(abstractValueDomain))) {
-        if (listInputs.isEmpty) {
-          createFunction = commonElements.mapLiteralUntypedEmptyMaker;
-        } else {
-          createFunction = commonElements.mapLiteralUntypedMaker;
-        }
-      } else {
-        inputs.addAll(typeInputs);
-      }
-    }
-
-    // If rti is needed and the map literal has no type parameters,
-    // 'constructor' is a static function that forwards the call to the factory
-    // constructor without type parameters.
-    assert(createFunction is ConstructorElement ||
-        createFunction is FunctionElement);
-
-    // The instruction type will always be a subtype of the mapLiteralClass, but
-    // type inference might discover a more specific type, or find nothing (in
-    // dart2js unit tests).
-    TypeMask mapType = new TypeMask.nonNullSubtype(
-        commonElements.mapLiteralClass, closedWorld);
-    TypeMask returnTypeMask = TypeMaskFactory.inferredReturnTypeForElement(
-        createFunction, globalInferenceResults);
-    TypeMask instructionType =
-        mapType.intersection(returnTypeMask, closedWorld);
-
-    addInlinedInstantiation(expectedType);
-    pushInvokeStatic(node, createFunction, inputs,
-        typeMask: instructionType, instanceType: expectedType);
-    removeInlinedInstantiation(expectedType);
-  }
-
-  visitLiteralMapEntry(ast.LiteralMapEntry node) {
-    visit(node.value);
-    visit(node.key);
-  }
-
-  visitNamedArgument(ast.NamedArgument node) {
-    visit(node.expression);
-  }
-
-  Map<ast.CaseMatch, ConstantValue> buildSwitchCaseConstants(
-      ast.SwitchStatement node) {
-    Map<ast.CaseMatch, ConstantValue> constants =
-        new Map<ast.CaseMatch, ConstantValue>();
-    for (ast.SwitchCase switchCase in node.cases) {
-      for (ast.Node labelOrCase in switchCase.labelsAndCases) {
-        if (labelOrCase is ast.CaseMatch) {
-          ast.CaseMatch match = labelOrCase;
-          ConstantValue constant = getConstantForNode(match.expression);
-          constants[labelOrCase] = constant;
-        }
-      }
-    }
-    return constants;
-  }
-
-  visitSwitchStatement(ast.SwitchStatement node) {
-    SourceInformation sourceInformation =
-        sourceInformationBuilder.buildSwitch(node);
-    Map<ast.CaseMatch, ConstantValue> constants =
-        buildSwitchCaseConstants(node);
-
-    // The switch case indices must match those computed in
-    // [SwitchCaseJumpHandler].
-    bool hasContinue = false;
-    Map<ast.SwitchCase, int> caseIndex = new Map<ast.SwitchCase, int>();
-    int switchIndex = 1;
-    bool hasDefault = false;
-    for (ast.SwitchCase switchCase in node.cases) {
-      for (ast.Node labelOrCase in switchCase.labelsAndCases) {
-        ast.Node label = labelOrCase.asLabel();
-        if (label != null) {
-          LabelDefinition labelElement = elements.getLabelDefinition(label);
-          if (labelElement != null && labelElement.isContinueTarget) {
-            hasContinue = true;
-          }
-        }
-      }
-      if (switchCase.isDefaultCase) {
-        hasDefault = true;
-      }
-      caseIndex[switchCase] = switchIndex;
-      switchIndex++;
-    }
-    if (!hasContinue) {
-      // If the switch statement has no switch cases targeted by continue
-      // statements we encode the switch statement directly.
-      buildSimpleSwitchStatement(node, constants, sourceInformation);
-    } else {
-      buildComplexSwitchStatement(
-          node, constants, caseIndex, hasDefault, sourceInformation);
-    }
-  }
-
-  /**
-   * Builds a simple switch statement which does not handle uses of continue
-   * statements to labeled switch cases.
-   */
-  void buildSimpleSwitchStatement(
-      ast.SwitchStatement node,
-      Map<ast.CaseMatch, ConstantValue> constants,
-      SourceInformation sourceInformation) {
-    JumpHandler jumpHandler = createJumpHandler(
-        node, elements.getTargetDefinition(node),
-        isLoopJump: false);
-    HInstruction buildExpression() {
-      visit(node.expression);
-      return pop();
-    }
-
-    Iterable<ConstantValue> getConstants(ast.SwitchCase switchCase) {
-      List<ConstantValue> constantList = <ConstantValue>[];
-      for (ast.Node labelOrCase in switchCase.labelsAndCases) {
-        if (labelOrCase is ast.CaseMatch) {
-          constantList.add(constants[labelOrCase]);
-        }
-      }
-      return constantList;
-    }
-
-    bool isDefaultCase(ast.SwitchCase switchCase) {
-      return switchCase.isDefaultCase;
-    }
-
-    void buildSwitchCase(ast.SwitchCase node) {
-      visit(node.statements);
-    }
-
-    handleSwitch(node, jumpHandler, buildExpression, node.cases, getConstants,
-        isDefaultCase, buildSwitchCase, sourceInformation);
-    jumpHandler.close();
-  }
-
-  /**
-   * Builds a switch statement that can handle arbitrary uses of continue
-   * statements to labeled switch cases.
-   */
-  void buildComplexSwitchStatement(
-      ast.SwitchStatement node,
-      Map<ast.CaseMatch, ConstantValue> constants,
-      Map<ast.SwitchCase, int> caseIndex,
-      bool hasDefault,
-      SourceInformation sourceInformation) {
-    // If the switch statement has switch cases targeted by continue
-    // statements we create the following encoding:
-    //
-    //   switch (e) {
-    //     l_1: case e0: s_1; break;
-    //     l_2: case e1: s_2; continue l_i;
-    //     ...
-    //     l_n: default: s_n; continue l_j;
-    //   }
-    //
-    // is encoded as
-    //
-    //   var target;
-    //   switch (e) {
-    //     case e1: target = 1; break;
-    //     case e2: target = 2; break;
-    //     ...
-    //     default: target = n; break;
-    //   }
-    //   l: while (true) {
-    //    switch (target) {
-    //       case 1: s_1; break l;
-    //       case 2: s_2; target = i; continue l;
-    //       ...
-    //       case n: s_n; target = j; continue l;
-    //     }
-    //   }
-
-    JumpTarget switchTarget = elements.getTargetDefinition(node);
-    HInstruction initialValue = graph.addConstantNull(closedWorld);
-    localsHandler.updateLocal(switchTarget, initialValue);
-
-    JumpHandler jumpHandler =
-        createJumpHandler(node, switchTarget, isLoopJump: false);
-    dynamic switchCases = node.cases;
-    if (!hasDefault) {
-      // Use [:null:] as the marker for a synthetic default clause.
-      // The synthetic default is added because otherwise, there would be no
-      // good place to give a default value to the local.
-      switchCases = node.cases.nodes.toList()..add(null);
-    }
-    HInstruction buildExpression() {
-      visit(node.expression);
-      return pop();
-    }
-
-    Iterable<ConstantValue> getConstants(ast.SwitchCase switchCase) {
-      List<ConstantValue> constantList = <ConstantValue>[];
-      if (switchCase != null) {
-        for (ast.Node labelOrCase in switchCase.labelsAndCases) {
-          if (labelOrCase is ast.CaseMatch) {
-            constantList.add(constants[labelOrCase]);
-          }
-        }
-      }
-      return constantList;
-    }
-
-    bool isDefaultCase(ast.SwitchCase switchCase) {
-      return switchCase == null || switchCase.isDefaultCase;
-    }
-
-    void buildSwitchCase(ast.SwitchCase switchCase) {
-      SourceInformation caseSourceInformation = sourceInformation;
-      if (switchCase != null) {
-        caseSourceInformation = sourceInformationBuilder.buildGoto(switchCase);
-        // Generate 'target = i; break;' for switch case i.
-        int index = caseIndex[switchCase];
-        HInstruction value = graph.addConstantInt(index, closedWorld);
-        localsHandler.updateLocal(switchTarget, value,
-            sourceInformation: caseSourceInformation);
-      } else {
-        // Generate synthetic default case 'target = null; break;'.
-        HInstruction value = graph.addConstantNull(closedWorld);
-        localsHandler.updateLocal(switchTarget, value,
-            sourceInformation: caseSourceInformation);
-      }
-      jumpTargets[switchTarget].generateBreak(caseSourceInformation);
-    }
-
-    handleSwitch(node, jumpHandler, buildExpression, switchCases, getConstants,
-        isDefaultCase, buildSwitchCase, sourceInformation);
-    jumpHandler.close();
-
-    HInstruction buildCondition() => graph.addConstantBool(true, closedWorld);
-
-    void buildSwitch() {
-      HInstruction buildExpression() {
-        return localsHandler.readLocal(switchTarget);
-      }
-
-      Iterable<ConstantValue> getConstants(ast.SwitchCase switchCase) {
-        return <ConstantValue>[constantSystem.createInt(caseIndex[switchCase])];
-      }
-
-      void buildSwitchCase(ast.SwitchCase switchCase) {
-        visit(switchCase.statements);
-        if (!isAborted()) {
-          // Ensure that we break the loop if the case falls through. (This
-          // is only possible for the last case.)
-          jumpTargets[switchTarget].generateBreak(sourceInformation);
-        }
-      }
-
-      // Pass a [NullJumpHandler] because the target for the contained break
-      // is not the generated switch statement but instead the loop generated
-      // in the call to [handleLoop] below.
-      handleSwitch(
-          node,
-          new NullJumpHandler(reporter),
-          buildExpression,
-          node.cases,
-          getConstants,
-          (_) => false, // No case is default.
-          buildSwitchCase,
-          sourceInformation);
-    }
-
-    void buildLoop() {
-      loopHandler.handleLoop(
-          node,
-          closureDataLookup.getCapturedLoopScope(node),
-          switchTarget,
-          () {},
-          buildCondition,
-          () {},
-          buildSwitch,
-          sourceInformationBuilder.buildLoop(node));
-    }
-
-    if (hasDefault) {
-      buildLoop();
-    } else {
-      // If the switch statement has no default case, surround the loop with
-      // a test of the target.
-      void buildCondition() {
-        js.Template code = js.js.parseForeignJS('#');
-        push(new HForeignCode(
-            code, commonMasks.boolType, [localsHandler.readLocal(switchTarget)],
-            nativeBehavior: native.NativeBehavior.PURE));
-      }
-
-      handleIf(
-          node: node,
-          visitCondition: buildCondition,
-          visitThen: buildLoop,
-          visitElse: () => {},
-          sourceInformation: sourceInformation);
-    }
-  }
-
-  /**
-   * Creates a switch statement.
-   *
-   * [jumpHandler] is the [JumpHandler] for the created switch statement.
-   * [buildExpression] creates the switch expression.
-   * [switchCases] must be either an [Iterable] of [ast.SwitchCase] nodes or
-   *   a [Link] or a [ast.NodeList] of [ast.SwitchCase] nodes.
-   * [getConstants] returns the set of constants for a switch case.
-   * [isDefaultCase] returns true if the provided switch case should be
-   *   considered default for the created switch statement.
-   * [buildSwitchCase] creates the statements for the switch case.
-   */
-  void handleSwitch(
-      ast.Node errorNode,
-      JumpHandler jumpHandler,
-      HInstruction buildExpression(),
-      var switchCases,
-      Iterable<ConstantValue> getConstants(ast.SwitchCase switchCase),
-      bool isDefaultCase(ast.SwitchCase switchCase),
-      void buildSwitchCase(ast.SwitchCase switchCase),
-      SourceInformation sourceInformation) {
-    HBasicBlock expressionStart = openNewBlock();
-    HInstruction expression = buildExpression();
-    if (switchCases.isEmpty) {
-      return;
-    }
-
-    HSwitch switchInstruction =
-        new HSwitch(abstractValueDomain, <HInstruction>[expression]);
-    HBasicBlock expressionEnd = close(switchInstruction);
-    LocalsHandler savedLocals = localsHandler;
-
-    List<HStatementInformation> statements = <HStatementInformation>[];
-    bool hasDefault = false;
-    HasNextIterator<ast.Node> caseIterator =
-        new HasNextIterator<ast.Node>(switchCases.iterator);
-    while (caseIterator.hasNext) {
-      ast.SwitchCase switchCase = caseIterator.next();
-      HBasicBlock block = graph.addNewBlock();
-      for (ConstantValue constant in getConstants(switchCase)) {
-        HConstant hConstant = graph.addConstant(constant, closedWorld);
-        switchInstruction.inputs.add(hConstant);
-        hConstant.usedBy.add(switchInstruction);
-        expressionEnd.addSuccessor(block);
-      }
-
-      if (isDefaultCase(switchCase)) {
-        // An HSwitch has n inputs and n+1 successors, the last being the
-        // default case.
-        expressionEnd.addSuccessor(block);
-        hasDefault = true;
-      }
-      open(block);
-      localsHandler = new LocalsHandler.from(savedLocals);
-      buildSwitchCase(switchCase);
-      if (!isAborted()) {
-        if (caseIterator.hasNext && isReachable) {
-          pushInvokeStatic(switchCase, commonElements.fallThroughError, []);
-          HInstruction error = pop();
-          closeAndGotoExit(
-              new HThrow(abstractValueDomain, error, error.sourceInformation));
-        } else if (!isDefaultCase(switchCase)) {
-          // If there is no default, we will add one later to avoid
-          // the critical edge. So we generate a break statement to make
-          // sure the last case does not fall through to the default case.
-          jumpHandler.generateBreak(sourceInformation);
-        }
-      }
-      statements.add(
-          new HSubGraphBlockInformation(new SubGraph(block, lastOpenedBlock)));
-    }
-
-    // Add a join-block if necessary.
-    // We create [joinBlock] early, and then go through the cases that might
-    // want to jump to it. In each case, if we add [joinBlock] as a successor
-    // of another block, we also add an element to [caseHandlers] that is used
-    // to create the phis in [joinBlock].
-    // If we never jump to the join block, [caseHandlers] will stay empty, and
-    // the join block is never added to the graph.
-    HBasicBlock joinBlock = new HBasicBlock();
-    List<LocalsHandler> caseHandlers = <LocalsHandler>[];
-    jumpHandler.forEachBreak((HBreak instruction, LocalsHandler locals) {
-      instruction.block.addSuccessor(joinBlock);
-      caseHandlers.add(locals);
-    });
-    jumpHandler.forEachContinue((HContinue instruction, LocalsHandler locals) {
-      assert(false, failedAt(errorNode, 'Continue cannot target a switch.'));
-    });
-    if (!isAborted()) {
-      current.close(new HGoto(abstractValueDomain));
-      lastOpenedBlock.addSuccessor(joinBlock);
-      caseHandlers.add(localsHandler);
-    }
-    if (!hasDefault) {
-      // Always create a default case, to avoid a critical edge in the
-      // graph.
-      HBasicBlock defaultCase = addNewBlock();
-      expressionEnd.addSuccessor(defaultCase);
-      open(defaultCase);
-      close(new HGoto(abstractValueDomain));
-      defaultCase.addSuccessor(joinBlock);
-      caseHandlers.add(savedLocals);
-      statements.add(new HSubGraphBlockInformation(
-          new SubGraph(defaultCase, defaultCase)));
-    }
-    assert(caseHandlers.length == joinBlock.predecessors.length);
-    if (caseHandlers.length != 0) {
-      graph.addBlock(joinBlock);
-      open(joinBlock);
-      if (caseHandlers.length == 1) {
-        localsHandler = caseHandlers[0];
-      } else {
-        localsHandler = savedLocals.mergeMultiple(caseHandlers, joinBlock);
-      }
-    } else {
-      // The joinblock is not used.
-      joinBlock = null;
-    }
-
-    HSubExpressionBlockInformation expressionInfo =
-        new HSubExpressionBlockInformation(
-            new SubExpression(expressionStart, expressionEnd));
-    expressionStart.setBlockFlow(
-        new HSwitchBlockInformation(expressionInfo, statements,
-            jumpHandler.target, jumpHandler.labels, sourceInformation),
-        joinBlock);
-
-    jumpHandler.close();
-  }
-
-  visitSwitchCase(ast.SwitchCase node) {
-    reporter.internalError(node, 'SsaFromAstMixin.visitSwitchCase.');
-  }
-
-  visitCaseMatch(ast.CaseMatch node) {
-    reporter.internalError(node, 'SsaFromAstMixin.visitCaseMatch.');
-  }
-
-  /// Calls [buildTry] inside a synthetic try block with [buildFinally] in the
-  /// finally block.
-  ///
-  /// Note that to get the right locals behavior, the code visited by [buildTry]
-  /// and [buildFinally] must have been analyzed as if inside a try-statement by
-  /// [ClosureTranslator].
-  void buildProtectedByFinally(void buildTry(), void buildFinally()) {
-    // Save the current locals. The finally block must not reuse the existing
-    // locals handler. None of the variables that have been defined in the
-    // body-block will be used, but for loops we will add (unnecessary) phis
-    // that will reference the body variables. This makes it look as if the
-    // variables were used in a non-dominated block.
-    LocalsHandler savedLocals = new LocalsHandler.from(localsHandler);
-    HBasicBlock enterBlock = openNewBlock();
-    HTry tryInstruction = new HTry(abstractValueDomain);
-    close(tryInstruction);
-    bool oldInTryStatement = inTryStatement;
-    inTryStatement = true;
-
-    HBasicBlock startTryBlock;
-    HBasicBlock endTryBlock;
-    HBasicBlock startFinallyBlock;
-    HBasicBlock endFinallyBlock;
-
-    startTryBlock = graph.addNewBlock();
-    open(startTryBlock);
-    buildTry();
-    // We use a [HExitTry] instead of a [HGoto] for the try block
-    // because it will have two successors: the join block, and
-    // the finally block.
-    if (!isAborted()) endTryBlock = close(new HExitTry(abstractValueDomain));
-    SubGraph bodyGraph = new SubGraph(startTryBlock, lastOpenedBlock);
-
-    SubGraph finallyGraph = null;
-
-    localsHandler = new LocalsHandler.from(savedLocals);
-    startFinallyBlock = graph.addNewBlock();
-    open(startFinallyBlock);
-    buildFinally();
-    if (!isAborted()) endFinallyBlock = close(new HGoto(abstractValueDomain));
-    tryInstruction.finallyBlock = startFinallyBlock;
-    finallyGraph = new SubGraph(startFinallyBlock, lastOpenedBlock);
-
-    HBasicBlock exitBlock = graph.addNewBlock();
-
-    void addExitTrySuccessor(HBasicBlock successor) {
-      // Iterate over all blocks created inside this try/catch, and
-      // attach successor information to blocks that end with
-      // [HExitTry].
-      for (int i = startTryBlock.id; i < successor.id; i++) {
-        HBasicBlock block = graph.blocks[i];
-        var last = block.last;
-        if (last is HExitTry) {
-          block.addSuccessor(successor);
-        }
-      }
-    }
-
-    // Setup all successors. The entry block that contains the [HTry]
-    // has 1) the body 2) the finally, and 4) the exit
-    // blocks as successors.
-    enterBlock.addSuccessor(startTryBlock);
-    enterBlock.addSuccessor(startFinallyBlock);
-    enterBlock.addSuccessor(exitBlock);
-
-    // The body has the finally block as successor.
-    if (endTryBlock != null) {
-      endTryBlock.addSuccessor(startFinallyBlock);
-      endTryBlock.addSuccessor(exitBlock);
-    }
-
-    // The finally block has the exit block as successor.
-    endFinallyBlock.addSuccessor(exitBlock);
-
-    // If a block inside try/catch aborts (eg with a return statement),
-    // we explicitly mark this block a predecessor of the catch
-    // block and the finally block.
-    addExitTrySuccessor(startFinallyBlock);
-
-    // Use the locals handler not altered by the catch and finally
-    // blocks.
-    // TODO(sigurdm): We can probably do this, because try-variables are boxed.
-    // Need to verify.
-    localsHandler = savedLocals;
-    open(exitBlock);
-    enterBlock.setBlockFlow(
-        new HTryBlockInformation(
-            wrapStatementGraph(bodyGraph),
-            null, // No catch-variable.
-            null, // No catchGraph.
-            wrapStatementGraph(finallyGraph)),
-        exitBlock);
-    inTryStatement = oldInTryStatement;
-  }
-
-  visitTryStatement(ast.TryStatement node) {
-    // Save the current locals. The catch block and the finally block
-    // must not reuse the existing locals handler. None of the variables
-    // that have been defined in the body-block will be used, but for
-    // loops we will add (unnecessary) phis that will reference the body
-    // variables. This makes it look as if the variables were used
-    // in a non-dominated block.
-    LocalsHandler savedLocals = new LocalsHandler.from(localsHandler);
-    HBasicBlock enterBlock = openNewBlock();
-    HTry tryInstruction = new HTry(abstractValueDomain);
-    close(tryInstruction);
-    bool oldInTryStatement = inTryStatement;
-    inTryStatement = true;
-
-    HBasicBlock startTryBlock;
-    HBasicBlock endTryBlock;
-    HBasicBlock startCatchBlock;
-    HBasicBlock endCatchBlock;
-    HBasicBlock startFinallyBlock;
-    HBasicBlock endFinallyBlock;
-
-    startTryBlock = graph.addNewBlock();
-    open(startTryBlock);
-    visit(node.tryBlock);
-    // We use a [HExitTry] instead of a [HGoto] for the try block
-    // because it will have multiple successors: the join block, and
-    // the catch or finally block.
-    if (!isAborted()) endTryBlock = close(new HExitTry(abstractValueDomain));
-    SubGraph bodyGraph = new SubGraph(startTryBlock, lastOpenedBlock);
-    SubGraph catchGraph = null;
-    HLocalValue exception = null;
-
-    if (!node.catchBlocks.isEmpty) {
-      localsHandler = new LocalsHandler.from(savedLocals);
-      startCatchBlock = graph.addNewBlock();
-      open(startCatchBlock);
-      // Note that the name of this local is irrelevant.
-      SyntheticLocal local = localsHandler.createLocal('exception');
-      SourceInformation trySourceInformation =
-          sourceInformationBuilder.buildTry(node);
-      exception = new HLocalValue(local, commonMasks.nonNullType)
-        ..sourceInformation = trySourceInformation;
-      add(exception);
-      HInstruction oldRethrowableException = rethrowableException;
-      rethrowableException = exception;
-
-      pushInvokeStatic(node, commonElements.exceptionUnwrapper, [exception],
-          sourceInformation: trySourceInformation);
-      HInvokeStatic unwrappedException = pop();
-      tryInstruction.exception = exception;
-      Link<ast.Node> link = node.catchBlocks.nodes;
-
-      void pushCondition(ast.CatchBlock catchBlock) {
-        if (catchBlock.onKeyword != null) {
-          ResolutionDartType type = elements.getType(catchBlock.type);
-          if (type == null) {
-            reporter.internalError(catchBlock.type, 'On with no type.');
-          }
-          HInstruction condition = buildIsNode(
-              catchBlock.type,
-              type,
-              unwrappedException,
-              sourceInformationBuilder.buildCatch(catchBlock.type));
-          push(condition);
-        } else {
-          ast.VariableDefinitions declaration = catchBlock.formals.nodes.head;
-          HInstruction condition = null;
-          if (declaration.type == null) {
-            condition = graph.addConstantBool(true, closedWorld);
-            stack.add(condition);
-          } else {
-            // TODO(aprelev@gmail.com): Once old catch syntax is removed
-            // "if" condition above and this "else" branch should be deleted as
-            // type of declared variable won't matter for the catch
-            // condition.
-            ResolutionDartType type = elements.getType(declaration.type);
-            if (type == null) {
-              reporter.internalError(catchBlock, 'Catch with unresolved type.');
-            }
-            condition = buildIsNode(declaration.type, type, unwrappedException,
-                sourceInformationBuilder.buildCatch(declaration));
-            push(condition);
-          }
-        }
-      }
-
-      void visitThen() {
-        ast.CatchBlock catchBlock = link.head;
-        link = link.tail;
-        if (catchBlock.exception != null) {
-          LocalVariableElement exceptionVariable =
-              elements[catchBlock.exception];
-          localsHandler.updateLocal(exceptionVariable, unwrappedException,
-              sourceInformation:
-                  sourceInformationBuilder.buildCatch(catchBlock.exception));
-        }
-        ast.Node trace = catchBlock.trace;
-        if (trace != null) {
-          pushInvokeStatic(
-              trace, commonElements.traceFromException, [exception]);
-          HInstruction traceInstruction = pop();
-          LocalVariableElement traceVariable = elements[trace];
-          localsHandler.updateLocal(traceVariable, traceInstruction);
-        }
-        visit(catchBlock);
-      }
-
-      void visitElse() {
-        if (link.isEmpty) {
-          closeAndGotoExit(new HThrow(
-              abstractValueDomain, exception, exception.sourceInformation,
-              isRethrow: true));
-        } else {
-          ast.CatchBlock newBlock = link.head;
-          handleIf(
-              node: node,
-              visitCondition: () {
-                pushCondition(newBlock);
-              },
-              visitThen: visitThen,
-              visitElse: visitElse,
-              sourceInformation: sourceInformationBuilder.buildCatch(newBlock));
-        }
-      }
-
-      ast.CatchBlock firstBlock = link.head;
-      handleIf(
-          node: node,
-          visitCondition: () {
-            pushCondition(firstBlock);
-          },
-          visitThen: visitThen,
-          visitElse: visitElse,
-          sourceInformation: sourceInformationBuilder.buildCatch(firstBlock));
-      if (!isAborted()) endCatchBlock = close(new HGoto(abstractValueDomain));
-
-      rethrowableException = oldRethrowableException;
-      tryInstruction.catchBlock = startCatchBlock;
-      catchGraph = new SubGraph(startCatchBlock, lastOpenedBlock);
-    }
-
-    SubGraph finallyGraph = null;
-    if (node.finallyBlock != null) {
-      localsHandler = new LocalsHandler.from(savedLocals);
-      startFinallyBlock = graph.addNewBlock();
-      open(startFinallyBlock);
-      visit(node.finallyBlock);
-      if (!isAborted()) endFinallyBlock = close(new HGoto(abstractValueDomain));
-      tryInstruction.finallyBlock = startFinallyBlock;
-      finallyGraph = new SubGraph(startFinallyBlock, lastOpenedBlock);
-    }
-
-    HBasicBlock exitBlock = graph.addNewBlock();
-
-    addOptionalSuccessor(b1, b2) {
-      if (b2 != null) b1.addSuccessor(b2);
-    }
-
-    addExitTrySuccessor(successor) {
-      if (successor == null) return;
-      // Iterate over all blocks created inside this try/catch, and
-      // attach successor information to blocks that end with
-      // [HExitTry].
-      for (int i = startTryBlock.id; i < successor.id; i++) {
-        HBasicBlock block = graph.blocks[i];
-        var last = block.last;
-        if (last is HExitTry) {
-          block.addSuccessor(successor);
-        }
-      }
-    }
-
-    // Setup all successors. The entry block that contains the [HTry]
-    // has 1) the body, 2) the catch, 3) the finally, and 4) the exit
-    // blocks as successors.
-    enterBlock.addSuccessor(startTryBlock);
-    addOptionalSuccessor(enterBlock, startCatchBlock);
-    addOptionalSuccessor(enterBlock, startFinallyBlock);
-    enterBlock.addSuccessor(exitBlock);
-
-    // The body has either the catch or the finally block as successor.
-    if (endTryBlock != null) {
-      assert(startCatchBlock != null || startFinallyBlock != null);
-      endTryBlock.addSuccessor(
-          startCatchBlock != null ? startCatchBlock : startFinallyBlock);
-      endTryBlock.addSuccessor(exitBlock);
-    }
-
-    // The catch block has either the finally or the exit block as
-    // successor.
-    if (endCatchBlock != null) {
-      endCatchBlock.addSuccessor(
-          startFinallyBlock != null ? startFinallyBlock : exitBlock);
-    }
-
-    // The finally block has the exit block as successor.
-    if (endFinallyBlock != null) {
-      endFinallyBlock.addSuccessor(exitBlock);
-    }
-
-    // If a block inside try/catch aborts (eg with a return statement),
-    // we explicitly mark this block a predecessor of the catch
-    // block and the finally block.
-    addExitTrySuccessor(startCatchBlock);
-    addExitTrySuccessor(startFinallyBlock);
-
-    // Use the locals handler not altered by the catch and finally
-    // blocks.
-    localsHandler = savedLocals;
-    open(exitBlock);
-    enterBlock.setBlockFlow(
-        new HTryBlockInformation(wrapStatementGraph(bodyGraph), exception,
-            wrapStatementGraph(catchGraph), wrapStatementGraph(finallyGraph)),
-        exitBlock);
-    inTryStatement = oldInTryStatement;
-  }
-
-  visitCatchBlock(ast.CatchBlock node) {
-    visit(node.block);
-  }
-
-  visitTypedef(ast.Typedef node) {
-    failedAt(node, 'SsaFromAstMixin.visitTypedef not implemented.');
-  }
-
-  visitTypeVariable(ast.TypeVariable node) {
-    failedAt(node, 'SsaFromAstMixin.visitTypeVariable not implemented.');
-  }
-
-  /**
-   * This method is invoked before inlining the body of [function] into this
-   * [SsaBuilder].
-   */
-  void enterInlinedMethod(
-      MethodElement function,
-      ResolvedAst functionResolvedAst,
-      List<HInstruction> compiledArguments,
-      ResolutionInterfaceType instanceType) {
-    AstInliningState state = new AstInliningState(
-        function,
-        returnLocal,
-        returnType,
-        resolvedAst,
-        stack,
-        localsHandler,
-        inTryStatement,
-        isCalledOnce(functionResolvedAst.element),
-        elementInferenceResults);
-    resolvedAst = functionResolvedAst;
-    elementInferenceResults = _resultOf(functionResolvedAst.element);
-    inliningStack.add(state);
-
-    // Setting up the state of the (AST) builder is performed even when the
-    // inlined function is in IR, because the irInliner uses the [returnElement]
-    // of the AST builder.
-    setupStateForInlining(function, compiledArguments,
-        instanceType: instanceType);
-  }
-
-  void leaveInlinedMethod() {
-    HInstruction result = localsHandler.readLocal(returnLocal);
-    AstInliningState state = inliningStack.removeLast();
-    restoreState(state);
-    stack.add(result);
-  }
-
-  void doInline(ResolvedAst resolvedAst) {
-    visitInlinedFunction(resolvedAst);
-  }
-
-  void emitReturn(HInstruction value, ast.Node node) {
-    if (inliningStack.isEmpty) {
-      closeAndGotoExit(new HReturn(abstractValueDomain, value,
-          sourceInformationBuilder.buildReturn(node)));
-    } else {
-      localsHandler.updateLocal(returnLocal, value);
-    }
-  }
-
-  @override
-  void handleTypeLiteralConstantCompounds(
-      ast.SendSet node, ConstantExpression constant, CompoundRhs rhs, _) {
-    handleTypeLiteralCompound(node);
-  }
-
-  @override
-  void handleTypeVariableTypeLiteralCompounds(
-      ast.SendSet node, TypeVariableElement typeVariable, CompoundRhs rhs, _) {
-    handleTypeLiteralCompound(node);
-  }
-
-  void handleTypeLiteralCompound(ast.SendSet node) {
-    generateIsDeferredLoadedCheckOfSend(node);
-    ast.Identifier selector = node.selector;
-    generateThrowNoSuchMethod(node, selector.source,
-        argumentNodes: node.arguments);
-  }
-
-  @override
-  void visitConstantGet(ast.Send node, ConstantExpression constant, _) {
-    visitNode(node);
-  }
-
-  @override
-  void visitConstantInvoke(ast.Send node, ConstantExpression constant,
-      ast.NodeList arguments, CallStructure callStreucture, _) {
-    visitNode(node);
-  }
-
-  @override
-  void errorUndefinedBinaryExpression(
-      ast.Send node, ast.Node left, ast.Operator operator, ast.Node right, _) {
-    visitNode(node);
-  }
-
-  @override
-  void errorUndefinedUnaryExpression(
-      ast.Send node, ast.Operator operator, ast.Node expression, _) {
-    visitNode(node);
-  }
-
-  @override
-  void bulkHandleError(ast.Node node, ErroneousElement error, _) {
-    // TODO(johnniwinther): Use an uncatchable error when supported.
-    generateRuntimeError(node, error.message);
-  }
-}
-
-/**
- * Visitor that handles generation of string literals (LiteralString,
- * StringInterpolation), and otherwise delegates to the given visitor for
- * non-literal subexpressions.
- */
-class StringBuilderVisitor extends ast.Visitor {
-  final SsaAstGraphBuilder builder;
-  final ast.Node diagnosticNode;
-
-  /**
-   * The string value generated so far.
-   */
-  HInstruction result = null;
-
-  StringBuilderVisitor(this.builder, this.diagnosticNode);
-
-  void visit(ast.Node node) {
-    node.accept(this);
-  }
-
-  visitNode(ast.Node node) {
-    builder.reporter.internalError(node, 'Unexpected node.');
-  }
-
-  void visitExpression(ast.Node node) {
-    node.accept(builder);
-    HInstruction expression = builder.pop();
-
-    // We want to use HStringify when:
-    //   1. The value is known to be a primitive type, because it might get
-    //      constant-folded and codegen has some tricks with JavaScript
-    //      conversions.
-    //   2. The value can be primitive, because the library stringifier has
-    //      fast-path code for most primitives.
-    if (expression.canBePrimitive(builder.abstractValueDomain)) {
-      append(stringify(node, expression));
-      return;
-    }
-
-    // If the `toString` method is guaranteed to return a string we can call it
-    // directly.
-    Selector selector = Selectors.toString_;
-    TypeMask type = TypeMaskFactory.inferredTypeForSelector(
-        selector, expression.instructionType, builder.globalInferenceResults);
-    if (type.containsOnlyString(builder.closedWorld)) {
-      builder.pushInvokeDynamic(node, selector, expression.instructionType,
-          <HInstruction>[expression]);
-      append(builder.pop());
-      return;
-    }
-
-    append(stringify(node, expression));
-  }
-
-  void visitStringInterpolation(ast.StringInterpolation node) {
-    node.visitChildren(this);
-  }
-
-  void visitStringInterpolationPart(ast.StringInterpolationPart node) {
-    visit(node.expression);
-    visit(node.string);
-  }
-
-  void visitStringJuxtaposition(ast.StringJuxtaposition node) {
-    node.visitChildren(this);
-  }
-
-  void visitNodeList(ast.NodeList node) {
-    node.visitChildren(this);
-  }
-
-  void append(HInstruction expression) {
-    result = (result == null) ? expression : concat(result, expression);
-  }
-
-  HInstruction concat(HInstruction left, HInstruction right) {
-    HInstruction instruction =
-        new HStringConcat(left, right, builder.commonMasks.stringType);
-    builder.add(instruction);
-    return instruction;
-  }
-
-  HInstruction stringify(ast.Node node, HInstruction expression) {
-    HInstruction instruction =
-        new HStringify(expression, builder.commonMasks.stringType)
-          ..sourceInformation = expression.sourceInformation;
-    builder.add(instruction);
-    return instruction;
-  }
-}
-
-/**
- * This class visits the method that is a candidate for inlining and
- * finds whether it is too difficult to inline.
- */
-// TODO(karlklose): refactor to make it possible to distinguish between
-// implementation restrictions (for example, we *can't* inline multiple returns)
-// and heuristics (we *shouldn't* inline large functions).
-class InlineWeeder extends ast.Visitor {
-  // Invariant: *INSIDE_LOOP* > *OUTSIDE_LOOP*
-  static const INLINING_NODES_OUTSIDE_LOOP = 18;
-  static const INLINING_NODES_OUTSIDE_LOOP_ARG_FACTOR = 3;
-  static const INLINING_NODES_INSIDE_LOOP = 42;
-  static const INLINING_NODES_INSIDE_LOOP_ARG_FACTOR = 4;
-
-  bool seenReturn = false;
-  String tooDifficultReason;
-  int nodeCount = 0;
-  final int maxInliningNodes; // `null` for unbounded.
-  final bool allowLoops;
-  final bool enableUserAssertions;
-  final TreeElements elements;
-
-  InlineWeeder._(this.elements, this.maxInliningNodes, this.allowLoops,
-      this.enableUserAssertions);
-
-  bool get tooDifficult => tooDifficultReason != null;
-
-  static bool canBeInlined(ResolvedAst resolvedAst, int maxInliningNodes,
-      {bool allowLoops: false, bool enableUserAssertions: null}) {
-    return cannotBeInlinedReason(resolvedAst, maxInliningNodes,
-            allowLoops: allowLoops,
-            enableUserAssertions: enableUserAssertions) ==
-        null;
-  }
-
-  static String cannotBeInlinedReason(
-      ResolvedAst resolvedAst, int maxInliningNodes,
-      {bool allowLoops: false, bool enableUserAssertions: null}) {
-    assert(enableUserAssertions is bool); // Ensure we passed it.
-    if (resolvedAst.elements.containsTryStatement) return 'try';
-
-    InlineWeeder weeder = new InlineWeeder._(resolvedAst.elements,
-        maxInliningNodes, allowLoops, enableUserAssertions);
-    ast.FunctionExpression functionExpression = resolvedAst.node;
-
-    weeder.visit(functionExpression.initializers);
-    weeder.visit(functionExpression.body);
-    weeder.visit(functionExpression.asyncModifier);
-    return weeder.tooDifficultReason;
-  }
-
-  bool registerNode() {
-    if (maxInliningNodes == null) return true;
-    if (nodeCount++ > maxInliningNodes) {
-      tooDifficultReason = 'too many nodes';
-      return false;
-    } else {
-      return true;
-    }
-  }
-
-  void visit(ast.Node node) {
-    if (node != null) node.accept(this);
-  }
-
-  void visitNode(ast.Node node) {
-    if (!registerNode()) return;
-    if (seenReturn) {
-      tooDifficultReason = 'code after return';
-    } else {
-      node.visitChildren(this);
-    }
-  }
-
-  @override
-  void visitAssert(ast.Assert node) {
-    if (enableUserAssertions) {
-      visitNode(node);
-    }
-  }
-
-  @override
-  void visitAsyncModifier(ast.AsyncModifier node) {
-    if (node.isYielding || node.isAsynchronous) {
-      tooDifficultReason = 'async/await';
-    }
-  }
-
-  void visitFunctionExpression(ast.Node node) {
-    if (!registerNode()) return;
-    tooDifficultReason = 'closure';
-  }
-
-  void visitFunctionDeclaration(ast.Node node) {
-    if (!registerNode()) return;
-    tooDifficultReason = 'closure';
-  }
-
-  void visitSend(ast.Send node) {
-    // TODO(sra): Investigate following, and possibly count occurrences, since
-    // repeated references might cause a temporary to be assigned.
-    //
-    //     Element element = elements[node];
-    //     if (element != null && element.isParameter) {
-    //       // Don't count as additional node, since it's likely that passing
-    //       // the argument would cost us as much space as we inline.
-    //       return;
-    //     }
-    if (!registerNode()) return;
-    node.visitChildren(this);
-  }
-
-  visitLoop(ast.Node node) {
-    // It's actually not difficult to inline a method with a loop, but
-    // our measurements show that it's currently better to not inline a
-    // method that contains a loop.
-    if (!allowLoops) {
-      tooDifficultReason = 'loop';
-    }
-  }
-
-  void visitRedirectingFactoryBody(ast.RedirectingFactoryBody node) {
-    if (!registerNode()) return;
-    tooDifficultReason = 'redirecting factory';
-  }
-
-  void visitConditional(ast.Conditional node) {
-    // Heuristic: In "parameter ? A : B" there is a high probability that
-    // parameter is a constant. Assuming the parameter is constant, we can
-    // compute a count that is bounded by the largest arm rather than the sum of
-    // both arms.
-    visit(node.condition);
-    if (tooDifficult) return;
-    int commonPrefixCount = nodeCount;
-
-    visit(node.thenExpression);
-    if (tooDifficult) return;
-    int thenCount = nodeCount - commonPrefixCount;
-
-    nodeCount = commonPrefixCount;
-    visit(node.elseExpression);
-    if (tooDifficult) return;
-    int elseCount = nodeCount - commonPrefixCount;
-
-    nodeCount = commonPrefixCount + thenCount + elseCount;
-    if (node.condition.asSend() != null &&
-        elements[node.condition]?.isParameter == true) {
-      nodeCount =
-          commonPrefixCount + (thenCount > elseCount ? thenCount : elseCount);
-    }
-    // This is last so that [tooDifficult] is always updated.
-    if (!registerNode()) return;
-  }
-
-  void visitRethrow(ast.Rethrow node) {
-    if (!registerNode()) return;
-    tooDifficultReason = 'rethrow';
-  }
-
-  void visitReturn(ast.Return node) {
-    if (!registerNode()) return;
-    if (seenReturn || identical(node.beginToken.stringValue, 'native')) {
-      tooDifficultReason = 'code after return';
-      return;
-    }
-    node.visitChildren(this);
-    seenReturn = true;
-  }
-
-  void visitThrow(ast.Throw node) {
-    if (!registerNode()) return;
-    // For now, we don't want to handle throw after a return even if
-    // it is in an "if".
-    if (seenReturn) {
-      tooDifficultReason = 'code after return';
-    } else {
-      node.visitChildren(this);
-    }
-  }
-}
-
-abstract class InliningState {
-  /**
-   * Invariant: [function] must be an implementation element.
-   */
-  final MethodElement function;
-
-  InliningState(this.function) {
-    assert(function.isImplementation);
-  }
-}
-
-class AstInliningState extends InliningState {
-  final Local oldReturnLocal;
-  final ResolutionDartType oldReturnType;
-  final ResolvedAst oldResolvedAst;
-  final List<HInstruction> oldStack;
-  final LocalsHandler oldLocalsHandler;
-  final bool inTryStatement;
-  final bool allFunctionsCalledOnce;
-  final GlobalTypeInferenceElementResult oldElementInferenceResults;
-
-  AstInliningState(
-      MethodElement function,
-      this.oldReturnLocal,
-      this.oldReturnType,
-      this.oldResolvedAst,
-      this.oldStack,
-      this.oldLocalsHandler,
-      this.inTryStatement,
-      this.allFunctionsCalledOnce,
-      this.oldElementInferenceResults)
-      : super(function);
-}
-
-class AstTypeBuilder extends TypeBuilder {
-  AstTypeBuilder(GraphBuilder builder) : super(builder);
-
-  ClassTypeVariableAccess computeTypeVariableAccess(MemberEntity member) {
-    bool isClosure = member.enclosingClass.isClosure;
-    if (isClosure) {
-      ClosureClassElement closureClass = member.enclosingClass;
-      LocalFunctionElement localFunction = closureClass.methodElement;
-      member = localFunction.memberContext;
-    }
-    bool isInConstructorContext =
-        member.isConstructor || member is ConstructorBodyEntity;
-    if (isClosure) {
-      if ((member is ConstructorEntity && member.isFactoryConstructor) ||
-          (isInConstructorContext)) {
-        // The type variable is used from a closure in a factory constructor.
-        // The value of the type argument is stored as a local on the closure
-        // itself.
-        return ClassTypeVariableAccess.parameter;
-      } else if (member.isFunction ||
-          member.isGetter ||
-          member.isSetter ||
-          isInConstructorContext) {
-        // The type variable is stored on the "enclosing object" and needs to be
-        // accessed using the this-reference in the closure.
-        return ClassTypeVariableAccess.property;
-      } else {
-        assert(member.isField);
-        // The type variable is stored in a parameter of the method.
-        return ClassTypeVariableAccess.parameter;
-      }
-    } else if (isInConstructorContext) {
-      // The type variable is stored in a parameter of the method.
-      return ClassTypeVariableAccess.parameter;
-    } else if (member.isInstanceMember) {
-      if (member.isField) {
-        // The type variable is stored in a parameter or on `this` depending
-        // on the context.
-        return ClassTypeVariableAccess.instanceField;
-      } else {
-        // The type variable is stored on the object.
-        return ClassTypeVariableAccess.property;
-      }
-    } else {
-      return ClassTypeVariableAccess.none;
-    }
-  }
-
-  /// In checked mode, generate type tests for the parameters of the inlined
-  /// function.
-  void potentiallyCheckInlinedParameterTypes(covariant MethodElement function) {
-    if (!checkOrTrustTypes) return;
-
-    FunctionSignature signature = function.functionSignature;
-    signature.forEachParameter((_parameter) {
-      ParameterElement parameter = _parameter;
-      HInstruction argument = builder.localsHandler.readLocal(parameter);
-      potentiallyCheckOrTrustTypeOfParameter(argument, parameter.type);
-    });
-  }
-}
diff --git a/pkg/compiler/lib/src/ssa/builder_kernel.dart b/pkg/compiler/lib/src/ssa/builder_kernel.dart
index 6836904..26834cf 100644
--- a/pkg/compiler/lib/src/ssa/builder_kernel.dart
+++ b/pkg/compiler/lib/src/ssa/builder_kernel.dart
@@ -17,11 +17,8 @@
         StringConstantValue,
         TypeConstantValue;
 import '../dump_info.dart';
-import '../elements/elements.dart' show ErroneousElement;
 import '../elements/entities.dart';
 import '../elements/jumps.dart';
-import '../elements/resolution_types.dart'
-    show MalformedType, MethodTypeVariableType;
 import '../elements/types.dart';
 import '../io/source_information.dart';
 import '../js/js.dart' as js;
@@ -34,7 +31,6 @@
 import '../kernel/element_map.dart';
 import '../kernel/kernel_backend_strategy.dart';
 import '../native/native.dart' as native;
-import '../resolution/tree_elements.dart';
 import '../types/masks.dart';
 import '../types/types.dart';
 import '../universe/call_structure.dart';
@@ -97,10 +93,6 @@
   @override
   JavaScriptBackend get backend => compiler.backend;
 
-  @override
-  TreeElements get elements =>
-      throw new UnsupportedError('KernelSsaGraphBuilder.elements');
-
   final SourceInformationStrategy<ir.Node> _sourceInformationStrategy;
   final KernelToElementMapForBuilding _elementMap;
   final GlobalTypeInferenceResults _globalInferenceResults;
@@ -335,7 +327,7 @@
       // Use dynamic type because the type computed by the inferrer is
       // narrowed to the type annotation.
       HInstruction parameter =
-          new HParameterValue(field, commonMasks.dynamicType);
+          new HParameterValue(field, abstractValueDomain.dynamicType);
       // Add the parameter as the last instruction of the entry block.
       // If the method is intercepted, we want the actual receiver
       // to be the first parameter.
@@ -377,7 +369,7 @@
       return typeBuilder.potentiallyCheckOrTrustTypeOfAssignment(value, type,
           kind: HTypeConversion.BOOLEAN_CONVERSION_CHECK);
     }
-    HInstruction result = new HBoolify(value, commonMasks.boolType);
+    HInstruction result = new HBoolify(value, abstractValueDomain.boolType);
     add(result);
     return result;
   }
@@ -400,7 +392,8 @@
       TypeVariableType typeVariableType = _typeVariable;
       HInstruction param;
       if (needsTypeArguments) {
-        param = addParameter(typeVariableType.element, commonMasks.nonNullType);
+        param = addParameter(
+            typeVariableType.element, abstractValueDomain.nonNullType);
       } else {
         // Unused, so bind to `dynamic`.
         param = graph.addConstantNull(closedWorld);
@@ -428,7 +421,8 @@
     typeVariables.forEach((TypeVariableType typeVariableType) {
       HInstruction param;
       if (needsTypeArguments) {
-        param = addParameter(typeVariableType.element, commonMasks.nonNullType);
+        param = addParameter(
+            typeVariableType.element, abstractValueDomain.nonNullType);
       } else {
         // Unused, so bind to `dynamic`.
         param = graph.addConstantNull(closedWorld);
@@ -515,7 +509,7 @@
       // Null guard ensures an error if we are being called from an explicit
       // 'new' of the constructor instead of via an upgrade. It is optimized out
       // if there are field initializers.
-      add(new HFieldGet(null, newObject, commonMasks.dynamicType,
+      add(new HFieldGet(null, newObject, abstractValueDomain.dynamicType,
           isAssignable: false));
       for (int i = 0; i < fields.length; i++) {
         add(new HFieldSet(abstractValueDomain, fields[i], newObject,
@@ -541,7 +535,7 @@
             TypeInfoExpressionKind.INSTANCE,
             thisType,
             typeArguments,
-            commonMasks.dynamicType);
+            abstractValueDomain.dynamicType);
         add(typeInfo);
         constructorArguments.add(typeInfo);
       }
@@ -645,8 +639,8 @@
   void _invokeConstructorBody(ir.Constructor constructor,
       List<HInstruction> inputs, SourceInformation sourceInformation) {
     MemberEntity constructorBody = _elementMap.getConstructorBody(constructor);
-    HInvokeConstructorBody invoke = new HInvokeConstructorBody(
-        constructorBody, inputs, commonMasks.nonNullType, sourceInformation);
+    HInvokeConstructorBody invoke = new HInvokeConstructorBody(constructorBody,
+        inputs, abstractValueDomain.nonNullType, sourceInformation);
     add(invoke);
   }
 
@@ -941,7 +935,7 @@
         TypeInfoExpressionKind.COMPLETE,
         _elementMap.getFunctionType(originalClosureNode),
         typeArguments,
-        commonMasks.functionType));
+        abstractValueDomain.functionType));
     HInstruction value = pop();
     close(new HReturn(abstractValueDomain, value,
             _sourceInformationBuilder.buildReturn(originalClosureNode)))
@@ -978,7 +972,7 @@
             visitCondition: () {
               HParameterValue parameter = parameters.values.first;
               push(new HIdentity(parameter, graph.addConstantNull(closedWorld),
-                  null, commonMasks.boolType));
+                  null, abstractValueDomain.boolType));
             },
             visitThen: () {
               closeAndGotoExit(new HReturn(
@@ -990,10 +984,35 @@
             sourceInformation: _sourceInformationBuilder.buildIf(functionNode));
       }
     }
+    if (const bool.fromEnvironment('unreachable-throw')) {
+      var emptyParameters = parameters.values
+          .where((p) => abstractValueDomain.isEmpty(p.instructionType));
+      if (emptyParameters.length > 0) {
+        addComment('${emptyParameters} inferred as [empty]');
+        add(new HInvokeStatic(
+            commonElements.assertUnreachableMethod,
+            <HInstruction>[],
+            abstractValueDomain.dynamicType,
+            const <DartType>[]));
+        closeFunction();
+        return;
+      }
+    }
     functionNode.body.accept(this);
     closeFunction();
   }
 
+  /// Adds a JavaScript comment to the output. The comment will be omitted in
+  /// minified mode.  Each line in [text] is preceded with `//` and indented.
+  /// Use sparingly. In order for the comment to be retained it is modeled as
+  /// having side effects which will inhibit code motion.
+  // TODO(sra): Figure out how to keep comment anchored without effects.
+  void addComment(String text) {
+    add(new HForeignCode(js.js.statementTemplateYielding(new js.Comment(text)),
+        abstractValueDomain.dynamicType, <HInstruction>[],
+        isStatement: true));
+  }
+
   /// Builds a SSA graph for a sync*/async/async* generator.
   void buildGenerator(FunctionEntity function, ir.FunctionNode functionNode) {
     // TODO(sra): Optimize by generating a merged entry + body when (1) there
@@ -1047,7 +1066,7 @@
     push(new HInvokeGeneratorBody(
         body,
         inputs,
-        commonMasks.dynamicType, // TODO: better type.
+        abstractValueDomain.dynamicType, // TODO: better type.
         sourceInformation));
 
     closeAndGotoExit(
@@ -1071,6 +1090,9 @@
     // because that is where the type guards will also be inserted.
     // This way we ensure that a type guard will dominate the type
     // check.
+
+    checkTypeVariableBounds(targetElement);
+
     MemberDefinition definition =
         _elementMap.getMemberDefinition(targetElement);
     bool nodeIsConstructorBody = definition.kind == MemberKind.constructorBody;
@@ -1092,8 +1114,6 @@
 
     function.positionalParameters.forEach(_handleParameter);
     function.namedParameters.toList()..forEach(_handleParameter);
-
-    checkTypeVariableBounds(targetElement);
   }
 
   void checkTypeVariableBounds(FunctionEntity method) {
@@ -1157,7 +1177,7 @@
           _pushStaticInvocation(
               _commonElements.closureConverter,
               [argument, graph.addConstantInt(arity, closedWorld)],
-              commonMasks.dynamicType,
+              abstractValueDomain.dynamicType,
               const <DartType>[]);
           argument = pop();
         }
@@ -1167,7 +1187,7 @@
       String arguments = templateArguments.join(',');
 
       // TODO(sra): Use declared type or NativeBehavior type.
-      TypeMask typeMask = commonMasks.dynamicType;
+      TypeMask typeMask = abstractValueDomain.dynamicType;
       String template;
       if (targetElement.isGetter) {
         template = '${templateReceiver}$nativeName';
@@ -1265,8 +1285,10 @@
   void _trap(String message) {
     HInstruction nullValue = graph.addConstantNull(closedWorld);
     HInstruction errorMessage = graph.addConstantString(message, closedWorld);
-    HInstruction trap = new HForeignCode(js.js.parseForeignJS("#.#"),
-        commonMasks.dynamicType, <HInstruction>[nullValue, errorMessage]);
+    HInstruction trap = new HForeignCode(
+        js.js.parseForeignJS("#.#"),
+        abstractValueDomain.dynamicType,
+        <HInstruction>[nullValue, errorMessage]);
     trap.sideEffects
       ..setAllSideEffects()
       ..setDependsOnSomething();
@@ -1307,7 +1329,7 @@
     push(new HInvokeStatic(
         commonElements.loadDeferredLibrary,
         [graph.addConstantString(loadId, closedWorld)],
-        commonMasks.nonNullType,
+        abstractValueDomain.nonNullType,
         const <DartType>[],
         targetCanThrow: false));
   }
@@ -1482,7 +1504,8 @@
     HInstruction originalLength = null; // Set for growable lists.
 
     HInstruction buildGetLength(SourceInformation sourceInformation) {
-      HGetLength result = new HGetLength(array, commonMasks.positiveIntType,
+      HGetLength result = new HGetLength(
+          array, abstractValueDomain.positiveIntType,
           isAssignable: !isFixed)
         ..sourceInformation = sourceInformation;
       add(result);
@@ -1499,7 +1522,8 @@
       SourceInformation sourceInformation =
           _sourceInformationBuilder.buildForInMoveNext(node);
       HInstruction length = buildGetLength(sourceInformation);
-      push(new HIdentity(length, originalLength, null, commonMasks.boolType)
+      push(new HIdentity(
+          length, originalLength, null, abstractValueDomain.boolType)
         ..sourceInformation = sourceInformation);
       _pushStaticInvocation(
           _commonElements.checkConcurrentModificationError,
@@ -1532,7 +1556,7 @@
           sourceInformation: sourceInformation);
       HInstruction length = buildGetLength(sourceInformation);
       HInstruction compare =
-          new HLess(index, length, null, commonMasks.boolType)
+          new HLess(index, length, null, abstractValueDomain.boolType)
             ..sourceInformation = sourceInformation;
       add(compare);
       return compare;
@@ -1584,7 +1608,7 @@
           sourceInformation: sourceInformation);
       HInstruction one = graph.addConstantInt(1, closedWorld);
       HInstruction addInstruction =
-          new HAdd(index, one, null, commonMasks.positiveIntType)
+          new HAdd(index, one, null, abstractValueDomain.positiveIntType)
             ..sourceInformation = sourceInformation;
       add(addInstruction);
       localsHandler.updateLocal(indexVariable, addInstruction,
@@ -1759,7 +1783,7 @@
     FunctionEntity typeInfoSetterFn = _commonElements.setRuntimeTypeInfo;
     // TODO(efortuna): Insert source information in this static invocation.
     _pushStaticInvocation(typeInfoSetterFn, <HInstruction>[newObject, typeInfo],
-        commonMasks.dynamicType, const <DartType>[],
+        abstractValueDomain.dynamicType, const <DartType>[],
         sourceInformation: sourceInformation);
 
     // The new object will now be referenced through the
@@ -1972,17 +1996,7 @@
     }
 
     DartType type = _elementMap.getDartType(node.type);
-    if (type.isMalformed) {
-      // TODO(johnniwinther): This branch is no longer needed.
-      if (type is MalformedType) {
-        ErroneousElement element = type.element;
-        generateTypeError(element.message, sourceInformation);
-      } else {
-        assert(type is MethodTypeVariableType);
-        stack.add(expressionInstruction);
-      }
-    } else if (!node.isTypeError ||
-        options.implicitDowncastCheckPolicy.isEmitted) {
+    if (!node.isTypeError || options.implicitDowncastCheckPolicy.isEmitted) {
       HInstruction converted = typeBuilder.buildTypeConversion(
           expressionInstruction,
           localsHandler.substInContext(type),
@@ -2394,8 +2408,8 @@
       // null, so we don't drop into the while loop.
       void buildCondition() {
         js.Template code = js.js.parseForeignJS('#');
-        push(new HForeignCode(
-            code, commonMasks.boolType, [localsHandler.readLocal(switchTarget)],
+        push(new HForeignCode(code, abstractValueDomain.boolType,
+            [localsHandler.readLocal(switchTarget)],
             nativeBehavior: native.NativeBehavior.PURE));
       }
 
@@ -2773,8 +2787,11 @@
     HInstruction value = typeBuilder.analyzeTypeArgument(
         dartType, sourceElement,
         sourceInformation: sourceInformation);
-    _pushStaticInvocation(_commonElements.runtimeTypeToString,
-        <HInstruction>[value], commonMasks.stringType, const <DartType>[],
+    _pushStaticInvocation(
+        _commonElements.runtimeTypeToString,
+        <HInstruction>[value],
+        abstractValueDomain.stringType,
+        const <DartType>[],
         sourceInformation: sourceInformation);
     _pushStaticInvocation(
         _commonElements.createRuntimeType,
@@ -3291,7 +3308,7 @@
       return globalInferenceResults
               .resultOfMember(element)
               .typeOfNewList(node) ??
-          commonMasks.dynamicType;
+          abstractValueDomain.dynamicType;
     }
 
     if (isFixedListConstructorCall) {
@@ -3307,7 +3324,7 @@
         HTypeConversion conversion = new HTypeConversion(
             null,
             HTypeConversion.ARGUMENT_TYPE_CHECK,
-            commonMasks.numType,
+            abstractValueDomain.numType,
             lengthInput,
             sourceInformation);
         add(conversion);
@@ -3331,8 +3348,8 @@
       }
 
       var inferredType = _inferredTypeOfNewList(invocation);
-      resultType = inferredType.containsAll(closedWorld)
-          ? commonMasks.fixedListType
+      resultType = abstractValueDomain.containsAll(inferredType)
+          ? abstractValueDomain.fixedListType
           : inferredType;
       HForeignCode foreign = new HForeignCode(
           code, resultType, <HInstruction>[lengthInput],
@@ -3349,14 +3366,14 @@
         js.Template code = js.js.parseForeignJS(r'#.fixed$length = Array');
         // We set the instruction as [canThrow] to avoid it being dead code.
         // We need a finer grained side effect.
-        add(new HForeignCode(code, commonMasks.nullType, [stack.last],
+        add(new HForeignCode(code, abstractValueDomain.nullType, [stack.last],
             throwBehavior: native.NativeThrowBehavior.MAY));
       }
     } else if (isGrowableListConstructorCall) {
       push(buildLiteralList(<HInstruction>[]));
       var inferredType = _inferredTypeOfNewList(invocation);
-      resultType = inferredType.containsAll(closedWorld)
-          ? commonMasks.growableListType
+      resultType = abstractValueDomain.containsAll(inferredType)
+          ? abstractValueDomain.growableListType
           : inferredType;
       stack.last.instructionType = resultType;
     } else if (isJSArrayTypedConstructor) {
@@ -3459,7 +3476,7 @@
       TypeVariableType variable = _typeVariable;
       typeArguments.add(variable);
       HInstruction readType = new HTypeInfoReadVariable.intercepted(
-          variable, interceptor, object, commonMasks.dynamicType);
+          variable, interceptor, object, abstractValueDomain.dynamicType);
       add(readType);
       inputs.add(readType);
     });
@@ -3470,7 +3487,7 @@
     Selector selector =
         new Selector.callClosure(0, const <String>[], typeArguments.length);
     push(new HInvokeClosure(
-        selector, inputs, commonMasks.dynamicType, typeArguments));
+        selector, inputs, abstractValueDomain.dynamicType, typeArguments));
 
     return true;
   }
@@ -3480,10 +3497,6 @@
     String name = target.name.name;
     if (name == 'JS') {
       handleForeignJs(invocation);
-    } else if (name == 'JS_CURRENT_ISOLATE_CONTEXT') {
-      // TODO(sigmund): delete. The only reference left to this foreign function
-      // is from the deprecated dart:mirrors code.
-      handleForeignJsCurrentIsolateContext(invocation);
     } else if (name == 'DART_CLOSURE_TO_JS') {
       handleForeignDartClosureToJs(invocation, 'DART_CLOSURE_TO_JS');
     } else if (name == 'RAW_DART_FUNCTION_REF') {
@@ -3588,22 +3601,6 @@
     return stringConstant.stringValue;
   }
 
-  void handleForeignJsCurrentIsolateContext(ir.StaticInvocation invocation) {
-    if (_unexpectedForeignArguments(invocation,
-        minPositional: 0, maxPositional: 0)) {
-      // Result expected on stack.
-      stack.add(graph.addConstantNull(closedWorld));
-      return;
-    }
-
-    // Isolates cannot be spawned, so we just generate code to fetch the static
-    // state.
-    String name = namer.staticStateHolder;
-    push(new HForeignCode(
-        js.js.parseForeignJS(name), commonMasks.dynamicType, <HInstruction>[],
-        nativeBehavior: native.NativeBehavior.DEPENDS_OTHER));
-  }
-
   void handleForeignDartClosureToJs(
       ir.StaticInvocation invocation, String name) {
     // TODO(sra): Do we need to wrap the closure in something that saves the
@@ -3634,7 +3631,7 @@
             push(new HForeignCode(
                 js.js.expressionTemplateYielding(emitter
                     .staticFunctionAccess(_elementMap.getMethod(staticTarget))),
-                commonMasks.dynamicType,
+                abstractValueDomain.dynamicType,
                 <HInstruction>[],
                 nativeBehavior: native.NativeBehavior.PURE,
                 foreignFunction: _elementMap.getMethod(staticTarget)));
@@ -3667,7 +3664,7 @@
     SideEffects sideEffects = new SideEffects.empty();
     sideEffects.setAllSideEffects();
     push(new HForeignCode(js.js.parseForeignJS("$isolateName = #"),
-        commonMasks.dynamicType, inputs,
+        abstractValueDomain.dynamicType, inputs,
         nativeBehavior: native.NativeBehavior.CHANGES_OTHER,
         effects: sideEffects));
   }
@@ -3681,7 +3678,7 @@
     }
 
     push(new HForeignCode(js.js.parseForeignJS(namer.staticStateHolder),
-        commonMasks.dynamicType, <HInstruction>[],
+        abstractValueDomain.dynamicType, <HInstruction>[],
         nativeBehavior: native.NativeBehavior.DEPENDS_OTHER));
   }
 
@@ -3918,7 +3915,8 @@
       return;
     }
     List<HInstruction> inputs = _visitPositionalArguments(invocation.arguments);
-    push(new HStringConcat(inputs[0], inputs[1], commonMasks.stringType));
+    push(new HStringConcat(
+        inputs[0], inputs[1], abstractValueDomain.stringType));
   }
 
   void _pushStaticInvocation(MemberEntity target, List<HInstruction> arguments,
@@ -4068,14 +4066,14 @@
       }
       // TODO(efortuna): Source information.
       return new HForeignCode(
-          codeTemplate, commonMasks.dynamicType, filteredArguments,
+          codeTemplate, abstractValueDomain.dynamicType, filteredArguments,
           nativeBehavior: nativeBehavior);
     }
 
     var target = new HForeignCode(
         js.js.parseForeignJS("${nativeData.getFixedBackendMethodPath(element)}."
             "${nativeData.getFixedBackendName(element)}"),
-        commonMasks.dynamicType,
+        abstractValueDomain.dynamicType,
         <HInstruction>[]);
     add(target);
     // Strip off trailing arguments that were not specified.
@@ -4125,7 +4123,8 @@
     nativeBehavior.codeTemplate = codeTemplate;
 
     // TODO(efortuna): Add source information.
-    return new HForeignCode(codeTemplate, commonMasks.dynamicType, inputs,
+    return new HForeignCode(
+        codeTemplate, abstractValueDomain.dynamicType, inputs,
         nativeBehavior: nativeBehavior);
   }
 
@@ -4186,7 +4185,7 @@
       return;
     }
     HInstruction instruction = new HInvokeStatic(
-        target, arguments, commonMasks.functionType, <DartType>[],
+        target, arguments, abstractValueDomain.functionType, <DartType>[],
         targetCanThrow: targetCanThrow);
     // TODO(sra): ..sourceInformation = sourceInformation
     instruction.sideEffects
@@ -4225,7 +4224,7 @@
   HInterceptor _interceptorFor(
       HInstruction intercepted, SourceInformation sourceInformation) {
     HInterceptor interceptor =
-        new HInterceptor(intercepted, commonMasks.nonNullType)
+        new HInterceptor(intercepted, abstractValueDomain.nonNullType)
           ..sourceInformation = sourceInformation;
     add(interceptor);
     return interceptor;
@@ -4291,7 +4290,7 @@
           argumentNamesInstruction,
           graph.addConstantInt(typeArguments.length, closedWorld),
         ],
-        commonMasks.dynamicType,
+        abstractValueDomain.dynamicType,
         typeArguments);
 
     _buildInvokeSuper(Selectors.noSuchMethod_, containingClass, noSuchMethod,
@@ -4589,11 +4588,11 @@
         representation,
       ];
       _pushStaticInvocation(_commonElements.functionTypeTest, inputs,
-          commonMasks.boolType, const <DartType>[],
+          abstractValueDomain.boolType, const <DartType>[],
           sourceInformation: sourceInformation);
       HInstruction call = pop();
-      push(new HIs.compound(typeValue, expression, call, commonMasks.boolType,
-          sourceInformation));
+      push(new HIs.compound(typeValue, expression, call,
+          abstractValueDomain.boolType, sourceInformation));
       return;
     }
 
@@ -4605,11 +4604,11 @@
         representation,
       ];
       _pushStaticInvocation(_commonElements.futureOrTest, inputs,
-          commonMasks.boolType, const <DartType>[],
+          abstractValueDomain.boolType, const <DartType>[],
           sourceInformation: sourceInformation);
       HInstruction call = pop();
-      push(new HIs.compound(typeValue, expression, call, commonMasks.boolType,
-          sourceInformation));
+      push(new HIs.compound(typeValue, expression, call,
+          abstractValueDomain.boolType, sourceInformation));
       return;
     }
 
@@ -4619,11 +4618,11 @@
       _pushStaticInvocation(
           _commonElements.checkSubtypeOfRuntimeType,
           <HInstruction>[expression, runtimeType],
-          commonMasks.boolType,
+          abstractValueDomain.boolType,
           const <DartType>[],
           sourceInformation: sourceInformation);
-      push(new HIs.variable(typeValue, expression, pop(), commonMasks.boolType,
-          sourceInformation));
+      push(new HIs.variable(typeValue, expression, pop(),
+          abstractValueDomain.boolType, sourceInformation));
       return;
     }
 
@@ -4648,16 +4647,16 @@
         asFieldName
       ];
       _pushStaticInvocation(_commonElements.checkSubtype, inputs,
-          commonMasks.boolType, const <DartType>[],
+          abstractValueDomain.boolType, const <DartType>[],
           sourceInformation: sourceInformation);
-      push(new HIs.compound(typeValue, expression, pop(), commonMasks.boolType,
-          sourceInformation));
+      push(new HIs.compound(typeValue, expression, pop(),
+          abstractValueDomain.boolType, sourceInformation));
       return;
     }
 
     if (backend.hasDirectCheckFor(closedWorld.commonElements, typeValue)) {
-      push(new HIs.direct(
-          typeValue, expression, commonMasks.boolType, sourceInformation));
+      push(new HIs.direct(typeValue, expression, abstractValueDomain.boolType,
+          sourceInformation));
       return;
     }
     // The interceptor is not always needed.  It is removed by optimization
@@ -4666,7 +4665,7 @@
         typeValue,
         expression,
         _interceptorFor(expression, sourceInformation),
-        commonMasks.boolType,
+        abstractValueDomain.boolType,
         sourceInformation));
     return;
   }
@@ -4736,7 +4735,7 @@
   @override
   void visitNot(ir.Not node) {
     node.operand.accept(this);
-    push(new HNot(popBoolified(), commonMasks.boolType)
+    push(new HNot(popBoolified(), abstractValueDomain.boolType)
       ..sourceInformation = _sourceInformationBuilder.buildUnary(node));
   }
 
@@ -4969,7 +4968,8 @@
       if (function.isInstanceMember &&
           function is! ConstructorBodyEntity &&
           (mask == null || mask.isNullable)) {
-        add(new HFieldGet(null, providedArguments[0], commonMasks.dynamicType,
+        add(new HFieldGet(
+            null, providedArguments[0], abstractValueDomain.dynamicType,
             isAssignable: false)
           ..sourceInformation = sourceInformation);
       }
@@ -5259,7 +5259,7 @@
 
   /// Run this builder on the body of the [function] to be inlined.
   void _visitInlinedFunction(FunctionEntity function) {
-    typeBuilder.potentiallyCheckInlinedParameterTypes(function);
+    _potentiallyCheckInlinedParameterTypes(function);
 
     MemberDefinition definition = _elementMap.getMemberDefinition(function);
     switch (definition.kind) {
@@ -5296,6 +5296,44 @@
     failedAt(function, "Unexpected inlined function: $definition");
   }
 
+  /// Generates type tests for the parameters of the inlined function.
+  void _potentiallyCheckInlinedParameterTypes(FunctionEntity function) {
+    if (!typeBuilder.checkOrTrustTypes) return;
+
+    // TODO(sra): Incorporate properties of call site to help determine which
+    // type parameters and value parameters need to be checked.
+    bool trusted = false;
+    if (options.strongMode) {
+      if (function.isStatic ||
+          function.isTopLevel ||
+          function.isConstructor ||
+          function is ConstructorBodyEntity) {
+        // We inline static methods, top-level methods, constructors and
+        // constructor bodies only from direct call sites.
+        trusted = true;
+      }
+    }
+
+    if (!trusted) {
+      checkTypeVariableBounds(function);
+    }
+
+    KernelToLocalsMap localsMap = _globalLocalsMap.getLocalsMap(function);
+    forEachOrderedParameter(_globalLocalsMap, _elementMap, function,
+        (Local parameter) {
+      HInstruction argument = localsHandler.readLocal(parameter);
+      DartType type = localsMap.getLocalType(_elementMap, parameter);
+      HInstruction checkedOrTrusted;
+      if (trusted) {
+        checkedOrTrusted = typeBuilder.trustTypeOfParameter(argument, type);
+      } else {
+        checkedOrTrusted =
+            typeBuilder.potentiallyCheckOrTrustTypeOfParameter(argument, type);
+      }
+      localsHandler.updateLocal(parameter, checkedOrTrusted);
+    });
+  }
+
   bool get _allInlinedFunctionsCalledOnce {
     return _inliningStack.isEmpty || _inliningStack.last.allFunctionsCalledOnce;
   }
@@ -5320,7 +5358,7 @@
       add(new HInvokeStatic(
           commonElements.traceHelper,
           <HInstruction>[nameConstant],
-          commonMasks.dynamicType,
+          abstractValueDomain.dynamicType,
           const <DartType>[]));
     }
   }
@@ -5336,7 +5374,7 @@
       add(new HInvokeStatic(
           commonElements.traceHelper,
           <HInstruction>[idConstant, nameConstant],
-          commonMasks.dynamicType,
+          abstractValueDomain.dynamicType,
           const <DartType>[]));
     }
   }
@@ -5696,8 +5734,9 @@
     kernelBuilder.open(startCatchBlock);
     // Note that the name of this local is irrelevant.
     SyntheticLocal local = kernelBuilder.localsHandler.createLocal('exception');
-    exception = new HLocalValue(local, kernelBuilder.commonMasks.nonNullType)
-      ..sourceInformation = trySourceInformation;
+    exception =
+        new HLocalValue(local, kernelBuilder.abstractValueDomain.nonNullType)
+          ..sourceInformation = trySourceInformation;
     kernelBuilder.add(exception);
     HInstruction oldRethrowableException = kernelBuilder.rethrowableException;
     kernelBuilder.rethrowableException = exception;
@@ -5818,21 +5857,6 @@
   ClassTypeVariableAccess computeTypeVariableAccess(MemberEntity member) {
     return _elementMap.getClassTypeVariableAccessForMember(member);
   }
-
-  /// In checked mode, generate type tests for the parameters of the inlined
-  /// function.
-  void potentiallyCheckInlinedParameterTypes(FunctionEntity function) {
-    if (!checkOrTrustTypes) return;
-
-    KernelToLocalsMap localsMap = _globalLocalsMap.getLocalsMap(function);
-    forEachOrderedParameter(_globalLocalsMap, _elementMap, function,
-        (Local parameter) {
-      HInstruction argument = builder.localsHandler.readLocal(parameter);
-      potentiallyCheckOrTrustTypeOfParameter(
-          argument, localsMap.getLocalType(_elementMap, parameter));
-    });
-    builder.checkTypeVariableBounds(function);
-  }
 }
 
 class _ErroneousInitializerVisitor extends ir.Visitor<bool> {
diff --git a/pkg/compiler/lib/src/ssa/codegen.dart b/pkg/compiler/lib/src/ssa/codegen.dart
index 49cf09b..5d70634 100644
--- a/pkg/compiler/lib/src/ssa/codegen.dart
+++ b/pkg/compiler/lib/src/ssa/codegen.dart
@@ -10,7 +10,6 @@
 import '../constants/constant_system.dart';
 import '../constants/values.dart';
 import '../common_elements.dart' show CommonElements;
-import '../elements/elements.dart' show MethodElement;
 import '../elements/entities.dart';
 import '../elements/jumps.dart';
 import '../elements/types.dart';
@@ -27,7 +26,7 @@
 import '../native/native.dart' as native;
 import '../options.dart';
 import '../types/abstract_value_domain.dart';
-import '../types/types.dart';
+import '../types/masks.dart';
 import '../universe/call_structure.dart' show CallStructure;
 import '../universe/selector.dart' show Selector;
 import '../universe/use.dart'
@@ -2443,17 +2442,8 @@
       pushStatement(
           new js.Throw(value).withSourceInformation(sourceInformation));
     } else {
-      Entity element = _work.element;
-      if (element is MethodElement && element.asyncMarker.isYielding) {
-        // `return <expr>;` is illegal in a sync* or async* function.
-        // To have the async-translator working, we avoid introducing
-        // `return` nodes.
-        pushStatement(new js.ExpressionStatement(value)
-            .withSourceInformation(sourceInformation));
-      } else {
-        pushStatement(
-            new js.Return(value).withSourceInformation(sourceInformation));
-      }
+      pushStatement(
+          new js.Return(value).withSourceInformation(sourceInformation));
     }
   }
 
diff --git a/pkg/compiler/lib/src/ssa/codegen_helpers.dart b/pkg/compiler/lib/src/ssa/codegen_helpers.dart
index d7194b8..bfa7fb2 100644
--- a/pkg/compiler/lib/src/ssa/codegen_helpers.dart
+++ b/pkg/compiler/lib/src/ssa/codegen_helpers.dart
@@ -8,7 +8,7 @@
 import '../js_backend/interceptor_data.dart';
 import '../options.dart';
 import '../types/abstract_value_domain.dart';
-import '../types/types.dart';
+import '../types/masks.dart';
 import '../universe/selector.dart' show Selector;
 import '../world.dart' show ClosedWorld;
 import 'nodes.dart';
diff --git a/pkg/compiler/lib/src/ssa/graph_builder.dart b/pkg/compiler/lib/src/ssa/graph_builder.dart
index 4215366..6dc7c0a 100644
--- a/pkg/compiler/lib/src/ssa/graph_builder.dart
+++ b/pkg/compiler/lib/src/ssa/graph_builder.dart
@@ -20,12 +20,11 @@
 import '../js_backend/native_data.dart';
 import '../js_backend/js_interop_analysis.dart';
 import '../js_backend/interceptor_data.dart';
-import '../js_backend/mirrors_data.dart';
 import '../js_backend/runtime_types.dart';
 import '../js_emitter/code_emitter_task.dart';
 import '../options.dart';
-import '../resolution/tree_elements.dart';
 import '../types/abstract_value_domain.dart';
+import '../types/masks.dart';
 import '../types/types.dart';
 import '../world.dart' show ClosedWorld;
 import 'jump_handler.dart';
@@ -50,9 +49,6 @@
   /// breaks.
   bool inTryStatement = false;
 
-  /// The tree elements for the element being built into an SSA graph.
-  TreeElements get elements;
-
   /// The JavaScript backend we are targeting in this compilation.
   JavaScriptBackend get backend;
 
@@ -63,8 +59,6 @@
   AbstractValueDomain get abstractValueDomain =>
       closedWorld.abstractValueDomain;
 
-  CommonMasks get commonMasks => closedWorld.abstractValueDomain;
-
   DiagnosticReporter get reporter => backend.reporter;
 
   CompilerOptions get options => compiler.options;
@@ -97,8 +91,6 @@
 
   FunctionInlineCache get inlineCache => backend.inlineCache;
 
-  MirrorsData get mirrorsData => backend.mirrorsData;
-
   JsInteropAnalysis get jsInteropAnalysis => backend.jsInteropAnalysis;
 
   DeferredLoadTask get deferredLoadTask => compiler.deferredLoadTask;
@@ -250,7 +242,7 @@
   MemberEntity get sourceElement;
 
   HLiteralList buildLiteralList(List<HInstruction> inputs) {
-    return new HLiteralList(inputs, commonMasks.growableListType);
+    return new HLiteralList(inputs, abstractValueDomain.growableListType);
   }
 
   HInstruction callSetRuntimeTypeInfoWithTypeArguments(
@@ -266,7 +258,7 @@
         TypeInfoExpressionKind.INSTANCE,
         closedWorld.elementEnvironment.getThisType(type.element),
         rtiInputs,
-        closedWorld.abstractValueDomain.dynamicType);
+        abstractValueDomain.dynamicType);
     add(typeInfo);
     return callSetRuntimeTypeInfo(typeInfo, newObject, sourceInformation);
   }
@@ -298,7 +290,7 @@
   bool getFlagValue(String flagName) {
     switch (flagName) {
       case 'MUST_RETAIN_METADATA':
-        return mirrorsData.mustRetainMetadata;
+        return false;
       case 'USE_CONTENT_SECURITY_POLICY':
         return options.useContentSecurityPolicy;
       case 'IS_FULL_EMITTER':
diff --git a/pkg/compiler/lib/src/ssa/interceptor_simplifier.dart b/pkg/compiler/lib/src/ssa/interceptor_simplifier.dart
index 11b98a0..a3ec846 100644
--- a/pkg/compiler/lib/src/ssa/interceptor_simplifier.dart
+++ b/pkg/compiler/lib/src/ssa/interceptor_simplifier.dart
@@ -8,7 +8,7 @@
 import '../elements/entities.dart';
 import '../js_backend/interceptor_data.dart';
 import '../types/abstract_value_domain.dart';
-import '../types/types.dart';
+import '../types/masks.dart';
 import '../universe/selector.dart' show Selector;
 import '../world.dart' show ClosedWorld;
 import 'nodes.dart';
diff --git a/pkg/compiler/lib/src/ssa/invoke_dynamic_specializers.dart b/pkg/compiler/lib/src/ssa/invoke_dynamic_specializers.dart
index 0ca17d5..ac8576f 100644
--- a/pkg/compiler/lib/src/ssa/invoke_dynamic_specializers.dart
+++ b/pkg/compiler/lib/src/ssa/invoke_dynamic_specializers.dart
@@ -8,6 +8,7 @@
 import '../elements/entities.dart';
 import '../elements/names.dart';
 import '../options.dart';
+import '../types/masks.dart';
 import '../types/types.dart';
 import '../universe/call_structure.dart';
 import '../universe/selector.dart';
diff --git a/pkg/compiler/lib/src/ssa/jump_handler.dart b/pkg/compiler/lib/src/ssa/jump_handler.dart
index 3687961..20d604b0 100644
--- a/pkg/compiler/lib/src/ssa/jump_handler.dart
+++ b/pkg/compiler/lib/src/ssa/jump_handler.dart
@@ -5,7 +5,6 @@
 import '../common.dart';
 import '../elements/jumps.dart';
 import '../io/source_information.dart';
-import '../tree/tree.dart' as ast;
 
 import 'graph_builder.dart';
 import 'locals_handler.dart';
@@ -221,33 +220,3 @@
     super.close();
   }
 }
-
-/// Special [JumpHandler] implementation used to handle continue statements
-/// targeting switch cases.
-class AstSwitchCaseJumpHandler extends SwitchCaseJumpHandler {
-  AstSwitchCaseJumpHandler(
-      GraphBuilder builder, JumpTarget target, ast.SwitchStatement node)
-      : super(builder, target) {
-    // The switch case indices must match those computed in
-    // [SsaFromAstMixin.buildSwitchCaseConstants].
-    // Switch indices are 1-based so we can bypass the synthetic loop when no
-    // cases match simply by branching on the index (which defaults to null).
-    int switchIndex = 1;
-    for (ast.SwitchCase switchCase in node.cases) {
-      for (ast.Node labelOrCase in switchCase.labelsAndCases) {
-        ast.Node label = labelOrCase.asLabel();
-        if (label != null) {
-          LabelDefinition labelElement =
-              builder.elements.getLabelDefinition(label);
-          if (labelElement != null && labelElement.isContinueTarget) {
-            JumpTarget continueTarget = labelElement.target;
-            targetIndexMap[continueTarget] = switchIndex;
-            assert(builder.jumpTargets[continueTarget] == null);
-            builder.jumpTargets[continueTarget] = this;
-          }
-        }
-      }
-      switchIndex++;
-    }
-  }
-}
diff --git a/pkg/compiler/lib/src/ssa/kernel_impact.dart b/pkg/compiler/lib/src/ssa/kernel_impact.dart
index 7b93861..28185e0 100644
--- a/pkg/compiler/lib/src/ssa/kernel_impact.dart
+++ b/pkg/compiler/lib/src/ssa/kernel_impact.dart
@@ -295,11 +295,20 @@
         isEmpty: literal.entries.isEmpty));
   }
 
+  @override
   void visitMapEntry(ir.MapEntry entry) {
     visitNode(entry.key);
     visitNode(entry.value);
   }
 
+  @override
+  void visitConditionalExpression(ir.ConditionalExpression node) {
+    visitNode(node.condition);
+    visitNode(node.then);
+    visitNode(node.otherwise);
+    // Don't visit the static type.
+  }
+
   List<DartType> _visitArguments(ir.Arguments arguments) {
     arguments.positional.forEach(visitNode);
     arguments.named.forEach(visitNode);
diff --git a/pkg/compiler/lib/src/ssa/kernel_string_builder.dart b/pkg/compiler/lib/src/ssa/kernel_string_builder.dart
index 92e4b4d..3b52451 100644
--- a/pkg/compiler/lib/src/ssa/kernel_string_builder.dart
+++ b/pkg/compiler/lib/src/ssa/kernel_string_builder.dart
@@ -57,14 +57,14 @@
 
   HInstruction concat(HInstruction left, HInstruction right) {
     HInstruction instruction =
-        new HStringConcat(left, right, builder.commonMasks.stringType);
+        new HStringConcat(left, right, builder.abstractValueDomain.stringType);
     builder.add(instruction);
     return instruction;
   }
 
   HInstruction stringify(HInstruction expression) {
     HInstruction instruction =
-        new HStringify(expression, builder.commonMasks.stringType)
+        new HStringify(expression, builder.abstractValueDomain.stringType)
           ..sourceInformation = expression.sourceInformation;
     builder.add(instruction);
     return instruction;
diff --git a/pkg/compiler/lib/src/ssa/locals_handler.dart b/pkg/compiler/lib/src/ssa/locals_handler.dart
index 2f3973b..bf5b34b 100644
--- a/pkg/compiler/lib/src/ssa/locals_handler.dart
+++ b/pkg/compiler/lib/src/ssa/locals_handler.dart
@@ -4,7 +4,6 @@
 
 import '../closure.dart';
 import '../common.dart';
-import '../elements/elements.dart';
 import '../elements/entities.dart';
 import '../elements/types.dart';
 import '../io/source_information.dart';
@@ -12,7 +11,8 @@
 import '../js_backend/interceptor_data.dart';
 import '../js_model/closure.dart' show JRecordField, JClosureField;
 import '../js_model/locals.dart' show JLocal;
-import '../tree/tree.dart' as ast;
+import '../types/abstract_value_domain.dart';
+import '../types/masks.dart';
 import '../types/types.dart';
 import '../world.dart' show ClosedWorld;
 
@@ -68,7 +68,8 @@
 
   ClosedWorld get closedWorld => builder.closedWorld;
 
-  CommonMasks get commonMasks => closedWorld.abstractValueDomain;
+  AbstractValueDomain get _abstractValueDomain =>
+      closedWorld.abstractValueDomain;
 
   GlobalTypeInferenceResults get _globalInferenceResults =>
       builder.globalInferenceResults;
@@ -118,7 +119,7 @@
   }
 
   HInstruction createBox(SourceInformation sourceInformation) {
-    HInstruction box = new HCreateBox(commonMasks.nonNullType)
+    HInstruction box = new HCreateBox(_abstractValueDomain.nonNullType)
       ..sourceInformation = sourceInformation;
     builder.add(box);
     return box;
@@ -137,7 +138,8 @@
     if (forGenerativeConstructorBody) {
       // The box is passed as a parameter to a generative
       // constructor body.
-      box = builder.addParameter(closureInfo.context, commonMasks.nonNullType);
+      box = builder.addParameter(
+          closureInfo.context, _abstractValueDomain.nonNullType);
     } else {
       box = createBox(sourceInformation);
     }
@@ -148,12 +150,8 @@
     closureInfo.forEachBoxedVariable((Local from, FieldEntity to) {
       // The [from] can only be a parameter for function-scopes and not
       // loop scopes.
-      bool isParameter;
-      if (from is JLocal) {
-        isParameter = from.isRegularParameter;
-      } else if (from is LocalVariableElement) {
-        isParameter = from.isRegularParameter;
-      }
+      JLocal jFrom = from;
+      bool isParameter = jFrom.isRegularParameter;
       assert(isParameter != null);
       if (isParameter && !forGenerativeConstructorBody) {
         // Now that the redirection is set up, the update to the local will
@@ -201,8 +199,6 @@
       Map<Local, TypeMask> parameters,
       SourceInformation sourceInformation,
       {bool isGenerativeConstructorBody}) {
-    assert(!(element is MemberElement && !element.isImplementation),
-        failedAt(element));
     this.scopeInfo = scopeInfo;
 
     parameters.forEach((Local local, TypeMask typeMask) {
@@ -234,7 +230,7 @@
       });
       // Inside closure redirect references to itself to [:this:].
       HThis thisInstruction =
-          new HThis(closureData.thisLocal, commonMasks.nonNullType);
+          new HThis(closureData.thisLocal, _abstractValueDomain.nonNullType);
       builder.graph.thisInstruction = thisInstruction;
       builder.graph.entry.addAtEntry(thisInstruction);
       updateLocal(closureData.closureEntity, thisInstruction);
@@ -304,8 +300,7 @@
     if (scopeInfo is! ClosureRepresentationInfo) return false;
     FieldEntity redirectTarget = redirectionMapping[local];
     if (redirectTarget == null) return false;
-    return redirectTarget is ClosureFieldElement ||
-        redirectTarget is JClosureField;
+    return redirectTarget is JClosureField;
   }
 
   bool isBoxed(Local local) {
@@ -347,7 +342,7 @@
       FieldEntity redirect = redirectionMapping[local];
       HInstruction receiver = readLocal(closureData.closureEntity);
       TypeMask type = local is BoxLocal
-          ? commonMasks.nonNullType
+          ? _abstractValueDomain.nonNullType
           : getTypeOfCapturedVariable(redirect);
       HInstruction fieldGet = new HFieldGet(redirect, receiver, type);
       builder.add(fieldGet);
@@ -360,9 +355,7 @@
       // accessed through a closure-field.
       // Calling [readLocal] makes sure we generate the correct code to get
       // the box.
-      if (redirect is BoxFieldElement) {
-        localBox = redirect.box;
-      } else if (redirect is JRecordField) {
+      if (redirect is JRecordField) {
         localBox = redirect.box;
       }
       assert(localBox != null);
@@ -375,8 +368,8 @@
     } else {
       assert(_isUsedInTryOrGenerator(local));
       HLocalValue localValue = getLocal(local);
-      HInstruction instruction = new HLocalGet(
-          local, localValue, commonMasks.dynamicType, sourceInformation);
+      HInstruction instruction = new HLocalGet(local, localValue,
+          _abstractValueDomain.dynamicType, sourceInformation);
       builder.add(instruction);
       return instruction;
     }
@@ -402,8 +395,9 @@
     }
 
     return activationVariables.putIfAbsent(local, () {
-      HLocalValue localValue = new HLocalValue(local, commonMasks.nonNullType)
-        ..sourceInformation = sourceInformation;
+      HLocalValue localValue =
+          new HLocalValue(local, _abstractValueDomain.nonNullType)
+            ..sourceInformation = sourceInformation;
       builder.graph.entry.addAtExit(localValue);
       return localValue;
     });
@@ -431,9 +425,7 @@
       FieldEntity redirect = redirectionMapping[local];
       assert(redirect != null);
       BoxLocal localBox;
-      if (redirect is BoxFieldElement) {
-        localBox = redirect.box;
-      } else if (redirect is JRecordField) {
+      if (redirect is JRecordField) {
         localBox = redirect.box;
       }
       assert(localBox != null);
@@ -522,8 +514,8 @@
       if (isAccessedDirectly(local)) {
         // We know 'this' cannot be modified.
         if (local != scopeInfo.thisLocal) {
-          HPhi phi =
-              new HPhi.singleInput(local, instruction, commonMasks.dynamicType);
+          HPhi phi = new HPhi.singleInput(
+              local, instruction, _abstractValueDomain.dynamicType);
           loopEntry.addPhi(phi);
           directLocals[local] = phi;
         } else {
@@ -590,8 +582,10 @@
         if (identical(instruction, mine)) {
           joinedLocals[local] = instruction;
         } else {
-          HInstruction phi = new HPhi.manyInputs(local,
-              <HInstruction>[mine, instruction], commonMasks.dynamicType);
+          HInstruction phi = new HPhi.manyInputs(
+              local,
+              <HInstruction>[mine, instruction],
+              _abstractValueDomain.dynamicType);
           joinBlock.addPhi(phi);
           joinedLocals[local] = phi;
         }
@@ -613,7 +607,7 @@
     HInstruction thisValue = null;
     directLocals.forEach((Local local, HInstruction instruction) {
       if (local != scopeInfo.thisLocal) {
-        HPhi phi = new HPhi.noInputs(local, commonMasks.dynamicType);
+        HPhi phi = new HPhi.noInputs(local, _abstractValueDomain.dynamicType);
         joinedLocals[local] = phi;
         joinBlock.addPhi(phi);
       } else {
diff --git a/pkg/compiler/lib/src/ssa/loop_handler.dart b/pkg/compiler/lib/src/ssa/loop_handler.dart
index 89ea833..77c2882 100644
--- a/pkg/compiler/lib/src/ssa/loop_handler.dart
+++ b/pkg/compiler/lib/src/ssa/loop_handler.dart
@@ -7,9 +7,7 @@
 import '../closure.dart' show CapturedLoopScope;
 import '../elements/jumps.dart';
 import '../io/source_information.dart';
-import '../tree/tree.dart' as ast;
 
-import 'builder.dart';
 import 'builder_kernel.dart';
 import 'graph_builder.dart';
 import 'jump_handler.dart';
@@ -312,35 +310,6 @@
       {bool isLoopJump});
 }
 
-/// A loop handler for the builder that just uses AST nodes directly.
-class SsaLoopHandler extends LoopHandler<ast.Node> {
-  final SsaAstGraphBuilder builder;
-
-  SsaLoopHandler(SsaAstGraphBuilder builder)
-      : this.builder = builder,
-        super(builder);
-
-  @override
-  int loopKind(ast.Node node) => node.accept(const _SsaLoopTypeVisitor());
-
-  @override
-  JumpHandler createJumpHandler(ast.Node node, JumpTarget jumpTarget,
-          {bool isLoopJump}) =>
-      builder.createJumpHandler(node, jumpTarget, isLoopJump: isLoopJump);
-}
-
-class _SsaLoopTypeVisitor extends ast.Visitor {
-  const _SsaLoopTypeVisitor();
-  int visitNode(ast.Node node) => HLoopBlockInformation.NOT_A_LOOP;
-  int visitWhile(ast.While node) => HLoopBlockInformation.WHILE_LOOP;
-  int visitFor(ast.For node) => HLoopBlockInformation.FOR_LOOP;
-  int visitDoWhile(ast.DoWhile node) => HLoopBlockInformation.DO_WHILE_LOOP;
-  int visitAsyncForIn(ast.AsyncForIn node) => HLoopBlockInformation.FOR_IN_LOOP;
-  int visitSyncForIn(ast.SyncForIn node) => HLoopBlockInformation.FOR_IN_LOOP;
-  int visitSwitchStatement(ast.SwitchStatement node) =>
-      HLoopBlockInformation.SWITCH_CONTINUE_LOOP;
-}
-
 // TODO(het): Since kernel simplifies loop breaks and continues, we should
 // rewrite the loop handler from scratch to account for the simplified structure
 class KernelLoopHandler extends LoopHandler<ir.TreeNode> {
diff --git a/pkg/compiler/lib/src/ssa/optimize.dart b/pkg/compiler/lib/src/ssa/optimize.dart
index 170afb3..f521421 100644
--- a/pkg/compiler/lib/src/ssa/optimize.dart
+++ b/pkg/compiler/lib/src/ssa/optimize.dart
@@ -18,6 +18,7 @@
 import '../native/native.dart' as native;
 import '../options.dart';
 import '../types/abstract_value_domain.dart';
+import '../types/masks.dart';
 import '../types/types.dart';
 import '../universe/selector.dart' show Selector;
 import '../universe/side_effects.dart' show SideEffects;
diff --git a/pkg/compiler/lib/src/ssa/ssa_branch_builder.dart b/pkg/compiler/lib/src/ssa/ssa_branch_builder.dart
index f628a1e..f6bfb90 100644
--- a/pkg/compiler/lib/src/ssa/ssa_branch_builder.dart
+++ b/pkg/compiler/lib/src/ssa/ssa_branch_builder.dart
@@ -161,8 +161,9 @@
       boolifiedLeft = builder.popBoolified();
       builder.stack.add(boolifiedLeft);
       if (!isAnd) {
-        builder.push(new HNot(builder.pop(), builder.commonMasks.boolType)
-          ..sourceInformation = sourceInformation);
+        builder.push(
+            new HNot(builder.pop(), builder.abstractValueDomain.boolType)
+              ..sourceInformation = sourceInformation);
       }
     }
 
@@ -178,7 +179,7 @@
     HPhi result = new HPhi.manyInputs(
         null,
         <HInstruction>[boolifiedRight, notIsAnd],
-        builder.commonMasks.dynamicType)
+        builder.abstractValueDomain.dynamicType)
       ..sourceInformation = sourceInformation;
     builder.current.addPhi(result);
     builder.stack.add(result);
@@ -205,7 +206,7 @@
     if (isExpression) {
       assert(thenValue != null && elseValue != null);
       HPhi phi = new HPhi.manyInputs(null, <HInstruction>[thenValue, elseValue],
-          builder.commonMasks.dynamicType);
+          builder.abstractValueDomain.dynamicType);
       joinBranch.block.addPhi(phi);
       builder.stack.add(phi);
     }
diff --git a/pkg/compiler/lib/src/ssa/type_builder.dart b/pkg/compiler/lib/src/ssa/type_builder.dart
index c9b456e..81268b8 100644
--- a/pkg/compiler/lib/src/ssa/type_builder.dart
+++ b/pkg/compiler/lib/src/ssa/type_builder.dart
@@ -7,7 +7,7 @@
 import '../elements/entities.dart';
 import '../elements/types.dart';
 import '../io/source_information.dart';
-import '../types/types.dart';
+import '../types/masks.dart';
 import '../universe/use.dart' show TypeUse;
 
 /// Enum that defines how a member has access to the current type variables.
@@ -75,6 +75,14 @@
     return other;
   }
 
+  HInstruction trustTypeOfParameter(HInstruction original, DartType type) {
+    if (type == null) return original;
+    HInstruction trusted = _trustType(original, type);
+    if (trusted == original) return original;
+    builder.add(trusted);
+    return trusted;
+  }
+
   HInstruction potentiallyCheckOrTrustTypeOfParameter(
       HInstruction original, DartType type) {
     if (type == null) return original;
@@ -171,11 +179,11 @@
     HInstruction target =
         builder.localsHandler.readThis(sourceInformation: sourceInformation);
     HInstruction interceptor =
-        new HInterceptor(target, builder.commonMasks.nonNullType)
+        new HInterceptor(target, builder.abstractValueDomain.nonNullType)
           ..sourceInformation = sourceInformation;
     builder.add(interceptor);
     builder.push(new HTypeInfoReadVariable.intercepted(
-        variable, interceptor, target, builder.commonMasks.dynamicType)
+        variable, interceptor, target, builder.abstractValueDomain.dynamicType)
       ..sourceInformation = sourceInformation);
     return builder.pop();
   }
@@ -197,7 +205,7 @@
         TypeInfoExpressionKind.INSTANCE,
         builder.closedWorld.elementEnvironment.getThisType(interface.element),
         inputs,
-        builder.commonMasks.dynamicType)
+        builder.abstractValueDomain.dynamicType)
       ..sourceInformation = sourceInformation;
     return representation;
   }
@@ -229,16 +237,12 @@
         TypeInfoExpressionKind.COMPLETE,
         argument,
         inputs,
-        builder.commonMasks.dynamicType)
+        builder.abstractValueDomain.dynamicType)
       ..sourceInformation = sourceInformation;
     builder.add(result);
     return result;
   }
 
-  /// In checked mode, generate type tests for the parameters of the inlined
-  /// function.
-  void potentiallyCheckInlinedParameterTypes(FunctionEntity function);
-
   bool get checkOrTrustTypes =>
       builder.options.strongMode ||
       builder.options.enableTypeAssertions ||
@@ -254,10 +258,9 @@
     if (type == null) return original;
     if (type.isTypeVariable) {
       TypeVariableType typeVariable = type;
-      // GENERIC_METHODS: The following statement was added for parsing and
-      // ignoring method type variables; must be generalized for full support of
-      // generic methods.
-      if (typeVariable.element.typeDeclaration is! ClassEntity) {
+      // In Dart 1, method type variables are ignored.
+      if (!builder.options.strongMode &&
+          typeVariable.element.typeDeclaration is! ClassEntity) {
         type = const DynamicType();
       }
     }
diff --git a/pkg/compiler/lib/src/ssa/types.dart b/pkg/compiler/lib/src/ssa/types.dart
index d93488d..9e938c4 100644
--- a/pkg/compiler/lib/src/ssa/types.dart
+++ b/pkg/compiler/lib/src/ssa/types.dart
@@ -5,6 +5,7 @@
 import '../common_elements.dart' show CommonElements;
 import '../elements/entities.dart';
 import '../native/native.dart' as native;
+import '../types/masks.dart';
 import '../types/types.dart';
 import '../universe/selector.dart' show Selector;
 import '../world.dart' show ClosedWorld;
diff --git a/pkg/compiler/lib/src/ssa/types_propagation.dart b/pkg/compiler/lib/src/ssa/types_propagation.dart
index f5e50bb..d0a0f44 100644
--- a/pkg/compiler/lib/src/ssa/types_propagation.dart
+++ b/pkg/compiler/lib/src/ssa/types_propagation.dart
@@ -6,6 +6,7 @@
 import '../elements/entities.dart';
 import '../options.dart';
 import '../types/abstract_value_domain.dart';
+import '../types/masks.dart';
 import '../types/types.dart';
 import '../universe/selector.dart' show Selector;
 import '../world.dart' show ClosedWorld;
diff --git a/pkg/compiler/lib/src/string_validator.dart b/pkg/compiler/lib/src/string_validator.dart
deleted file mode 100644
index 75f59f5..0000000
--- a/pkg/compiler/lib/src/string_validator.dart
+++ /dev/null
@@ -1,214 +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.
-
-// Check the validity of string literals.
-
-library stringvalidator;
-
-import 'dart:collection';
-
-import 'common.dart';
-import 'package:front_end/src/fasta/scanner.dart' show Token;
-import 'tree/dartstring.dart' show DartString;
-import 'tree/nodes.dart' show StringQuoting;
-import 'package:front_end/src/fasta/scanner/characters.dart';
-
-class StringValidator {
-  final DiagnosticReporter reporter;
-
-  StringValidator(this.reporter);
-
-  DartString validateInterpolationPart(Token token, StringQuoting quoting,
-      {bool isFirst: false, bool isLast: false}) {
-    String source = token.lexeme;
-    int leftQuote = 0;
-    int rightQuote = 0;
-    if (isFirst) leftQuote = quoting.leftQuoteLength;
-    if (isLast) rightQuote = quoting.rightQuoteLength;
-    String content = copyWithoutQuotes(source, leftQuote, rightQuote);
-    return validateString(
-        token, token.charOffset + leftQuote, content, quoting);
-  }
-
-  static StringQuoting quotingFromString(String sourceString) {
-    Iterator<int> source = sourceString.codeUnits.iterator;
-    bool raw = false;
-    int leftQuoteLength = 1;
-    source.moveNext();
-    int quoteChar = source.current;
-    if (quoteChar == $r) {
-      raw = true;
-      source.moveNext();
-      quoteChar = source.current;
-    }
-    assert(quoteChar == $SQ || quoteChar == $DQ);
-    // String has at least one quote. Check it if has three.
-    // If it only has two, the string must be an empty string literal,
-    // and end after the second quote.
-    if (source.moveNext() && source.current == quoteChar && source.moveNext()) {
-      int code = source.current;
-      assert(code == quoteChar); // If not, there is a bug in the parser.
-      leftQuoteLength = 3;
-
-      // Check if a multiline string starts with optional whitespace followed by
-      // a newline (CR, LF or CR+LF).
-      // We also accept if these characters are escaped by a backslash.
-      int newLineLength = 1;
-      while (true) {
-        // Due to string-interpolations we are not guaranteed to see the
-        // trailing quoting characters. The invocations to `moveNext()` may
-        // therefore return false and the `current`-getter return `null`. The
-        // code does not need to handle this specially (as it will not find the
-        // newline characters).
-        source.moveNext();
-        code = source.current;
-        if (code == $BACKSLASH) {
-          newLineLength++;
-          source.moveNext();
-          code = source.current;
-        }
-        if (code == $TAB || code == $SPACE) {
-          newLineLength++;
-          continue;
-        }
-        if (code == $CR) {
-          if (source.moveNext() && source.current == $LF) {
-            newLineLength++;
-          }
-          leftQuoteLength += newLineLength;
-        } else if (code == $LF) {
-          leftQuoteLength += newLineLength;
-        }
-        break;
-      }
-    }
-    return StringQuoting.getQuoting(quoteChar, raw, leftQuoteLength);
-  }
-
-  /**
-   * Return the string [string] witout its [initial] first and [terminal] last
-   * characters. This is intended to be used to remove quotes from string
-   * literals (including an initial 'r' for raw strings).
-   */
-  String copyWithoutQuotes(String string, int initial, int terminal) {
-    assert(0 <= initial);
-    assert(0 <= terminal);
-    assert(initial + terminal <= string.length);
-    return string.substring(initial, string.length - terminal);
-  }
-
-  void stringParseError(String message, Token token, int offset) {
-    reporter.reportErrorMessage(reporter.spanFromToken(token),
-        MessageKind.GENERIC, {'text': "$message @ $offset"});
-  }
-
-  /**
-   * Validates the escape sequences and special characters of a string literal.
-   * Returns a DartString if valid, and null if not.
-   */
-  DartString validateString(
-      Token token, int startOffset, String string, StringQuoting quoting) {
-    // We need to check for invalid x and u escapes, for line
-    // terminators in non-multiline strings, and for invalid Unicode
-    // code points (either directly or as u-escape values).
-    int length = 0;
-    int index = startOffset;
-    bool containsEscape = false;
-    var stringIter = string.codeUnits.iterator;
-    for (HasNextIterator<int> iter = new HasNextIterator(stringIter);
-        iter.hasNext;
-        length++) {
-      index++;
-      int code = iter.next();
-      if (code == $BACKSLASH) {
-        if (quoting.raw) continue;
-        containsEscape = true;
-        if (!iter.hasNext) {
-          stringParseError("Incomplete escape sequence", token, index);
-          return null;
-        }
-        index++;
-        code = iter.next();
-        if (code == $x) {
-          for (int i = 0; i < 2; i++) {
-            if (!iter.hasNext) {
-              stringParseError("Incomplete escape sequence", token, index);
-              return null;
-            }
-            index++;
-            code = iter.next();
-            if (!isHexDigit(code)) {
-              stringParseError(
-                  "Invalid character in escape sequence", token, index);
-              return null;
-            }
-          }
-          // A two-byte hex escape can't generate an invalid value.
-          continue;
-        } else if (code == $u) {
-          index++;
-          code = iter.hasNext ? iter.next() : 0;
-          int value = 0;
-          if (code == $OPEN_CURLY_BRACKET) {
-            // expect 1-6 hex digits.
-            int count = 0;
-            while (iter.hasNext) {
-              code = iter.next();
-              index++;
-              if (code == $CLOSE_CURLY_BRACKET) {
-                break;
-              }
-              if (!isHexDigit(code)) {
-                stringParseError(
-                    "Invalid character in escape sequence", token, index);
-                return null;
-              }
-              count++;
-              value = value * 16 + hexDigitValue(code);
-            }
-            if (code != $CLOSE_CURLY_BRACKET || count == 0 || count > 6) {
-              int errorPosition = index - count;
-              if (count > 6) errorPosition += 6;
-              stringParseError(
-                  "Invalid character in escape sequence", token, errorPosition);
-              return null;
-            }
-          } else {
-            // Expect four hex digits, including the one just read.
-            for (int i = 0; i < 4; i++) {
-              if (i > 0) {
-                if (iter.hasNext) {
-                  index++;
-                  code = iter.next();
-                } else {
-                  code = 0;
-                }
-              }
-              if (!isHexDigit(code)) {
-                stringParseError(
-                    "Invalid character in escape sequence", token, index);
-                return null;
-              }
-              value = value * 16 + hexDigitValue(code);
-            }
-          }
-          code = value;
-        }
-      }
-      if (code >= 0x10000) {
-        length++;
-        if (code > 0x10FFFF) {
-          stringParseError("Invalid code point", token, index);
-          return null;
-        }
-      }
-    }
-    // String literal successfully validated.
-    if (quoting.raw || !containsEscape) {
-      // A string without escapes could just as well have been raw.
-      return new DartString.rawString(string, length);
-    }
-    return new DartString.escapedString(string, length);
-  }
-}
diff --git a/pkg/compiler/lib/src/tree/dartstring.dart b/pkg/compiler/lib/src/tree/dartstring.dart
deleted file mode 100644
index 6df4af8..0000000
--- a/pkg/compiler/lib/src/tree/dartstring.dart
+++ /dev/null
@@ -1,266 +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.
-
-import 'dart:collection';
-
-import 'package:front_end/src/fasta/scanner/characters.dart';
-
-/**
- * The [DartString] type represents a Dart string value as a sequence of Unicode
- * Scalar Values.
- * After parsing, any valid [LiteralString] will contain a [DartString]
- * representing its content after removing quotes and resolving escapes in
- * its source.
- */
-abstract class DartString extends IterableBase<int> {
-  factory DartString.empty() => const LiteralDartString("");
-  // This is a convenience constructor. If you need a const literal DartString,
-  // use [const LiteralDartString(string)] directly.
-  factory DartString.literal(String string) => new LiteralDartString(string);
-  factory DartString.rawString(String source, int length) =>
-      new RawSourceDartString(source, length);
-  factory DartString.escapedString(String source, int length) =>
-      new EscapedSourceDartString(source, length);
-  factory DartString.concat(DartString first, DartString second) {
-    if (first.isEmpty) return second;
-    if (second.isEmpty) return first;
-    return new ConsDartString(first, second);
-  }
-  const DartString();
-
-  /**
-   * The length of this [DartString], which is the string length after
-   * escapes have been resolved.
-   */
-  int get length;
-  bool get isEmpty => length == 0;
-
-  Iterator<int> get iterator;
-
-  /**
-   * The string represented by this [DartString].
-   */
-  String slowToString();
-
-  bool operator ==(var other) {
-    if (other is! DartString) return false;
-    DartString otherString = other;
-    if (length != otherString.length) return false;
-    Iterator it1 = iterator;
-    Iterator it2 = otherString.iterator;
-    while (it1.moveNext()) {
-      if (!it2.moveNext()) return false;
-      if (it1.current != it2.current) return false;
-    }
-    return true;
-  }
-
-  int get hashCode => throw new UnsupportedError('DartString.hashCode');
-
-  /**
-   * A textual representation of this [DartString] with some debugging
-   * information.
-   */
-  String toString() => "DartString#${length}:${slowToString()}";
-}
-
-/**
- * A [DartString] where the content is represented by an actual [String].
- */
-class LiteralDartString extends DartString {
-  final String string;
-  const LiteralDartString(this.string);
-  int get length => string.length;
-  Iterator<int> get iterator => string.codeUnits.iterator;
-  String slowToString() => string;
-}
-
-/**
- * A [DartString] whereSource the content comes from a slice of the program
- * source.
- */
-abstract class SourceBasedDartString extends DartString {
-  /**
-   * The source string containing explicit escapes from which this [DartString]
-   * is built.
-   */
-  final String source;
-  final int length;
-  SourceBasedDartString(this.source, this.length);
-  Iterator<int> get iterator;
-}
-
-/**
- * Special case of a [SourceBasedDartString] where we know the source doesn't
- * contain any escapes.
- */
-class RawSourceDartString extends SourceBasedDartString {
-  RawSourceDartString(source, length) : super(source, length);
-  Iterator<int> get iterator => source.codeUnits.iterator;
-  String slowToString() => source;
-}
-
-/**
- * General case of a [SourceBasedDartString] where the source might contain
- * escapes.
- */
-class EscapedSourceDartString extends SourceBasedDartString {
-  String toStringCache;
-  EscapedSourceDartString(source, length) : super(source, length);
-  Iterator<int> get iterator {
-    if (toStringCache != null) return toStringCache.codeUnits.iterator;
-    return new StringEscapeIterator(source);
-  }
-
-  String slowToString() {
-    if (toStringCache != null) return toStringCache;
-    StringBuffer buffer = new StringBuffer();
-    StringEscapeIterator it = new StringEscapeIterator(source);
-    while (it.moveNext()) {
-      buffer.writeCharCode(it.current);
-    }
-    toStringCache = buffer.toString();
-    return toStringCache;
-  }
-}
-
-/**
- * The concatenation of two [DartString]s.
- */
-class ConsDartString extends DartString {
-  final DartString left;
-  final DartString right;
-  final int length;
-  String toStringCache;
-  ConsDartString(DartString left, DartString right)
-      : this.left = left,
-        this.right = right,
-        length = left.length + right.length;
-
-  Iterator<int> get iterator => new ConsDartStringIterator(this);
-
-  String slowToString() {
-    if (toStringCache != null) return toStringCache;
-    toStringCache = left.slowToString() + right.slowToString();
-    return toStringCache;
-  }
-
-  String get source => slowToString();
-}
-
-class ConsDartStringIterator implements Iterator<int> {
-  HasNextIterator<int> currentIterator;
-  DartString right;
-  bool hasNextLookAhead;
-  int _current = null;
-
-  ConsDartStringIterator(ConsDartString cons)
-      : currentIterator = new HasNextIterator<int>(cons.left.iterator),
-        right = cons.right {
-    hasNextLookAhead = currentIterator.hasNext;
-    if (!hasNextLookAhead) {
-      nextPart();
-    }
-  }
-
-  int get current => _current;
-
-  bool moveNext() {
-    if (!hasNextLookAhead) {
-      _current = null;
-      return false;
-    }
-    _current = currentIterator.next();
-    hasNextLookAhead = currentIterator.hasNext;
-    if (!hasNextLookAhead) {
-      nextPart();
-    }
-    return true;
-  }
-
-  void nextPart() {
-    if (right != null) {
-      currentIterator = new HasNextIterator<int>(right.iterator);
-      right = null;
-      hasNextLookAhead = currentIterator.hasNext;
-    }
-  }
-}
-
-/**
- *Iterator that returns the actual string contents of a string with escapes.
- */
-class StringEscapeIterator implements Iterator<int> {
-  final Iterator<int> source;
-  int _current = null;
-
-  StringEscapeIterator(String source) : this.source = source.codeUnits.iterator;
-
-  int get current => _current;
-
-  bool moveNext() {
-    if (!source.moveNext()) {
-      _current = null;
-      return false;
-    }
-    int code = source.current;
-    if (code != $BACKSLASH) {
-      _current = code;
-      return true;
-    }
-    source.moveNext();
-    code = source.current;
-    switch (code) {
-      case $n:
-        _current = $LF;
-        break;
-      case $r:
-        _current = $CR;
-        break;
-      case $t:
-        _current = $TAB;
-        break;
-      case $b:
-        _current = $BS;
-        break;
-      case $f:
-        _current = $FF;
-        break;
-      case $v:
-        _current = $VTAB;
-        break;
-      case $x:
-        source.moveNext();
-        int value = hexDigitValue(source.current);
-        source.moveNext();
-        value = value * 16 + hexDigitValue(source.current);
-        _current = value;
-        break;
-      case $u:
-        int value = 0;
-        source.moveNext();
-        code = source.current;
-        if (code == $OPEN_CURLY_BRACKET) {
-          source.moveNext();
-          while (source.current != $CLOSE_CURLY_BRACKET) {
-            value = value * 16 + hexDigitValue(source.current);
-            source.moveNext();
-          }
-          _current = value;
-          break;
-        }
-        // Four digit hex value.
-        value = hexDigitValue(code);
-        for (int i = 0; i < 3; i++) {
-          source.moveNext();
-          value = value * 16 + hexDigitValue(source.current);
-        }
-        _current = value;
-        break;
-      default:
-        _current = code;
-    }
-    return true;
-  }
-}
diff --git a/pkg/compiler/lib/src/tree/nodes.dart b/pkg/compiler/lib/src/tree/nodes.dart
deleted file mode 100644
index d83c8d4..0000000
--- a/pkg/compiler/lib/src/tree/nodes.dart
+++ /dev/null
@@ -1,3370 +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.
-
-import 'dart:collection' show IterableMixin;
-
-import 'package:front_end/src/fasta/fasta_codes.dart' show Message;
-import 'package:front_end/src/fasta/scanner.dart' show Token;
-import 'package:front_end/src/fasta/scanner/token_constants.dart' as Tokens
-    show PLUS_TOKEN;
-import 'package:front_end/src/fasta/scanner/characters.dart';
-import 'package:front_end/src/scanner/token.dart' show BeginToken, TokenType;
-
-import '../common.dart';
-import '../elements/elements.dart' show MetadataAnnotation;
-import '../util/util.dart';
-import 'dartstring.dart';
-import 'prettyprint.dart';
-import 'unparser.dart';
-
-abstract class Visitor<R> {
-  const Visitor();
-
-  R visitNode(Node node);
-
-  R visitAssert(Assert node) => visitStatement(node);
-  R visitAsyncForIn(AsyncForIn node) => visitForIn(node);
-  R visitAsyncModifier(AsyncModifier node) => visitNode(node);
-  R visitAwait(Await node) => visitExpression(node);
-  R visitBlock(Block node) => visitStatement(node);
-  R visitBreakStatement(BreakStatement node) => visitGotoStatement(node);
-  R visitCascade(Cascade node) => visitExpression(node);
-  R visitCascadeReceiver(CascadeReceiver node) => visitExpression(node);
-  R visitCaseMatch(CaseMatch node) => visitNode(node);
-  R visitCatchBlock(CatchBlock node) => visitNode(node);
-  R visitClassNode(ClassNode node) => visitNode(node);
-  R visitCombinator(Combinator node) => visitNode(node);
-  R visitConditional(Conditional node) => visitExpression(node);
-  R visitConditionalUri(ConditionalUri node) => visitNode(node);
-  R visitContinueStatement(ContinueStatement node) => visitGotoStatement(node);
-  R visitDottedName(DottedName node) => visitExpression(node);
-  R visitDoWhile(DoWhile node) => visitLoop(node);
-  R visitEmptyStatement(EmptyStatement node) => visitStatement(node);
-  R visitEnum(Enum node) => visitNode(node);
-  R visitExport(Export node) => visitLibraryDependency(node);
-  R visitExpression(Expression node) => visitNode(node);
-  R visitExpressionStatement(ExpressionStatement node) => visitStatement(node);
-  R visitFor(For node) => visitLoop(node);
-  R visitForIn(ForIn node) => visitLoop(node);
-  R visitFunctionDeclaration(FunctionDeclaration node) => visitStatement(node);
-  R visitFunctionExpression(FunctionExpression node) => visitExpression(node);
-  R visitFunctionTypeAnnotation(FunctionTypeAnnotation node) {
-    return visitTypeAnnotation(node);
-  }
-
-  R visitGotoStatement(GotoStatement node) => visitStatement(node);
-  R visitIdentifier(Identifier node) => visitExpression(node);
-  R visitImport(Import node) => visitLibraryDependency(node);
-  R visitIf(If node) => visitStatement(node);
-  R visitLabel(Label node) => visitNode(node);
-  R visitLabeledStatement(LabeledStatement node) => visitStatement(node);
-  R visitLibraryDependency(LibraryDependency node) => visitLibraryTag(node);
-  R visitLibraryName(LibraryName node) => visitLibraryTag(node);
-  R visitLibraryTag(LibraryTag node) => visitNode(node);
-  R visitLiteral(Literal node) => visitExpression(node);
-  R visitLiteralBool(LiteralBool node) => visitLiteral(node);
-  R visitLiteralDouble(LiteralDouble node) => visitLiteral(node);
-  R visitLiteralInt(LiteralInt node) => visitLiteral(node);
-  R visitLiteralList(LiteralList node) => visitExpression(node);
-  R visitLiteralMap(LiteralMap node) => visitExpression(node);
-  R visitLiteralMapEntry(LiteralMapEntry node) => visitNode(node);
-  R visitLiteralNull(LiteralNull node) => visitLiteral(node);
-  R visitLiteralString(LiteralString node) => visitStringNode(node);
-  R visitStringJuxtaposition(StringJuxtaposition node) => visitStringNode(node);
-  R visitSyncForIn(SyncForIn node) => visitForIn(node);
-  R visitLoop(Loop node) => visitStatement(node);
-  R visitMetadata(Metadata node) => visitNode(node);
-  R visitMixinApplication(MixinApplication node) => visitNode(node);
-  R visitModifiers(Modifiers node) => visitNode(node);
-  R visitNamedArgument(NamedArgument node) => visitExpression(node);
-  R visitNamedMixinApplication(NamedMixinApplication node) {
-    return visitMixinApplication(node);
-  }
-
-  R visitNewExpression(NewExpression node) => visitExpression(node);
-  R visitNodeList(NodeList node) => visitNode(node);
-  R visitNominalTypeAnnotation(NominalTypeAnnotation node) {
-    return visitTypeAnnotation(node);
-  }
-
-  R visitOperator(Operator node) => visitIdentifier(node);
-  R visitParenthesizedExpression(ParenthesizedExpression node) {
-    return visitExpression(node);
-  }
-
-  R visitPart(Part node) => visitLibraryTag(node);
-  R visitPartOf(PartOf node) => visitNode(node);
-  R visitPostfix(Postfix node) => visitNodeList(node);
-  R visitPrefix(Prefix node) => visitNodeList(node);
-  R visitRedirectingFactoryBody(RedirectingFactoryBody node) {
-    return visitStatement(node);
-  }
-
-  R visitRethrow(Rethrow node) => visitStatement(node);
-  R visitReturn(Return node) => visitStatement(node);
-  R visitSend(Send node) => visitExpression(node);
-  R visitSendSet(SendSet node) => visitSend(node);
-  R visitStatement(Statement node) => visitNode(node);
-  R visitStringNode(StringNode node) => visitExpression(node);
-  R visitStringInterpolation(StringInterpolation node) => visitStringNode(node);
-  R visitStringInterpolationPart(StringInterpolationPart node) {
-    return visitNode(node);
-  }
-
-  R visitSwitchCase(SwitchCase node) => visitNode(node);
-  R visitSwitchStatement(SwitchStatement node) => visitStatement(node);
-  R visitLiteralSymbol(LiteralSymbol node) => visitExpression(node);
-  R visitThrow(Throw node) => visitExpression(node);
-  R visitTryStatement(TryStatement node) => visitStatement(node);
-  R visitTypeAnnotation(TypeAnnotation node) => visitNode(node);
-  R visitTypedef(Typedef node) => visitNode(node);
-  R visitTypeVariable(TypeVariable node) => visitNode(node);
-  R visitVariableDefinitions(VariableDefinitions node) => visitStatement(node);
-  R visitWhile(While node) => visitLoop(node);
-  R visitYield(Yield node) => visitStatement(node);
-}
-
-/// Visitor for [Node]s that take an additional argument of type [A] and returns
-/// a value of type [R].
-abstract class Visitor1<R, A> {
-  const Visitor1();
-
-  R visitNode(Node node, A arg);
-
-  R visitAssert(Assert node, A arg) => visitStatement(node, arg);
-  R visitAsyncForIn(AsyncForIn node, A arg) => visitForIn(node, arg);
-  R visitAsyncModifier(AsyncModifier node, A arg) => visitNode(node, arg);
-  R visitAwait(Await node, A arg) => visitExpression(node, arg);
-  R visitBlock(Block node, A arg) => visitStatement(node, arg);
-  R visitBreakStatement(BreakStatement node, A arg) {
-    return visitGotoStatement(node, arg);
-  }
-
-  R visitCascade(Cascade node, A arg) => visitExpression(node, arg);
-  R visitCascadeReceiver(CascadeReceiver node, A arg) {
-    return visitExpression(node, arg);
-  }
-
-  R visitCaseMatch(CaseMatch node, A arg) => visitNode(node, arg);
-  R visitCatchBlock(CatchBlock node, A arg) => visitNode(node, arg);
-  R visitClassNode(ClassNode node, A arg) => visitNode(node, arg);
-  R visitCombinator(Combinator node, A arg) => visitNode(node, arg);
-  R visitConditional(Conditional node, A arg) => visitExpression(node, arg);
-  R visitConditionalUri(ConditionalUri node, A arg) {
-    return visitNode(node, arg);
-  }
-
-  R visitContinueStatement(ContinueStatement node, A arg) {
-    return visitGotoStatement(node, arg);
-  }
-
-  R visitDottedName(DottedName node, A arg) {
-    return visitExpression(node, arg);
-  }
-
-  R visitDoWhile(DoWhile node, A arg) => visitLoop(node, arg);
-  R visitEmptyStatement(EmptyStatement node, A arg) {
-    return visitStatement(node, arg);
-  }
-
-  R visitEnum(Enum node, A arg) => visitNode(node, arg);
-  R visitExport(Export node, A arg) => visitLibraryDependency(node, arg);
-  R visitExpression(Expression node, A arg) => visitNode(node, arg);
-  R visitExpressionStatement(ExpressionStatement node, A arg) {
-    return visitStatement(node, arg);
-  }
-
-  R visitFor(For node, A arg) => visitLoop(node, arg);
-  R visitForIn(ForIn node, A arg) => visitLoop(node, arg);
-  R visitFunctionDeclaration(FunctionDeclaration node, A arg) {
-    return visitStatement(node, arg);
-  }
-
-  R visitFunctionExpression(FunctionExpression node, A arg) {
-    return visitExpression(node, arg);
-  }
-
-  R visitFunctionTypeAnnotation(FunctionTypeAnnotation node, A arg) {
-    return visitTypeAnnotation(node, arg);
-  }
-
-  R visitGotoStatement(GotoStatement node, A arg) {
-    return visitStatement(node, arg);
-  }
-
-  R visitIdentifier(Identifier node, A arg) {
-    return visitExpression(node, arg);
-  }
-
-  R visitImport(Import node, A arg) {
-    return visitLibraryDependency(node, arg);
-  }
-
-  R visitIf(If node, A arg) => visitStatement(node, arg);
-  R visitLabel(Label node, A arg) => visitNode(node, arg);
-  R visitLabeledStatement(LabeledStatement node, A arg) {
-    return visitStatement(node, arg);
-  }
-
-  R visitLibraryDependency(LibraryDependency node, A arg) {
-    return visitLibraryTag(node, arg);
-  }
-
-  R visitLibraryName(LibraryName node, A arg) => visitLibraryTag(node, arg);
-  R visitLibraryTag(LibraryTag node, A arg) => visitNode(node, arg);
-  R visitLiteral(Literal node, A arg) => visitExpression(node, arg);
-  R visitLiteralBool(LiteralBool node, A arg) => visitLiteral(node, arg);
-  R visitLiteralDouble(LiteralDouble node, A arg) => visitLiteral(node, arg);
-  R visitLiteralInt(LiteralInt node, A arg) => visitLiteral(node, arg);
-  R visitLiteralList(LiteralList node, A arg) => visitExpression(node, arg);
-  R visitLiteralMap(LiteralMap node, A arg) => visitExpression(node, arg);
-  R visitLiteralMapEntry(LiteralMapEntry node, A arg) => visitNode(node, arg);
-  R visitLiteralNull(LiteralNull node, A arg) => visitLiteral(node, arg);
-  R visitLiteralString(LiteralString node, A arg) => visitStringNode(node, arg);
-  R visitStringJuxtaposition(StringJuxtaposition node, A arg) {
-    return visitStringNode(node, arg);
-  }
-
-  R visitSyncForIn(SyncForIn node, A arg) => visitForIn(node, arg);
-  R visitLoop(Loop node, A arg) => visitStatement(node, arg);
-  R visitMetadata(Metadata node, A arg) => visitNode(node, arg);
-  R visitMixinApplication(MixinApplication node, A arg) => visitNode(node, arg);
-  R visitModifiers(Modifiers node, A arg) => visitNode(node, arg);
-  R visitNamedArgument(NamedArgument node, A arg) => visitExpression(node, arg);
-  R visitNamedMixinApplication(NamedMixinApplication node, A arg) {
-    return visitMixinApplication(node, arg);
-  }
-
-  R visitNewExpression(NewExpression node, A arg) => visitExpression(node, arg);
-  R visitNodeList(NodeList node, A arg) => visitNode(node, arg);
-  R visitNominalTypeAnnotation(NominalTypeAnnotation node, A arg) {
-    return visitTypeAnnotation(node, arg);
-  }
-
-  R visitOperator(Operator node, A arg) => visitIdentifier(node, arg);
-  R visitParenthesizedExpression(ParenthesizedExpression node, A arg) {
-    return visitExpression(node, arg);
-  }
-
-  R visitPart(Part node, A arg) => visitLibraryTag(node, arg);
-  R visitPartOf(PartOf node, A arg) => visitNode(node, arg);
-  R visitPostfix(Postfix node, A arg) => visitNodeList(node, arg);
-  R visitPrefix(Prefix node, A arg) => visitNodeList(node, arg);
-  R visitRedirectingFactoryBody(RedirectingFactoryBody node, A arg) {
-    return visitStatement(node, arg);
-  }
-
-  R visitRethrow(Rethrow node, A arg) => visitStatement(node, arg);
-  R visitReturn(Return node, A arg) => visitStatement(node, arg);
-  R visitSend(Send node, A arg) => visitExpression(node, arg);
-  R visitSendSet(SendSet node, A arg) => visitSend(node, arg);
-  R visitStatement(Statement node, A arg) => visitNode(node, arg);
-  R visitStringNode(StringNode node, A arg) => visitExpression(node, arg);
-  R visitStringInterpolation(StringInterpolation node, A arg) {
-    return visitStringNode(node, arg);
-  }
-
-  R visitStringInterpolationPart(StringInterpolationPart node, A arg) {
-    return visitNode(node, arg);
-  }
-
-  R visitSwitchCase(SwitchCase node, A arg) => visitNode(node, arg);
-  R visitSwitchStatement(SwitchStatement node, A arg) {
-    return visitStatement(node, arg);
-  }
-
-  R visitLiteralSymbol(LiteralSymbol node, A arg) => visitExpression(node, arg);
-  R visitThrow(Throw node, A arg) => visitExpression(node, arg);
-  R visitTryStatement(TryStatement node, A arg) => visitStatement(node, arg);
-  R visitTypedef(Typedef node, A arg) => visitNode(node, arg);
-  R visitTypeAnnotation(TypeAnnotation node, A arg) => visitNode(node, arg);
-  R visitTypeVariable(TypeVariable node, A arg) => visitNode(node, arg);
-  R visitVariableDefinitions(VariableDefinitions node, A arg) {
-    return visitStatement(node, arg);
-  }
-
-  R visitWhile(While node, A arg) => visitLoop(node, arg);
-  R visitYield(Yield node, A arg) => visitStatement(node, arg);
-}
-
-Token firstBeginToken(Node first, Node second) {
-  Token token = null;
-  if (first != null) {
-    token = first.getBeginToken();
-  }
-  if (token == null && second != null) {
-    // [token] might be null even when [first] is not, e.g. for empty Modifiers.
-    token = second.getBeginToken();
-  }
-  return token;
-}
-
-/**
- * A node in a syntax tree.
- *
- * The abstract part of "abstract syntax tree" is invalidated when
- * supporting tools such as code formatting. These tools need concrete
- * syntax such as parentheses and no constant folding.
- *
- * We support these tools by storing additional references back to the
- * token stream. These references are stored in fields ending with
- * "Token".
- */
-abstract class Node extends NullTreeElementMixin implements Spannable {
-  final int hashCode = _HASH_COUNTER = (_HASH_COUNTER + 1).toUnsigned(30);
-  static int _HASH_COUNTER = 0;
-
-  Node();
-
-  accept(Visitor visitor);
-
-  accept1(Visitor1 visitor, arg);
-
-  visitChildren(Visitor visitor);
-
-  visitChildren1(Visitor1 visitor, arg);
-
-  /**
-   * Returns this node unparsed to Dart source string.
-   */
-  toString() => unparse(this);
-
-  /**
-   * Returns Xml-like tree representation of this node.
-   */
-  toDebugString() {
-    return PrettyPrinter.prettyPrint(this);
-  }
-
-  String getObjectDescription() => super.toString();
-
-  Token getBeginToken();
-
-  /// Returns the token that ends the 'prefix' of this node.
-  ///
-  /// For instance the end of the parameters in a [FunctionExpression] or the
-  /// last token before the start of a class body for a [ClassNode].
-  Token getPrefixEndToken() => getEndToken();
-
-  Token getEndToken();
-
-  Assert asAssert() => null;
-  AsyncModifier asAsyncModifier() => null;
-  Await asAwait() => null;
-  Block asBlock() => null;
-  BreakStatement asBreakStatement() => null;
-  Cascade asCascade() => null;
-  CascadeReceiver asCascadeReceiver() => null;
-  CaseMatch asCaseMatch() => null;
-  CatchBlock asCatchBlock() => null;
-  ClassNode asClassNode() => null;
-  Combinator asCombinator() => null;
-  Conditional asConditional() => null;
-  ConditionalUri asConditionalUri() => null;
-  ContinueStatement asContinueStatement() => null;
-  DottedName asDottedName() => null;
-  DoWhile asDoWhile() => null;
-  EmptyStatement asEmptyStatement() => null;
-  Enum asEnum() => null;
-  ErrorExpression asErrorExpression() => null;
-  Export asExport() => null;
-  Expression asExpression() => null;
-  ExpressionStatement asExpressionStatement() => null;
-  For asFor() => null;
-  SyncForIn asSyncForIn() => null;
-  AsyncForIn asAsyncForIn() => null;
-  ForIn asForIn() => null;
-  FunctionDeclaration asFunctionDeclaration() => null;
-  FunctionExpression asFunctionExpression() => null;
-  FunctionTypeAnnotation asFunctionTypeAnnotation() => null;
-  Identifier asIdentifier() => null;
-  If asIf() => null;
-  Import asImport() => null;
-  Label asLabel() => null;
-  LabeledStatement asLabeledStatement() => null;
-  LibraryName asLibraryName() => null;
-  LibraryDependency asLibraryDependency() => null;
-  LiteralBool asLiteralBool() => null;
-  LiteralDouble asLiteralDouble() => null;
-  LiteralInt asLiteralInt() => null;
-  LiteralList asLiteralList() => null;
-  LiteralMap asLiteralMap() => null;
-  LiteralMapEntry asLiteralMapEntry() => null;
-  LiteralNull asLiteralNull() => null;
-  LiteralString asLiteralString() => null;
-  LiteralSymbol asLiteralSymbol() => null;
-  Metadata asMetadata() => null;
-  MixinApplication asMixinApplication() => null;
-  Modifiers asModifiers() => null;
-  NamedArgument asNamedArgument() => null;
-  NamedMixinApplication asNamedMixinApplication() => null;
-  NewExpression asNewExpression() => null;
-  NodeList asNodeList() => null;
-  NominalTypeAnnotation asNominalTypeAnnotation() => null;
-  Operator asOperator() => null;
-  ParenthesizedExpression asParenthesizedExpression() => null;
-  Part asPart() => null;
-  PartOf asPartOf() => null;
-  RedirectingFactoryBody asRedirectingFactoryBody() => null;
-  Rethrow asRethrow() => null;
-  Return asReturn() => null;
-  Send asSend() => null;
-  SendSet asSendSet() => null;
-  Statement asStatement() => null;
-  StringInterpolation asStringInterpolation() => null;
-  StringInterpolationPart asStringInterpolationPart() => null;
-  StringJuxtaposition asStringJuxtaposition() => null;
-  StringNode asStringNode() => null;
-  SwitchCase asSwitchCase() => null;
-  SwitchStatement asSwitchStatement() => null;
-  Throw asThrow() => null;
-  TryStatement asTryStatement() => null;
-  TypeVariable asTypeVariable() => null;
-  Typedef asTypedef() => null;
-  VariableDefinitions asVariableDefinitions() => null;
-  While asWhile() => null;
-  Yield asYield() => null;
-
-  bool isValidBreakTarget() => false;
-  bool isValidContinueTarget() => false;
-  bool isThis() => false;
-  bool isSuper() => false;
-
-  bool get isErroneous => false;
-}
-
-// Used for caching boolean values on the stack
-class Flag extends Node {
-  static final TRUE = new Flag._(true);
-  static final FALSE = new Flag._(false);
-
-  final bool value;
-
-  Flag._(this.value);
-
-  @override
-  accept(Visitor visitor) {
-    throw 'not implemented';
-  }
-
-  @override
-  accept1(Visitor1 visitor, arg) {
-    throw 'not implemented';
-  }
-
-  @override
-  Token getBeginToken() {
-    return null;
-  }
-
-  @override
-  Token getEndToken() {
-    throw 'not implemented';
-  }
-
-  @override
-  visitChildren(Visitor visitor) {
-    throw 'not implemented';
-  }
-
-  @override
-  visitChildren1(Visitor1 visitor, arg) {
-    throw 'not implemented';
-  }
-}
-
-// Used for caching tokens on the stack
-class TokenNode extends Node {
-  final Token token;
-
-  TokenNode(this.token);
-
-  @override
-  accept(Visitor visitor) {
-    throw 'not implemented';
-  }
-
-  @override
-  accept1(Visitor1 visitor, arg) {
-    throw 'not implemented';
-  }
-
-  @override
-  Token getBeginToken() {
-    throw 'not implemented';
-  }
-
-  @override
-  Token getEndToken() {
-    throw 'not implemented';
-  }
-
-  @override
-  visitChildren(Visitor visitor) {
-    throw 'not implemented';
-  }
-
-  @override
-  visitChildren1(Visitor1 visitor, arg) {
-    throw 'not implemented';
-  }
-}
-
-class ClassNode extends Node {
-  final Modifiers modifiers;
-  final Identifier name;
-  final Node superclass;
-  final NodeList interfaces;
-  final NodeList typeParameters;
-  final NodeList body;
-
-  final Token beginToken;
-  final Token extendsKeyword;
-  final Token endToken;
-
-  ClassNode(
-      this.modifiers,
-      this.name,
-      this.typeParameters,
-      this.superclass,
-      this.interfaces,
-      this.beginToken,
-      this.extendsKeyword,
-      this.body,
-      this.endToken);
-
-  ClassNode asClassNode() => this;
-
-  accept(Visitor visitor) => visitor.visitClassNode(this);
-
-  accept1(Visitor1 visitor, arg) => visitor.visitClassNode(this, arg);
-
-  visitChildren(Visitor visitor) {
-    if (name != null) name.accept(visitor);
-    if (typeParameters != null) typeParameters.accept(visitor);
-    if (superclass != null) superclass.accept(visitor);
-    if (interfaces != null) interfaces.accept(visitor);
-    if (body != null) body.accept(visitor);
-  }
-
-  visitChildren1(Visitor1 visitor, arg) {
-    if (name != null) name.accept1(visitor, arg);
-    if (typeParameters != null) typeParameters.accept1(visitor, arg);
-    if (superclass != null) superclass.accept1(visitor, arg);
-    if (interfaces != null) interfaces.accept1(visitor, arg);
-    if (body != null) body.accept1(visitor, arg);
-  }
-
-  Token getBeginToken() => beginToken;
-
-  @override
-  Token getPrefixEndToken() {
-    Token token;
-    if (interfaces != null) {
-      token = interfaces.getEndToken();
-    }
-    if (token == null && superclass != null) {
-      token = superclass.getEndToken();
-    }
-    if (token == null && typeParameters != null) {
-      token == typeParameters.getEndToken();
-    }
-    if (token == null) {
-      token = name.getEndToken();
-    }
-    assert(token != null);
-    return token;
-  }
-
-  Token getEndToken() => endToken;
-}
-
-class MixinApplication extends Node {
-  final NominalTypeAnnotation superclass;
-  final NodeList mixins;
-
-  MixinApplication(this.superclass, this.mixins);
-
-  MixinApplication asMixinApplication() => this;
-
-  accept(Visitor visitor) => visitor.visitMixinApplication(this);
-
-  accept1(Visitor1 visitor, arg) => visitor.visitMixinApplication(this, arg);
-
-  visitChildren(Visitor visitor) {
-    if (superclass != null) superclass.accept(visitor);
-    if (mixins != null) mixins.accept(visitor);
-  }
-
-  visitChildren1(Visitor1 visitor, arg) {
-    if (superclass != null) superclass.accept1(visitor, arg);
-    if (mixins != null) mixins.accept1(visitor, arg);
-  }
-
-  Token getBeginToken() => superclass.getBeginToken();
-  Token getEndToken() => mixins.getEndToken();
-}
-
-class NamedMixinApplication extends Node implements MixinApplication {
-  final Identifier name;
-  final NodeList typeParameters;
-
-  final Modifiers modifiers;
-  final MixinApplication mixinApplication;
-  final NodeList interfaces;
-
-  final Token classKeyword;
-  final Token endToken;
-
-  NamedMixinApplication(this.name, this.typeParameters, this.modifiers,
-      this.mixinApplication, this.interfaces, this.classKeyword, this.endToken);
-
-  NominalTypeAnnotation get superclass => mixinApplication.superclass;
-  NodeList get mixins => mixinApplication.mixins;
-
-  MixinApplication asMixinApplication() => this;
-  NamedMixinApplication asNamedMixinApplication() => this;
-
-  accept(Visitor visitor) => visitor.visitNamedMixinApplication(this);
-
-  accept1(Visitor1 visitor, arg) {
-    return visitor.visitNamedMixinApplication(this, arg);
-  }
-
-  visitChildren(Visitor visitor) {
-    name.accept(visitor);
-    if (typeParameters != null) typeParameters.accept(visitor);
-    if (modifiers != null) modifiers.accept(visitor);
-    if (interfaces != null) interfaces.accept(visitor);
-    mixinApplication.accept(visitor);
-  }
-
-  visitChildren1(Visitor1 visitor, arg) {
-    name.accept1(visitor, arg);
-    if (typeParameters != null) typeParameters.accept1(visitor, arg);
-    if (modifiers != null) modifiers.accept1(visitor, arg);
-    if (interfaces != null) interfaces.accept1(visitor, arg);
-    mixinApplication.accept1(visitor, arg);
-  }
-
-  Token getBeginToken() => classKeyword;
-  Token getEndToken() => endToken;
-}
-
-abstract class Expression extends Node {
-  Expression();
-
-  Expression asExpression() => this;
-}
-
-abstract class Statement extends Node {
-  Statement();
-
-  Statement asStatement() => this;
-
-  bool isValidBreakTarget() => true;
-}
-
-/// Erroneous expression that behaves as a literal null.
-class ErrorExpression extends LiteralNull {
-  ErrorExpression(token) : super(token);
-
-  ErrorExpression asErrorExpression() => this;
-
-  bool get isErroneous => true;
-}
-
-/**
- * A message send aka method invocation. In Dart, most operations can
- * (and should) be considered as message sends. Getters and setters
- * are just methods with a special syntax. Consequently, we model
- * property access, assignment, operators, and method calls with this
- * one node.
- */
-class Send extends Expression with StoredTreeElementMixin {
-  final Node receiver;
-  final Node selector;
-  final NodeList argumentsNode;
-  final NodeList typeArgumentsNode;
-
-  /// Whether this is a conditional send of the form `a?.b`.
-  final bool isConditional;
-
-  Link<Node> get arguments => argumentsNode.nodes;
-
-  Send(
-      [this.receiver,
-      this.selector,
-      this.argumentsNode,
-      this.typeArgumentsNode,
-      this.isConditional = false]);
-  Send.postfix(this.receiver, this.selector,
-      [Node argument = null, this.isConditional = false])
-      : argumentsNode = (argument == null)
-            ? new Postfix()
-            : new Postfix.singleton(argument),
-        typeArgumentsNode = null;
-  Send.prefix(this.receiver, this.selector,
-      [Node argument = null, this.isConditional = false])
-      : argumentsNode =
-            (argument == null) ? new Prefix() : new Prefix.singleton(argument),
-        typeArgumentsNode = null;
-
-  Send asSend() => this;
-
-  accept(Visitor visitor) => visitor.visitSend(this);
-
-  accept1(Visitor1 visitor, arg) => visitor.visitSend(this, arg);
-
-  visitChildren(Visitor visitor) {
-    if (receiver != null) receiver.accept(visitor);
-    if (selector != null) selector.accept(visitor);
-    if (argumentsNode != null) argumentsNode.accept(visitor);
-  }
-
-  visitChildren1(Visitor1 visitor, arg) {
-    if (receiver != null) receiver.accept1(visitor, arg);
-    if (selector != null) selector.accept1(visitor, arg);
-    if (argumentsNode != null) argumentsNode.accept1(visitor, arg);
-  }
-
-  int argumentCount() {
-    return (argumentsNode == null) ? -1 : argumentsNode.slowLength();
-  }
-
-  bool get isSuperCall {
-    return receiver != null && receiver.isSuper();
-  }
-
-  bool get isOperator => selector is Operator;
-  bool get isPropertyAccess => argumentsNode == null;
-  bool get isFunctionObjectInvocation => selector == null;
-  bool get isPrefix => argumentsNode is Prefix;
-  bool get isPostfix => argumentsNode is Postfix;
-  bool get isCall => !isOperator && !isPropertyAccess;
-  bool get isIndex =>
-      isOperator && identical(selector.asOperator().source, '[]');
-  bool get isLogicalAnd =>
-      isOperator && identical(selector.asOperator().source, '&&');
-  bool get isLogicalOr =>
-      isOperator && identical(selector.asOperator().source, '||');
-  bool get isIfNull =>
-      isOperator && identical(selector.asOperator().source, '??');
-
-  bool get isTypeCast {
-    return isOperator && identical(selector.asOperator().source, 'as');
-  }
-
-  bool get isTypeTest {
-    return isOperator && identical(selector.asOperator().source, 'is');
-  }
-
-  bool get isIsNotCheck {
-    return isTypeTest && arguments.head.asSend() != null;
-  }
-
-  TypeAnnotation get typeAnnotationFromIsCheckOrCast {
-    assert(isOperator);
-    assert(identical(selector.asOperator().source, 'is') ||
-        identical(selector.asOperator().source, 'as'));
-    return isIsNotCheck ? arguments.head.asSend().receiver : arguments.head;
-  }
-
-  Token getBeginToken() {
-    if (isPrefix && !isIndex) return selector.getBeginToken();
-    return firstBeginToken(receiver, selector);
-  }
-
-  Token getEndToken() {
-    if (isPrefix) {
-      if (receiver != null) return receiver.getEndToken();
-      if (selector != null) return selector.getEndToken();
-      return null;
-    }
-    if (!isPostfix && argumentsNode != null) {
-      Token token = argumentsNode.getEndToken();
-      if (token != null) return token;
-    }
-    if (selector != null) return selector.getEndToken();
-    return getBeginToken();
-  }
-
-  Send copyWithReceiver(Node newReceiver, bool isConditional) {
-    assert(receiver == null);
-    return new Send(
-        newReceiver, selector, argumentsNode, typeArgumentsNode, isConditional);
-  }
-}
-
-class Postfix extends NodeList {
-  Postfix() : super(null, const Link<Node>());
-  Postfix.singleton(Node argument) : super.singleton(argument);
-}
-
-class Prefix extends NodeList {
-  Prefix() : super(null, const Link<Node>());
-  Prefix.singleton(Node argument) : super.singleton(argument);
-}
-
-class SendSet extends Send {
-  final Operator assignmentOperator;
-  SendSet(receiver, selector, this.assignmentOperator, argumentsNode,
-      [bool isConditional = false])
-      : super(receiver, selector, argumentsNode, null, isConditional);
-  SendSet.postfix(receiver, selector, this.assignmentOperator,
-      [Node argument = null, bool isConditional = false])
-      : super.postfix(receiver, selector, argument, isConditional);
-  SendSet.prefix(receiver, selector, this.assignmentOperator,
-      [Node argument = null, bool isConditional = false])
-      : super.prefix(receiver, selector, argument, isConditional);
-
-  SendSet asSendSet() => this;
-
-  accept(Visitor visitor) => visitor.visitSendSet(this);
-
-  accept1(Visitor1 visitor, arg) => visitor.visitSendSet(this, arg);
-
-  visitChildren(Visitor visitor) {
-    super.visitChildren(visitor);
-    if (assignmentOperator != null) assignmentOperator.accept(visitor);
-  }
-
-  visitChildren1(Visitor1 visitor, arg) {
-    super.visitChildren1(visitor, arg);
-    if (assignmentOperator != null) assignmentOperator.accept1(visitor, arg);
-  }
-
-  /// `true` if this send is not a simple assignment.
-  bool get isComplex => !identical(assignmentOperator.source, '=');
-
-  /// Whether this is an if-null assignment of the form `a ??= b`.
-  bool get isIfNullAssignment => identical(assignmentOperator.source, '??=');
-
-  Send copyWithReceiver(Node newReceiver, bool isConditional) {
-    assert(receiver == null);
-    return new SendSet(newReceiver, selector, assignmentOperator, argumentsNode,
-        isConditional);
-  }
-
-  Token getBeginToken() {
-    if (isPrefix) return assignmentOperator.getBeginToken();
-    return super.getBeginToken();
-  }
-
-  Token getEndToken() {
-    if (isPostfix) return assignmentOperator.getEndToken();
-    return super.getEndToken();
-  }
-}
-
-class NewExpression extends Expression {
-  /** The token NEW or CONST or `null` for metadata */
-  final Token newToken;
-
-  // Note: we expect that send.receiver is null.
-  final Send send;
-
-  NewExpression([this.newToken, this.send]);
-
-  NewExpression asNewExpression() => this;
-
-  accept(Visitor visitor) => visitor.visitNewExpression(this);
-
-  accept1(Visitor1 visitor, arg) => visitor.visitNewExpression(this, arg);
-
-  visitChildren(Visitor visitor) {
-    if (send != null) send.accept(visitor);
-  }
-
-  visitChildren1(Visitor1 visitor, arg) {
-    if (send != null) send.accept1(visitor, arg);
-  }
-
-  bool get isConst {
-    return newToken == null || identical(newToken.stringValue, 'const');
-  }
-
-  Token getBeginToken() => newToken != null ? newToken : send.getBeginToken();
-
-  Token getEndToken() => send.getEndToken();
-}
-
-class NodeList extends Node with IterableMixin<Node> {
-  final Link<Node> nodes;
-  final Token beginToken;
-  final Token endToken;
-  final String delimiter;
-  bool get isEmpty => nodes.isEmpty;
-
-  NodeList([this.beginToken, this.nodes, this.endToken, this.delimiter]);
-
-  Iterator<Node> get iterator => nodes.iterator;
-
-  NodeList.singleton(Node node) : this(null, const Link<Node>().prepend(node));
-  NodeList.empty() : this(null, const Link<Node>());
-
-  NodeList asNodeList() => this;
-
-  // Override [IterableMixin.toString] with same code as [Node.toString].
-  toString() => unparse(this);
-
-  get length {
-    throw new UnsupportedError('use slowLength() instead of get:length');
-  }
-
-  int slowLength() {
-    int result = 0;
-    for (Link<Node> cursor = nodes; !cursor.isEmpty; cursor = cursor.tail) {
-      result++;
-    }
-    return result;
-  }
-
-  accept(Visitor visitor) => visitor.visitNodeList(this);
-
-  accept1(Visitor1 visitor, arg) => visitor.visitNodeList(this, arg);
-
-  visitChildren(Visitor visitor) {
-    if (nodes == null) return;
-    for (Link<Node> link = nodes; !link.isEmpty; link = link.tail) {
-      if (link.head != null) link.head.accept(visitor);
-    }
-  }
-
-  visitChildren1(Visitor1 visitor, arg) {
-    if (nodes == null) return;
-    for (Link<Node> link = nodes; !link.isEmpty; link = link.tail) {
-      if (link.head != null) link.head.accept1(visitor, arg);
-    }
-  }
-
-  Token getBeginToken() {
-    if (beginToken != null) return beginToken;
-    if (nodes != null) {
-      for (Link<Node> link = nodes; !link.isEmpty; link = link.tail) {
-        if (link.head.getBeginToken() != null) {
-          return link.head.getBeginToken();
-        }
-        if (link.head.getEndToken() != null) {
-          return link.head.getEndToken();
-        }
-      }
-    }
-    return endToken;
-  }
-
-  Token getEndToken() {
-    if (endToken != null) return endToken;
-    if (nodes != null) {
-      Link<Node> link = nodes;
-      if (link.isEmpty) return beginToken;
-      while (!link.tail.isEmpty) link = link.tail;
-      Node lastNode = link.head;
-      if (lastNode != null) {
-        if (lastNode.getEndToken() != null) return lastNode.getEndToken();
-        if (lastNode.getBeginToken() != null) return lastNode.getBeginToken();
-      }
-    }
-    return beginToken;
-  }
-}
-
-class Block extends Statement {
-  final NodeList statements;
-
-  Block(this.statements);
-
-  Block asBlock() => this;
-
-  accept(Visitor visitor) => visitor.visitBlock(this);
-
-  accept1(Visitor1 visitor, arg) => visitor.visitBlock(this, arg);
-
-  visitChildren(Visitor visitor) {
-    if (statements != null) statements.accept(visitor);
-  }
-
-  visitChildren1(Visitor1 visitor, arg) {
-    if (statements != null) statements.accept1(visitor, arg);
-  }
-
-  Token getBeginToken() => statements.getBeginToken();
-
-  Token getEndToken() => statements.getEndToken();
-}
-
-class If extends Statement {
-  final ParenthesizedExpression condition;
-  final Statement thenPart;
-  final Statement elsePart;
-
-  final Token ifToken;
-  final Token elseToken;
-
-  If(this.condition, this.thenPart, this.elsePart, this.ifToken,
-      this.elseToken);
-
-  If asIf() => this;
-
-  bool get hasElsePart => elsePart != null;
-
-  accept(Visitor visitor) => visitor.visitIf(this);
-
-  accept1(Visitor1 visitor, arg) => visitor.visitIf(this, arg);
-
-  visitChildren(Visitor visitor) {
-    if (condition != null) condition.accept(visitor);
-    if (thenPart != null) thenPart.accept(visitor);
-    if (elsePart != null) elsePart.accept(visitor);
-  }
-
-  visitChildren1(Visitor1 visitor, arg) {
-    if (condition != null) condition.accept1(visitor, arg);
-    if (thenPart != null) thenPart.accept1(visitor, arg);
-    if (elsePart != null) elsePart.accept1(visitor, arg);
-  }
-
-  Token getBeginToken() => ifToken;
-
-  Token getEndToken() {
-    if (elsePart == null) return thenPart.getEndToken();
-    return elsePart.getEndToken();
-  }
-}
-
-class Conditional extends Expression {
-  final Expression condition;
-  final Expression thenExpression;
-  final Expression elseExpression;
-
-  final Token questionToken;
-  final Token colonToken;
-
-  Conditional(this.condition, this.thenExpression, this.elseExpression,
-      this.questionToken, this.colonToken);
-
-  Conditional asConditional() => this;
-
-  accept(Visitor visitor) => visitor.visitConditional(this);
-
-  accept1(Visitor1 visitor, arg) => visitor.visitConditional(this, arg);
-
-  visitChildren(Visitor visitor) {
-    condition.accept(visitor);
-    thenExpression.accept(visitor);
-    elseExpression.accept(visitor);
-  }
-
-  visitChildren1(Visitor1 visitor, arg) {
-    condition.accept1(visitor, arg);
-    thenExpression.accept1(visitor, arg);
-    elseExpression.accept1(visitor, arg);
-  }
-
-  Token getBeginToken() => condition.getBeginToken();
-
-  Token getEndToken() => elseExpression.getEndToken();
-}
-
-class For extends Loop {
-  /** Either a variable declaration or an expression. */
-  final Node initializer;
-  /** Either an expression statement or an empty statement. */
-  final Statement conditionStatement;
-  final NodeList update;
-
-  final Token forToken;
-
-  For(this.initializer, this.conditionStatement, this.update, body,
-      this.forToken)
-      : super(body);
-
-  For asFor() => this;
-
-  Expression get condition {
-    ExpressionStatement expressionStatement =
-        conditionStatement.asExpressionStatement();
-    if (expressionStatement != null) {
-      return expressionStatement.expression;
-    } else {
-      return null;
-    }
-  }
-
-  accept(Visitor visitor) => visitor.visitFor(this);
-
-  accept1(Visitor1 visitor, arg) => visitor.visitFor(this, arg);
-
-  visitChildren(Visitor visitor) {
-    if (initializer != null) initializer.accept(visitor);
-    if (conditionStatement != null) conditionStatement.accept(visitor);
-    if (update != null) update.accept(visitor);
-    if (body != null) body.accept(visitor);
-  }
-
-  visitChildren1(Visitor1 visitor, arg) {
-    if (initializer != null) initializer.accept1(visitor, arg);
-    if (conditionStatement != null) conditionStatement.accept1(visitor, arg);
-    if (update != null) update.accept1(visitor, arg);
-    if (body != null) body.accept1(visitor, arg);
-  }
-
-  Token getBeginToken() => forToken;
-
-  Token getEndToken() {
-    return body.getEndToken();
-  }
-}
-
-class FunctionDeclaration extends Statement {
-  final FunctionExpression function;
-
-  FunctionDeclaration(this.function);
-
-  FunctionDeclaration asFunctionDeclaration() => this;
-
-  accept(Visitor visitor) => visitor.visitFunctionDeclaration(this);
-
-  accept1(Visitor1 visitor, arg) => visitor.visitFunctionDeclaration(this, arg);
-
-  visitChildren(Visitor visitor) => function.accept(visitor);
-
-  visitChildren1(Visitor1 visitor, arg) => function.accept1(visitor, arg);
-
-  Token getBeginToken() => function.getBeginToken();
-
-  @override
-  Token getPrefixEndToken() => function.getPrefixEndToken();
-
-  Token getEndToken() => function.getEndToken();
-}
-
-/// Node representing the method implementation modifiers `sync*`, `async`, and
-/// `async*` or the invalid modifier `sync`.
-class AsyncModifier extends Node {
-  /// The `async` or `sync` token.
-  final Token asyncToken;
-
-  /// The `*` token.
-  final Token starToken;
-
-  AsyncModifier(this.asyncToken, this.starToken);
-
-  AsyncModifier asAsyncModifier() => this;
-
-  accept(Visitor visitor) => visitor.visitAsyncModifier(this);
-
-  accept1(Visitor1 visitor, arg) => visitor.visitAsyncModifier(this, arg);
-
-  visitChildren(Visitor visitor) {}
-
-  visitChildren1(Visitor1 visitor, arg) {}
-
-  Token getBeginToken() => asyncToken;
-
-  Token getEndToken() => starToken != null ? starToken : asyncToken;
-
-  /// Is `true` if this modifier is either `async` or `async*`.
-  bool get isAsynchronous => asyncToken.lexeme == 'async';
-
-  /// Is `true` if this modifier is either `sync*` or `async*`.
-  bool get isYielding => starToken != null;
-}
-
-class FunctionExpression extends Expression with StoredTreeElementMixin {
-  final Node name;
-  final NodeList typeVariables;
-
-  /**
-   * List of VariableDefinitions or NodeList.
-   *
-   * A NodeList can only occur at the end and holds named parameters.
-   */
-  final NodeList parameters;
-
-  final Statement body;
-  final TypeAnnotation returnType;
-  final Modifiers modifiers;
-  final NodeList initializers;
-
-  final Token getOrSet;
-  final AsyncModifier asyncModifier;
-
-  FunctionExpression(
-      this.name,
-      this.typeVariables,
-      this.parameters,
-      this.body,
-      this.returnType,
-      this.modifiers,
-      this.initializers,
-      this.getOrSet,
-      this.asyncModifier) {
-    assert(modifiers != null);
-  }
-
-  FunctionExpression asFunctionExpression() => this;
-
-  accept(Visitor visitor) => visitor.visitFunctionExpression(this);
-
-  accept1(Visitor1 visitor, arg) => visitor.visitFunctionExpression(this, arg);
-
-  bool get isRedirectingFactory {
-    return body != null && body.asRedirectingFactoryBody() != null;
-  }
-
-  visitChildren(Visitor visitor) {
-    if (modifiers != null) modifiers.accept(visitor);
-    if (returnType != null) returnType.accept(visitor);
-    if (name != null) name.accept(visitor);
-    if (typeVariables != null) typeVariables.accept(visitor);
-    if (parameters != null) parameters.accept(visitor);
-    if (initializers != null) initializers.accept(visitor);
-    if (asyncModifier != null) asyncModifier.accept(visitor);
-    if (body != null) body.accept(visitor);
-  }
-
-  visitChildren1(Visitor1 visitor, arg) {
-    if (modifiers != null) modifiers.accept1(visitor, arg);
-    if (returnType != null) returnType.accept1(visitor, arg);
-    if (name != null) name.accept1(visitor, arg);
-    if (typeVariables != null) typeVariables.accept1(visitor, arg);
-    if (parameters != null) parameters.accept1(visitor, arg);
-    if (initializers != null) initializers.accept1(visitor, arg);
-    if (asyncModifier != null) asyncModifier.accept1(visitor, arg);
-    if (body != null) body.accept1(visitor, arg);
-  }
-
-  bool get hasBody => body.asEmptyStatement() == null;
-
-  bool get hasEmptyBody {
-    Block block = body.asBlock();
-    if (block == null) return false;
-    return block.statements.isEmpty;
-  }
-
-  Token getBeginToken() {
-    Token token = firstBeginToken(modifiers, returnType);
-    if (token != null) return token;
-    if (getOrSet != null) return getOrSet;
-    return firstBeginToken(name, parameters);
-  }
-
-  @override
-  Token getPrefixEndToken() {
-    return parameters != null ? parameters.getEndToken() : name.getEndToken();
-  }
-
-  Token getEndToken() {
-    Token token = (body == null) ? null : body.getEndToken();
-    token = (token == null) ? parameters.getEndToken() : token;
-    return (token == null) ? name.getEndToken() : token;
-  }
-}
-
-typedef void DecodeErrorHandler(Token token, var error);
-
-abstract class Literal<T> extends Expression {
-  final Token token;
-  final DecodeErrorHandler handler;
-
-  Literal(Token this.token, DecodeErrorHandler this.handler);
-
-  T get value;
-
-  visitChildren(Visitor visitor) {}
-
-  visitChildren1(Visitor1 visitor, arg) {}
-
-  Token getBeginToken() => token;
-
-  Token getEndToken() => token;
-}
-
-class LiteralInt extends Literal<int> {
-  LiteralInt(Token token, DecodeErrorHandler handler) : super(token, handler);
-
-  LiteralInt asLiteralInt() => this;
-
-  int get value {
-    try {
-      Token valueToken = token;
-      if (identical(valueToken.kind, Tokens.PLUS_TOKEN)) {
-        valueToken = valueToken.next;
-      }
-      return int.parse(valueToken.lexeme);
-    } on FormatException catch (ex) {
-      handler(token, ex);
-      throw new ArgumentError("handler didn't throw; aborting");
-    }
-  }
-
-  accept(Visitor visitor) => visitor.visitLiteralInt(this);
-
-  accept1(Visitor1 visitor, arg) => visitor.visitLiteralInt(this, arg);
-}
-
-class LiteralDouble extends Literal<double> {
-  LiteralDouble(Token token, DecodeErrorHandler handler)
-      : super(token, handler);
-
-  LiteralDouble asLiteralDouble() => this;
-
-  double get value {
-    try {
-      Token valueToken = token;
-      if (identical(valueToken.kind, Tokens.PLUS_TOKEN)) {
-        valueToken = valueToken.next;
-      }
-      return double.parse(valueToken.lexeme);
-    } on FormatException catch (ex) {
-      handler(token, ex);
-      throw new ArgumentError("handler didn't throw; aborting");
-    }
-  }
-
-  accept(Visitor visitor) => visitor.visitLiteralDouble(this);
-
-  accept1(Visitor1 visitor, arg) => visitor.visitLiteralDouble(this, arg);
-}
-
-class LiteralBool extends Literal<bool> {
-  LiteralBool(Token token, DecodeErrorHandler handler) : super(token, handler);
-
-  LiteralBool asLiteralBool() => this;
-
-  bool get value {
-    if (identical(token.stringValue, 'true')) return true;
-    if (identical(token.stringValue, 'false')) return false;
-    (this.handler)(token, "not a bool ${token.lexeme}");
-    throw false;
-  }
-
-  accept(Visitor visitor) => visitor.visitLiteralBool(this);
-
-  accept1(Visitor1 visitor, arg) => visitor.visitLiteralBool(this, arg);
-}
-
-class StringQuoting {
-  /// Cache of common quotings.
-  static const List<StringQuoting> _mapping = const <StringQuoting>[
-    const StringQuoting($SQ, raw: false, leftQuoteLength: 1),
-    const StringQuoting($SQ, raw: true, leftQuoteLength: 1),
-    const StringQuoting($DQ, raw: false, leftQuoteLength: 1),
-    const StringQuoting($DQ, raw: true, leftQuoteLength: 1),
-    // No string quotes with 2 characters.
-    null,
-    null,
-    null,
-    null,
-    // Multiline quotings.
-    const StringQuoting($SQ, raw: false, leftQuoteLength: 3),
-    const StringQuoting($SQ, raw: true, leftQuoteLength: 3),
-    const StringQuoting($DQ, raw: false, leftQuoteLength: 3),
-    const StringQuoting($DQ, raw: true, leftQuoteLength: 3),
-    // Leading single whitespace or escaped newline.
-    const StringQuoting($SQ, raw: false, leftQuoteLength: 4),
-    const StringQuoting($SQ, raw: true, leftQuoteLength: 4),
-    const StringQuoting($DQ, raw: false, leftQuoteLength: 4),
-    const StringQuoting($DQ, raw: true, leftQuoteLength: 4),
-    // Other combinations of leading whitespace and/or escaped newline.
-    const StringQuoting($SQ, raw: false, leftQuoteLength: 5),
-    const StringQuoting($SQ, raw: true, leftQuoteLength: 5),
-    const StringQuoting($DQ, raw: false, leftQuoteLength: 5),
-    const StringQuoting($DQ, raw: true, leftQuoteLength: 5),
-    const StringQuoting($SQ, raw: false, leftQuoteLength: 6),
-    const StringQuoting($SQ, raw: true, leftQuoteLength: 6),
-    const StringQuoting($DQ, raw: false, leftQuoteLength: 6),
-    const StringQuoting($DQ, raw: true, leftQuoteLength: 6)
-  ];
-
-  final bool raw;
-  final int leftQuoteCharCount;
-  final int quote;
-  const StringQuoting(this.quote, {this.raw, int leftQuoteLength})
-      : this.leftQuoteCharCount = leftQuoteLength;
-  String get quoteChar => identical(quote, $DQ) ? '"' : "'";
-
-  int get leftQuoteLength => (raw ? 1 : 0) + leftQuoteCharCount;
-  int get rightQuoteLength => (leftQuoteCharCount > 2) ? 3 : 1;
-  static StringQuoting getQuoting(int quote, bool raw, int leftQuoteLength) {
-    int quoteKindOffset = (quote == $DQ) ? 2 : 0;
-    int rawOffset = raw ? 1 : 0;
-    int index = (leftQuoteLength - 1) * 4 + rawOffset + quoteKindOffset;
-    if (index < _mapping.length) return _mapping[index];
-    return new StringQuoting(quote, raw: raw, leftQuoteLength: leftQuoteLength);
-  }
-}
-
-/**
-  * Superclass for classes representing string literals.
-  */
-abstract class StringNode extends Expression {
-  DartString get dartString;
-  bool get isInterpolation;
-
-  StringNode asStringNode() => this;
-}
-
-class LiteralString extends StringNode {
-  final Token token;
-  /** Non-null on validated string literals. */
-  final DartString dartString;
-
-  LiteralString(this.token, this.dartString);
-
-  LiteralString asLiteralString() => this;
-
-  bool get isInterpolation => false;
-
-  Token getBeginToken() => token;
-  Token getEndToken() => token;
-
-  accept(Visitor visitor) => visitor.visitLiteralString(this);
-
-  accept1(Visitor1 visitor, arg) => visitor.visitLiteralString(this, arg);
-
-  void visitChildren(Visitor visitor) {}
-
-  void visitChildren1(Visitor1 visitor, arg) {}
-}
-
-class LiteralNull extends Literal<String> {
-  LiteralNull(Token token) : super(token, null);
-
-  LiteralNull asLiteralNull() => this;
-
-  String get value => null;
-
-  accept(Visitor visitor) => visitor.visitLiteralNull(this);
-
-  accept1(Visitor1 visitor, arg) => visitor.visitLiteralNull(this, arg);
-}
-
-class LiteralList extends Expression {
-  final NodeList typeArguments;
-  final NodeList elements;
-
-  final Token constKeyword;
-
-  LiteralList(this.typeArguments, this.elements, this.constKeyword);
-
-  bool get isConst => constKeyword != null;
-
-  LiteralList asLiteralList() => this;
-  accept(Visitor visitor) => visitor.visitLiteralList(this);
-
-  accept1(Visitor1 visitor, arg) => visitor.visitLiteralList(this, arg);
-
-  visitChildren(Visitor visitor) {
-    if (typeArguments != null) typeArguments.accept(visitor);
-    elements.accept(visitor);
-  }
-
-  visitChildren1(Visitor1 visitor, arg) {
-    if (typeArguments != null) typeArguments.accept1(visitor, arg);
-    elements.accept1(visitor, arg);
-  }
-
-  Token getBeginToken() {
-    if (constKeyword != null) return constKeyword;
-    return firstBeginToken(typeArguments, elements);
-  }
-
-  Token getEndToken() => elements.getEndToken();
-}
-
-class LiteralSymbol extends Expression {
-  final Token hashToken;
-  // TODO: this could be a DottedNamed.
-  final NodeList identifiers;
-
-  LiteralSymbol(this.hashToken, this.identifiers);
-
-  LiteralSymbol asLiteralSymbol() => this;
-
-  accept(Visitor visitor) => visitor.visitLiteralSymbol(this);
-
-  accept1(Visitor1 visitor, arg) => visitor.visitLiteralSymbol(this, arg);
-
-  void visitChildren(Visitor visitor) {
-    if (identifiers != null) identifiers.accept(visitor);
-  }
-
-  void visitChildren1(Visitor1 visitor, arg) {
-    if (identifiers != null) identifiers.accept1(visitor, arg);
-  }
-
-  Token getBeginToken() => hashToken;
-
-  Token getEndToken() => identifiers.getEndToken();
-
-  String get slowNameString {
-    Unparser unparser = new Unparser();
-    unparser.unparseNodeListOfIdentifiers(identifiers);
-    return unparser.result;
-  }
-}
-
-class Identifier extends Expression with StoredTreeElementMixin {
-  final Token token;
-
-  String get source => token.lexeme;
-
-  Identifier(Token this.token);
-
-  bool isThis() => identical(source, 'this');
-
-  bool isSuper() => identical(source, 'super');
-
-  Identifier asIdentifier() => this;
-
-  accept(Visitor visitor) => visitor.visitIdentifier(this);
-
-  accept1(Visitor1 visitor, arg) => visitor.visitIdentifier(this, arg);
-
-  visitChildren(Visitor visitor) {}
-
-  visitChildren1(Visitor1 visitor, arg) {}
-
-  Token getBeginToken() => token;
-
-  Token getEndToken() => token;
-}
-
-// TODO(floitsch): a dotted identifier isn't really an expression. Should it
-// inherit from Node instead?
-class DottedName extends Expression {
-  final Token token;
-  final NodeList identifiers;
-
-  DottedName(this.token, this.identifiers);
-
-  DottedName asDottedName() => this;
-
-  accept(Visitor visitor) => visitor.visitDottedName(this);
-
-  accept1(Visitor1 visitor, arg) => visitor.visitDottedName(this, arg);
-
-  void visitChildren(Visitor visitor) {
-    identifiers.accept(visitor);
-  }
-
-  void visitChildren1(Visitor1 visitor, arg) {
-    identifiers.accept1(visitor, arg);
-  }
-
-  Token getBeginToken() => token;
-  Token getEndToken() => identifiers.getEndToken();
-
-  String get slowNameString {
-    Unparser unparser = new Unparser();
-    unparser.unparseNodeListOfIdentifiers(identifiers);
-    return unparser.result;
-  }
-}
-
-class Operator extends Identifier {
-  static const COMPLEX_OPERATORS = const [
-    "--",
-    "++",
-    '+=',
-    "-=",
-    "*=",
-    "/=",
-    "%=",
-    "&=",
-    "|=",
-    "~/=",
-    "^=",
-    ">>=",
-    "<<=",
-    "??="
-  ];
-
-  static const INCREMENT_OPERATORS = const <String>["++", "--"];
-
-  Operator(Token token) : super(token);
-
-  Operator asOperator() => this;
-
-  accept(Visitor visitor) => visitor.visitOperator(this);
-
-  accept1(Visitor1 visitor, arg) => visitor.visitOperator(this, arg);
-}
-
-class Return extends Statement {
-  final Node expression;
-  final Token beginToken;
-  final Token endToken;
-
-  Return(this.beginToken, this.endToken, this.expression);
-
-  Return asReturn() => this;
-
-  bool get hasExpression => expression != null;
-
-  /// `true` if this return is of the form `=> e;`.
-  bool get isArrowBody => beginToken.type == TokenType.FUNCTION;
-
-  accept(Visitor visitor) => visitor.visitReturn(this);
-
-  accept1(Visitor1 visitor, arg) => visitor.visitReturn(this, arg);
-
-  visitChildren(Visitor visitor) {
-    if (expression != null) expression.accept(visitor);
-  }
-
-  visitChildren1(Visitor1 visitor, arg) {
-    if (expression != null) expression.accept1(visitor, arg);
-  }
-
-  Token getBeginToken() => beginToken;
-
-  Token getEndToken() {
-    if (endToken == null) return expression.getEndToken();
-    return endToken;
-  }
-}
-
-class Yield extends Statement {
-  final Node expression;
-  final Token yieldToken;
-  final Token starToken;
-  final Token endToken;
-
-  Yield(this.yieldToken, this.starToken, this.expression, this.endToken);
-
-  Yield asYield() => this;
-
-  bool get hasStar => starToken != null;
-
-  accept(Visitor visitor) => visitor.visitYield(this);
-
-  accept1(Visitor1 visitor, arg) => visitor.visitYield(this, arg);
-
-  visitChildren(Visitor visitor) {
-    expression.accept(visitor);
-  }
-
-  visitChildren1(Visitor1 visitor, arg) {
-    expression.accept1(visitor, arg);
-  }
-
-  Token getBeginToken() => yieldToken;
-
-  Token getEndToken() => endToken;
-}
-
-class RedirectingFactoryBody extends Statement with StoredTreeElementMixin {
-  final Node constructorReference;
-  final Token beginToken;
-  final Token endToken;
-
-  RedirectingFactoryBody(
-      this.beginToken, this.endToken, this.constructorReference);
-
-  RedirectingFactoryBody asRedirectingFactoryBody() => this;
-
-  accept(Visitor visitor) => visitor.visitRedirectingFactoryBody(this);
-
-  accept1(Visitor1 visitor, arg) {
-    return visitor.visitRedirectingFactoryBody(this, arg);
-  }
-
-  visitChildren(Visitor visitor) {
-    constructorReference.accept(visitor);
-  }
-
-  visitChildren1(Visitor1 visitor, arg) {
-    constructorReference.accept1(visitor, arg);
-  }
-
-  Token getBeginToken() => beginToken;
-
-  Token getEndToken() => endToken;
-}
-
-class ExpressionStatement extends Statement {
-  final Expression expression;
-  final Token endToken;
-
-  ExpressionStatement(this.expression, this.endToken);
-
-  ExpressionStatement asExpressionStatement() => this;
-
-  accept(Visitor visitor) => visitor.visitExpressionStatement(this);
-
-  accept1(Visitor1 visitor, arg) => visitor.visitExpressionStatement(this, arg);
-
-  visitChildren(Visitor visitor) {
-    if (expression != null) expression.accept(visitor);
-  }
-
-  visitChildren1(Visitor1 visitor, arg) {
-    if (expression != null) expression.accept1(visitor, arg);
-  }
-
-  Token getBeginToken() => expression.getBeginToken();
-
-  Token getEndToken() => endToken;
-}
-
-class Throw extends Expression {
-  final Expression expression;
-
-  final Token throwToken;
-  final Token endToken;
-
-  Throw(this.expression, this.throwToken, this.endToken);
-
-  Throw asThrow() => this;
-
-  accept(Visitor visitor) => visitor.visitThrow(this);
-
-  accept1(Visitor1 visitor, arg) => visitor.visitThrow(this, arg);
-
-  visitChildren(Visitor visitor) {
-    expression.accept(visitor);
-  }
-
-  visitChildren1(Visitor1 visitor, arg) {
-    expression.accept1(visitor, arg);
-  }
-
-  Token getBeginToken() => throwToken;
-
-  Token getEndToken() => endToken;
-}
-
-class Await extends Expression {
-  final Expression expression;
-
-  final Token awaitToken;
-
-  Await(this.awaitToken, this.expression);
-
-  Await asAwait() => this;
-
-  accept(Visitor visitor) => visitor.visitAwait(this);
-
-  accept1(Visitor1 visitor, arg) => visitor.visitAwait(this, arg);
-
-  visitChildren(Visitor visitor) {
-    expression.accept(visitor);
-  }
-
-  visitChildren1(Visitor1 visitor, arg) {
-    expression.accept1(visitor, arg);
-  }
-
-  Token getBeginToken() => awaitToken;
-
-  Token getEndToken() => expression.getEndToken();
-}
-
-class Assert extends Statement {
-  final Token assertToken;
-  final Expression condition;
-  /** Message may be `null`. */
-  final Expression message;
-  final Token semicolonToken;
-
-  Assert(this.assertToken, this.condition, this.message, this.semicolonToken);
-
-  Assert asAssert() => this;
-
-  bool get hasMessage => message != null;
-
-  accept(Visitor visitor) => visitor.visitAssert(this);
-
-  accept1(Visitor1 visitor, arg) => visitor.visitAssert(this, arg);
-
-  visitChildren(Visitor visitor) {
-    condition.accept(visitor);
-    if (message != null) message.accept(visitor);
-  }
-
-  visitChildren1(Visitor1 visitor, arg) {
-    condition.accept1(visitor, arg);
-    if (message != null) message.accept1(visitor, arg);
-  }
-
-  Token getBeginToken() => assertToken;
-  Token getEndToken() => semicolonToken;
-}
-
-class Rethrow extends Statement {
-  final Token throwToken;
-  final Token endToken;
-
-  Rethrow(this.throwToken, this.endToken);
-
-  Rethrow asRethrow() => this;
-
-  accept(Visitor visitor) => visitor.visitRethrow(this);
-
-  accept1(Visitor1 visitor, arg) => visitor.visitRethrow(this, arg);
-
-  visitChildren(Visitor visitor) {}
-
-  visitChildren1(Visitor1 visitor, arg) {}
-
-  Token getBeginToken() => throwToken;
-  Token getEndToken() => endToken;
-}
-
-abstract class TypeAnnotation extends Node {}
-
-class NominalTypeAnnotation extends TypeAnnotation {
-  final Expression typeName;
-  final NodeList typeArguments;
-
-  NominalTypeAnnotation(this.typeName, this.typeArguments);
-
-  NominalTypeAnnotation asNominalTypeAnnotation() => this;
-
-  accept(Visitor visitor) => visitor.visitNominalTypeAnnotation(this);
-
-  accept1(Visitor1 visitor, arg) {
-    return visitor.visitNominalTypeAnnotation(this, arg);
-  }
-
-  visitChildren(Visitor visitor) {
-    typeName.accept(visitor);
-    if (typeArguments != null) typeArguments.accept(visitor);
-  }
-
-  visitChildren1(Visitor1 visitor, arg) {
-    typeName.accept1(visitor, arg);
-    if (typeArguments != null) typeArguments.accept1(visitor, arg);
-  }
-
-  Token getBeginToken() => typeName.getBeginToken();
-
-  Token getEndToken() {
-    if (typeArguments != null) return typeArguments.getEndToken();
-    return typeName.getEndToken();
-  }
-}
-
-class TypeVariable extends Node {
-  final Identifier name;
-  final Token extendsOrSuper;
-  final TypeAnnotation bound;
-  TypeVariable(this.name, this.extendsOrSuper, this.bound);
-
-  accept(Visitor visitor) => visitor.visitTypeVariable(this);
-
-  accept1(Visitor1 visitor, arg) => visitor.visitTypeVariable(this, arg);
-
-  visitChildren(Visitor visitor) {
-    name.accept(visitor);
-    if (bound != null) {
-      bound.accept(visitor);
-    }
-  }
-
-  visitChildren1(Visitor1 visitor, arg) {
-    name.accept1(visitor, arg);
-    if (bound != null) {
-      bound.accept1(visitor, arg);
-    }
-  }
-
-  TypeVariable asTypeVariable() => this;
-
-  Token getBeginToken() => name.getBeginToken();
-
-  Token getEndToken() {
-    return (bound != null) ? bound.getEndToken() : name.getEndToken();
-  }
-}
-
-class VariableDefinitions extends Statement {
-  final NodeList metadata;
-  final TypeAnnotation type;
-  final Modifiers modifiers;
-  final NodeList definitions;
-
-  VariableDefinitions(this.type, this.modifiers, this.definitions)
-      : this.metadata = null {
-    assert(modifiers != null);
-  }
-
-  // TODO(johnniwinther): Make this its own node type.
-  VariableDefinitions.forParameter(
-      this.metadata, this.type, this.modifiers, this.definitions) {
-    assert(modifiers != null);
-  }
-
-  VariableDefinitions asVariableDefinitions() => this;
-
-  accept(Visitor visitor) => visitor.visitVariableDefinitions(this);
-
-  accept1(Visitor1 visitor, arg) => visitor.visitVariableDefinitions(this, arg);
-
-  visitChildren(Visitor visitor) {
-    if (metadata != null) metadata.accept(visitor);
-    if (type != null) type.accept(visitor);
-    if (definitions != null) definitions.accept(visitor);
-  }
-
-  visitChildren1(Visitor1 visitor, arg) {
-    if (metadata != null) metadata.accept1(visitor, arg);
-    if (type != null) type.accept1(visitor, arg);
-    if (definitions != null) definitions.accept1(visitor, arg);
-  }
-
-  Token getBeginToken() {
-    var token = firstBeginToken(modifiers, type);
-    if (token == null) {
-      token = definitions.getBeginToken();
-    }
-    return token;
-  }
-
-  Token getEndToken() {
-    var result = definitions.getEndToken();
-    if (result != null) return result;
-    assert(definitions.nodes.length == 1);
-    assert(definitions.nodes.last == null);
-    return type.getEndToken();
-  }
-}
-
-abstract class Loop extends Statement {
-  Expression get condition;
-  final Statement body;
-
-  Loop(this.body);
-
-  bool isValidContinueTarget() => true;
-}
-
-class DoWhile extends Loop {
-  final Token doKeyword;
-  final Token whileKeyword;
-  final Token endToken;
-
-  final Expression condition;
-
-  DoWhile(Statement body, Expression this.condition, Token this.doKeyword,
-      Token this.whileKeyword, Token this.endToken)
-      : super(body);
-
-  DoWhile asDoWhile() => this;
-
-  accept(Visitor visitor) => visitor.visitDoWhile(this);
-
-  accept1(Visitor1 visitor, arg) => visitor.visitDoWhile(this, arg);
-
-  visitChildren(Visitor visitor) {
-    if (condition != null) condition.accept(visitor);
-    if (body != null) body.accept(visitor);
-  }
-
-  visitChildren1(Visitor1 visitor, arg) {
-    if (condition != null) condition.accept1(visitor, arg);
-    if (body != null) body.accept1(visitor, arg);
-  }
-
-  Token getBeginToken() => doKeyword;
-
-  Token getEndToken() => endToken;
-}
-
-class While extends Loop {
-  final Token whileKeyword;
-  final Expression condition;
-
-  While(Expression this.condition, Statement body, Token this.whileKeyword)
-      : super(body);
-
-  While asWhile() => this;
-
-  accept(Visitor visitor) => visitor.visitWhile(this);
-
-  accept1(Visitor1 visitor, arg) => visitor.visitWhile(this, arg);
-
-  visitChildren(Visitor visitor) {
-    if (condition != null) condition.accept(visitor);
-    if (body != null) body.accept(visitor);
-  }
-
-  visitChildren1(Visitor1 visitor, arg) {
-    if (condition != null) condition.accept1(visitor, arg);
-    if (body != null) body.accept1(visitor, arg);
-  }
-
-  Token getBeginToken() => whileKeyword;
-
-  Token getEndToken() => body.getEndToken();
-}
-
-class ParenthesizedExpression extends Expression {
-  final Expression expression;
-  final BeginToken beginToken;
-
-  ParenthesizedExpression(
-      Expression this.expression, BeginToken this.beginToken);
-
-  ParenthesizedExpression asParenthesizedExpression() => this;
-
-  accept(Visitor visitor) => visitor.visitParenthesizedExpression(this);
-
-  accept1(Visitor1 visitor, arg) {
-    return visitor.visitParenthesizedExpression(this, arg);
-  }
-
-  visitChildren(Visitor visitor) {
-    if (expression != null) expression.accept(visitor);
-  }
-
-  visitChildren1(Visitor1 visitor, arg) {
-    if (expression != null) expression.accept1(visitor, arg);
-  }
-
-  Token getBeginToken() => beginToken;
-
-  Token getEndToken() => beginToken.endGroup;
-}
-
-/** Representation of modifiers such as static, abstract, final, etc. */
-class Modifiers extends Node {
-  /**
-   * Pseudo-constant for empty modifiers.
-   */
-  static final Modifiers EMPTY = new Modifiers(new NodeList.empty());
-
-  /* TODO(ahe): The following should be validated relating to modifiers:
-   * 1. The nodes must come in a certain order.
-   * 2. The keywords "var" and "final" may not be used at the same time.
-   * 3. The keywords "abstract" and "external" may not be used at the same time.
-   * 4. The type of an element must be null if isVar() is true.
-   */
-
-  final NodeList nodes;
-  /** Bit pattern to easy check what modifiers are present. */
-  final int flags;
-
-  static const int FLAG_STATIC = 1;
-  static const int FLAG_ABSTRACT = FLAG_STATIC << 1;
-  static const int FLAG_FINAL = FLAG_ABSTRACT << 1;
-  static const int FLAG_VAR = FLAG_FINAL << 1;
-  static const int FLAG_CONST = FLAG_VAR << 1;
-  static const int FLAG_FACTORY = FLAG_CONST << 1;
-  static const int FLAG_EXTERNAL = FLAG_FACTORY << 1;
-  static const int FLAG_COVARIANT = FLAG_EXTERNAL << 1;
-
-  Modifiers(NodeList nodes) : this.withFlags(nodes, computeFlags(nodes.nodes));
-
-  Modifiers.withFlags(this.nodes, this.flags);
-
-  static int computeFlags(Link<Node> nodes) {
-    int flags = 0;
-    for (; !nodes.isEmpty; nodes = nodes.tail) {
-      String value = nodes.head.asIdentifier().source;
-      if (identical(value, 'static'))
-        flags |= FLAG_STATIC;
-      else if (identical(value, 'abstract'))
-        flags |= FLAG_ABSTRACT;
-      else if (identical(value, 'final'))
-        flags |= FLAG_FINAL;
-      else if (identical(value, 'var'))
-        flags |= FLAG_VAR;
-      else if (identical(value, 'const'))
-        flags |= FLAG_CONST;
-      else if (identical(value, 'factory'))
-        flags |= FLAG_FACTORY;
-      else if (identical(value, 'external'))
-        flags |= FLAG_EXTERNAL;
-      else if (identical(value, 'covariant'))
-        flags |= FLAG_COVARIANT;
-      else
-        throw 'internal error: ${nodes.head}';
-    }
-    return flags;
-  }
-
-  Node findModifier(String modifier) {
-    Link<Node> nodeList = nodes.nodes;
-    for (; !nodeList.isEmpty; nodeList = nodeList.tail) {
-      String value = nodeList.head.asIdentifier().source;
-      if (identical(value, modifier)) {
-        return nodeList.head;
-      }
-    }
-    return null;
-  }
-
-  Modifiers asModifiers() => this;
-  Token getBeginToken() => nodes.getBeginToken();
-  Token getEndToken() => nodes.getEndToken();
-
-  accept(Visitor visitor) => visitor.visitModifiers(this);
-
-  accept1(Visitor1 visitor, arg) => visitor.visitModifiers(this, arg);
-
-  visitChildren(Visitor visitor) => nodes.accept(visitor);
-
-  visitChildren1(Visitor1 visitor, arg) => nodes.accept1(visitor, arg);
-
-  bool get isStatic => (flags & FLAG_STATIC) != 0;
-  bool get isAbstract => (flags & FLAG_ABSTRACT) != 0;
-  bool get isFinal => (flags & FLAG_FINAL) != 0;
-  bool get isVar => (flags & FLAG_VAR) != 0;
-  bool get isConst => (flags & FLAG_CONST) != 0;
-  bool get isFactory => (flags & FLAG_FACTORY) != 0;
-  bool get isExternal => (flags & FLAG_EXTERNAL) != 0;
-  bool get isCovariant => (flags & FLAG_COVARIANT) != 0;
-
-  Node getStatic() => findModifier('static');
-
-  /**
-   * Use this to check if the declaration is either explicitly or implicitly
-   * final.
-   */
-  bool get isFinalOrConst => isFinal || isConst;
-
-  String toString() {
-    return modifiersToString(
-        isStatic: isStatic,
-        isAbstract: isAbstract,
-        isFinal: isFinal,
-        isVar: isVar,
-        isConst: isConst,
-        isFactory: isFactory,
-        isExternal: isExternal,
-        isCovariant: isCovariant);
-  }
-}
-
-class StringInterpolation extends StringNode {
-  final LiteralString string;
-  final NodeList parts;
-
-  StringInterpolation(this.string, this.parts);
-
-  StringInterpolation asStringInterpolation() => this;
-
-  DartString get dartString => null;
-  bool get isInterpolation => true;
-
-  accept(Visitor visitor) => visitor.visitStringInterpolation(this);
-
-  accept1(Visitor1 visitor, arg) => visitor.visitStringInterpolation(this, arg);
-
-  visitChildren(Visitor visitor) {
-    string.accept(visitor);
-    parts.accept(visitor);
-  }
-
-  visitChildren1(Visitor1 visitor, arg) {
-    string.accept1(visitor, arg);
-    parts.accept1(visitor, arg);
-  }
-
-  Token getBeginToken() => string.getBeginToken();
-  Token getEndToken() => parts.getEndToken();
-}
-
-class StringInterpolationPart extends Node {
-  final Expression expression;
-  final LiteralString string;
-
-  StringInterpolationPart(this.expression, this.string);
-
-  StringInterpolationPart asStringInterpolationPart() => this;
-
-  accept(Visitor visitor) => visitor.visitStringInterpolationPart(this);
-
-  accept1(Visitor1 visitor, arg) {
-    return visitor.visitStringInterpolationPart(this, arg);
-  }
-
-  visitChildren(Visitor visitor) {
-    expression.accept(visitor);
-    string.accept(visitor);
-  }
-
-  visitChildren1(Visitor1 visitor, arg) {
-    expression.accept1(visitor, arg);
-    string.accept1(visitor, arg);
-  }
-
-  Token getBeginToken() => expression.getBeginToken();
-
-  Token getEndToken() => string.getEndToken();
-}
-
-/**
- * A class representing juxtaposed string literals.
- * The string literals can be both plain literals and string interpolations.
- */
-class StringJuxtaposition extends StringNode {
-  final Expression first;
-  final Expression second;
-
-  /**
-   * Caches the check for whether this juxtaposition contains a string
-   * interpolation
-   */
-  bool isInterpolationCache = null;
-
-  /**
-   * Caches a Dart string representation of the entire juxtaposition's
-   * content. Only juxtapositions that don't (transitively) contains
-   * interpolations have a static representation.
-   */
-  DartString dartStringCache = null;
-
-  StringJuxtaposition(this.first, this.second);
-
-  StringJuxtaposition asStringJuxtaposition() => this;
-
-  bool get isInterpolation {
-    if (isInterpolationCache == null) {
-      isInterpolationCache = (first.accept(const IsInterpolationVisitor()) ||
-          second.accept(const IsInterpolationVisitor()));
-    }
-    return isInterpolationCache;
-  }
-
-  /**
-   * Retrieve a single DartString that represents this entire juxtaposition
-   * of string literals.
-   * Should only be called if [isInterpolation] returns false.
-   */
-  DartString get dartString {
-    if (isInterpolation) {
-      failedAt(this, "Getting dartString on interpolation;");
-    }
-    if (dartStringCache == null) {
-      DartString firstString = first.accept(const GetDartStringVisitor());
-      DartString secondString = second.accept(const GetDartStringVisitor());
-      if (firstString == null || secondString == null) {
-        return null;
-      }
-      dartStringCache = new DartString.concat(firstString, secondString);
-    }
-    return dartStringCache;
-  }
-
-  accept(Visitor visitor) => visitor.visitStringJuxtaposition(this);
-
-  accept1(Visitor1 visitor, arg) => visitor.visitStringJuxtaposition(this, arg);
-
-  void visitChildren(Visitor visitor) {
-    first.accept(visitor);
-    second.accept(visitor);
-  }
-
-  void visitChildren1(Visitor1 visitor, arg) {
-    first.accept1(visitor, arg);
-    second.accept1(visitor, arg);
-  }
-
-  Token getBeginToken() => first.getBeginToken();
-
-  Token getEndToken() => second.getEndToken();
-}
-
-class EmptyStatement extends Statement {
-  final Token semicolonToken;
-
-  EmptyStatement(this.semicolonToken);
-
-  EmptyStatement asEmptyStatement() => this;
-
-  accept(Visitor visitor) => visitor.visitEmptyStatement(this);
-
-  accept1(Visitor1 visitor, arg) => visitor.visitEmptyStatement(this, arg);
-
-  visitChildren(Visitor visitor) {}
-
-  visitChildren1(Visitor1 visitor, arg) {}
-
-  Token getBeginToken() => semicolonToken;
-
-  Token getEndToken() => semicolonToken;
-}
-
-class LiteralMap extends Expression {
-  final NodeList typeArguments;
-  final NodeList entries;
-
-  final Token constKeyword;
-
-  LiteralMap(this.typeArguments, this.entries, this.constKeyword);
-
-  bool get isConst => constKeyword != null;
-
-  LiteralMap asLiteralMap() => this;
-
-  accept(Visitor visitor) => visitor.visitLiteralMap(this);
-
-  accept1(Visitor1 visitor, arg) => visitor.visitLiteralMap(this, arg);
-
-  visitChildren(Visitor visitor) {
-    if (typeArguments != null) typeArguments.accept(visitor);
-    entries.accept(visitor);
-  }
-
-  visitChildren1(Visitor1 visitor, arg) {
-    if (typeArguments != null) typeArguments.accept1(visitor, arg);
-    entries.accept1(visitor, arg);
-  }
-
-  Token getBeginToken() {
-    if (constKeyword != null) return constKeyword;
-    return firstBeginToken(typeArguments, entries);
-  }
-
-  Token getEndToken() => entries.getEndToken();
-}
-
-class LiteralMapEntry extends Node {
-  final Expression key;
-  final Expression value;
-
-  final Token colonToken;
-
-  LiteralMapEntry(this.key, this.colonToken, this.value);
-
-  LiteralMapEntry asLiteralMapEntry() => this;
-
-  accept(Visitor visitor) => visitor.visitLiteralMapEntry(this);
-
-  accept1(Visitor1 visitor, arg) => visitor.visitLiteralMapEntry(this, arg);
-
-  visitChildren(Visitor visitor) {
-    key.accept(visitor);
-    value.accept(visitor);
-  }
-
-  visitChildren1(Visitor1 visitor, arg) {
-    key.accept1(visitor, arg);
-    value.accept1(visitor, arg);
-  }
-
-  Token getBeginToken() => key.getBeginToken();
-
-  Token getEndToken() => value.getEndToken();
-}
-
-class NamedArgument extends Expression {
-  final Identifier name;
-  final Expression expression;
-
-  final Token colonToken;
-
-  NamedArgument(this.name, this.colonToken, this.expression);
-
-  NamedArgument asNamedArgument() => this;
-
-  accept(Visitor visitor) => visitor.visitNamedArgument(this);
-
-  accept1(Visitor1 visitor, arg) => visitor.visitNamedArgument(this, arg);
-
-  visitChildren(Visitor visitor) {
-    name.accept(visitor);
-    expression.accept(visitor);
-  }
-
-  visitChildren1(Visitor1 visitor, arg) {
-    name.accept1(visitor, arg);
-    expression.accept1(visitor, arg);
-  }
-
-  Token getBeginToken() => name.getBeginToken();
-
-  Token getEndToken() => expression.getEndToken();
-}
-
-class SwitchStatement extends Statement {
-  final ParenthesizedExpression parenthesizedExpression;
-  final NodeList cases;
-
-  final Token switchKeyword;
-
-  SwitchStatement(this.parenthesizedExpression, this.cases, this.switchKeyword);
-
-  SwitchStatement asSwitchStatement() => this;
-
-  Expression get expression => parenthesizedExpression.expression;
-
-  accept(Visitor visitor) => visitor.visitSwitchStatement(this);
-
-  accept1(Visitor1 visitor, arg) => visitor.visitSwitchStatement(this, arg);
-
-  visitChildren(Visitor visitor) {
-    parenthesizedExpression.accept(visitor);
-    cases.accept(visitor);
-  }
-
-  visitChildren1(Visitor1 visitor, arg) {
-    parenthesizedExpression.accept1(visitor, arg);
-    cases.accept1(visitor, arg);
-  }
-
-  Token getBeginToken() => switchKeyword;
-
-  Token getEndToken() => cases.getEndToken();
-}
-
-class CaseMatch extends Node {
-  final Token caseKeyword;
-  final Expression expression;
-  final Token colonToken;
-  CaseMatch(this.caseKeyword, this.expression, this.colonToken);
-
-  CaseMatch asCaseMatch() => this;
-  Token getBeginToken() => caseKeyword;
-  Token getEndToken() => colonToken;
-
-  accept(Visitor visitor) => visitor.visitCaseMatch(this);
-
-  accept1(Visitor1 visitor, arg) => visitor.visitCaseMatch(this, arg);
-
-  visitChildren(Visitor visitor) => expression.accept(visitor);
-
-  visitChildren1(Visitor1 visitor, arg) => expression.accept1(visitor, arg);
-}
-
-class SwitchCase extends Node {
-  // The labels and case patterns are collected in [labelsAndCases].
-  // The default keyword, if present, is collected in [defaultKeyword].
-  // Any actual switch case must have at least one 'case' or 'default'
-  // clause.
-  // Notice: The labels and cases can occur interleaved in the source.
-  // They are separated here, since the order is irrelevant to the meaning
-  // of the switch.
-
-  /** List of [Label] and [CaseMatch] nodes. */
-  final NodeList labelsAndCases;
-  /** A "default" keyword token, if applicable. */
-  final Token defaultKeyword;
-  /** List of statements, the body of the case. */
-  final NodeList statements;
-
-  final Token startToken;
-
-  SwitchCase(this.labelsAndCases, this.defaultKeyword, this.statements,
-      this.startToken);
-
-  SwitchCase asSwitchCase() => this;
-
-  bool get isDefaultCase => defaultKeyword != null;
-
-  bool isValidContinueTarget() => true;
-
-  accept(Visitor visitor) => visitor.visitSwitchCase(this);
-
-  accept1(Visitor1 visitor, arg) => visitor.visitSwitchCase(this, arg);
-
-  visitChildren(Visitor visitor) {
-    labelsAndCases.accept(visitor);
-    statements.accept(visitor);
-  }
-
-  visitChildren1(Visitor1 visitor, arg) {
-    labelsAndCases.accept1(visitor, arg);
-    statements.accept1(visitor, arg);
-  }
-
-  Token getBeginToken() {
-    return startToken;
-  }
-
-  Token getEndToken() {
-    if (statements.nodes.isEmpty) {
-      // All cases must have at least one expression or be the default.
-      if (defaultKeyword != null) {
-        // The colon after 'default'.
-        return defaultKeyword.next;
-      }
-      // The colon after the last expression.
-      return labelsAndCases.getEndToken();
-    } else {
-      return statements.getEndToken();
-    }
-  }
-}
-
-abstract class GotoStatement extends Statement {
-  final Identifier target;
-  final Token keywordToken;
-  final Token semicolonToken;
-
-  GotoStatement(this.target, this.keywordToken, this.semicolonToken);
-
-  visitChildren(Visitor visitor) {
-    if (target != null) target.accept(visitor);
-  }
-
-  visitChildren1(Visitor1 visitor, arg) {
-    if (target != null) target.accept1(visitor, arg);
-  }
-
-  Token getBeginToken() => keywordToken;
-
-  Token getEndToken() => semicolonToken;
-
-  // TODO(ahe): make class abstract instead of adding an abstract method.
-  accept(Visitor visitor);
-}
-
-class BreakStatement extends GotoStatement {
-  BreakStatement(Identifier target, Token keywordToken, Token semicolonToken)
-      : super(target, keywordToken, semicolonToken);
-
-  BreakStatement asBreakStatement() => this;
-
-  accept(Visitor visitor) => visitor.visitBreakStatement(this);
-
-  accept1(Visitor1 visitor, arg) => visitor.visitBreakStatement(this, arg);
-}
-
-class ContinueStatement extends GotoStatement {
-  ContinueStatement(Identifier target, Token keywordToken, Token semicolonToken)
-      : super(target, keywordToken, semicolonToken);
-
-  ContinueStatement asContinueStatement() => this;
-
-  accept(Visitor visitor) => visitor.visitContinueStatement(this);
-
-  accept1(Visitor1 visitor, arg) => visitor.visitContinueStatement(this, arg);
-}
-
-abstract class ForIn extends Loop {
-  final Node declaredIdentifier;
-  final Expression expression;
-
-  final Token forToken;
-  final Token inToken;
-
-  ForIn(this.declaredIdentifier, this.expression, Statement body, this.forToken,
-      this.inToken)
-      : super(body);
-
-  Expression get condition => null;
-
-  ForIn asForIn() => this;
-
-  Token getEndToken() => body.getEndToken();
-}
-
-class SyncForIn extends ForIn with StoredTreeElementMixin {
-  SyncForIn(declaredIdentifier, expression, Statement body, forToken, inToken)
-      : super(declaredIdentifier, expression, body, forToken, inToken);
-
-  SyncForIn asSyncForIn() => this;
-
-  accept(Visitor visitor) => visitor.visitSyncForIn(this);
-
-  accept1(Visitor1 visitor, arg) => visitor.visitSyncForIn(this, arg);
-
-  visitChildren(Visitor visitor) {
-    declaredIdentifier.accept(visitor);
-    expression.accept(visitor);
-    body.accept(visitor);
-  }
-
-  visitChildren1(Visitor1 visitor, arg) {
-    declaredIdentifier.accept1(visitor, arg);
-    expression.accept1(visitor, arg);
-    body.accept1(visitor, arg);
-  }
-
-  Token getBeginToken() => forToken;
-}
-
-class AsyncForIn extends ForIn with StoredTreeElementMixin {
-  final Token awaitToken;
-
-  AsyncForIn(declaredIdentifier, expression, Statement body, this.awaitToken,
-      forToken, inToken)
-      : super(declaredIdentifier, expression, body, forToken, inToken);
-
-  AsyncForIn asAsyncForIn() => this;
-
-  accept(Visitor visitor) => visitor.visitAsyncForIn(this);
-
-  accept1(Visitor1 visitor, arg) => visitor.visitAsyncForIn(this, arg);
-
-  visitChildren(Visitor visitor) {
-    declaredIdentifier.accept(visitor);
-    expression.accept(visitor);
-    body.accept(visitor);
-  }
-
-  visitChildren1(Visitor1 visitor, arg) {
-    declaredIdentifier.accept1(visitor, arg);
-    expression.accept1(visitor, arg);
-    body.accept1(visitor, arg);
-  }
-
-  Token getBeginToken() => awaitToken;
-}
-
-class Label extends Node {
-  final Identifier identifier;
-  final Token colonToken;
-
-  Label(this.identifier, this.colonToken);
-
-  String get labelName => identifier.source;
-
-  Label asLabel() => this;
-
-  accept(Visitor visitor) => visitor.visitLabel(this);
-
-  accept1(Visitor1 visitor, arg) => visitor.visitLabel(this, arg);
-
-  void visitChildren(Visitor visitor) {
-    identifier.accept(visitor);
-  }
-
-  void visitChildren1(Visitor1 visitor, arg) {
-    identifier.accept1(visitor, arg);
-  }
-
-  Token getBeginToken() => identifier.token;
-  Token getEndToken() => colonToken;
-}
-
-class LabeledStatement extends Statement {
-  final NodeList labels;
-  final Statement statement;
-
-  LabeledStatement(this.labels, this.statement);
-
-  LabeledStatement asLabeledStatement() => this;
-
-  accept(Visitor visitor) => visitor.visitLabeledStatement(this);
-
-  accept1(Visitor1 visitor, arg) => visitor.visitLabeledStatement(this, arg);
-
-  visitChildren(Visitor visitor) {
-    labels.accept(visitor);
-    statement.accept(visitor);
-  }
-
-  visitChildren1(Visitor1 visitor, arg) {
-    labels.accept1(visitor, arg);
-    statement.accept1(visitor, arg);
-  }
-
-  Token getBeginToken() => labels.getBeginToken();
-
-  Token getEndToken() => statement.getEndToken();
-
-  bool isValidContinueTarget() => statement.isValidContinueTarget();
-}
-
-abstract class LibraryTag extends Node {
-  final List<MetadataAnnotation> metadata;
-
-  LibraryTag(this.metadata);
-
-  bool get isLibraryName => false;
-  bool get isImport => false;
-  bool get isExport => false;
-  bool get isPart => false;
-  bool get isPartOf => false;
-}
-
-class LibraryName extends LibraryTag {
-  final Expression name;
-
-  final Token libraryKeyword;
-
-  LibraryName(this.libraryKeyword, this.name, List<MetadataAnnotation> metadata)
-      : super(metadata);
-
-  bool get isLibraryName => true;
-
-  LibraryName asLibraryName() => this;
-
-  accept(Visitor visitor) => visitor.visitLibraryName(this);
-
-  accept1(Visitor1 visitor, arg) => visitor.visitLibraryName(this, arg);
-
-  visitChildren(Visitor visitor) => name.accept(visitor);
-
-  visitChildren1(Visitor1 visitor, arg) => name.accept1(visitor, arg);
-
-  Token getBeginToken() => libraryKeyword;
-
-  Token getEndToken() => name.getEndToken().next;
-}
-
-/**
- * This tag describes a dependency between one library and the exported
- * identifiers of another library. The other library is specified by the [uri].
- * Combinators filter away some identifiers from the other library.
- */
-abstract class LibraryDependency extends LibraryTag {
-  final StringNode uri;
-  final NodeList conditionalUris;
-  final NodeList combinators;
-
-  LibraryDependency(this.uri, this.conditionalUris, this.combinators,
-      List<MetadataAnnotation> metadata)
-      : super(metadata);
-
-  LibraryDependency asLibraryDependency() => this;
-
-  bool get hasConditionalUris => conditionalUris != null;
-}
-
-/**
- * An [:import:] library tag.
- *
- * An import tag is dependency on another library where the exported identifiers
- * are put into the import scope of the importing library. The import scope is
- * only visible inside the library.
- */
-class Import extends LibraryDependency {
-  final Identifier prefix;
-  final Token importKeyword;
-  final bool isDeferred;
-
-  Import(this.importKeyword, StringNode uri, NodeList conditionalUris,
-      this.prefix, NodeList combinators, List<MetadataAnnotation> metadata,
-      {this.isDeferred})
-      : super(uri, conditionalUris, combinators, metadata);
-
-  bool get isImport => true;
-
-  Import asImport() => this;
-
-  accept(Visitor visitor) => visitor.visitImport(this);
-
-  accept1(Visitor1 visitor, arg) => visitor.visitImport(this, arg);
-
-  visitChildren(Visitor visitor) {
-    uri.accept(visitor);
-    if (prefix != null) prefix.accept(visitor);
-    if (combinators != null) combinators.accept(visitor);
-  }
-
-  visitChildren1(Visitor1 visitor, arg) {
-    uri.accept1(visitor, arg);
-    if (prefix != null) prefix.accept1(visitor, arg);
-    if (combinators != null) combinators.accept1(visitor, arg);
-  }
-
-  Token getBeginToken() => importKeyword;
-
-  Token getEndToken() {
-    if (combinators != null) return combinators.getEndToken().next;
-    if (prefix != null) return prefix.getEndToken().next;
-    if (conditionalUris != null) return conditionalUris.getEndToken().next;
-    return uri.getEndToken().next;
-  }
-}
-
-/**
- * A conditional uri inside an import or export clause.
- *
- * Example:
- *
- *     import 'foo.dart'
- *       if (some.condition == "someValue") 'bar.dart'
- *       if (other.condition) 'gee.dart';
- */
-class ConditionalUri extends Node {
-  final Token ifToken;
-  final DottedName key;
-  // Value may be null.
-  final LiteralString value;
-  final StringNode uri;
-
-  ConditionalUri(this.ifToken, this.key, this.value, this.uri);
-
-  ConditionalUri asConditionalUri() => this;
-
-  accept(Visitor visitor) => visitor.visitConditionalUri(this);
-
-  accept1(Visitor1 visitor, arg) => visitor.visitConditionalUri(this, arg);
-
-  visitChildren(Visitor visitor) {
-    key.accept(visitor);
-    if (value != null) value.accept(visitor);
-    uri.accept(visitor);
-  }
-
-  visitChildren1(Visitor1 visitor, arg) {
-    key.accept1(visitor, arg);
-    if (value != null) value.accept1(visitor, arg);
-    uri.accept1(visitor, arg);
-  }
-
-  Token getBeginToken() => ifToken;
-
-  Token getEndToken() => uri.getEndToken();
-}
-
-/**
- * An `enum` declaration.
- *
- * An `enum` defines a number of named constants inside a non-extensible class
- */
-class Enum extends Node {
-  /** The name of the enum class. */
-  final Identifier name;
-  /** The names of the enum constants. */
-  final NodeList names;
-  final Token enumToken;
-
-  Enum(this.enumToken, this.name, this.names);
-
-  Enum asEnum() => this;
-
-  accept(Visitor visitor) => visitor.visitEnum(this);
-
-  accept1(Visitor1 visitor, arg) => visitor.visitEnum(this, arg);
-
-  visitChildren(Visitor visitor) {
-    name.accept(visitor);
-    if (names != null) names.accept(visitor);
-  }
-
-  visitChildren1(Visitor1 visitor, arg) {
-    name.accept1(visitor, arg);
-    if (names != null) names.accept1(visitor, arg);
-  }
-
-  Token getBeginToken() => enumToken;
-  Token getEndToken() => names.getEndToken();
-}
-
-/**
- * An [:export:] library tag.
- *
- * An export tag is dependency on another library where the exported identifiers
- * are put into the export scope of the exporting library. The export scope is
- * not visible inside the library.
- */
-class Export extends LibraryDependency {
-  final Token exportKeyword;
-
-  Export(this.exportKeyword, StringNode uri, NodeList conditionalUris,
-      NodeList combinators, List<MetadataAnnotation> metadata)
-      : super(uri, conditionalUris, combinators, metadata);
-
-  bool get isExport => true;
-
-  Export asExport() => this;
-
-  accept(Visitor visitor) => visitor.visitExport(this);
-
-  accept1(Visitor1 visitor, arg) => visitor.visitExport(this, arg);
-
-  visitChildren(Visitor visitor) {
-    uri.accept(visitor);
-    if (combinators != null) combinators.accept(visitor);
-  }
-
-  visitChildren1(Visitor1 visitor, arg) {
-    uri.accept1(visitor, arg);
-    if (combinators != null) combinators.accept1(visitor, arg);
-  }
-
-  Token getBeginToken() => exportKeyword;
-
-  Token getEndToken() {
-    if (combinators != null) return combinators.getEndToken().next;
-    if (conditionalUris != null) return conditionalUris.getEndToken().next;
-    return uri.getEndToken().next;
-  }
-}
-
-class Part extends LibraryTag {
-  final StringNode uri;
-
-  final Token partKeyword;
-
-  Part(this.partKeyword, this.uri, List<MetadataAnnotation> metadata)
-      : super(metadata);
-
-  bool get isPart => true;
-
-  Part asPart() => this;
-
-  accept(Visitor visitor) => visitor.visitPart(this);
-
-  accept1(Visitor1 visitor, arg) => visitor.visitPart(this, arg);
-
-  visitChildren(Visitor visitor) => uri.accept(visitor);
-
-  visitChildren1(Visitor1 visitor, arg) => uri.accept1(visitor, arg);
-
-  Token getBeginToken() => partKeyword;
-
-  Token getEndToken() => uri.getEndToken().next;
-}
-
-class PartOf extends Node {
-  final Expression name;
-
-  final Token partKeyword;
-
-  final List<MetadataAnnotation> metadata;
-
-  PartOf(this.partKeyword, this.name, this.metadata);
-
-  Token get ofKeyword => partKeyword.next;
-
-  bool get isPartOf => true;
-
-  PartOf asPartOf() => this;
-
-  accept(Visitor visitor) => visitor.visitPartOf(this);
-
-  accept1(Visitor1 visitor, arg) => visitor.visitPartOf(this, arg);
-
-  visitChildren(Visitor visitor) => name.accept(visitor);
-
-  visitChildren1(Visitor1 visitor, arg) => name.accept1(visitor, arg);
-
-  Token getBeginToken() => partKeyword;
-
-  Token getEndToken() => name.getEndToken().next;
-}
-
-class Combinator extends Node {
-  final NodeList identifiers;
-
-  final Token keywordToken;
-
-  Combinator(this.identifiers, this.keywordToken);
-
-  bool get isShow => identical(keywordToken.stringValue, 'show');
-
-  bool get isHide => identical(keywordToken.stringValue, 'hide');
-
-  Combinator asCombinator() => this;
-
-  accept(Visitor visitor) => visitor.visitCombinator(this);
-
-  accept1(Visitor1 visitor, arg) => visitor.visitCombinator(this, arg);
-
-  visitChildren(Visitor visitor) => identifiers.accept(visitor);
-
-  visitChildren1(Visitor1 visitor, arg) => identifiers.accept1(visitor, arg);
-
-  Token getBeginToken() => keywordToken;
-
-  Token getEndToken() => identifiers.getEndToken();
-}
-
-class Typedef extends Node {
-  final bool isGeneralizedTypeAlias;
-
-  /// Parameters to the template.
-  ///
-  /// For example, `T` and `S` are template parameters in the following
-  /// typedef: `typedef F<S, T> = Function(S, T)`, or, in the inlined syntax,
-  /// `typedef F<S, T>(S x, T y)`.
-  final NodeList templateParameters;
-
-  final TypeAnnotation returnType;
-  final Identifier name;
-
-  /// The generic type parameters to the function type.
-  ///
-  /// For example `A` and `B` (but not `T`) are type parameters in
-  /// `typedef F<T> = Function<A, B>(A, B, T)`;
-  final NodeList typeParameters;
-  final NodeList formals;
-
-  final Token typedefKeyword;
-  final Token endToken;
-
-  Typedef(
-      this.isGeneralizedTypeAlias,
-      this.templateParameters,
-      this.returnType,
-      this.name,
-      this.typeParameters,
-      this.formals,
-      this.typedefKeyword,
-      this.endToken);
-
-  Typedef asTypedef() => this;
-
-  accept(Visitor visitor) => visitor.visitTypedef(this);
-
-  accept1(Visitor1 visitor, arg) => visitor.visitTypedef(this, arg);
-
-  visitChildren(Visitor visitor) {
-    if (templateParameters != null) templateParameters.accept(visitor);
-    if (returnType != null) returnType.accept(visitor);
-    name.accept(visitor);
-    if (typeParameters != null) typeParameters.accept(visitor);
-    formals.accept(visitor);
-  }
-
-  visitChildren1(Visitor1 visitor, arg) {
-    if (templateParameters != null) templateParameters.accept1(visitor, arg);
-    if (returnType != null) returnType.accept1(visitor, arg);
-    name.accept1(visitor, arg);
-    if (typeParameters != null) typeParameters.accept1(visitor, arg);
-    formals.accept1(visitor, arg);
-  }
-
-  Token getBeginToken() => typedefKeyword;
-
-  Token getEndToken() => endToken;
-}
-
-class FunctionTypeAnnotation extends TypeAnnotation {
-  final TypeAnnotation returnType;
-  final Token functionToken;
-  final NodeList typeParameters;
-  final NodeList formals;
-
-  FunctionTypeAnnotation(
-      this.returnType, this.functionToken, this.typeParameters, this.formals);
-
-  FunctionTypeAnnotation asFunctionTypeAnnotation() => this;
-
-  accept(Visitor visitor) => visitor.visitFunctionTypeAnnotation(this);
-
-  accept1(Visitor1 visitor, arg) {
-    return visitor.visitFunctionTypeAnnotation(this, arg);
-  }
-
-  visitChildren(Visitor visitor) {
-    if (returnType != null) returnType.accept(visitor);
-    if (typeParameters != null) typeParameters.accept(visitor);
-    formals.accept(visitor);
-  }
-
-  visitChildren1(Visitor1 visitor, arg) {
-    if (returnType != null) returnType.accept1(visitor, arg);
-    if (typeParameters != null) typeParameters.accept1(visitor, arg);
-    formals.accept1(visitor, arg);
-  }
-
-  Token getBeginToken() {
-    if (returnType != null) return returnType.getBeginToken();
-    return functionToken;
-  }
-
-  Token getEndToken() => formals.getEndToken();
-}
-
-class TryStatement extends Statement {
-  final Block tryBlock;
-  final NodeList catchBlocks;
-  final Block finallyBlock;
-
-  final Token tryKeyword;
-  final Token finallyKeyword;
-
-  TryStatement(this.tryBlock, this.catchBlocks, this.finallyBlock,
-      this.tryKeyword, this.finallyKeyword);
-
-  TryStatement asTryStatement() => this;
-
-  accept(Visitor visitor) => visitor.visitTryStatement(this);
-
-  accept1(Visitor1 visitor, arg) => visitor.visitTryStatement(this, arg);
-
-  visitChildren(Visitor visitor) {
-    tryBlock.accept(visitor);
-    catchBlocks.accept(visitor);
-    if (finallyBlock != null) finallyBlock.accept(visitor);
-  }
-
-  visitChildren1(Visitor1 visitor, arg) {
-    tryBlock.accept1(visitor, arg);
-    catchBlocks.accept1(visitor, arg);
-    if (finallyBlock != null) finallyBlock.accept1(visitor, arg);
-  }
-
-  Token getBeginToken() => tryKeyword;
-
-  Token getEndToken() {
-    if (finallyBlock != null) return finallyBlock.getEndToken();
-    if (!catchBlocks.isEmpty) return catchBlocks.getEndToken();
-    return tryBlock.getEndToken();
-  }
-}
-
-class Cascade extends Expression {
-  final Expression expression;
-  Cascade(this.expression);
-
-  Cascade asCascade() => this;
-  accept(Visitor visitor) => visitor.visitCascade(this);
-
-  accept1(Visitor1 visitor, arg) => visitor.visitCascade(this, arg);
-
-  void visitChildren(Visitor visitor) {
-    expression.accept(visitor);
-  }
-
-  void visitChildren1(Visitor1 visitor, arg) {
-    expression.accept1(visitor, arg);
-  }
-
-  Token getBeginToken() => expression.getBeginToken();
-
-  Token getEndToken() => expression.getEndToken();
-}
-
-class CascadeReceiver extends Expression {
-  final Expression expression;
-  final Token cascadeOperator;
-  CascadeReceiver(this.expression, this.cascadeOperator);
-
-  CascadeReceiver asCascadeReceiver() => this;
-  accept(Visitor visitor) => visitor.visitCascadeReceiver(this);
-
-  accept1(Visitor1 visitor, arg) => visitor.visitCascadeReceiver(this, arg);
-
-  void visitChildren(Visitor visitor) {
-    expression.accept(visitor);
-  }
-
-  void visitChildren1(Visitor1 visitor, arg) {
-    expression.accept1(visitor, arg);
-  }
-
-  Token getBeginToken() => expression.getBeginToken();
-
-  Token getEndToken() => expression.getEndToken();
-}
-
-class CatchBlock extends Node {
-  final TypeAnnotation type;
-  final NodeList formals;
-  final Block block;
-
-  final Token onKeyword;
-  final Token catchKeyword;
-
-  CatchBlock(
-      this.type, this.formals, this.block, this.onKeyword, this.catchKeyword);
-
-  CatchBlock asCatchBlock() => this;
-
-  accept(Visitor visitor) => visitor.visitCatchBlock(this);
-
-  accept1(Visitor1 visitor, arg) => visitor.visitCatchBlock(this, arg);
-
-  Node get exception {
-    if (formals == null || formals.nodes.isEmpty) return null;
-    VariableDefinitions declarations = formals.nodes.head;
-    return declarations.definitions.nodes.head;
-  }
-
-  Node get trace {
-    if (formals == null || formals.nodes.isEmpty) return null;
-    Link<Node> declarations = formals.nodes.tail;
-    if (declarations.isEmpty) return null;
-    VariableDefinitions head = declarations.head;
-    return head.definitions.nodes.head;
-  }
-
-  visitChildren(Visitor visitor) {
-    if (type != null) type.accept(visitor);
-    if (formals != null) formals.accept(visitor);
-    block.accept(visitor);
-  }
-
-  visitChildren1(Visitor1 visitor, arg) {
-    if (type != null) type.accept1(visitor, arg);
-    if (formals != null) formals.accept1(visitor, arg);
-    block.accept1(visitor, arg);
-  }
-
-  Token getBeginToken() => onKeyword != null ? onKeyword : catchKeyword;
-
-  Token getEndToken() => block.getEndToken();
-}
-
-class Metadata extends Node {
-  final Token token;
-  final Expression expression;
-
-  Metadata(this.token, this.expression);
-
-  Metadata asMetadata() => this;
-
-  accept(Visitor visitor) => visitor.visitMetadata(this);
-
-  accept1(Visitor1 visitor, arg) => visitor.visitMetadata(this, arg);
-
-  visitChildren(Visitor visitor) {
-    expression.accept(visitor);
-  }
-
-  visitChildren1(Visitor1 visitor, arg) {
-    expression.accept1(visitor, arg);
-  }
-
-  Token getBeginToken() => token;
-
-  Token getEndToken() => expression.getEndToken();
-}
-
-class Initializers {
-  static bool isSuperConstructorCall(Send node) {
-    return (node.receiver == null && node.selector.isSuper()) ||
-        (node.receiver != null &&
-            node.receiver.isSuper() &&
-            !node.isConditional &&
-            node.selector.asIdentifier() != null);
-  }
-
-  static bool isConstructorRedirect(Send node) {
-    return (node.receiver == null && node.selector.isThis()) ||
-        (node.receiver != null &&
-            node.receiver.isThis() &&
-            !node.isConditional &&
-            node.selector.asIdentifier() != null);
-  }
-}
-
-class GetDartStringVisitor extends Visitor<DartString> {
-  const GetDartStringVisitor();
-  DartString visitNode(Node node) => null;
-  DartString visitStringJuxtaposition(StringJuxtaposition node) =>
-      node.dartString;
-  DartString visitLiteralString(LiteralString node) => node.dartString;
-}
-
-class IsInterpolationVisitor extends Visitor<bool> {
-  const IsInterpolationVisitor();
-  bool visitNode(Node node) => false;
-  bool visitStringInterpolation(StringInterpolation node) => true;
-  bool visitStringJuxtaposition(StringJuxtaposition node) =>
-      node.isInterpolation;
-}
-
-/// Erroneous node used to recover from parser errors.  Implements various
-/// interfaces and provides bare minimum of implementation to avoid unnecessary
-/// messages.
-class ErrorNode extends Node
-    implements FunctionExpression, VariableDefinitions, Typedef {
-  final Token token;
-  final Message message;
-  final Identifier name;
-  final NodeList definitions;
-
-  ErrorNode.internal(this.token, this.message, this.name, this.definitions);
-
-  factory ErrorNode(Token token, Message message) {
-    Identifier name = new Identifier(token);
-    NodeList definitions =
-        new NodeList(null, const Link<Node>().prepend(name), null, null);
-    return new ErrorNode.internal(token, message, name, definitions);
-  }
-
-  Token get beginToken => token;
-  Token get endToken => token;
-
-  Token getBeginToken() => token;
-
-  Token getEndToken() => token;
-
-  accept(Visitor visitor) {}
-
-  accept1(Visitor1 visitor, arg) {}
-
-  visitChildren(Visitor visitor) {}
-
-  visitChildren1(Visitor1 visitor, arg) {}
-
-  bool get isErroneous => true;
-
-  // FunctionExpression.
-  get asyncModifier => null;
-  get typeVariables => null;
-  get parameters => null;
-  get body => null;
-  get returnType => null;
-  get modifiers => Modifiers.EMPTY;
-  get initializers => null;
-  get getOrSet => null;
-  get isRedirectingFactory => false;
-  bool get hasBody => false;
-  bool get hasEmptyBody => false;
-
-  // VariableDefinitions.
-  get metadata => null;
-  get type => null;
-
-  // Typedef.
-  get isGeneralizedTypeAlias => null;
-  get templateParameters => null;
-  get typeParameters => null;
-  get formals => null;
-  get typedefKeyword => null;
-}
-
-/**
- * Encapsulates the field [TreeElementMixin._element].
- *
- * This library is an implementation detail of dart2js, and should not
- * be imported except by resolution and tree node libraries, or for
- * testing.
- *
- * We have taken great care to ensure AST nodes can be cached between
- * compiler instances.  Part of this requires that we always access
- * resolution results through TreeElements.
- *
- * So please, do not add additional elements to this library, and do
- * not import it.
- */
-/// Interface for associating
-abstract class TreeElementMixin {
-  Object get _element;
-  void set _element(Object value);
-}
-
-/// Null implementation of [TreeElementMixin] which does not allow association
-/// of elements.
-///
-/// This class is the superclass of all AST nodes.
-abstract class NullTreeElementMixin implements TreeElementMixin, Spannable {
-  // Deliberately using [Object] here to thwart code completion.
-  // You're not really supposed to access this field anyways.
-  Object get _element => null;
-  set _element(_) {
-    assert(false,
-        failedAt(this, "Elements cannot be associated with ${runtimeType}."));
-  }
-}
-
-/// Actual implementation of [TreeElementMixin] which stores the associated
-/// element in the private field [_element].
-///
-/// This class is mixed into the node classes that are actually associated with
-/// elements.
-abstract class StoredTreeElementMixin implements TreeElementMixin {
-  Object _element;
-}
-
-/**
- * Do not call this method directly.  Instead, use an instance of
- * TreeElements.
- *
- * Using [Object] as return type to thwart code completion.
- */
-Object getTreeElement(TreeElementMixin node) => node._element;
-
-/**
- * Do not call this method directly.  Instead, use an instance of
- * TreeElements.
- */
-void setTreeElement(TreeElementMixin node, Object value) {
-  node._element = value;
-}
diff --git a/pkg/compiler/lib/src/tree/prettyprint.dart b/pkg/compiler/lib/src/tree/prettyprint.dart
deleted file mode 100644
index a6bdb4c..0000000
--- a/pkg/compiler/lib/src/tree/prettyprint.dart
+++ /dev/null
@@ -1,490 +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.
-
-import 'package:front_end/src/fasta/scanner.dart' show Token;
-import '../util/util.dart';
-import 'nodes.dart';
-
-/**
- * Pretty-prints Node tree in XML-like format.
- *
- * TODO(smok): Add main() to run from command-line to print out tree for given
- * .dart file.
- */
-class PrettyPrinter extends Indentation with Tagging<Node> implements Visitor {
-  @override
-  void addDefaultParameters(Node node, Map params) {
-    params['getBeginToken'] = tokenToStringOrNull(node.getBeginToken());
-    params['getEndToken'] = tokenToStringOrNull(node.getEndToken());
-  }
-
-  String valueToString(var value) {
-    if (value is Token) {
-      return value.lexeme;
-    }
-    return value;
-  }
-
-  /**
-   * Pretty-prints given node tree into string.
-   */
-  static String prettyPrint(Node node) {
-    var p = new PrettyPrinter();
-    node.accept(p);
-    return p.sb.toString();
-  }
-
-  visitNodeWithChildren(Node node, String type) {
-    openNode(node, type);
-    node.visitChildren(this);
-    closeNode();
-  }
-
-  visitAssert(Assert node) {
-    visitNodeWithChildren(node, "Assert");
-  }
-
-  visitAsyncModifier(AsyncModifier node) {
-    openAndCloseNode(node, "AsyncModifier",
-        {'asyncToken': node.asyncToken, 'starToken': node.starToken});
-  }
-
-  visitBlock(Block node) {
-    visitNodeWithChildren(node, "Block");
-  }
-
-  visitBreakStatement(BreakStatement node) {
-    visitNodeWithChildren(node, "BreakStatement");
-  }
-
-  visitCascade(Cascade node) {
-    visitNodeWithChildren(node, "Cascade");
-  }
-
-  visitCascadeReceiver(CascadeReceiver node) {
-    visitNodeWithChildren(node, "CascadeReceiver");
-  }
-
-  visitCaseMatch(CaseMatch node) {
-    visitNodeWithChildren(node, "CaseMatch");
-  }
-
-  visitCatchBlock(CatchBlock node) {
-    visitNodeWithChildren(node, "CatchBlock");
-  }
-
-  visitClassNode(ClassNode node) {
-    openNode(node, "ClassNode",
-        {"extendsKeyword": tokenToStringOrNull(node.extendsKeyword)});
-    visitChildNode(node.name, "name");
-    visitChildNode(node.superclass, "superclass");
-    visitChildNode(node.interfaces, "interfaces");
-    visitChildNode(node.typeParameters, "typeParameters");
-    closeNode();
-  }
-
-  visitConditional(Conditional node) {
-    visitNodeWithChildren(node, "Conditional");
-  }
-
-  visitConditionalUri(ConditionalUri node) {
-    visitNodeWithChildren(node, "ConditionalUri");
-  }
-
-  visitContinueStatement(ContinueStatement node) {
-    visitNodeWithChildren(node, "ContinueStatement");
-  }
-
-  visitDottedName(DottedName node) {
-    openNode(node, "DottedName");
-    visitChildNode(node.identifiers, "identifiers");
-    closeNode();
-  }
-
-  visitDoWhile(DoWhile node) {
-    visitNodeWithChildren(node, "DoWhile");
-  }
-
-  visitEmptyStatement(EmptyStatement node) {
-    visitNodeWithChildren(node, "EmptyStatement");
-  }
-
-  visitEnum(Enum node) {
-    visitNodeWithChildren(node, "Enum");
-  }
-
-  visitExpressionStatement(ExpressionStatement node) {
-    visitNodeWithChildren(node, "ExpressionStatement");
-  }
-
-  visitFor(For node) {
-    visitNodeWithChildren(node, "For");
-  }
-
-  visitForIn(ForIn node) {
-    node.visitChildren(this);
-    closeNode();
-  }
-
-  visitAsyncForIn(AsyncForIn node) {
-    openNode(node, "AsyncForIn");
-    visitForIn(node);
-  }
-
-  visitSyncForIn(SyncForIn node) {
-    openNode(node, "SyncForIn");
-    visitForIn(node);
-  }
-
-  visitFunctionDeclaration(FunctionDeclaration node) {
-    visitNodeWithChildren(node, "FunctionDeclaration");
-  }
-
-  visitFunctionExpression(FunctionExpression node) {
-    openNode(node, "FunctionExpression",
-        {"getOrSet": tokenToStringOrNull(node.getOrSet)});
-    visitChildNode(node.modifiers, "modifiers");
-    visitChildNode(node.returnType, "returnType");
-    visitChildNode(node.name, "name");
-    visitChildNode(node.parameters, "parameters");
-    visitChildNode(node.initializers, "initializers");
-    visitChildNode(node.body, "body");
-    closeNode();
-  }
-
-  visitFunctionTypeAnnotation(FunctionTypeAnnotation node) {
-    openNode(node, "FunctionTypeAnnotation");
-    visitChildNode(node.returnType, "returnType");
-    visitChildNode(node.typeParameters, "typeParameters");
-    visitChildNode(node.formals, "formals");
-    closeNode();
-  }
-
-  visitIdentifier(Identifier node) {
-    openAndCloseNode(node, "Identifier", {"token": node.token});
-  }
-
-  visitIf(If node) {
-    visitNodeWithChildren(node, "If");
-  }
-
-  visitLabel(Label node) {
-    visitNodeWithChildren(node, "Label");
-  }
-
-  visitLabeledStatement(LabeledStatement node) {
-    visitNodeWithChildren(node, "LabeledStatement");
-  }
-
-  // Custom.
-  printLiteral(Literal node, String type) {
-    openAndCloseNode(node, type, {"value": node.value.toString()});
-  }
-
-  visitLiteralBool(LiteralBool node) {
-    printLiteral(node, "LiteralBool");
-  }
-
-  visitLiteralDouble(LiteralDouble node) {
-    printLiteral(node, "LiteralDouble");
-  }
-
-  visitLiteralInt(LiteralInt node) {
-    printLiteral(node, "LiteralInt");
-  }
-
-  /** Returns token string value or [:null:] if token is [:null:]. */
-  tokenToStringOrNull(Token token) => token == null ? null : token.stringValue;
-
-  visitLiteralList(LiteralList node) {
-    openNode(node, "LiteralList",
-        {"constKeyword": tokenToStringOrNull(node.constKeyword)});
-    visitChildNode(node.typeArguments, "typeArguments");
-    visitChildNode(node.elements, "elements");
-    closeNode();
-  }
-
-  visitLiteralMap(LiteralMap node) {
-    visitNodeWithChildren(node, "LiteralMap");
-  }
-
-  visitLiteralMapEntry(LiteralMapEntry node) {
-    visitNodeWithChildren(node, "LiteralMapEntry");
-  }
-
-  visitLiteralNull(LiteralNull node) {
-    printLiteral(node, "LiteralNull");
-  }
-
-  visitLiteralString(LiteralString node) {
-    openAndCloseNode(node, "LiteralString", {"value": node.token});
-  }
-
-  visitMixinApplication(MixinApplication node) {
-    visitNodeWithChildren(node, "MixinApplication");
-  }
-
-  visitModifiers(Modifiers node) {
-    visitNodeWithChildren(node, "Modifiers");
-  }
-
-  visitNamedArgument(NamedArgument node) {
-    visitNodeWithChildren(node, "NamedArgument");
-  }
-
-  visitNamedMixinApplication(NamedMixinApplication node) {
-    visitNodeWithChildren(node, "NamedMixinApplication");
-  }
-
-  visitNewExpression(NewExpression node) {
-    visitNodeWithChildren(node, "NewExpression");
-  }
-
-  visitNodeList(NodeList node) {
-    var params = {"delimiter": node.delimiter};
-    if (node.isEmpty) {
-      openAndCloseNode(node, "NodeList", params);
-    } else {
-      openNode(node, "NodeList", params);
-      node.visitChildren(this);
-      closeNode();
-    }
-  }
-
-  visitNominalTypeAnnotation(NominalTypeAnnotation node) {
-    openNode(node, "NominalTypeAnnotation");
-    visitChildNode(node.typeName, "typeName");
-    visitChildNode(node.typeArguments, "typeArguments");
-    closeNode();
-  }
-
-  visitOperator(Operator node) {
-    openAndCloseNode(node, "Operator", {"value": node.token});
-  }
-
-  visitParenthesizedExpression(ParenthesizedExpression node) {
-    visitNodeWithChildren(node, "ParenthesizedExpression");
-  }
-
-  visitRedirectingFactoryBody(RedirectingFactoryBody node) {
-    openNode(node, "RedirectingFactoryBody");
-    visitChildNode(node.constructorReference, "constructorReference");
-    closeNode();
-  }
-
-  visitRethrow(Rethrow node) {
-    visitNodeWithChildren(node, "Rethrow");
-  }
-
-  visitReturn(Return node) {
-    openNode(node, "Return");
-    visitChildNode(node.expression, "expression");
-    closeNode();
-  }
-
-  visitYield(Yield node) {
-    openNode(node, "Yield", {'star': node.starToken});
-    visitChildNode(node.expression, "expression");
-    closeNode();
-  }
-
-  visitChildNode(Node node, String fieldName) {
-    if (node == null) return;
-    addCurrentIndent();
-    sb.write("<$fieldName>\n");
-    pushTag(fieldName);
-    node.accept(this);
-    popTag();
-    addCurrentIndent();
-    sb.write("</$fieldName>\n");
-  }
-
-  openSendNodeWithFields(Send node, String type) {
-    openNode(node, type, {
-      "isPrefix": "${node.isPrefix}",
-      "isPostfix": "${node.isPostfix}",
-      "isIndex": "${node.isIndex}"
-    });
-    visitChildNode(node.receiver, "receiver");
-    visitChildNode(node.selector, "selector");
-    visitChildNode(node.argumentsNode, "argumentsNode");
-  }
-
-  visitSend(Send node) {
-    openSendNodeWithFields(node, "Send");
-    closeNode();
-  }
-
-  visitSendSet(SendSet node) {
-    openSendNodeWithFields(node, "SendSet");
-    visitChildNode(node.assignmentOperator, "assignmentOperator");
-    closeNode();
-  }
-
-  visitStringInterpolation(StringInterpolation node) {
-    visitNodeWithChildren(node, "StringInterpolation");
-  }
-
-  visitStringInterpolationPart(StringInterpolationPart node) {
-    visitNodeWithChildren(node, "StringInterpolationPart");
-  }
-
-  visitStringJuxtaposition(StringJuxtaposition node) {
-    visitNodeWithChildren(node, "StringJuxtaposition");
-  }
-
-  visitSwitchCase(SwitchCase node) {
-    visitNodeWithChildren(node, "SwitchCase");
-  }
-
-  visitSwitchStatement(SwitchStatement node) {
-    visitNodeWithChildren(node, "SwitchStatement");
-  }
-
-  visitLiteralSymbol(LiteralSymbol node) {
-    openNode(node, "LiteralSymbol");
-    visitChildNode(node.identifiers, "identifiers");
-    closeNode();
-  }
-
-  visitThrow(Throw node) {
-    visitNodeWithChildren(node, "Throw");
-  }
-
-  visitAwait(Await node) {
-    visitNodeWithChildren(node, "Await");
-  }
-
-  visitTryStatement(TryStatement node) {
-    visitNodeWithChildren(node, "TryStatement");
-  }
-
-  visitTypedef(Typedef node) {
-    visitNodeWithChildren(node, "Typedef");
-  }
-
-  visitTypeVariable(TypeVariable node) {
-    openNode(node, "TypeVariable");
-    visitChildNode(node.name, "name");
-    visitChildNode(node.bound, "bound");
-    closeNode();
-  }
-
-  visitVariableDefinitions(VariableDefinitions node) {
-    openNode(node, "VariableDefinitions");
-    visitChildNode(node.type, "type");
-    visitChildNode(node.modifiers, "modifiers");
-    visitChildNode(node.definitions, "definitions");
-    closeNode();
-  }
-
-  visitWhile(While node) {
-    visitNodeWithChildren(node, "While");
-  }
-
-  visitMetadata(Metadata node) {
-    openNode(node, "Metadata", {"token": node.token});
-    visitChildNode(node.expression, "expression");
-    closeNode();
-  }
-
-  visitCombinator(Combinator node) {
-    openNode(node, "Combinator",
-        {"isShow": "${node.isShow}", "isHide": "${node.isHide}"});
-    closeNode();
-  }
-
-  visitExport(Export node) {
-    openNode(node, "Export");
-    visitChildNode(node.uri, "uri");
-    if (node.conditionalUris != null) {
-      visitChildNode(node.conditionalUris, "conditionalUris");
-    }
-    visitChildNode(node.combinators, "combinators");
-    closeNode();
-  }
-
-  visitImport(Import node) {
-    openNode(node, "Import", {"isDeferred": "${node.isDeferred}"});
-    visitChildNode(node.uri, "uri");
-    if (node.conditionalUris != null) {
-      visitChildNode(node.conditionalUris, "conditionalUris");
-    }
-    visitChildNode(node.combinators, "combinators");
-    if (node.prefix != null) {
-      visitChildNode(node.prefix, "prefix");
-    }
-    closeNode();
-  }
-
-  visitPart(Part node) {
-    openNode(node, "Part");
-    visitChildNode(node.uri, "uri");
-    closeNode();
-  }
-
-  visitPartOf(PartOf node) {
-    openNode(node, "PartOf");
-    visitChildNode(node.name, "name");
-    closeNode();
-  }
-
-  visitLibraryName(LibraryName node) {
-    openNode(node, "LibraryName");
-    visitChildNode(node.name, "name");
-    closeNode();
-  }
-
-  visitNode(Node node) {
-    unimplemented('visitNode', node: node);
-  }
-
-  visitLibraryDependency(Node node) {
-    unimplemented('visitNode', node: node);
-  }
-
-  visitLibraryTag(LibraryTag node) {
-    unimplemented('visitNode', node: node);
-  }
-
-  visitLiteral(Literal node) {
-    unimplemented('visitNode', node: node);
-  }
-
-  visitLoop(Loop node) {
-    unimplemented('visitNode', node: node);
-  }
-
-  visitPostfix(Postfix node) {
-    unimplemented('visitNode', node: node);
-  }
-
-  visitPrefix(Prefix node) {
-    unimplemented('visitNode', node: node);
-  }
-
-  visitStringNode(StringNode node) {
-    unimplemented('visitNode', node: node);
-  }
-
-  visitStatement(Statement node) {
-    unimplemented('visitNode', node: node);
-  }
-
-  visitExpression(Expression node) {
-    unimplemented('visitNode', node: node);
-  }
-
-  visitGotoStatement(GotoStatement node) {
-    unimplemented('visitNode', node: node);
-  }
-
-  visitTypeAnnotation(TypeAnnotation node) {
-    unimplemented('visitNode', node: node);
-  }
-
-  unimplemented(String message, {Node node}) {
-    throw message;
-  }
-}
diff --git a/pkg/compiler/lib/src/tree/tree.dart b/pkg/compiler/lib/src/tree/tree.dart
deleted file mode 100644
index 71e9b6d..0000000
--- a/pkg/compiler/lib/src/tree/tree.dart
+++ /dev/null
@@ -1,10 +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.
-
-library tree;
-
-export 'dartstring.dart';
-export 'nodes.dart';
-export 'prettyprint.dart';
-export 'unparser.dart';
diff --git a/pkg/compiler/lib/src/tree/unparser.dart b/pkg/compiler/lib/src/tree/unparser.dart
deleted file mode 100644
index f6901e9..0000000
--- a/pkg/compiler/lib/src/tree/unparser.dart
+++ /dev/null
@@ -1,922 +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.
-
-import 'package:front_end/src/fasta/scanner.dart' show Token;
-import 'package:front_end/src/fasta/scanner/token_constants.dart' as Tokens
-    show IDENTIFIER_TOKEN, KEYWORD_TOKEN, PLUS_TOKEN;
-import '../util/util.dart';
-import 'nodes.dart';
-
-String unparse(Node node, {minify: true}) {
-  Unparser unparser = new Unparser(minify: minify);
-  unparser.unparse(node);
-  return unparser.result;
-}
-
-class Unparser extends Indentation implements Visitor {
-  final StringBuffer sb = new StringBuffer();
-
-  String get result => sb.toString();
-
-  Unparser({this.minify: true, this.stripTypes: false});
-
-  bool minify;
-  bool stripTypes;
-
-  void newline() {
-    if (!minify) {
-      sb.write("\n");
-      onEmptyLine = true;
-    }
-  }
-
-  void space([String token = " "]) {
-    write(minify ? "" : token);
-  }
-
-  void addToken(Token token) {
-    if (token == null) return;
-    write(token.lexeme);
-    if (identical(token.kind, Tokens.KEYWORD_TOKEN) ||
-        identical(token.kind, Tokens.IDENTIFIER_TOKEN)) {
-      write(' ');
-    }
-  }
-
-  bool onEmptyLine = true;
-
-  write(object) {
-    String s = object.toString();
-    if (s == '') return;
-    if (onEmptyLine) {
-      sb.write(indentation);
-    }
-    sb.write(s);
-    onEmptyLine = false;
-  }
-
-  unparse(Node node) {
-    visit(node);
-  }
-
-  visit(Node node) {
-    if (node != null) node.accept(this);
-  }
-
-  visitAssert(Assert node) {
-    write(node.assertToken.lexeme);
-    write('(');
-    visit(node.condition);
-    if (node.hasMessage) {
-      write(',');
-      space();
-      visit(node.message);
-    }
-    write(');');
-  }
-
-  visitBlock(Block node) => unparseBlockStatements(node.statements);
-
-  unparseBlockStatements(NodeList statements) {
-    addToken(statements.beginToken);
-
-    Link<Node> nodes = statements.nodes;
-    if (nodes != null && !nodes.isEmpty) {
-      indentMore();
-      newline();
-      visit(nodes.head);
-      for (Link link = nodes.tail; !link.isEmpty; link = link.tail) {
-        newline();
-        visit(link.head);
-      }
-      indentLess();
-      newline();
-    }
-    if (statements.endToken != null) {
-      write(statements.endToken.lexeme);
-    }
-  }
-
-  visitCascade(Cascade node) {
-    visit(node.expression);
-  }
-
-  visitCascadeReceiver(CascadeReceiver node) {
-    visit(node.expression);
-  }
-
-  unparseClassWithBody(ClassNode node, members) {
-    if (!node.modifiers.nodes.isEmpty) {
-      visit(node.modifiers);
-      write(' ');
-    }
-    write('class ');
-    visit(node.name);
-    if (node.typeParameters != null) {
-      visit(node.typeParameters);
-    }
-    if (node.extendsKeyword != null) {
-      write(' ');
-      addToken(node.extendsKeyword);
-      visit(node.superclass);
-    }
-    if (!node.interfaces.isEmpty) {
-      write(' ');
-      visit(node.interfaces);
-    }
-    space();
-    write('{');
-    if (!members.isEmpty) {
-      newline();
-      indentMore();
-      for (Node member in members) {
-        visit(member);
-        newline();
-      }
-      indentLess();
-    }
-    write('}');
-  }
-
-  visitEnum(Enum node) {
-    sb.write('enum ');
-    visit(node.name);
-    sb.write(' ');
-    visit(node.names);
-  }
-
-  visitClassNode(ClassNode node) {
-    unparseClassWithBody(node, node.body.nodes);
-  }
-
-  visitMixinApplication(MixinApplication node) {
-    visit(node.superclass);
-    write(' with ');
-    visit(node.mixins);
-  }
-
-  visitNamedMixinApplication(NamedMixinApplication node) {
-    if (!node.modifiers.nodes.isEmpty) {
-      visit(node.modifiers);
-      write(' ');
-    }
-    write('class ');
-    visit(node.name);
-    if (node.typeParameters != null) {
-      visit(node.typeParameters);
-    }
-    write(' = ');
-    visit(node.mixinApplication);
-    if (node.interfaces != null) {
-      write(' implements ');
-      visit(node.interfaces);
-    }
-    write(';');
-  }
-
-  visitConditional(Conditional node) {
-    visit(node.condition);
-    space();
-    write(node.questionToken.lexeme);
-    space();
-    visit(node.thenExpression);
-    space();
-    write(node.colonToken.lexeme);
-    space();
-    visit(node.elseExpression);
-  }
-
-  visitExpressionStatement(ExpressionStatement node) {
-    visit(node.expression);
-    write(node.endToken.lexeme);
-  }
-
-  visitFor(For node) {
-    write(node.forToken.lexeme);
-    space();
-    write('(');
-    visit(node.initializer);
-    write(';');
-    if (node.conditionStatement is! EmptyStatement) space();
-    visit(node.conditionStatement);
-    if (!node.update.nodes.isEmpty) space();
-    visit(node.update);
-    write(')');
-    space();
-    visit(node.body);
-  }
-
-  visitFunctionDeclaration(FunctionDeclaration node) {
-    visit(node.function);
-  }
-
-  void unparseFunctionName(Node name) {
-    // TODO(antonm): that's a workaround as currently FunctionExpression
-    // names are modelled with Send and it emits operator[] as only
-    // operator, without [] which are expected to be emitted with
-    // arguments.
-    if (name is Send) {
-      Send send = name;
-      assert(send is! SendSet);
-      if (!send.isOperator) {
-        // Looks like a factory method.
-        visit(send.receiver);
-        write('.');
-      } else {
-        visit(send.receiver);
-        Identifier identifier = send.selector.asIdentifier();
-        if (identical(identifier.token.kind, Tokens.KEYWORD_TOKEN)) {
-          write(' ');
-        } else if (identifier.source == 'negate') {
-          // TODO(ahe): Remove special case for negate.
-          write(' ');
-        }
-      }
-      visit(send.selector);
-    } else {
-      visit(name);
-    }
-  }
-
-  visitAsyncModifier(AsyncModifier node) {
-    write(node.asyncToken.lexeme);
-    if (node.starToken != null) {
-      write(node.starToken.lexeme);
-    }
-  }
-
-  visitFunctionExpression(FunctionExpression node) {
-    if (!node.modifiers.nodes.isEmpty) {
-      visit(node.modifiers);
-      write(' ');
-    }
-    if (node.returnType != null && !stripTypes) {
-      visit(node.returnType);
-      write(' ');
-    }
-    if (node.getOrSet != null) {
-      write(node.getOrSet.lexeme);
-      write(' ');
-    }
-    unparseFunctionName(node.name);
-    visit(node.typeVariables);
-    visit(node.parameters);
-    if (node.initializers != null) {
-      space();
-      write(':');
-      space();
-      unparseNodeListFrom(node.initializers, node.initializers.nodes,
-          spaces: true);
-    }
-    if (node.asyncModifier != null) {
-      if (node.getOrSet != null) {
-        write(' ');
-      } else {
-        // Space is optional if this is not a getter.
-        space();
-      }
-      visit(node.asyncModifier);
-    }
-    if (node.body != null && node.body is! EmptyStatement) {
-      space();
-    }
-    visit(node.body);
-  }
-
-  visitIdentifier(Identifier node) {
-    write(node.token.lexeme);
-  }
-
-  visitIf(If node) {
-    write(node.ifToken.lexeme);
-    space();
-    visit(node.condition);
-    space();
-    visit(node.thenPart);
-    if (node.hasElsePart) {
-      space();
-      write(node.elseToken.lexeme);
-      space();
-      if (node.elsePart is! Block && minify) write(' ');
-      visit(node.elsePart);
-    }
-  }
-
-  visitLiteralBool(LiteralBool node) {
-    write(node.token.lexeme);
-  }
-
-  visitLiteralDouble(LiteralDouble node) {
-    write(node.token.lexeme);
-    // -Lit is represented as a send.
-    if (node.token.kind == Tokens.PLUS_TOKEN) write(node.token.next.lexeme);
-  }
-
-  visitLiteralInt(LiteralInt node) {
-    write(node.token.lexeme);
-    // -Lit is represented as a send.
-    if (node.token.kind == Tokens.PLUS_TOKEN) write(node.token.next.lexeme);
-  }
-
-  visitLiteralString(LiteralString node) {
-    write(node.token.lexeme);
-  }
-
-  visitStringJuxtaposition(StringJuxtaposition node) {
-    visit(node.first);
-    write(" ");
-    visit(node.second);
-  }
-
-  visitLiteralNull(LiteralNull node) {
-    write(node.token.lexeme);
-  }
-
-  visitLiteralSymbol(LiteralSymbol node) {
-    write(node.hashToken.lexeme);
-    unparseNodeListOfIdentifiers(node.identifiers);
-  }
-
-  unparseNodeListOfIdentifiers(NodeList node) {
-    // Manually print the list to avoid spaces around operators in unminified
-    // code.
-    Link<Node> l = node.nodes;
-    write(l.head.asIdentifier().token.lexeme);
-    for (l = l.tail; !l.isEmpty; l = l.tail) {
-      write(".");
-      write(l.head.asIdentifier().token.lexeme);
-    }
-  }
-
-  visitNewExpression(NewExpression node) {
-    addToken(node.newToken);
-    visit(node.send);
-  }
-
-  visitLiteralList(LiteralList node) {
-    if (node.constKeyword != null) write(node.constKeyword.lexeme);
-    visit(node.typeArguments);
-    visit(node.elements);
-    // If list is empty, emit space after [] to disambiguate cases like []==[].
-    if (minify && node.elements.isEmpty) write(' ');
-  }
-
-  visitModifiers(Modifiers node) {
-    // Spaces are already included as delimiter.
-    unparseNodeList(node.nodes, spaces: false);
-  }
-
-  /**
-   * Unparses given NodeList starting from specific node.
-   */
-  unparseNodeListFrom(NodeList node, Link<Node> from, {bool spaces: true}) {
-    if (from.isEmpty) return;
-    String delimiter = (node.delimiter == null) ? "" : "${node.delimiter}";
-    visit(from.head);
-    for (Link link = from.tail; !link.isEmpty; link = link.tail) {
-      write(delimiter);
-      if (spaces) space();
-      visit(link.head);
-    }
-  }
-
-  unparseNodeList(NodeList node, {bool spaces: true}) {
-    addToken(node.beginToken);
-    if (node.nodes != null) {
-      unparseNodeListFrom(node, node.nodes, spaces: spaces);
-    }
-    // If the NodeList is a single "[]" token
-    // then beginToken == endToken and only write beginToken.
-    if (node.endToken != null && node.endToken != node.beginToken) {
-      write(node.endToken.lexeme);
-    }
-  }
-
-  visitNodeList(NodeList node) {
-    unparseNodeList(node);
-  }
-
-  visitOperator(Operator node) {
-    visitIdentifier(node);
-  }
-
-  visitRedirectingFactoryBody(RedirectingFactoryBody node) {
-    space();
-    write(node.beginToken.lexeme);
-    space();
-    visit(node.constructorReference);
-    write(node.endToken.lexeme);
-  }
-
-  visitRethrow(Rethrow node) {
-    write('rethrow;');
-  }
-
-  visitReturn(Return node) {
-    write(node.beginToken.lexeme);
-    if (node.hasExpression && node.beginToken.stringValue != '=>') {
-      write(' ');
-    }
-    if (node.beginToken.stringValue == '=>') space();
-    visit(node.expression);
-    if (node.endToken != null) write(node.endToken.lexeme);
-  }
-
-  visitYield(Yield node) {
-    write(node.yieldToken.lexeme);
-    if (node.starToken != null) {
-      write(node.starToken.lexeme);
-    }
-    write(' ');
-    visit(node.expression);
-    write(node.endToken.lexeme);
-  }
-
-  unparseSendReceiver(Send node, {bool spacesNeeded: false}) {
-    if (node.receiver == null) return;
-    visit(node.receiver);
-    CascadeReceiver asCascadeReceiver = node.receiver.asCascadeReceiver();
-    if (asCascadeReceiver != null) {
-      newline();
-      indentMore();
-      indentMore();
-      write(asCascadeReceiver.cascadeOperator.lexeme);
-      indentLess();
-      indentLess();
-    } else if (node.selector.asOperator() == null) {
-      write(node.isConditional ? '?.' : '.');
-    } else if (spacesNeeded) {
-      write(' ');
-    }
-  }
-
-  unparseSendArgument(Send node, {bool spacesNeeded: false}) {
-    if (node.argumentsNode == null) return;
-
-    if (node.isIsNotCheck) {
-      Send argNode = node.arguments.head;
-      visit(argNode.selector);
-      space();
-      visit(argNode.receiver);
-    } else {
-      if (spacesNeeded) write(' ');
-      visit(node.typeArgumentsNode);
-      visit(node.argumentsNode);
-    }
-  }
-
-  visitSend(Send node) {
-    Operator op = node.selector.asOperator();
-    String opString = op != null ? op.source : null;
-    bool spacesNeeded = minify
-        ? identical(opString, 'is') || identical(opString, 'as')
-        : (opString != null && !node.isPrefix && !node.isIndex);
-
-    void minusMinusSpace(Node other) {
-      if (other != null && opString == '-') {
-        Token beginToken = other.getBeginToken();
-        if (beginToken != null &&
-            beginToken.stringValue != null &&
-            beginToken.stringValue.startsWith('-')) {
-          sb.write(' ');
-          spacesNeeded = false;
-        }
-      }
-    }
-
-    if (node.isPrefix) {
-      visit(node.selector);
-      // Add a space for sequences like - -x (double unary minus).
-      minusMinusSpace(node.receiver);
-    }
-
-    unparseSendReceiver(node, spacesNeeded: spacesNeeded);
-    if (!node.isPrefix && !node.isIndex) {
-      visit(node.selector);
-    }
-    minusMinusSpace(node.argumentsNode);
-
-    unparseSendArgument(node, spacesNeeded: spacesNeeded);
-  }
-
-  visitSendSet(SendSet node) {
-    if (node.isPrefix) {
-      if (minify) {
-        write(' ');
-      }
-      visit(node.assignmentOperator);
-    }
-    unparseSendReceiver(node);
-    if (node.isIndex) {
-      write('[');
-      visit(node.arguments.head);
-      write(']');
-      if (!node.isPrefix) {
-        if (!node.isPostfix) {
-          space();
-        }
-        visit(node.assignmentOperator);
-        if (!node.isPostfix) {
-          space();
-        }
-      }
-      unparseNodeListFrom(node.argumentsNode, node.argumentsNode.nodes.tail);
-    } else {
-      visit(node.selector);
-      if (!node.isPrefix) {
-        if (!node.isPostfix && node.assignmentOperator.source != ':') {
-          space();
-        }
-        visit(node.assignmentOperator);
-        if (!node.isPostfix) {
-          space();
-        }
-        if (minify && node.assignmentOperator.source != '=') {
-          write(' ');
-        }
-      }
-      visit(node.argumentsNode);
-    }
-  }
-
-  visitThrow(Throw node) {
-    write(node.throwToken.lexeme);
-    write(' ');
-    visit(node.expression);
-  }
-
-  visitAwait(Await node) {
-    write(node.awaitToken.lexeme);
-    write(' ');
-    visit(node.expression);
-  }
-
-  visitNominalTypeAnnotation(NominalTypeAnnotation node) {
-    visit(node.typeName);
-    visit(node.typeArguments);
-  }
-
-  visitFunctionTypeAnnotation(FunctionTypeAnnotation node) {
-    visit(node.returnType);
-    write(' Function');
-    visit(node.typeParameters);
-    visit(node.formals);
-  }
-
-  visitTypeVariable(TypeVariable node) {
-    visit(node.name);
-    if (node.bound != null) {
-      write(' extends ');
-      visit(node.bound);
-    }
-  }
-
-  visitVariableDefinitions(VariableDefinitions node) {
-    if (node.metadata != null) {
-      visit(node.metadata);
-      write(' ');
-    }
-    visit(node.modifiers);
-    if (!node.modifiers.nodes.isEmpty) {
-      write(' ');
-    }
-    // TODO(sigurdm): Avoid writing the space when [stripTypes], but still write
-    // it if the 'type; is var.
-    if (node.type != null) {
-      visit(node.type);
-      write(' ');
-    }
-    visit(node.definitions);
-  }
-
-  visitDoWhile(DoWhile node) {
-    write(node.doKeyword.lexeme);
-    if (node.body is! Block) {
-      write(' ');
-    } else {
-      space();
-    }
-    visit(node.body);
-    space();
-    write(node.whileKeyword.lexeme);
-    space();
-    visit(node.condition);
-    write(node.endToken.lexeme);
-  }
-
-  visitWhile(While node) {
-    write(node.whileKeyword.lexeme);
-    space();
-    visit(node.condition);
-    space();
-    visit(node.body);
-  }
-
-  visitParenthesizedExpression(ParenthesizedExpression node) {
-    write(node.getBeginToken().lexeme);
-    visit(node.expression);
-    write(node.getEndToken().lexeme);
-  }
-
-  visitStringInterpolation(StringInterpolation node) {
-    visit(node.string);
-    unparseNodeList(node.parts, spaces: false);
-  }
-
-  visitStringInterpolationPart(StringInterpolationPart node) {
-    write('\${'); // TODO(ahe): Preserve the real tokens.
-    visit(node.expression);
-    write('}');
-    visit(node.string);
-  }
-
-  visitEmptyStatement(EmptyStatement node) {
-    write(node.semicolonToken.lexeme);
-  }
-
-  visitGotoStatement(GotoStatement node) {
-    write(node.keywordToken.lexeme);
-    if (node.target != null) {
-      write(' ');
-      visit(node.target);
-    }
-    write(node.semicolonToken.lexeme);
-  }
-
-  visitBreakStatement(BreakStatement node) {
-    visitGotoStatement(node);
-  }
-
-  visitContinueStatement(ContinueStatement node) {
-    visitGotoStatement(node);
-  }
-
-  visitForIn(ForIn node) {
-    write(node.forToken.lexeme);
-    space();
-    write('(');
-    visit(node.declaredIdentifier);
-    write(' ');
-    addToken(node.inToken);
-    visit(node.expression);
-    write(')');
-    space();
-    visit(node.body);
-  }
-
-  visitAsyncForIn(AsyncForIn node) {
-    write(node.awaitToken.lexeme);
-    write(' ');
-    visitForIn(node);
-  }
-
-  visitSyncForIn(SyncForIn node) {
-    visitForIn(node);
-  }
-
-  visitLabel(Label node) {
-    visit(node.identifier);
-    write(node.colonToken.lexeme);
-  }
-
-  visitLabeledStatement(LabeledStatement node) {
-    visit(node.labels);
-    visit(node.statement);
-  }
-
-  visitLiteralMap(LiteralMap node) {
-    if (node.constKeyword != null) write(node.constKeyword.lexeme);
-    if (node.typeArguments != null) visit(node.typeArguments);
-    visit(node.entries);
-  }
-
-  visitLiteralMapEntry(LiteralMapEntry node) {
-    visit(node.key);
-    write(node.colonToken.lexeme);
-    space();
-    visit(node.value);
-  }
-
-  visitNamedArgument(NamedArgument node) {
-    visit(node.name);
-    write(node.colonToken.lexeme);
-    space();
-    visit(node.expression);
-  }
-
-  visitSwitchStatement(SwitchStatement node) {
-    addToken(node.switchKeyword);
-    visit(node.parenthesizedExpression);
-    space();
-    unparseNodeList(node.cases, spaces: false);
-  }
-
-  visitSwitchCase(SwitchCase node) {
-    newline();
-    indentMore();
-    visit(node.labelsAndCases);
-    if (node.isDefaultCase) {
-      write('default:');
-    }
-    unparseBlockStatements(node.statements);
-    indentLess();
-  }
-
-  unparseLibraryName(String libraryName) {
-    write('library $libraryName;');
-    newline();
-  }
-
-  unparseImportTag(String uri,
-      {String prefix,
-      List<String> shows: const <String>[],
-      bool isDeferred: false}) {
-    String deferredString = isDeferred ? ' deferred' : '';
-    String prefixString = prefix == null ? '' : ' as $prefix';
-    String showString = shows.isEmpty ? '' : ' show ${shows.join(", ")}';
-    write('import "$uri"$deferredString$prefixString$showString;');
-    newline();
-  }
-
-  unparseExportTag(String uri, {List<String> shows: const []}) {
-    String suffix = shows.isEmpty ? '' : ' show ${shows.join(", ")}';
-    write('export "$uri"$suffix;');
-    newline();
-  }
-
-  visitTryStatement(TryStatement node) {
-    addToken(node.tryKeyword);
-    visit(node.tryBlock);
-    visit(node.catchBlocks);
-    if (node.finallyKeyword != null) {
-      space();
-      addToken(node.finallyKeyword);
-      visit(node.finallyBlock);
-    }
-  }
-
-  visitCaseMatch(CaseMatch node) {
-    addToken(node.caseKeyword);
-    visit(node.expression);
-    write(node.colonToken.lexeme);
-  }
-
-  visitCatchBlock(CatchBlock node) {
-    addToken(node.onKeyword);
-    if (node.type != null) {
-      visit(node.type);
-      write(' ');
-    }
-    space();
-    addToken(node.catchKeyword);
-    visit(node.formals);
-    space();
-    visit(node.block);
-  }
-
-  visitTypedef(Typedef node) {
-    addToken(node.typedefKeyword);
-    if (node.returnType != null) {
-      visit(node.returnType);
-      write(' ');
-    }
-    visit(node.name);
-    if (node.templateParameters != null) {
-      visit(node.templateParameters);
-    }
-    visit(node.formals);
-    write(node.endToken.lexeme);
-  }
-
-  visitLibraryName(LibraryName node) {
-    addToken(node.libraryKeyword);
-    node.visitChildren(this);
-    write(node.getEndToken().lexeme);
-    newline();
-  }
-
-  visitConditionalUri(ConditionalUri node) {
-    write(node.ifToken.lexeme);
-    space();
-    write('(');
-    visit(node.key);
-    if (node.value != null) {
-      space();
-      write("==");
-      space();
-      visit(node.value);
-    }
-    write(")");
-    space();
-    visit(node.uri);
-  }
-
-  visitDottedName(DottedName node) {
-    unparseNodeListOfIdentifiers(node.identifiers);
-  }
-
-  visitImport(Import node) {
-    addToken(node.importKeyword);
-    visit(node.uri);
-    if (node.hasConditionalUris) {
-      write(' ');
-      visitNodeList(node.conditionalUris);
-    }
-    if (node.isDeferred) {
-      write(' deferred');
-    }
-    if (node.prefix != null) {
-      write(' as ');
-      visit(node.prefix);
-    }
-    if (node.combinators != null) {
-      write(' ');
-      visit(node.combinators);
-    }
-    write(node.getEndToken().lexeme);
-    newline();
-  }
-
-  visitExport(Export node) {
-    addToken(node.exportKeyword);
-    visit(node.uri);
-    if (node.hasConditionalUris) {
-      write(' ');
-      visitNodeList(node.conditionalUris);
-    }
-    if (node.combinators != null) {
-      write(' ');
-      visit(node.combinators);
-    }
-    write(node.getEndToken().lexeme);
-    newline();
-  }
-
-  visitPart(Part node) {
-    addToken(node.partKeyword);
-    visit(node.uri);
-    write(node.getEndToken().lexeme);
-  }
-
-  visitPartOf(PartOf node) {
-    addToken(node.partKeyword);
-    addToken(node.ofKeyword);
-    visit(node.name);
-    write(node.getEndToken().lexeme);
-  }
-
-  visitCombinator(Combinator node) {
-    addToken(node.keywordToken);
-    visit(node.identifiers);
-  }
-
-  visitMetadata(Metadata node) {
-    addToken(node.token);
-    visit(node.expression);
-  }
-
-  visitNode(Node node) {
-    throw 'internal error'; // Should not be called.
-  }
-
-  visitExpression(Expression node) {
-    throw 'internal error'; // Should not be called.
-  }
-
-  visitLibraryTag(LibraryTag node) {
-    throw 'internal error'; // Should not be called.
-  }
-
-  visitLibraryDependency(Node node) {
-    throw 'internal error'; // Should not be called.
-  }
-
-  visitLiteral(Literal node) {
-    throw 'internal error'; // Should not be called.
-  }
-
-  visitLoop(Loop node) {
-    throw 'internal error'; // Should not be called.
-  }
-
-  visitPostfix(Postfix node) {
-    throw 'internal error'; // Should not be called.
-  }
-
-  visitPrefix(Prefix node) {
-    throw 'internal error'; // Should not be called.
-  }
-
-  visitStatement(Statement node) {
-    throw 'internal error'; // Should not be called.
-  }
-
-  visitStringNode(StringNode node) {
-    throw 'internal error'; // Should not be called.
-  }
-
-  visitTypeAnnotation(TypeAnnotation node) {
-    throw 'internal error'; // Should not be called.
-  }
-}
diff --git a/pkg/compiler/lib/src/typechecker.dart b/pkg/compiler/lib/src/typechecker.dart
deleted file mode 100644
index 5709a40..0000000
--- a/pkg/compiler/lib/src/typechecker.dart
+++ /dev/null
@@ -1,2064 +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.
-
-library dart2js.typechecker;
-
-import 'common/names.dart' show Identifiers;
-import 'common/resolution.dart' show Resolution;
-import 'common/tasks.dart' show CompilerTask;
-import 'common.dart';
-import 'compiler.dart' show Compiler;
-import 'constants/expressions.dart';
-import 'constants/values.dart';
-import 'common_elements.dart';
-import 'elements/resolution_types.dart';
-import 'elements/elements.dart'
-    show
-        AbstractFieldElement,
-        AstElement,
-        ClassElement,
-        ConstructorElement,
-        Element,
-        Elements,
-        EnumClassElement,
-        EnumConstantElement,
-        ExecutableElement,
-        FieldElement,
-        FormalElement,
-        FunctionElement,
-        GetterElement,
-        InitializingFormalElement,
-        LibraryElement,
-        MemberSignature,
-        ResolvedAst,
-        SetterElement,
-        TypeDeclarationElement,
-        TypedElement,
-        VariableElement;
-import 'elements/entities.dart' show AsyncMarker;
-import 'elements/names.dart';
-import 'enqueue.dart' show DeferredAction;
-import 'resolution/class_members.dart' show MembersCreator, ErroneousMember;
-import 'resolution/tree_elements.dart' show TreeElements;
-import 'tree/tree.dart';
-import 'util/util.dart' show Link, LinkBuilder;
-
-class TypeCheckerTask extends CompilerTask {
-  final Compiler compiler;
-  TypeCheckerTask(Compiler compiler)
-      : compiler = compiler,
-        super(compiler.measurer);
-
-  String get name => "Type checker";
-  DiagnosticReporter get reporter => compiler.reporter;
-
-  void check(AstElement element) {
-    if (element.isClass) return;
-    if (element.isTypedef) return;
-    ResolvedAst resolvedAst = element.resolvedAst;
-    reporter.withCurrentElement(element.implementation, () {
-      measure(() {
-        TypeCheckerVisitor visitor = new TypeCheckerVisitor(
-            compiler, resolvedAst.elements, compiler.resolution.types);
-        if (element.isField) {
-          visitor.analyzingInitializer = true;
-          ResolutionDartType type =
-              visitor.analyzeVariableTypeAnnotation(resolvedAst.node);
-          visitor.analyzeVariableInitializer(element, type, resolvedAst.body);
-        } else {
-          resolvedAst.node.accept(visitor);
-        }
-      });
-    });
-  }
-}
-
-/**
- * Class used to report different warnings for different kinds of members.
- */
-class MemberKind {
-  static const MemberKind METHOD = const MemberKind("method");
-  static const MemberKind OPERATOR = const MemberKind("operator");
-  static const MemberKind GETTER = const MemberKind("getter");
-  static const MemberKind SETTER = const MemberKind("setter");
-
-  final String name;
-
-  const MemberKind(this.name);
-
-  String toString() => name;
-}
-
-/**
- * [ElementAccess] represents the access of [element], either as a property
- * access or invocation.
- */
-abstract class ElementAccess {
-  Element get element;
-
-  String get name => element.name;
-
-  ResolutionDartType computeType(Resolution resolution);
-
-  /// Returns [: true :] if the element can be access as an invocation.
-  bool isCallable(Compiler compiler) {
-    if (element != null && element.isAbstractField) {
-      AbstractFieldElement abstractFieldElement = element;
-      if (abstractFieldElement.getter == null) {
-        // Setters cannot be invoked as function invocations.
-        return false;
-      }
-    }
-    ResolutionInterfaceType functionType =
-        compiler.resolution.commonElements.functionType;
-    return compiler.resolution.types
-        .isAssignable(computeType(compiler.resolution), functionType);
-  }
-}
-
-/// An access of a instance member.
-class MemberAccess extends ElementAccess {
-  final MemberSignature member;
-
-  MemberAccess(MemberSignature this.member);
-
-  Element get element => member.declarations.first.element;
-
-  ResolutionDartType computeType(Resolution resolution) => member.type;
-
-  String toString() => 'MemberAccess($member)';
-}
-
-/// An access of an unresolved element.
-class DynamicAccess implements ElementAccess {
-  const DynamicAccess();
-
-  Element get element => null;
-
-  String get name => 'dynamic';
-
-  ResolutionDartType computeType(Resolution resolution) =>
-      const ResolutionDynamicType();
-
-  bool isCallable(Compiler compiler) => true;
-
-  String toString() => 'DynamicAccess';
-}
-
-/**
- * An access of a resolved top-level or static property or function, or an
- * access of a resolved element through [:this:].
- */
-class ResolvedAccess extends ElementAccess {
-  final Element element;
-
-  ResolvedAccess(Element this.element) {
-    assert(element != null);
-  }
-
-  ResolutionDartType computeType(Resolution resolution) {
-    if (element.isGetter) {
-      GetterElement getter = element;
-      ResolutionFunctionType functionType = getter.computeType(resolution);
-      return functionType.returnType;
-    } else if (element.isSetter) {
-      SetterElement setter = element;
-      ResolutionFunctionType functionType = setter.computeType(resolution);
-      if (functionType.parameterTypes.length != 1) {
-        // TODO(johnniwinther,karlklose): this happens for malformed static
-        // setters. Treat them the same as instance members.
-        return const ResolutionDynamicType();
-      }
-      return functionType.parameterTypes.first;
-    } else if (element.isTypedef || element.isClass) {
-      TypeDeclarationElement typeDeclaration = element;
-      typeDeclaration.computeType(resolution);
-      return typeDeclaration.thisType;
-    } else {
-      TypedElement typedElement = element;
-      typedElement.computeType(resolution);
-      return typedElement.type;
-    }
-  }
-
-  String toString() => 'ResolvedAccess($element)';
-}
-
-/// An access to a promoted variable.
-class PromotedAccess extends ElementAccess {
-  final VariableElement element;
-  final ResolutionDartType type;
-
-  PromotedAccess(VariableElement this.element, ResolutionDartType this.type) {
-    assert(element != null);
-    assert(type != null);
-  }
-
-  ResolutionDartType computeType(Resolution resolution) => type;
-
-  String toString() => 'PromotedAccess($element,$type)';
-}
-
-/**
- * An access of a resolved top-level or static property or function, or an
- * access of a resolved element through [:this:].
- */
-class TypeAccess extends ElementAccess {
-  final ResolutionDartType type;
-  TypeAccess(ResolutionDartType this.type) {
-    assert(type != null);
-  }
-
-  Element get element => type.element;
-
-  ResolutionDartType computeType(Resolution resolution) => type;
-
-  String toString() => 'TypeAccess($type)';
-}
-
-/**
- * An access of a type literal.
- */
-class TypeLiteralAccess extends ElementAccess {
-  final ResolutionDartType type;
-
-  TypeLiteralAccess(this.type) {
-    assert(type != null);
-  }
-
-  Element get element => type.element;
-
-  String get name => type.name;
-
-  ResolutionInterfaceType computeType(Resolution resolution) =>
-      resolution.commonElements.typeType;
-
-  String toString() => 'TypeLiteralAccess($type)';
-}
-
-/// An access to the 'call' method of a function type.
-class FunctionCallAccess implements ElementAccess {
-  final Element element;
-  final ResolutionDartType type;
-
-  const FunctionCallAccess(this.element, this.type);
-
-  String get name => 'call';
-
-  ResolutionDartType computeType(Resolution resolution) => type;
-
-  bool isCallable(Compiler compiler) => true;
-
-  String toString() => 'FunctionAccess($element, $type)';
-}
-
-/// An is-expression that potentially promotes a variable.
-class TypePromotion {
-  final Send node;
-  final VariableElement variable;
-  final ResolutionDartType type;
-  final List<TypePromotionMessage> messages = <TypePromotionMessage>[];
-
-  TypePromotion(this.node, this.variable, this.type);
-
-  bool get isValid => messages.isEmpty;
-
-  TypePromotion copy() {
-    return new TypePromotion(node, variable, type)..messages.addAll(messages);
-  }
-
-  void addHint(DiagnosticMessage hint,
-      [List<DiagnosticMessage> infos = const <DiagnosticMessage>[]]) {
-    messages.add(new TypePromotionMessage(hint, infos));
-  }
-
-  String toString() {
-    return 'Promote ${variable} to ${type}${isValid ? '' : ' (invalid)'}';
-  }
-}
-
-/// A hint or info message attached to a type promotion.
-class TypePromotionMessage {
-  DiagnosticMessage hint;
-  List<DiagnosticMessage> infos;
-
-  TypePromotionMessage(this.hint, this.infos);
-}
-
-class TypeCheckerVisitor extends Visitor<ResolutionDartType> {
-  final Compiler compiler;
-  final TreeElements elements;
-  final Types types;
-
-  Node lastSeenNode;
-  ResolutionDartType expectedReturnType;
-  AsyncMarker currentAsyncMarker = AsyncMarker.SYNC;
-
-  final ClassElement currentClass;
-
-  /// The immediately enclosing field, method or constructor being analyzed.
-  ExecutableElement executableContext;
-
-  CommonElements get commonElements => resolution.commonElements;
-
-  DiagnosticReporter get reporter => compiler.reporter;
-
-  Resolution get resolution => compiler.resolution;
-
-  ResolutionInterfaceType get intType => commonElements.intType;
-  ResolutionInterfaceType get doubleType => commonElements.doubleType;
-  ResolutionInterfaceType get boolType => commonElements.boolType;
-  ResolutionInterfaceType get stringType => commonElements.stringType;
-
-  ResolutionDartType thisType;
-  ResolutionDartType superType;
-
-  Link<ResolutionDartType> cascadeTypes = const Link<ResolutionDartType>();
-
-  bool analyzingInitializer = false;
-
-  Map<Node, List<TypePromotion>> shownTypePromotionsMap =
-      new Map<Node, List<TypePromotion>>();
-
-  Map<VariableElement, Link<TypePromotion>> typePromotionsMap =
-      new Map<VariableElement, Link<TypePromotion>>();
-
-  Set<TypePromotion> reportedTypePromotions = new Set<TypePromotion>();
-
-  void showTypePromotion(Node node, TypePromotion typePromotion) {
-    List<TypePromotion> shownTypePromotions =
-        shownTypePromotionsMap.putIfAbsent(node, () => <TypePromotion>[]);
-    shownTypePromotions.add(typePromotion);
-  }
-
-  void registerKnownTypePromotion(TypePromotion typePromotion) {
-    VariableElement variable = typePromotion.variable;
-    Link<TypePromotion> knownTypes = typePromotionsMap.putIfAbsent(
-        variable, () => const Link<TypePromotion>());
-    typePromotionsMap[variable] = knownTypes.prepend(typePromotion);
-  }
-
-  void unregisterKnownTypePromotion(TypePromotion typePromotion) {
-    VariableElement variable = typePromotion.variable;
-    Link<TypePromotion> knownTypes = typePromotionsMap[variable].tail;
-    if (knownTypes.isEmpty) {
-      typePromotionsMap.remove(variable);
-    } else {
-      typePromotionsMap[variable] = knownTypes;
-    }
-  }
-
-  List<TypePromotion> getShownTypePromotionsFor(Node node) {
-    List<TypePromotion> shownTypePromotions = shownTypePromotionsMap[node];
-    return shownTypePromotions != null ? shownTypePromotions : const [];
-  }
-
-  TypePromotion getKnownTypePromotion(VariableElement element) {
-    Link<TypePromotion> promotions = typePromotionsMap[element];
-    if (promotions != null) {
-      while (!promotions.isEmpty) {
-        TypePromotion typePromotion = promotions.head;
-        if (typePromotion.isValid) {
-          return typePromotion;
-        }
-        promotions = promotions.tail;
-      }
-    }
-    return null;
-  }
-
-  ResolutionDartType getKnownType(VariableElement element) {
-    TypePromotion typePromotion = getKnownTypePromotion(element);
-    if (typePromotion != null) return typePromotion.type;
-    return element.type;
-  }
-
-  TypeCheckerVisitor(this.compiler, TreeElements elements, this.types)
-      : this.elements = elements,
-        this.executableContext = elements.analyzedElement,
-        this.currentClass = elements.analyzedElement != null
-            ? elements.analyzedElement.enclosingClass
-            : null {
-    if (currentClass != null) {
-      thisType = currentClass.thisType;
-      superType = currentClass.supertype;
-    } else {
-      // If these are used, an error should have been reported by the resolver.
-      thisType = const ResolutionDynamicType();
-      superType = const ResolutionDynamicType();
-    }
-  }
-
-  LibraryElement get currentLibrary => elements.analyzedElement.library;
-
-  reportTypeWarning(Spannable spannable, MessageKind kind,
-      [Map arguments = const {}]) {
-    reporter.reportWarningMessage(spannable, kind, arguments);
-  }
-
-  reportMessage(Spannable spannable, MessageKind kind, Map arguments,
-      {bool isHint: false}) {
-    if (isHint) {
-      reporter.reportHintMessage(spannable, kind, arguments);
-    } else {
-      reporter.reportWarningMessage(spannable, kind, arguments);
-    }
-  }
-
-  reportTypePromotionHint(TypePromotion typePromotion) {
-    if (!reportedTypePromotions.contains(typePromotion)) {
-      reportedTypePromotions.add(typePromotion);
-      for (TypePromotionMessage message in typePromotion.messages) {
-        reporter.reportHint(message.hint, message.infos);
-      }
-    }
-  }
-
-  // TODO(karlklose): remove these functions.
-  ResolutionDartType unhandledExpression() => const ResolutionDynamicType();
-
-  ResolutionDartType analyzeNonVoid(Node node) {
-    ResolutionDartType type = analyze(node);
-    if (type.isVoid) {
-      reportTypeWarning(node, MessageKind.VOID_EXPRESSION);
-    }
-    return type;
-  }
-
-  ResolutionDartType analyzeWithDefault(
-      Node node, ResolutionDartType defaultValue) {
-    return node != null ? analyze(node) : defaultValue;
-  }
-
-  /// If [inInitializer] is true, assignment should be interpreted as write to
-  /// a field and not to a setter.
-  ResolutionDartType analyze(Node node,
-      {bool inInitializer: false, bool mustHaveType: true}) {
-    if (node == null) {
-      final String error = 'Unexpected node: null';
-      if (lastSeenNode != null) {
-        reporter.internalError(lastSeenNode, error);
-      } else {
-        reporter.internalError(executableContext, error);
-      }
-    } else {
-      lastSeenNode = node;
-    }
-    bool previouslyInitializer = analyzingInitializer;
-    analyzingInitializer = inInitializer;
-    ResolutionDartType result = node.accept(this);
-    analyzingInitializer = previouslyInitializer;
-    if (result == null && mustHaveType) {
-      reporter.internalError(node, 'Type is null.');
-    }
-    return result;
-  }
-
-  void analyzeUntyped(Node node, {bool inInitializer: false}) {
-    if (node != null) {
-      analyze(node, inInitializer: inInitializer, mustHaveType: false);
-    }
-  }
-
-  void checkTypePromotion(Node node, TypePromotion typePromotion,
-      {bool checkAccesses: false}) {
-    VariableElement variable = typePromotion.variable;
-    String variableName = variable.name;
-    List<Node> potentialMutationsIn =
-        elements.getPotentialMutationsIn(node, variable);
-    if (!potentialMutationsIn.isEmpty) {
-      DiagnosticMessage hint = reporter.createMessage(
-          typePromotion.node,
-          MessageKind.POTENTIAL_MUTATION,
-          {'variableName': variableName, 'shownType': typePromotion.type});
-      List<DiagnosticMessage> infos = <DiagnosticMessage>[];
-      for (Node mutation in potentialMutationsIn) {
-        infos.add(reporter.createMessage(
-            mutation,
-            MessageKind.POTENTIAL_MUTATION_HERE,
-            {'variableName': variableName}));
-      }
-      typePromotion.addHint(hint, infos);
-    }
-    List<Node> potentialMutationsInClosures =
-        elements.getPotentialMutationsInClosure(variable);
-    if (!potentialMutationsInClosures.isEmpty) {
-      DiagnosticMessage hint = reporter.createMessage(
-          typePromotion.node,
-          MessageKind.POTENTIAL_MUTATION_IN_CLOSURE,
-          {'variableName': variableName, 'shownType': typePromotion.type});
-      List<DiagnosticMessage> infos = <DiagnosticMessage>[];
-      for (Node mutation in potentialMutationsInClosures) {
-        infos.add(reporter.createMessage(
-            mutation,
-            MessageKind.POTENTIAL_MUTATION_IN_CLOSURE_HERE,
-            {'variableName': variableName}));
-      }
-      typePromotion.addHint(hint, infos);
-    }
-    if (checkAccesses) {
-      List<Node> accesses = elements.getAccessesByClosureIn(node, variable);
-      List<Node> mutations = elements.getPotentialMutations(variable);
-      if (!accesses.isEmpty && !mutations.isEmpty) {
-        DiagnosticMessage hint = reporter.createMessage(
-            typePromotion.node,
-            MessageKind.ACCESSED_IN_CLOSURE,
-            {'variableName': variableName, 'shownType': typePromotion.type});
-        List<DiagnosticMessage> infos = <DiagnosticMessage>[];
-        for (Node access in accesses) {
-          infos.add(reporter.createMessage(
-              access,
-              MessageKind.ACCESSED_IN_CLOSURE_HERE,
-              {'variableName': variableName}));
-        }
-        for (Node mutation in mutations) {
-          infos.add(reporter.createMessage(
-              mutation,
-              MessageKind.POTENTIAL_MUTATION_HERE,
-              {'variableName': variableName}));
-        }
-        typePromotion.addHint(hint, infos);
-      }
-    }
-  }
-
-  /// Show type promotions from [left] and [right] in [node] given that the
-  /// promoted variables are not potentially mutated in [right].
-  void reshowTypePromotions(Node node, Node left, Node right) {
-    for (TypePromotion typePromotion in getShownTypePromotionsFor(left)) {
-      typePromotion = typePromotion.copy();
-      checkTypePromotion(right, typePromotion);
-      showTypePromotion(node, typePromotion);
-    }
-
-    for (TypePromotion typePromotion in getShownTypePromotionsFor(right)) {
-      typePromotion = typePromotion.copy();
-      checkTypePromotion(right, typePromotion);
-      showTypePromotion(node, typePromotion);
-    }
-  }
-
-  /// Analyze [node] in the context of the known types shown in [context].
-  ResolutionDartType analyzeInPromotedContext(Node context, Node node,
-      {bool mustHaveType: true}) {
-    Link<TypePromotion> knownForNode = const Link<TypePromotion>();
-    for (TypePromotion typePromotion in getShownTypePromotionsFor(context)) {
-      typePromotion = typePromotion.copy();
-      checkTypePromotion(node, typePromotion, checkAccesses: true);
-      knownForNode = knownForNode.prepend(typePromotion);
-      registerKnownTypePromotion(typePromotion);
-    }
-
-    final ResolutionDartType type = analyze(node, mustHaveType: mustHaveType);
-
-    while (!knownForNode.isEmpty) {
-      unregisterKnownTypePromotion(knownForNode.head);
-      knownForNode = knownForNode.tail;
-    }
-
-    return type;
-  }
-
-  /**
-   * Check if a value of type [from] can be assigned to a variable, parameter or
-   * return value of type [to].  If `isConst == true`, an error is emitted in
-   * checked mode, otherwise a warning is issued.
-   */
-  bool checkAssignable(
-      Spannable spannable, ResolutionDartType from, ResolutionDartType to,
-      {bool isConst: false}) {
-    if (!types.isAssignable(from, to)) {
-      if (compiler.options.enableTypeAssertions && isConst) {
-        reporter.reportErrorMessage(spannable, MessageKind.NOT_ASSIGNABLE,
-            {'fromType': from, 'toType': to});
-      } else {
-        reporter.reportWarningMessage(spannable, MessageKind.NOT_ASSIGNABLE,
-            {'fromType': from, 'toType': to});
-      }
-      return false;
-    }
-    return true;
-  }
-
-  checkCondition(Expression condition) {
-    checkAssignable(condition, analyze(condition), boolType);
-  }
-
-  void pushCascadeType(ResolutionDartType type) {
-    cascadeTypes = cascadeTypes.prepend(type);
-  }
-
-  ResolutionDartType popCascadeType() {
-    ResolutionDartType type = cascadeTypes.head;
-    cascadeTypes = cascadeTypes.tail;
-    return type;
-  }
-
-  visitAssert(Assert node) {
-    analyze(node.condition);
-    if (node.hasMessage) analyze(node.message);
-  }
-
-  visitBlock(Block node) {
-    analyzeUntyped(node.statements);
-  }
-
-  ResolutionDartType visitCascade(Cascade node) {
-    analyze(node.expression);
-    return popCascadeType();
-  }
-
-  ResolutionDartType visitCascadeReceiver(CascadeReceiver node) {
-    ResolutionDartType type = analyze(node.expression);
-    pushCascadeType(type);
-    return type;
-  }
-
-  visitDoWhile(DoWhile node) {
-    analyzeUntyped(node.body);
-    checkCondition(node.condition);
-  }
-
-  visitExpressionStatement(ExpressionStatement node) {
-    Expression expression = node.expression;
-    analyze(expression);
-  }
-
-  /** Dart Programming Language Specification: 11.5.1 For Loop */
-  visitFor(For node) {
-    if (node.initializer != null) {
-      analyzeUntyped(node.initializer);
-    }
-    if (node.condition != null) {
-      checkCondition(node.condition);
-    }
-    if (node.update != null) {
-      analyzeUntyped(node.update);
-    }
-    analyzeUntyped(node.body);
-  }
-
-  visitFunctionDeclaration(FunctionDeclaration node) {
-    analyze(node.function);
-  }
-
-  ResolutionDartType visitFunctionExpression(FunctionExpression node) {
-    ResolutionDartType type;
-    ResolutionDartType returnType;
-    final FunctionElement element = elements.getFunctionDefinition(node);
-    assert(
-        element != null, failedAt(node, 'FunctionExpression with no element'));
-    if (Elements.isUnresolved(element)) return const ResolutionDynamicType();
-    if (element.isGenerativeConstructor) {
-      type = const ResolutionDynamicType();
-      returnType = const ResolutionVoidType();
-
-      element.functionSignature.forEachParameter((FormalElement parameter) {
-        if (parameter.isInitializingFormal) {
-          InitializingFormalElement fieldParameter = parameter;
-          checkAssignable(parameter, parameter.type,
-              fieldParameter.fieldElement.computeType(resolution));
-        }
-      });
-      if (node.initializers != null) {
-        analyzeUntyped(node.initializers, inInitializer: true);
-      }
-    } else {
-      ResolutionFunctionType functionType = element.computeType(resolution);
-      returnType = functionType.returnType;
-      type = functionType;
-    }
-    ExecutableElement previousExecutableContext = executableContext;
-    ResolutionDartType previousReturnType = expectedReturnType;
-    expectedReturnType = returnType;
-    AsyncMarker previousAsyncMarker = currentAsyncMarker;
-
-    executableContext = element;
-    currentAsyncMarker = element.asyncMarker;
-    analyzeUntyped(node.body);
-
-    executableContext = previousExecutableContext;
-    expectedReturnType = previousReturnType;
-    currentAsyncMarker = previousAsyncMarker;
-    return type;
-  }
-
-  ResolutionDartType visitIdentifier(Identifier node) {
-    if (node.isThis()) {
-      return thisType;
-    } else if (node.isSuper()) {
-      return superType;
-    } else {
-      TypedElement element = elements[node];
-      assert(element != null, failedAt(node, 'Missing element for identifier'));
-      assert(element.isVariable || element.isParameter || element.isField,
-          failedAt(node, 'Unexpected context element ${element}'));
-      return element.computeType(resolution);
-    }
-  }
-
-  visitIf(If node) {
-    Expression condition = node.condition.expression;
-    Statement thenPart = node.thenPart;
-
-    checkCondition(node.condition);
-    analyzeInPromotedContext(condition, thenPart, mustHaveType: false);
-    if (node.elsePart != null) {
-      analyzeUntyped(node.elsePart);
-    }
-  }
-
-  void checkPrivateAccess(Node node, Element element, String name) {
-    if (name != null &&
-        Name.isPrivateName(name) &&
-        element.library != currentLibrary) {
-      reportTypeWarning(node, MessageKind.PRIVATE_ACCESS,
-          {'name': name, 'libraryName': element.library.name});
-    }
-  }
-
-  ElementAccess lookupMember(Node node, ResolutionDartType receiverType,
-      String name, MemberKind memberKind, Element receiverElement,
-      {bool lookupClassMember: false, bool isHint: false}) {
-    if (receiverType.treatAsDynamic) {
-      return const DynamicAccess();
-    }
-
-    Name memberName = new Name(name, currentLibrary,
-        isSetter: memberKind == MemberKind.SETTER);
-
-    // Lookup the class or interface member [name] in [interface].
-    MemberSignature lookupMemberSignature(
-        Name name, ResolutionInterfaceType interface) {
-      MembersCreator.computeClassMembersByName(
-          resolution, interface.element, name.text);
-      return lookupClassMember || analyzingInitializer
-          ? interface.lookupClassMember(name)
-          : interface.lookupInterfaceMember(name);
-    }
-
-    // Compute the access of [name] on [type]. This function takes the special
-    // 'call' method into account.
-    ElementAccess getAccess(Name name, ResolutionDartType unaliasedBound,
-        ResolutionInterfaceType interface) {
-      MemberSignature member = lookupMemberSignature(memberName, interface);
-      if (member != null) {
-        if (member is ErroneousMember) {
-          return const DynamicAccess();
-        } else {
-          return new MemberAccess(member);
-        }
-      }
-      if (name == const PublicName('call')) {
-        if (unaliasedBound.isFunctionType) {
-          // This is an access the implicit 'call' method of a function type.
-          return new FunctionCallAccess(receiverElement, unaliasedBound);
-        }
-        ResolutionInterfaceType functionType = commonElements.functionType;
-        if (types.isSubtype(interface, functionType)) {
-          // This is an access of the special 'call' method implicitly defined
-          // on 'Function'. This method can be called with any arguments, which
-          // we ensure by giving it the type 'dynamic'.
-          return new FunctionCallAccess(null, const ResolutionDynamicType());
-        }
-      }
-      return null;
-    }
-
-    ResolutionDartType unaliasedBound =
-        Types.computeUnaliasedBound(resolution, receiverType);
-    if (unaliasedBound.treatAsDynamic) {
-      return new DynamicAccess();
-    }
-    ResolutionInterfaceType interface =
-        Types.computeInterfaceType(resolution, unaliasedBound);
-    ElementAccess access = getAccess(memberName, unaliasedBound, interface);
-    if (access != null) {
-      return access;
-    }
-    if (receiverElement != null &&
-        (receiverElement.isVariable || receiverElement.isParameter)) {
-      Link<TypePromotion> typePromotions = typePromotionsMap[receiverElement];
-      if (typePromotions != null) {
-        while (!typePromotions.isEmpty) {
-          TypePromotion typePromotion = typePromotions.head;
-          if (!typePromotion.isValid) {
-            ResolutionDartType unaliasedBound =
-                Types.computeUnaliasedBound(resolution, typePromotion.type);
-            if (!unaliasedBound.treatAsDynamic) {
-              ResolutionInterfaceType interface =
-                  Types.computeInterfaceType(resolution, unaliasedBound);
-              if (getAccess(memberName, unaliasedBound, interface) != null) {
-                reportTypePromotionHint(typePromotion);
-              }
-            }
-          }
-          typePromotions = typePromotions.tail;
-        }
-      }
-    }
-    // We didn't find a member with the correct name.  If this lookup is for a
-    // super or redirecting initializer, the resolver has already emitted an
-    // error message.  If the target is a proxy, no warning needs to be emitted.
-    // Otherwise, try to emit the most precise warning.
-    if (!interface.element.isProxy && !analyzingInitializer) {
-      bool foundPrivateMember = false;
-      if (memberName.isPrivate) {
-        void findPrivateMember(MemberSignature member) {
-          if (memberName.isSimilarTo(member.name)) {
-            PrivateName privateName = member.name;
-            LibraryElement library = privateName.library;
-            reportMessage(node, MessageKind.PRIVATE_ACCESS,
-                {'name': name, 'libraryName': library.name},
-                isHint: isHint);
-            foundPrivateMember = true;
-          }
-        }
-
-        // TODO(johnniwinther): Avoid computation of all class members.
-        MembersCreator.computeAllClassMembers(resolution, interface.element);
-        if (lookupClassMember) {
-          interface.element.forEachClassMember(findPrivateMember);
-        } else {
-          interface.element.forEachInterfaceMember(findPrivateMember);
-        }
-      }
-      if (!foundPrivateMember) {
-        switch (memberKind) {
-          case MemberKind.METHOD:
-            reportMessage(node, MessageKind.UNDEFINED_METHOD,
-                {'className': receiverType.name, 'memberName': name},
-                isHint: isHint);
-            break;
-          case MemberKind.OPERATOR:
-            reportMessage(node, MessageKind.UNDEFINED_OPERATOR,
-                {'className': receiverType.name, 'memberName': name},
-                isHint: isHint);
-            break;
-          case MemberKind.GETTER:
-            if (lookupMemberSignature(memberName.setter, interface) != null) {
-              // A setter is present so warn explicitly about the missing
-              // getter.
-              reportMessage(
-                  node,
-                  MessageKind.UNDEFINED_INSTANCE_GETTER_BUT_SETTER,
-                  {'className': receiverType.name, 'memberName': name},
-                  isHint: isHint);
-            } else if (name == 'await') {
-              Map arguments = {'className': receiverType.name};
-              String functionName = executableContext.name;
-              MessageKind kind;
-              if (functionName == '') {
-                kind = MessageKind.AWAIT_MEMBER_NOT_FOUND_IN_CLOSURE;
-              } else {
-                kind = MessageKind.AWAIT_MEMBER_NOT_FOUND;
-                arguments['functionName'] = functionName;
-              }
-              reportMessage(node, kind, arguments, isHint: isHint);
-            } else {
-              reportMessage(node, MessageKind.UNDEFINED_GETTER,
-                  {'className': receiverType.name, 'memberName': name},
-                  isHint: isHint);
-            }
-            break;
-          case MemberKind.SETTER:
-            reportMessage(node, MessageKind.UNDEFINED_SETTER,
-                {'className': receiverType.name, 'memberName': name},
-                isHint: isHint);
-            break;
-        }
-      }
-    }
-    return const DynamicAccess();
-  }
-
-  ResolutionDartType lookupMemberType(
-      Node node, ResolutionDartType type, String name, MemberKind memberKind,
-      {bool isHint: false}) {
-    return lookupMember(node, type, name, memberKind, null, isHint: isHint)
-        .computeType(resolution);
-  }
-
-  void analyzeArguments(Send send, Element element, ResolutionDartType type,
-      [LinkBuilder<ResolutionDartType> argumentTypes]) {
-    Link<Node> arguments = send.arguments;
-    type.computeUnaliased(resolution);
-    ResolutionDartType unaliasedType = type.unaliased;
-    if (identical(unaliasedType.kind, ResolutionTypeKind.FUNCTION)) {
-      /// Report [warning] including info(s) about the declaration of [element]
-      /// or [type].
-      void reportWarning(DiagnosticMessage warning) {
-        // TODO(johnniwinther): Support pointing to individual parameters on
-        // assignability warnings.
-        List<DiagnosticMessage> infos = <DiagnosticMessage>[];
-        Element declaration = element;
-        if (declaration == null) {
-          declaration = type.element;
-        } else if (type.isTypedef) {
-          infos.add(reporter.createMessage(declaration,
-              MessageKind.THIS_IS_THE_DECLARATION, {'name': element.name}));
-          declaration = type.element;
-        }
-        if (declaration != null) {
-          infos.add(reporter.createMessage(
-              declaration, MessageKind.THIS_IS_THE_METHOD));
-        }
-        reporter.reportWarning(warning, infos);
-      }
-
-      /// Report a warning on [node] if [argumentType] is not assignable to
-      /// [parameterType].
-      void checkAssignable(Spannable node, ResolutionDartType argumentType,
-          ResolutionDartType parameterType) {
-        if (!types.isAssignable(argumentType, parameterType)) {
-          reportWarning(reporter.createMessage(node, MessageKind.NOT_ASSIGNABLE,
-              {'fromType': argumentType, 'toType': parameterType}));
-        }
-      }
-
-      ResolutionFunctionType funType = unaliasedType;
-      Iterator<ResolutionDartType> parameterTypes =
-          funType.parameterTypes.iterator;
-      Iterator<ResolutionDartType> optionalParameterTypes =
-          funType.optionalParameterTypes.iterator;
-      while (!arguments.isEmpty) {
-        Node argument = arguments.head;
-        NamedArgument namedArgument = argument.asNamedArgument();
-        if (namedArgument != null) {
-          argument = namedArgument.expression;
-          String argumentName = namedArgument.name.source;
-          ResolutionDartType namedParameterType =
-              funType.getNamedParameterType(argumentName);
-          if (namedParameterType == null) {
-            // TODO(johnniwinther): Provide better information on the called
-            // function.
-            reportWarning(reporter.createMessage(
-                argument,
-                MessageKind.NAMED_ARGUMENT_NOT_FOUND,
-                {'argumentName': argumentName}));
-
-            ResolutionDartType argumentType = analyze(argument);
-            if (argumentTypes != null) argumentTypes.addLast(argumentType);
-          } else {
-            ResolutionDartType argumentType = analyze(argument);
-            if (argumentTypes != null) argumentTypes.addLast(argumentType);
-            checkAssignable(argument, argumentType, namedParameterType);
-          }
-        } else {
-          if (!parameterTypes.moveNext()) {
-            if (!optionalParameterTypes.moveNext()) {
-              // TODO(johnniwinther): Provide better information on the
-              // called function.
-              reportWarning(reporter.createMessage(
-                  argument, MessageKind.ADDITIONAL_ARGUMENT));
-
-              ResolutionDartType argumentType = analyze(argument);
-              if (argumentTypes != null) argumentTypes.addLast(argumentType);
-            } else {
-              ResolutionDartType argumentType = analyze(argument);
-              if (argumentTypes != null) argumentTypes.addLast(argumentType);
-              checkAssignable(
-                  argument, argumentType, optionalParameterTypes.current);
-            }
-          } else {
-            ResolutionDartType argumentType = analyze(argument);
-            if (argumentTypes != null) argumentTypes.addLast(argumentType);
-            checkAssignable(argument, argumentType, parameterTypes.current);
-          }
-        }
-        arguments = arguments.tail;
-      }
-      if (parameterTypes.moveNext()) {
-        // TODO(johnniwinther): Provide better information on the called
-        // function.
-        reportWarning(reporter.createMessage(send, MessageKind.MISSING_ARGUMENT,
-            {'argumentType': parameterTypes.current}));
-      }
-    } else {
-      while (!arguments.isEmpty) {
-        ResolutionDartType argumentType = analyze(arguments.head);
-        if (argumentTypes != null) argumentTypes.addLast(argumentType);
-        arguments = arguments.tail;
-      }
-    }
-  }
-
-  // Analyze the invocation [node] of [elementAccess].
-  //
-  // If provided [argumentTypes] is filled with the argument types during
-  // analysis.
-  ResolutionDartType analyzeInvocation(Send node, ElementAccess elementAccess,
-      [LinkBuilder<ResolutionDartType> argumentTypes]) {
-    ResolutionDartType type = elementAccess.computeType(resolution);
-    if (elementAccess.isCallable(compiler)) {
-      analyzeArguments(node, elementAccess.element, type, argumentTypes);
-    } else {
-      reportTypeWarning(
-          node, MessageKind.NOT_CALLABLE, {'elementName': elementAccess.name});
-      analyzeArguments(node, elementAccess.element,
-          const ResolutionDynamicType(), argumentTypes);
-    }
-    type.computeUnaliased(resolution);
-    type = type.unaliased;
-    if (type.isFunctionType) {
-      ResolutionFunctionType funType = type;
-      return funType.returnType;
-    } else {
-      return const ResolutionDynamicType();
-    }
-  }
-
-  /**
-   * Computes the [ElementAccess] for [name] on the [node] possibly using the
-   * [element] provided for [node] by the resolver.
-   */
-  ElementAccess computeAccess(
-      Send node, String name, Element element, MemberKind memberKind,
-      {bool lookupClassMember: false}) {
-    if (Elements.isMalformed(element)) {
-      return const DynamicAccess();
-    }
-    if (node.receiver != null) {
-      Element receiverElement = elements[node.receiver];
-      if (receiverElement != null) {
-        if (receiverElement.isPrefix) {
-          if (node.isConditional) {
-            // Skip cases like `prefix?.topLevel`.
-            return const DynamicAccess();
-          }
-          assert(
-              element != null, failedAt(node, 'Prefixed node has no element.'));
-          return computeResolvedAccess(node, name, element, memberKind);
-        }
-      }
-      // e.foo() for some expression e.
-      ResolutionDartType receiverType = analyze(node.receiver);
-      if (receiverType.treatAsDynamic || receiverType.isVoid) {
-        return const DynamicAccess();
-      }
-      return lookupMember(
-          node, receiverType, name, memberKind, elements[node.receiver],
-          lookupClassMember:
-              lookupClassMember || element != null && element.isStatic);
-    } else {
-      return computeResolvedAccess(node, name, element, memberKind);
-    }
-  }
-
-  /**
-   * Computes the [ElementAccess] for [name] on the [node] using the [element]
-   * provided for [node] by the resolver.
-   */
-  ElementAccess computeResolvedAccess(
-      Send node, String name, Element element, MemberKind memberKind) {
-    if (element == null) {
-      // foo() where foo is unresolved.
-      return lookupMember(node, thisType, name, memberKind, null);
-    } else if (element.isMalformed) {
-      // foo() where foo is erroneous.
-      return const DynamicAccess();
-    } else if (element.impliesType) {
-      // The literal `Foo` where Foo is a class, a typedef, or a type variable.
-      if (elements.isTypeLiteral(node)) {
-        return new TypeLiteralAccess(elements.getTypeLiteralType(node));
-      }
-      return createResolvedAccess(node, name, element);
-    } else if (element.isClassMember) {
-      // foo() where foo is a member.
-      return lookupMember(node, thisType, name, memberKind, null,
-          lookupClassMember: element.isStatic);
-    } else if (element.isFunction) {
-      // foo() where foo is a method in the same class.
-      return createResolvedAccess(node, name, element);
-    } else if (element.isVariable ||
-        element.isRegularParameter ||
-        element.isField ||
-        element.isInitializingFormal) {
-      // foo() where foo is a field in the same class.
-      return createResolvedAccess(node, name, element);
-    } else if (element.isGetter || element.isSetter) {
-      return createResolvedAccess(node, name, element);
-    } else {
-      reporter.internalError(
-          element, 'Unexpected element kind ${element.kind}.');
-      return null;
-    }
-  }
-
-  ElementAccess createResolvedAccess(Send node, String name, Element element) {
-    checkPrivateAccess(node, element, name);
-    return createPromotedAccess(element);
-  }
-
-  ElementAccess createPromotedAccess(Element element) {
-    if (element.isVariable || element.isParameter) {
-      TypePromotion typePromotion = getKnownTypePromotion(element);
-      if (typePromotion != null) {
-        return new PromotedAccess(element, typePromotion.type);
-      }
-    }
-    return new ResolvedAccess(element);
-  }
-
-  /**
-   * Computes the type of the access of [name] on the [node] possibly using the
-   * [element] provided for [node] by the resolver.
-   */
-  ResolutionDartType computeAccessType(
-      Send node, String name, Element element, MemberKind memberKind,
-      {bool lookupClassMember: false}) {
-    ResolutionDartType type = computeAccess(node, name, element, memberKind,
-            lookupClassMember: lookupClassMember)
-        .computeType(resolution);
-    if (type == null) {
-      reporter.internalError(node, 'Type is null on access of $name on $node.');
-    }
-    return type;
-  }
-
-  /// Compute a version of [shownType] that is more specific that [knownType].
-  /// This is used to provided better hints when trying to promote a supertype
-  /// to a raw subtype. For instance trying to promote `Iterable<int>` to `List`
-  /// we suggest the use of `List<int>`, which would make promotion valid.
-  ResolutionDartType computeMoreSpecificType(
-      ResolutionDartType shownType, ResolutionDartType knownType) {
-    if (knownType.isInterfaceType &&
-        shownType.isInterfaceType &&
-        types.isSubtype(shownType.asRaw(), knownType)) {
-      // For the comments in the block, assume the hierarchy:
-      //     class A<T, V> {}
-      //     class B<S, U> extends A<S, int> {}
-      // and a promotion from a [knownType] of `A<double, int>` to a
-      // [shownType] of `B`.
-      ResolutionInterfaceType knownInterfaceType = knownType;
-      ClassElement shownClass = shownType.element;
-
-      // Compute `B<double, dynamic>` as the subtype of `A<double, int>` using
-      // the relation between `A<S, int>` and `A<double, int>`.
-      MoreSpecificSubtypeVisitor visitor =
-          new MoreSpecificSubtypeVisitor(types);
-      ResolutionInterfaceType shownTypeGeneric =
-          visitor.computeMoreSpecific(shownClass, knownInterfaceType);
-
-      if (shownTypeGeneric != null &&
-          types.isMoreSpecific(shownTypeGeneric, knownType)) {
-        // This should be the case but we double-check.
-        // TODO(johnniwinther): Ensure that we don't suggest malbounded types.
-        return shownTypeGeneric;
-      }
-    }
-    return null;
-  }
-
-  ResolutionDartType visitSend(Send node) {
-    Element element = elements[node];
-
-    if (element != null && element.isConstructor) {
-      ResolutionDartType receiverType;
-      if (node.receiver != null) {
-        receiverType = analyze(node.receiver);
-      } else if (node.selector.isSuper()) {
-        // TODO(johnniwinther): Lookup super-member in class members.
-        receiverType = superType;
-      } else {
-        assert(node.selector.isThis());
-        receiverType = thisType;
-      }
-      ResolutionDartType constructorType =
-          computeConstructorType(element, receiverType);
-      analyzeArguments(node, element, constructorType);
-      return const ResolutionDynamicType();
-    }
-
-    Identifier selector = node.selector.asIdentifier();
-    if (Elements.isClosureSend(node, element)) {
-      if (element != null) {
-        if (element.isError) {
-          // foo() where foo is erroneous
-          return analyzeInvocation(node, const DynamicAccess());
-        } else {
-          assert(element.isLocal,
-              failedAt(node, "Unexpected element $element in closure send."));
-          // foo() where foo is a local or a parameter.
-          return analyzeInvocation(node, createPromotedAccess(element));
-        }
-      } else {
-        // exp() where exp is some complex expression like (o) or foo().
-        ResolutionDartType type = analyze(node.selector);
-        return analyzeInvocation(node, new TypeAccess(type));
-      }
-    } else if (Elements.isMalformed(element) && selector == null) {
-      // exp() where exp is an erroneous construct like `new Unresolved()`.
-      ResolutionDartType type = analyze(node.selector);
-      return analyzeInvocation(node, new TypeAccess(type));
-    }
-
-    String name = selector.source;
-
-    if (node.isOperator && identical(name, 'is')) {
-      analyze(node.receiver);
-      if (!node.isIsNotCheck) {
-        Element variable = elements[node.receiver];
-        if (variable == null) {
-          // Look for the variable element within parenthesized expressions.
-          ParenthesizedExpression parentheses =
-              node.receiver.asParenthesizedExpression();
-          while (parentheses != null) {
-            variable = elements[parentheses.expression];
-            if (variable != null) break;
-            parentheses = parentheses.expression.asParenthesizedExpression();
-          }
-        }
-
-        if (variable != null && (variable.isVariable || variable.isParameter)) {
-          ResolutionDartType knownType = getKnownType(variable);
-          if (!knownType.isDynamic) {
-            ResolutionDartType shownType =
-                elements.getType(node.arguments.head);
-            TypePromotion typePromotion =
-                new TypePromotion(node, variable, shownType);
-            if (!types.isMoreSpecific(shownType, knownType)) {
-              String variableName = variable.name;
-              if (!types.isSubtype(shownType, knownType)) {
-                typePromotion.addHint(reporter.createMessage(
-                    node, MessageKind.NOT_MORE_SPECIFIC_SUBTYPE, {
-                  'variableName': variableName,
-                  'shownType': shownType,
-                  'knownType': knownType
-                }));
-              } else {
-                ResolutionDartType shownTypeSuggestion =
-                    computeMoreSpecificType(shownType, knownType);
-                if (shownTypeSuggestion != null) {
-                  typePromotion.addHint(reporter.createMessage(
-                      node, MessageKind.NOT_MORE_SPECIFIC_SUGGESTION, {
-                    'variableName': variableName,
-                    'shownType': shownType,
-                    'shownTypeSuggestion': shownTypeSuggestion,
-                    'knownType': knownType
-                  }));
-                } else {
-                  typePromotion.addHint(reporter.createMessage(
-                      node, MessageKind.NOT_MORE_SPECIFIC, {
-                    'variableName': variableName,
-                    'shownType': shownType,
-                    'knownType': knownType
-                  }));
-                }
-              }
-            }
-            showTypePromotion(node, typePromotion);
-          }
-        }
-      }
-      return boolType;
-    }
-    if (node.isOperator && identical(name, 'as')) {
-      analyze(node.receiver);
-      return elements.getType(node.arguments.head);
-    } else if (node.isOperator) {
-      final Node receiver = node.receiver;
-      final ResolutionDartType receiverType = analyze(receiver);
-      if (identical(name, '==') ||
-          identical(name, '!=')
-          // TODO(johnniwinther): Remove these.
-          ||
-          identical(name, '===') ||
-          identical(name, '!==')) {
-        // Analyze argument.
-        analyze(node.arguments.head);
-        return boolType;
-      } else if (identical(name, '||')) {
-        checkAssignable(receiver, receiverType, boolType);
-        final Node argument = node.arguments.head;
-        final ResolutionDartType argumentType = analyze(argument);
-        checkAssignable(argument, argumentType, boolType);
-        return boolType;
-      } else if (identical(name, '&&')) {
-        checkAssignable(receiver, receiverType, boolType);
-        final Node argument = node.arguments.head;
-
-        final ResolutionDartType argumentType =
-            analyzeInPromotedContext(receiver, argument);
-
-        reshowTypePromotions(node, receiver, argument);
-
-        checkAssignable(argument, argumentType, boolType);
-        return boolType;
-      } else if (identical(name, '!')) {
-        checkAssignable(receiver, receiverType, boolType);
-        return boolType;
-      } else if (identical(name, '?')) {
-        return boolType;
-      } else if (identical(name, '??')) {
-        final Node argument = node.arguments.head;
-        final ResolutionDartType argumentType = analyze(argument);
-        return types.computeLeastUpperBound(receiverType, argumentType);
-      }
-      String operatorName = selector.source;
-      if (identical(name, '-') && node.arguments.isEmpty) {
-        operatorName = 'unary-';
-      }
-      assert(
-          identical(name, '+') ||
-              identical(name, '=') ||
-              identical(name, '-') ||
-              identical(name, '*') ||
-              identical(name, '/') ||
-              identical(name, '%') ||
-              identical(name, '~/') ||
-              identical(name, '|') ||
-              identical(name, '&') ||
-              identical(name, '^') ||
-              identical(name, '~') ||
-              identical(name, '<<') ||
-              identical(name, '>>') ||
-              identical(name, '<') ||
-              identical(name, '>') ||
-              identical(name, '<=') ||
-              identical(name, '>=') ||
-              identical(name, '[]'),
-          failedAt(node, 'Unexpected operator $name'));
-
-      // TODO(karlklose): handle `void` in expression context by calling
-      // [analyzeNonVoid] instead of [analyze].
-      ElementAccess access = receiverType.isVoid
-          ? const DynamicAccess()
-          : lookupMember(
-              node, receiverType, operatorName, MemberKind.OPERATOR, null);
-      LinkBuilder<ResolutionDartType> argumentTypesBuilder =
-          new LinkBuilder<ResolutionDartType>();
-      ResolutionDartType resultType =
-          analyzeInvocation(node, access, argumentTypesBuilder);
-      if (receiverType == intType) {
-        if (identical(name, '+') ||
-            identical(operatorName, '-') ||
-            identical(name, '*') ||
-            identical(name, '%')) {
-          ResolutionDartType argumentType = argumentTypesBuilder.toLink().head;
-          if (argumentType == intType) {
-            return intType;
-          } else if (argumentType == doubleType) {
-            return doubleType;
-          }
-        }
-      }
-      return resultType;
-    } else if (node.isPropertyAccess) {
-      ElementAccess access =
-          computeAccess(node, selector.source, element, MemberKind.GETTER);
-      return access.computeType(resolution);
-    } else if (node.isFunctionObjectInvocation) {
-      return unhandledExpression();
-    } else {
-      ElementAccess access =
-          computeAccess(node, selector.source, element, MemberKind.METHOD);
-      return analyzeInvocation(node, access);
-    }
-  }
-
-  /// Returns the first type in the list or [:dynamic:] if the list is empty.
-  ResolutionDartType firstType(List<ResolutionDartType> list) {
-    return list.isEmpty ? const ResolutionDynamicType() : list.first;
-  }
-
-  /**
-   * Returns the second type in the list or [:dynamic:] if the list is too
-   * short.
-   */
-  ResolutionDartType secondType(List<ResolutionDartType> list) {
-    return list.length < 2 ? const ResolutionDynamicType() : list[1];
-  }
-
-  /**
-   * Checks [: target o= value :] for some operator o, and returns the type
-   * of the result. This method also handles increment/decrement expressions
-   * like [: target++ :].
-   */
-  ResolutionDartType checkAssignmentOperator(SendSet node, String operatorName,
-      Node valueNode, ResolutionDartType value) {
-    assert(!node.isIndex, failedAt(node));
-    Element setterElement = elements[node];
-    Element getterElement = elements[node.selector];
-    Identifier selector = node.selector;
-    ResolutionDartType getter = computeAccessType(
-        node, selector.source, getterElement, MemberKind.GETTER);
-    ResolutionDartType setter = computeAccessType(
-        node, selector.source, setterElement, MemberKind.SETTER);
-    // [operator] is the type of operator+ or operator- on [target].
-    ResolutionDartType operator =
-        lookupMemberType(node, getter, operatorName, MemberKind.OPERATOR);
-    if (operator is ResolutionFunctionType) {
-      ResolutionFunctionType operatorType = operator;
-      // [result] is the type of target o value.
-      ResolutionDartType result = operatorType.returnType;
-      ResolutionDartType operatorArgument =
-          firstType(operatorType.parameterTypes);
-      // Check target o value.
-      bool validValue = checkAssignable(valueNode, value, operatorArgument);
-      if (validValue || !(node.isPrefix || node.isPostfix)) {
-        // Check target = result.
-        checkAssignable(node.assignmentOperator, result, setter);
-      }
-      return node.isPostfix ? getter : result;
-    }
-    return const ResolutionDynamicType();
-  }
-
-  /**
-   * Checks [: base[key] o= value :] for some operator o, and returns the type
-   * of the result. This method also handles increment/decrement expressions
-   * like [: base[key]++ :].
-   */
-  ResolutionDartType checkIndexAssignmentOperator(SendSet node,
-      String operatorName, Node valueNode, ResolutionDartType value) {
-    assert(node.isIndex, failedAt(node));
-    final ResolutionDartType base = analyze(node.receiver);
-    final Node keyNode = node.arguments.head;
-    final ResolutionDartType key = analyze(keyNode);
-
-    // [indexGet] is the type of operator[] on [base].
-    ResolutionDartType indexGet =
-        lookupMemberType(node, base, '[]', MemberKind.OPERATOR);
-    if (indexGet is ResolutionFunctionType) {
-      ResolutionFunctionType indexGetType = indexGet;
-      ResolutionDartType indexGetKey = firstType(indexGetType.parameterTypes);
-      // Check base[key].
-      bool validKey = checkAssignable(keyNode, key, indexGetKey);
-
-      // [element] is the type of base[key].
-      ResolutionDartType element = indexGetType.returnType;
-      // [operator] is the type of operator o on [element].
-      ResolutionDartType operator =
-          lookupMemberType(node, element, operatorName, MemberKind.OPERATOR);
-      if (operator is ResolutionFunctionType) {
-        ResolutionFunctionType operatorType = operator;
-
-        // Check base[key] o value.
-        ResolutionDartType operatorArgument =
-            firstType(operatorType.parameterTypes);
-        bool validValue = checkAssignable(valueNode, value, operatorArgument);
-
-        // [result] is the type of base[key] o value.
-        ResolutionDartType result = operatorType.returnType;
-
-        // [indexSet] is the type of operator[]= on [base].
-        ResolutionDartType indexSet =
-            lookupMemberType(node, base, '[]=', MemberKind.OPERATOR);
-        if (indexSet is ResolutionFunctionType) {
-          ResolutionFunctionType indexSetType = indexSet;
-          ResolutionDartType indexSetKey =
-              firstType(indexSetType.parameterTypes);
-          ResolutionDartType indexSetValue =
-              secondType(indexSetType.parameterTypes);
-
-          if (validKey || indexGetKey != indexSetKey) {
-            // Only check base[key] on []= if base[key] was valid for [] or
-            // if the key types differ.
-            checkAssignable(keyNode, key, indexSetKey);
-          }
-          // Check base[key] = result
-          if (validValue || !(node.isPrefix || node.isPostfix)) {
-            checkAssignable(node.assignmentOperator, result, indexSetValue);
-          }
-        }
-        return node.isPostfix ? element : result;
-      }
-    }
-    return const ResolutionDynamicType();
-  }
-
-  visitSendSet(SendSet node) {
-    Element element = elements[node];
-    Identifier selector = node.selector;
-    final name = node.assignmentOperator.source;
-    if (identical(name, '=') || identical(name, '??=')) {
-      // e1 = value
-      if (node.isIndex) {
-        // base[key] = value
-        final ResolutionDartType base = analyze(node.receiver);
-        final Node keyNode = node.arguments.head;
-        final ResolutionDartType key = analyze(keyNode);
-        final Node valueNode = node.arguments.tail.head;
-        final ResolutionDartType value = analyze(valueNode);
-        ResolutionDartType indexSet =
-            lookupMemberType(node, base, '[]=', MemberKind.OPERATOR);
-        ResolutionDartType indexSetValue = const ResolutionDynamicType();
-        if (indexSet is ResolutionFunctionType) {
-          ResolutionFunctionType indexSetType = indexSet;
-          ResolutionDartType indexSetKey =
-              firstType(indexSetType.parameterTypes);
-          checkAssignable(keyNode, key, indexSetKey);
-          indexSetValue = secondType(indexSetType.parameterTypes);
-          checkAssignable(node.assignmentOperator, value, indexSetValue);
-        }
-        return identical(name, '=')
-            ? value
-            : types.computeLeastUpperBound(value, indexSetValue);
-      } else {
-        // target = value
-        ResolutionDartType target;
-        if (analyzingInitializer) {
-          // Field declaration `Foo target = value;` or initializer
-          // `this.target = value`. Lookup the getter `target` in the class
-          // members.
-          target = computeAccessType(
-              node, selector.source, element, MemberKind.GETTER,
-              lookupClassMember: true);
-        } else {
-          // Normal assignment `target = value`.
-          target = computeAccessType(
-              node, selector.source, element, MemberKind.SETTER);
-        }
-        final Node valueNode = node.arguments.head;
-        final ResolutionDartType value = analyze(valueNode);
-        checkAssignable(node.assignmentOperator, value, target);
-        return identical(name, '=')
-            ? value
-            : types.computeLeastUpperBound(value, target);
-      }
-    } else if (identical(name, '++') || identical(name, '--')) {
-      // e++ or e--
-      String operatorName = identical(name, '++') ? '+' : '-';
-      if (node.isIndex) {
-        // base[key]++, base[key]--, ++base[key], or --base[key]
-        return checkIndexAssignmentOperator(
-            node, operatorName, node.assignmentOperator, intType);
-      } else {
-        // target++, target--, ++target, or --target
-        return checkAssignmentOperator(
-            node, operatorName, node.assignmentOperator, intType);
-      }
-    } else {
-      // e1 o= e2 for some operator o.
-      String operatorName;
-      switch (name) {
-        case '+=':
-          operatorName = '+';
-          break;
-        case '-=':
-          operatorName = '-';
-          break;
-        case '*=':
-          operatorName = '*';
-          break;
-        case '/=':
-          operatorName = '/';
-          break;
-        case '%=':
-          operatorName = '%';
-          break;
-        case '~/=':
-          operatorName = '~/';
-          break;
-        case '&=':
-          operatorName = '&';
-          break;
-        case '|=':
-          operatorName = '|';
-          break;
-        case '^=':
-          operatorName = '^';
-          break;
-        case '<<=':
-          operatorName = '<<';
-          break;
-        case '>>=':
-          operatorName = '>>';
-          break;
-        default:
-          reporter.internalError(node, 'Unexpected assignment operator $name.');
-      }
-      if (node.isIndex) {
-        // base[key] o= value for some operator o.
-        final Node valueNode = node.arguments.tail.head;
-        final ResolutionDartType value = analyze(valueNode);
-        return checkIndexAssignmentOperator(
-            node, operatorName, valueNode, value);
-      } else {
-        // target o= value for some operator o.
-        final Node valueNode = node.arguments.head;
-        final ResolutionDartType value = analyze(valueNode);
-        return checkAssignmentOperator(node, operatorName, valueNode, value);
-      }
-    }
-  }
-
-  ResolutionDartType visitLiteralInt(LiteralInt node) {
-    return intType;
-  }
-
-  ResolutionDartType visitLiteralDouble(LiteralDouble node) {
-    return doubleType;
-  }
-
-  ResolutionDartType visitLiteralBool(LiteralBool node) {
-    return boolType;
-  }
-
-  ResolutionDartType visitLiteralString(LiteralString node) {
-    return stringType;
-  }
-
-  ResolutionDartType visitStringJuxtaposition(StringJuxtaposition node) {
-    analyze(node.first);
-    analyze(node.second);
-    return stringType;
-  }
-
-  ResolutionDartType visitLiteralNull(LiteralNull node) {
-    return const ResolutionDynamicType();
-  }
-
-  ResolutionInterfaceType visitLiteralSymbol(LiteralSymbol node) {
-    return commonElements.symbolType;
-  }
-
-  ResolutionDartType computeConstructorType(
-      ConstructorElement constructor, ResolutionDartType type) {
-    if (Elements.isUnresolved(constructor))
-      return const ResolutionDynamicType();
-    ResolutionDartType constructorType = constructor.computeType(resolution);
-    if (identical(type.kind, ResolutionTypeKind.INTERFACE)) {
-      if (constructor.isSynthesized) {
-        // TODO(johnniwinther): Remove this when synthesized constructors handle
-        // type variables correctly.
-        ResolutionInterfaceType interfaceType = type;
-        ClassElement receiverElement = interfaceType.element;
-        while (receiverElement.isMixinApplication) {
-          receiverElement = receiverElement.supertype.element;
-        }
-        constructorType = constructorType
-            .substByContext(interfaceType.asInstanceOf(receiverElement));
-      } else {
-        constructorType = constructorType.substByContext(type);
-      }
-    }
-    return constructorType;
-  }
-
-  ResolutionDartType visitNewExpression(NewExpression node) {
-    Element element = elements[node.send];
-    if (Elements.isUnresolved(element)) return const ResolutionDynamicType();
-
-    checkPrivateAccess(node, element, element.name);
-
-    ResolutionDartType newType = elements.getType(node);
-    assert(newType != null,
-        failedAt(node, "No new type registered in $elements."));
-    ResolutionDartType constructorType =
-        computeConstructorType(element, newType);
-    analyzeArguments(node.send, element, constructorType);
-    return newType;
-  }
-
-  ResolutionDartType visitLiteralList(LiteralList node) {
-    ResolutionInterfaceType listType = elements.getType(node);
-    ResolutionDartType listElementType = firstType(listType.typeArguments);
-    for (Link<Node> link = node.elements.nodes;
-        !link.isEmpty;
-        link = link.tail) {
-      Node element = link.head;
-      ResolutionDartType elementType = analyze(element);
-      checkAssignable(element, elementType, listElementType,
-          isConst: node.isConst);
-    }
-    return listType;
-  }
-
-  visitNodeList(NodeList node) {
-    for (Link<Node> link = node.nodes; !link.isEmpty; link = link.tail) {
-      analyzeUntyped(link.head, inInitializer: analyzingInitializer);
-    }
-  }
-
-  visitRedirectingFactoryBody(RedirectingFactoryBody node) {
-    // TODO(lrn): Typecheck the body. It must refer to the constructor
-    // of a subtype.
-  }
-
-  visitRethrow(Rethrow node) {
-    // Nothing to do here.
-  }
-
-  /** Dart Programming Language Specification: 11.10 Return */
-  visitReturn(Return node) {
-    if (identical(node.beginToken.stringValue, 'native')) {
-      return null;
-    }
-
-    final Node expression = node.expression;
-
-    // Executing a return statement return e; [...] It is a static type warning
-    // if the type of e may not be assigned to the declared return type of the
-    // immediately enclosing function.
-    if (expression != null) {
-      ResolutionDartType expressionType = analyze(expression);
-      if (executableContext.isGenerativeConstructor) {
-        // The resolver already emitted an error for this expression.
-      } else {
-        if (currentAsyncMarker == AsyncMarker.ASYNC) {
-          ResolutionInterfaceType futureOfFlattenedType =
-              commonElements.futureType(types.flatten(expressionType));
-          expressionType = futureOfFlattenedType;
-        }
-        if (expectedReturnType.isVoid &&
-            !types.isAssignable(expressionType, const ResolutionVoidType())) {
-          // In `void f(...) => e`, `e` can have any type.
-          if (!node.isArrowBody) {
-            reportTypeWarning(expression, MessageKind.RETURN_VALUE_IN_VOID);
-          }
-        } else {
-          checkAssignable(expression, expressionType, expectedReturnType);
-        }
-      }
-    } else if (currentAsyncMarker != AsyncMarker.SYNC) {
-      // `return;` is allowed.
-    } else if (!types.isAssignable(
-        expectedReturnType, const ResolutionVoidType())) {
-      // Let f be the function immediately enclosing a return statement of the
-      // form 'return;' It is a static warning if both of the following
-      // conditions hold:
-      // - f is not a generative constructor.
-      // - The return type of f may not be assigned to void.
-      reportTypeWarning(
-          node, MessageKind.RETURN_NOTHING, {'returnType': expectedReturnType});
-    }
-  }
-
-  ResolutionDartType visitThrow(Throw node) {
-    // TODO(johnniwinther): Handle reachability.
-    analyze(node.expression);
-    return const ResolutionDynamicType();
-  }
-
-  ResolutionDartType visitAwait(Await node) {
-    ResolutionDartType expressionType = analyze(node.expression);
-    if (resolution.target.supportsAsyncAwait) {
-      return types.flatten(expressionType);
-    } else {
-      return const ResolutionDynamicType();
-    }
-  }
-
-  visitYield(Yield node) {
-    ResolutionDartType resultType = analyze(node.expression);
-    if (!node.hasStar) {
-      if (currentAsyncMarker.isAsync) {
-        ResolutionInterfaceType streamOfResultType =
-            commonElements.streamType(resultType);
-        resultType = streamOfResultType;
-      } else {
-        ResolutionInterfaceType iterableOfResultType =
-            commonElements.iterableType(resultType);
-        resultType = iterableOfResultType;
-      }
-    } else {
-      if (currentAsyncMarker.isAsync) {
-        // The static type of expression must be assignable to Stream.
-        ResolutionInterfaceType streamType = commonElements.streamType();
-        checkAssignable(node, resultType, streamType);
-      } else {
-        // The static type of expression must be assignable to Iterable.
-        ResolutionInterfaceType iterableType = commonElements.iterableType();
-        checkAssignable(node, resultType, iterableType);
-      }
-    }
-    // The static type of the result must be assignable to the declared type.
-    checkAssignable(node, resultType, expectedReturnType);
-  }
-
-  ResolutionDartType visitTypeAnnotation(TypeAnnotation node) {
-    return elements.getType(node);
-  }
-
-  ResolutionDartType analyzeVariableTypeAnnotation(VariableDefinitions node) {
-    ResolutionDartType type =
-        analyzeWithDefault(node.type, const ResolutionDynamicType());
-    if (type.isVoid) {
-      reportTypeWarning(node.type, MessageKind.VOID_VARIABLE);
-      type = const ResolutionDynamicType();
-    }
-    return type;
-  }
-
-  void analyzeVariableInitializer(
-      Spannable spannable, ResolutionDartType declaredType, Node initializer) {
-    if (initializer == null) return;
-
-    ResolutionDartType expressionType = analyzeNonVoid(initializer);
-    checkAssignable(spannable, expressionType, declaredType);
-  }
-
-  visitVariableDefinitions(VariableDefinitions node) {
-    ResolutionDartType type = analyzeVariableTypeAnnotation(node);
-    for (Link<Node> link = node.definitions.nodes;
-        !link.isEmpty;
-        link = link.tail) {
-      Node definition = link.head;
-      assert(definition is Identifier || definition is SendSet,
-          failedAt(definition, 'expected identifier or initialization'));
-      if (definition is SendSet) {
-        SendSet initialization = definition;
-        analyzeVariableInitializer(initialization.assignmentOperator, type,
-            initialization.arguments.head);
-        // TODO(sigmund): explore inferring a type for `var` using the RHS (like
-        // DDC does), for example:
-        // if (node.type == null && node.modifiers.isVar &&
-        //     !initializer.isDynamic) {
-        //   var variable = elements[definition];
-        //   if (variable != null) {
-        //     var typePromotion = new TypePromotion(
-        //         node, variable, initializer);
-        //     registerKnownTypePromotion(typePromotion);
-        //   }
-        // }
-      }
-    }
-  }
-
-  visitWhile(While node) {
-    checkCondition(node.condition);
-    analyzeUntyped(node.body);
-  }
-
-  ResolutionDartType visitParenthesizedExpression(
-      ParenthesizedExpression node) {
-    Expression expression = node.expression;
-    ResolutionDartType type = analyze(expression);
-    for (TypePromotion typePromotion in getShownTypePromotionsFor(expression)) {
-      showTypePromotion(node, typePromotion);
-    }
-    return type;
-  }
-
-  ResolutionDartType visitConditional(Conditional node) {
-    Expression condition = node.condition;
-    Expression thenExpression = node.thenExpression;
-
-    checkCondition(condition);
-
-    ResolutionDartType thenType =
-        analyzeInPromotedContext(condition, thenExpression);
-
-    ResolutionDartType elseType = analyze(node.elseExpression);
-    return types.computeLeastUpperBound(thenType, elseType);
-  }
-
-  visitStringInterpolation(StringInterpolation node) {
-    node.visitChildren(this);
-    return stringType;
-  }
-
-  visitStringInterpolationPart(StringInterpolationPart node) {
-    node.visitChildren(this);
-    return stringType;
-  }
-
-  visitEmptyStatement(EmptyStatement node) {
-    // Nothing to do here.
-  }
-
-  visitBreakStatement(BreakStatement node) {
-    // Nothing to do here.
-  }
-
-  visitContinueStatement(ContinueStatement node) {
-    // Nothing to do here.
-  }
-
-  ResolutionDartType computeForInElementType(ForIn node) {
-    VariableDefinitions declaredIdentifier =
-        node.declaredIdentifier.asVariableDefinitions();
-    if (declaredIdentifier != null) {
-      return analyzeWithDefault(
-          declaredIdentifier.type, const ResolutionDynamicType());
-    } else {
-      return analyze(node.declaredIdentifier);
-    }
-  }
-
-  visitAsyncForIn(AsyncForIn node) {
-    ResolutionDartType elementType = computeForInElementType(node);
-    ResolutionDartType expressionType = analyze(node.expression);
-    if (resolution.target.supportsAsyncAwait) {
-      ResolutionInterfaceType streamOfDynamic = commonElements.streamType();
-      if (!types.isAssignable(expressionType, streamOfDynamic)) {
-        reportMessage(node.expression, MessageKind.NOT_ASSIGNABLE,
-            {'fromType': expressionType, 'toType': streamOfDynamic},
-            isHint: true);
-      } else {
-        ResolutionInterfaceType interfaceType =
-            Types.computeInterfaceType(resolution, expressionType);
-        if (interfaceType != null) {
-          ResolutionInterfaceType streamType =
-              interfaceType.asInstanceOf(streamOfDynamic.element);
-          if (streamType != null) {
-            ResolutionDartType streamElementType =
-                streamType.typeArguments.first;
-            if (!types.isAssignable(streamElementType, elementType)) {
-              reportMessage(
-                  node.expression,
-                  MessageKind.FORIN_NOT_ASSIGNABLE,
-                  {
-                    'currentType': streamElementType,
-                    'expressionType': expressionType,
-                    'elementType': elementType
-                  },
-                  isHint: true);
-            }
-          }
-        }
-      }
-    }
-    analyzeUntyped(node.body);
-  }
-
-  visitSyncForIn(SyncForIn node) {
-    ResolutionDartType elementType = computeForInElementType(node);
-    ResolutionDartType expressionType = analyze(node.expression);
-    ResolutionDartType iteratorType = lookupMemberType(node.expression,
-        expressionType, Identifiers.iterator, MemberKind.GETTER);
-    ResolutionDartType currentType = lookupMemberType(
-        node.expression, iteratorType, Identifiers.current, MemberKind.GETTER,
-        isHint: true);
-    if (!types.isAssignable(currentType, elementType)) {
-      reportMessage(
-          node.expression,
-          MessageKind.FORIN_NOT_ASSIGNABLE,
-          {
-            'currentType': currentType,
-            'expressionType': expressionType,
-            'elementType': elementType
-          },
-          isHint: true);
-    }
-    analyzeUntyped(node.body);
-  }
-
-  visitLabeledStatement(LabeledStatement node) {
-    analyzeUntyped(node.statement);
-  }
-
-  visitLiteralMap(LiteralMap node) {
-    ResolutionInterfaceType mapType = elements.getType(node);
-    ResolutionDartType mapKeyType = firstType(mapType.typeArguments);
-    ResolutionDartType mapValueType = secondType(mapType.typeArguments);
-    bool isConst = node.isConst;
-    for (Link<Node> link = node.entries.nodes;
-        !link.isEmpty;
-        link = link.tail) {
-      LiteralMapEntry entry = link.head;
-      ResolutionDartType keyType = analyze(entry.key);
-      checkAssignable(entry.key, keyType, mapKeyType, isConst: isConst);
-      ResolutionDartType valueType = analyze(entry.value);
-      checkAssignable(entry.value, valueType, mapValueType, isConst: isConst);
-    }
-    return mapType;
-  }
-
-  visitNamedArgument(NamedArgument node) {
-    // Named arguments are visited as part of analyzing invocations of
-    // unresolved methods. For instance [: foo(a: 42); :] where 'foo' is neither
-    // found in the enclosing scope nor through lookup on 'this' or
-    // [: x.foo(b: 42); :] where 'foo' cannot be not found through lookup on
-    // the static type of 'x'.
-    return analyze(node.expression);
-  }
-
-  visitSwitchStatement(SwitchStatement node) {
-    // TODO(johnniwinther): Handle reachability based on reachability of
-    // switch cases.
-    // TODO(johnniwinther): Provide hint of duplicate case constants.
-
-    ResolutionDartType expressionType = analyze(node.expression);
-
-    // Check that all the case expressions are assignable to the expression.
-    bool hasDefaultCase = false;
-    for (SwitchCase switchCase in node.cases) {
-      if (switchCase.isDefaultCase) {
-        hasDefaultCase = true;
-      }
-      for (Node labelOrCase in switchCase.labelsAndCases) {
-        CaseMatch caseMatch = labelOrCase.asCaseMatch();
-        if (caseMatch == null) continue;
-
-        ResolutionDartType caseType = analyze(caseMatch.expression);
-        checkAssignable(caseMatch, expressionType, caseType);
-      }
-
-      analyzeUntyped(switchCase);
-    }
-
-    if (!hasDefaultCase && expressionType.isEnumType) {
-      compiler.enqueuer.resolution
-          .addDeferredAction(new DeferredAction(executableContext, () {
-        Map<ConstantValue, FieldElement> enumValues =
-            <ConstantValue, FieldElement>{};
-        List<FieldElement> unreferencedFields = <FieldElement>[];
-        EnumClassElement enumClass = expressionType.element;
-        enumClass.enumValues.forEach((EnumConstantElement field) {
-          // TODO(johnniwinther): Ensure that the enum constant is computed at
-          // this point.
-          ConstantValue constantValue = compiler.resolver.constantCompiler
-              .getConstantValueForVariable(field);
-          if (constantValue == null) {
-            // The field might not have been resolved.
-            unreferencedFields.add(field);
-          } else {
-            enumValues[constantValue] = field;
-          }
-        });
-
-        for (SwitchCase switchCase in node.cases) {
-          for (Node labelOrCase in switchCase.labelsAndCases) {
-            CaseMatch caseMatch = labelOrCase.asCaseMatch();
-            if (caseMatch != null) {
-              ConstantExpression caseConstant = compiler
-                  .resolver.constantCompiler
-                  .compileNode(caseMatch.expression, elements);
-              enumValues
-                  .remove(compiler.constants.getConstantValue(caseConstant));
-            }
-          }
-        }
-        unreferencedFields.addAll(enumValues.values);
-        if (!unreferencedFields.isEmpty) {
-          reporter.reportWarningMessage(node, MessageKind.MISSING_ENUM_CASES, {
-            'enumType': expressionType,
-            'enumValues': unreferencedFields.map((e) => e.name).join(', ')
-          });
-        }
-      }));
-    }
-  }
-
-  visitSwitchCase(SwitchCase node) {
-    analyzeUntyped(node.statements);
-  }
-
-  visitTryStatement(TryStatement node) {
-    // TODO(johnniwinther): Use reachability information of try-block,
-    // catch-blocks and finally-block to compute the whether the try statement
-    // is returning.
-    analyzeUntyped(node.tryBlock);
-    for (CatchBlock catchBlock in node.catchBlocks) {
-      analyzeUntyped(catchBlock);
-    }
-    analyzeUntyped(node.finallyBlock);
-  }
-
-  visitCatchBlock(CatchBlock node) {
-    analyzeUntyped(node.block);
-  }
-
-  visitTypedef(Typedef node) {
-    // Do not typecheck [Typedef] nodes.
-  }
-
-  visitNode(Node node) {
-    reporter.internalError(node,
-        'Unexpected node ${node.getObjectDescription()} in the type checker.');
-  }
-}
diff --git a/pkg/compiler/lib/src/types/abstract_value_domain.dart b/pkg/compiler/lib/src/types/abstract_value_domain.dart
index 3ce4ce1..6b35ca4 100644
--- a/pkg/compiler/lib/src/types/abstract_value_domain.dart
+++ b/pkg/compiler/lib/src/types/abstract_value_domain.dart
@@ -6,6 +6,7 @@
 
 import '../constants/values.dart' show ConstantValue;
 import '../elements/entities.dart';
+import '../universe/selector.dart';
 
 /// A value in an abstraction of runtime values.
 abstract class AbstractValue {}
@@ -63,7 +64,7 @@
 
   /// The [AbstractValue] that represents a non-null fixed size JavaScript array
   /// at runtime.
-  AbstractValue get fixedArrayType;
+  AbstractValue get fixedListType;
 
   /// The [AbstractValue] that represents a non-null 31-bit unsigned integer at
   /// runtime.
@@ -230,6 +231,10 @@
   /// [b].
   AbstractValue union(covariant AbstractValue a, covariant AbstractValue b);
 
+  /// Returns [AbstractValue] for the runtime values contained in at least one
+  /// of [values].
+  AbstractValue unionOfMany(List<AbstractValue> values);
+
   /// Returns [AbstractValue] for the runtime values that [a] and [b] have in
   /// common.
   AbstractValue intersection(
@@ -243,4 +248,24 @@
 
   /// Computes the [AbstractValue] corresponding to the constant [value].
   AbstractValue computeAbstractValueForConstant(ConstantValue value);
+
+  /// Returns the element type of [value] if it represents a container value
+  /// at runtime. Returns [dynamicType] otherwise.
+  AbstractValue getContainerElementType(AbstractValue value);
+
+  /// Returns the value type of [value] if it represents a map value at runtime.
+  /// Returns [dynamicType] otherwise.
+  AbstractValue getMapValueType(AbstractValue value);
+
+  /// Compute the type of all potential receivers of the set of live [members].
+  AbstractValue computeReceiver(Iterable<MemberEntity> members);
+
+  /// Returns whether [member] is a potential target when being
+  /// invoked on a [receiver]. [selector] is used to ensure library privacy is
+  /// taken into account.
+  bool canHit(AbstractValue receiver, MemberEntity member, Selector selector);
+
+  /// Returns whether [selector] invoked on a [receiver] can hit a
+  /// [noSuchMethod].
+  bool needsNoSuchMethodHandling(AbstractValue receiver, Selector selector);
 }
diff --git a/pkg/compiler/lib/src/types/flat_type_mask.dart b/pkg/compiler/lib/src/types/flat_type_mask.dart
index 932a128..f83240a 100644
--- a/pkg/compiler/lib/src/types/flat_type_mask.dart
+++ b/pkg/compiler/lib/src/types/flat_type_mask.dart
@@ -62,7 +62,8 @@
     if (((flags >> 1) == SUBCLASS) && !world.hasAnyStrictSubclass(base)) {
       flags = (flags & 0x1) | (EXACT << 1);
     }
-    return world.getCachedMask(
+    CommonMasks commonMasks = world.abstractValueDomain;
+    return commonMasks.getCachedMask(
         base, flags, () => new FlatTypeMask.internal(base, flags));
   }
 
diff --git a/pkg/compiler/lib/src/types/masks.dart b/pkg/compiler/lib/src/types/masks.dart
index 24203e1..8e4916c 100644
--- a/pkg/compiler/lib/src/types/masks.dart
+++ b/pkg/compiler/lib/src/types/masks.dart
@@ -63,10 +63,22 @@
   TypeMask _indexablePrimitiveType;
   TypeMask _readableArrayType;
   TypeMask _mutableArrayType;
-  TypeMask _fixedArrayType;
   TypeMask _unmodifiableArrayType;
   TypeMask _interceptorType;
 
+  /// Cache of [FlatTypeMask]s grouped by the 8 possible values of the
+  /// `FlatTypeMask.flags` property.
+  final List<Map<ClassEntity, TypeMask>> _canonicalizedTypeMasks =
+      new List<Map<ClassEntity, TypeMask>>.filled(8, null);
+
+  /// Return the cached mask for [base] with the given flags, or
+  /// calls [createMask] to create the mask and cache it.
+  TypeMask getCachedMask(ClassEntity base, int flags, TypeMask createMask()) {
+    Map<ClassEntity, TypeMask> cachedMasks =
+        _canonicalizedTypeMasks[flags] ??= <ClassEntity, TypeMask>{};
+    return cachedMasks.putIfAbsent(base, createMask);
+  }
+
   TypeMask get dynamicType => _dynamicType ??= new TypeMask.subclass(
       _closedWorld.commonElements.objectClass, _closedWorld);
 
@@ -149,9 +161,6 @@
       _mutableArrayType ??= new TypeMask.nonNullSubclass(
           commonElements.jsMutableArrayClass, _closedWorld);
 
-  TypeMask get fixedArrayType => _fixedArrayType ??=
-      new TypeMask.nonNullExact(commonElements.jsFixedArrayClass, _closedWorld);
-
   TypeMask get unmodifiableArrayType =>
       _unmodifiableArrayType ??= new TypeMask.nonNullExact(
           commonElements.jsUnmodifiableArrayClass, _closedWorld);
@@ -375,4 +384,62 @@
   AbstractValue computeAbstractValueForConstant(ConstantValue value) {
     return computeTypeMask(_closedWorld, value);
   }
+
+  @override
+  AbstractValue getMapValueType(AbstractValue value) {
+    if (value is MapTypeMask) {
+      return value.valueType ?? dynamicType;
+    }
+    return dynamicType;
+  }
+
+  @override
+  AbstractValue getContainerElementType(AbstractValue value) {
+    if (value is ContainerTypeMask) {
+      return value.elementType ?? dynamicType;
+    }
+    return dynamicType;
+  }
+
+  @override
+  AbstractValue unionOfMany(List<AbstractValue> values) {
+    TypeMask result = const TypeMask.nonNullEmpty();
+    for (TypeMask value in values) {
+      result = result.union(value, _closedWorld);
+    }
+    return result;
+  }
+
+  @override
+  AbstractValue computeReceiver(Iterable<MemberEntity> members) {
+    assert(_closedWorld
+        .hasAnyStrictSubclass(_closedWorld.commonElements.objectClass));
+    return new TypeMask.unionOf(
+        members.expand((MemberEntity element) {
+          ClassEntity cls = element.enclosingClass;
+          return [cls]..addAll(_closedWorld.mixinUsesOf(cls));
+        }).map((cls) {
+          if (_closedWorld.commonElements.jsNullClass == cls) {
+            return const TypeMask.empty();
+          } else if (_closedWorld.isInstantiated(cls)) {
+            return new TypeMask.nonNullSubclass(cls, _closedWorld);
+          } else {
+            // TODO(johnniwinther): Avoid the need for this case.
+            return const TypeMask.empty();
+          }
+        }),
+        _closedWorld);
+  }
+
+  @override
+  bool canHit(
+      covariant TypeMask receiver, MemberEntity member, Selector selector) {
+    return receiver.canHit(member, selector, _closedWorld);
+  }
+
+  @override
+  bool needsNoSuchMethodHandling(
+      covariant TypeMask receiver, Selector selector) {
+    return receiver.needsNoSuchMethodHandling(selector, _closedWorld);
+  }
 }
diff --git a/pkg/compiler/lib/src/types/types.dart b/pkg/compiler/lib/src/types/types.dart
index 963a622..704157c 100644
--- a/pkg/compiler/lib/src/types/types.dart
+++ b/pkg/compiler/lib/src/types/types.dart
@@ -7,16 +7,11 @@
 import '../common.dart' show failedAt;
 import '../common/tasks.dart' show CompilerTask;
 import '../compiler.dart' show Compiler;
-import '../elements/elements.dart';
 import '../elements/entities.dart';
 import '../inferrer/type_graph_inferrer.dart' show TypeGraphInferrer;
-import '../tree/tree.dart';
 import '../universe/selector.dart' show Selector;
-import '../util/util.dart' show Maplet;
 import '../world.dart' show ClosedWorld, ClosedWorldRefiner;
-
-import 'masks.dart';
-export 'masks.dart';
+import 'abstract_value_domain.dart';
 
 /// Results about a single element (e.g. a method, parameter, or field)
 /// produced by the global type-inference algorithm.
@@ -34,37 +29,33 @@
 
   /// The inferred type when this result belongs to a parameter or field
   /// element, null otherwise.
-  TypeMask get type;
+  AbstractValue get type;
 
   /// The inferred return type when this result belongs to a function element.
-  TypeMask get returnType;
+  AbstractValue get returnType;
 
   /// Returns the type of a list new expression [node].
-  TypeMask typeOfNewList(T node);
+  AbstractValue typeOfNewList(T node);
 
   /// Returns the type of a list literal [node].
-  TypeMask typeOfListLiteral(T node);
+  AbstractValue typeOfListLiteral(T node);
 
   /// Returns the type of a send [node].
   // TODO(johnniwinther): Rename this.
-  TypeMask typeOfSend(T node);
+  AbstractValue typeOfSend(T node);
 
   /// Returns the type of the getter in a complex send-set [node], for example,
   /// the type of the `a.f` getter in `a.f += b`.
-  TypeMask typeOfGetter(T node);
-
-  /// Returns the type of the operator of a complex send-set [node], for
-  /// example, the type of `+` in `a += b`.
-  TypeMask typeOfOperator(T node);
+  AbstractValue typeOfGetter(T node);
 
   /// Returns the type of the iterator in a [loop].
-  TypeMask typeOfIterator(T node);
+  AbstractValue typeOfIterator(T node);
 
   /// Returns the type of the `moveNext` call of an iterator in a [loop].
-  TypeMask typeOfIteratorMoveNext(T node);
+  AbstractValue typeOfIteratorMoveNext(T node);
 
   /// Returns the type of the `current` getter of an iterator in a [loop].
-  TypeMask typeOfIteratorCurrent(T node);
+  AbstractValue typeOfIteratorCurrent(T node);
 }
 
 abstract class GlobalTypeInferenceMemberResult<T>
@@ -85,28 +76,27 @@
   // TODO(sigmund): store relevant data & drop reference to inference engine.
   final TypesInferrer<T> _inferrer;
   final bool _isJsInterop;
-  final TypeMask _dynamic;
 
   GlobalTypeInferenceElementResultImpl(
-      this._data, this._inferrer, this._isJsInterop, this._dynamic);
+      this._data, this._inferrer, this._isJsInterop);
 
   bool get throwsAlways {
-    TypeMask mask = this.returnType;
+    AbstractValue mask = this.returnType;
     // Always throws if the return type was inferred to be non-null empty.
-    return mask != null && mask.isEmpty;
+    return mask != null && _inferrer.abstractValueDomain.isEmpty(mask);
   }
 
-  TypeMask typeOfNewList(T node) => _inferrer.getTypeForNewList(node);
+  AbstractValue typeOfNewList(T node) => _inferrer.getTypeForNewList(node);
 
-  TypeMask typeOfListLiteral(T node) => _inferrer.getTypeForNewList(node);
+  AbstractValue typeOfListLiteral(T node) => _inferrer.getTypeForNewList(node);
 
-  TypeMask typeOfSend(T node) => _data?.typeOfSend(node);
-  TypeMask typeOfGetter(T node) => _data?.typeOfGetter(node);
-  TypeMask typeOfOperator(T node) => _data?.typeOfOperator(node);
-  TypeMask typeOfIterator(T node) => _data?.typeOfIterator(node);
-  TypeMask typeOfIteratorMoveNext(T node) =>
+  AbstractValue typeOfSend(T node) => _data?.typeOfSend(node);
+  AbstractValue typeOfGetter(T node) => _data?.typeOfGetter(node);
+  AbstractValue typeOfIterator(T node) => _data?.typeOfIterator(node);
+  AbstractValue typeOfIteratorMoveNext(T node) =>
       _data?.typeOfIteratorMoveNext(node);
-  TypeMask typeOfIteratorCurrent(T node) => _data?.typeOfIteratorCurrent(node);
+  AbstractValue typeOfIteratorCurrent(T node) =>
+      _data?.typeOfIteratorCurrent(node);
 }
 
 class GlobalTypeInferenceMemberResultImpl<T>
@@ -119,17 +109,18 @@
       this._owner,
       GlobalTypeInferenceElementData data,
       TypesInferrer inferrer,
-      bool isJsInterop,
-      TypeMask _dynamic)
-      : super(data, inferrer, isJsInterop, _dynamic);
+      bool isJsInterop)
+      : super(data, inferrer, isJsInterop);
 
   bool get isCalledOnce => _inferrer.isMemberCalledOnce(_owner);
 
-  TypeMask get returnType =>
-      _isJsInterop ? _dynamic : _inferrer.getReturnTypeOfMember(_owner);
+  AbstractValue get returnType => _isJsInterop
+      ? _inferrer.abstractValueDomain.dynamicType
+      : _inferrer.getReturnTypeOfMember(_owner);
 
-  TypeMask get type =>
-      _isJsInterop ? _dynamic : _inferrer.getTypeOfMember(_owner);
+  AbstractValue get type => _isJsInterop
+      ? _inferrer.abstractValueDomain.dynamicType
+      : _inferrer.getTypeOfMember(_owner);
 }
 
 class GlobalTypeInferenceParameterResultImpl<T>
@@ -138,107 +129,50 @@
   // TODO(sigmund): delete, store data directly here.
   final Local _owner;
 
-  GlobalTypeInferenceParameterResultImpl(
-      this._owner, TypesInferrer inferrer, TypeMask _dynamic)
-      : super(null, inferrer, false, _dynamic);
+  GlobalTypeInferenceParameterResultImpl(this._owner, TypesInferrer inferrer)
+      : super(null, inferrer, false);
 
-  TypeMask get returnType =>
-      _isJsInterop ? _dynamic : _inferrer.getReturnTypeOfParameter(_owner);
+  AbstractValue get returnType => _isJsInterop
+      ? _inferrer.abstractValueDomain.dynamicType
+      : _inferrer.getReturnTypeOfParameter(_owner);
 
-  TypeMask get type =>
-      _isJsInterop ? _dynamic : _inferrer.getTypeOfParameter(_owner);
+  AbstractValue get type => _isJsInterop
+      ? _inferrer.abstractValueDomain.dynamicType
+      : _inferrer.getTypeOfParameter(_owner);
 }
 
 /// Internal data used during type-inference to store intermediate results about
 /// a single element.
 abstract class GlobalTypeInferenceElementData<T> {
   // TODO(johnniwinther): Remove this. Maybe split by access/invoke.
-  TypeMask typeOfSend(T node);
-  TypeMask typeOfGetter(T node);
-  TypeMask typeOfOperator(T node);
+  AbstractValue typeOfSend(T node);
+  AbstractValue typeOfGetter(T node);
 
-  void setTypeMask(T node, TypeMask mask);
+  void setTypeMask(T node, AbstractValue mask);
 
-  void setGetterTypeMaskInComplexSendSet(T node, TypeMask mask);
+  AbstractValue typeOfIterator(T node);
 
-  void setOperatorTypeMaskInComplexSendSet(T node, TypeMask mask);
+  AbstractValue typeOfIteratorMoveNext(T node);
 
-  TypeMask typeOfIterator(T node);
+  AbstractValue typeOfIteratorCurrent(T node);
 
-  TypeMask typeOfIteratorMoveNext(T node);
+  void setIteratorTypeMask(T node, AbstractValue mask);
 
-  TypeMask typeOfIteratorCurrent(T node);
+  void setMoveNextTypeMask(T node, AbstractValue mask);
 
-  void setIteratorTypeMask(T node, TypeMask mask);
-
-  void setMoveNextTypeMask(T node, TypeMask mask);
-
-  void setCurrentTypeMask(T node, TypeMask mask);
-}
-
-class AstGlobalTypeInferenceElementData
-    extends GlobalTypeInferenceElementData<Node> {
-  Map<Object, TypeMask> _typeMasks;
-
-  TypeMask _get(Object node) => _typeMasks != null ? _typeMasks[node] : null;
-  void _set(Object node, TypeMask mask) {
-    _typeMasks ??= new Maplet<Object, TypeMask>();
-    _typeMasks[node] = mask;
-  }
-
-  TypeMask typeOfSend(covariant Send node) => _get(node);
-  TypeMask typeOfGetter(covariant SendSet node) => _get(node.selector);
-  TypeMask typeOfOperator(covariant SendSet node) =>
-      _get(node.assignmentOperator);
-
-  void setTypeMask(covariant Send node, TypeMask mask) {
-    _set(node, mask);
-  }
-
-  void setGetterTypeMaskInComplexSendSet(
-      covariant SendSet node, TypeMask mask) {
-    _set(node.selector, mask);
-  }
-
-  void setOperatorTypeMaskInComplexSendSet(
-      covariant SendSet node, TypeMask mask) {
-    _set(node.assignmentOperator, mask);
-  }
-
-  // TODO(sigmund): clean up. We store data about 3 selectors for "for in"
-  // nodes: the iterator, move-next, and current element. Because our map keys
-  // are nodes, we need to fabricate different keys to keep these selectors
-  // separate. The current implementation does this by using
-  // children of the for-in node (these children were picked arbitrarily).
-
-  TypeMask typeOfIterator(covariant ForIn node) => _get(node);
-
-  TypeMask typeOfIteratorMoveNext(covariant ForIn node) => _get(node.forToken);
-
-  TypeMask typeOfIteratorCurrent(covariant ForIn node) => _get(node.inToken);
-
-  void setIteratorTypeMask(covariant ForIn node, TypeMask mask) {
-    _set(node, mask);
-  }
-
-  void setMoveNextTypeMask(covariant ForIn node, TypeMask mask) {
-    _set(node.forToken, mask);
-  }
-
-  void setCurrentTypeMask(covariant ForIn node, TypeMask mask) {
-    _set(node.inToken, mask);
-  }
+  void setCurrentTypeMask(T node, AbstractValue mask);
 }
 
 /// API to interact with the global type-inference engine.
 abstract class TypesInferrer<T> {
+  AbstractValueDomain get abstractValueDomain;
   void analyzeMain(FunctionEntity element);
-  TypeMask getReturnTypeOfMember(MemberEntity element);
-  TypeMask getReturnTypeOfParameter(Local element);
-  TypeMask getTypeOfMember(MemberEntity element);
-  TypeMask getTypeOfParameter(Local element);
-  TypeMask getTypeForNewList(T node);
-  TypeMask getTypeOfSelector(Selector selector, TypeMask mask);
+  AbstractValue getReturnTypeOfMember(MemberEntity element);
+  AbstractValue getReturnTypeOfParameter(Local element);
+  AbstractValue getTypeOfMember(MemberEntity element);
+  AbstractValue getTypeOfParameter(Local element);
+  AbstractValue getTypeForNewList(T node);
+  AbstractValue getTypeOfSelector(Selector selector, AbstractValue receiver);
   void clear();
   bool isMemberCalledOnce(MemberEntity element);
   bool isFixedArrayCheckedForGrowable(T node);
@@ -293,11 +227,9 @@
         parameter, () => createParameterResult(_inferrer, parameter));
   }
 
-  TypeMask get dynamicType => closedWorld.abstractValueDomain.dynamicType;
-
   /// Returns the type of a [selector] when applied to a receiver with the given
   /// type [mask].
-  TypeMask typeOfSelector(Selector selector, TypeMask mask) =>
+  AbstractValue typeOfSelector(Selector selector, AbstractValue mask) =>
       _inferrer.getTypeOfSelector(selector, mask);
 
   /// Returns whether a fixed-length constructor call goes through a growable
@@ -308,56 +240,6 @@
       _inferrer.isFixedArrayCheckedForGrowable(ctorCall);
 }
 
-/// Mixin that assert the types of the nodes used for querying type masks.
-abstract class AstGlobalTypeInferenceElementResultMixin
-    implements GlobalTypeInferenceElementResultImpl<Node> {
-  TypeMask typeOfNewList(covariant Send node) =>
-      _inferrer.getTypeForNewList(node);
-
-  TypeMask typeOfListLiteral(covariant LiteralList node) =>
-      _inferrer.getTypeForNewList(node);
-
-  TypeMask typeOfSend(covariant Send node) => _data?.typeOfSend(node);
-  TypeMask typeOfGetter(covariant SendSet node) => _data?.typeOfGetter(node);
-  TypeMask typeOfOperator(covariant SendSet node) =>
-      _data?.typeOfOperator(node);
-  TypeMask typeOfIterator(covariant ForIn node) => _data?.typeOfIterator(node);
-  TypeMask typeOfIteratorMoveNext(covariant ForIn node) =>
-      _data?.typeOfIteratorMoveNext(node);
-  TypeMask typeOfIteratorCurrent(covariant ForIn node) =>
-      _data?.typeOfIteratorCurrent(node);
-}
-
-class AstMemberResult = GlobalTypeInferenceMemberResultImpl<Node>
-    with AstGlobalTypeInferenceElementResultMixin;
-
-class AstParameterResult = GlobalTypeInferenceParameterResultImpl<Node>
-    with AstGlobalTypeInferenceElementResultMixin;
-
-class AstGlobalTypeInferenceResults extends GlobalTypeInferenceResults<Node> {
-  AstGlobalTypeInferenceResults(
-      TypesInferrer<Node> inferrer, ClosedWorld closedWorld)
-      : super(inferrer, closedWorld);
-
-  GlobalTypeInferenceMemberResult<Node> createMemberResult(
-      TypeGraphInferrer<Node> inferrer, covariant MemberElement member,
-      {bool isJsInterop: false}) {
-    return new AstMemberResult(
-        member,
-        // We store data in the context of the enclosing method, even
-        // for closure elements.
-        inferrer.inferrer.lookupDataOfMember(member.memberContext),
-        inferrer,
-        isJsInterop,
-        dynamicType);
-  }
-
-  GlobalTypeInferenceParameterResult<Node> createParameterResult(
-      TypeGraphInferrer<Node> inferrer, Local parameter) {
-    return new AstParameterResult(parameter, inferrer, dynamicType);
-  }
-}
-
 /// Global analysis that infers concrete types.
 class GlobalTypeInferenceTask extends CompilerTask {
   // TODO(sigmund): rename at the same time as our benchmarking tools.
diff --git a/pkg/compiler/lib/src/universe/class_hierarchy_builder.dart b/pkg/compiler/lib/src/universe/class_hierarchy_builder.dart
index c6cf563..337975f 100644
--- a/pkg/compiler/lib/src/universe/class_hierarchy_builder.dart
+++ b/pkg/compiler/lib/src/universe/class_hierarchy_builder.dart
@@ -4,7 +4,6 @@
 
 import '../common.dart';
 import '../common_elements.dart';
-import '../elements/elements.dart' show ClassElement, MixinApplicationElement;
 import '../elements/entities.dart';
 import '../elements/types.dart' show InterfaceType;
 import 'class_set.dart';
@@ -180,43 +179,3 @@
   /// Returns all supertypes of [cls].
   Iterable<InterfaceType> getSupertypes(covariant ClassEntity cls);
 }
-
-class ElementClassQueries extends ClassQueries {
-  final CommonElements commonElements;
-
-  ElementClassQueries(this.commonElements);
-
-  @override
-  ClassEntity getDeclaration(ClassElement cls) {
-    return cls.declaration;
-  }
-
-  @override
-  ClassEntity getAppliedMixin(ClassElement cls) {
-    if (cls.isMixinApplication) {
-      MixinApplicationElement mixinApplication = cls;
-      // Note: If [mixinApplication] is malformed [mixin] is `null`.
-      return mixinApplication.mixin;
-    }
-    return null;
-  }
-
-  @override
-  int getHierarchyDepth(ClassElement cls) => cls.hierarchyDepth;
-
-  @override
-  bool checkClass(ClassElement cls) => cls.isDeclaration;
-
-  @override
-  bool validateClass(ClassElement cls) => cls.isResolved;
-
-  @override
-  bool implementsFunction(ClassElement cls) =>
-      cls.implementsFunction(commonElements);
-
-  @override
-  ClassEntity getSuperClass(ClassElement cls) => cls.superclass;
-
-  @override
-  Iterable<InterfaceType> getSupertypes(ClassElement cls) => cls.allSupertypes;
-}
diff --git a/pkg/compiler/lib/src/universe/class_set.dart b/pkg/compiler/lib/src/universe/class_set.dart
index c5a4869..3dd5e16 100644
--- a/pkg/compiler/lib/src/universe/class_set.dart
+++ b/pkg/compiler/lib/src/universe/class_set.dart
@@ -6,7 +6,6 @@
 
 import 'dart:collection' show IterableBase;
 
-import '../elements/elements.dart' show ClassElement;
 import '../elements/entities.dart' show ClassEntity;
 import '../util/enumset.dart' show EnumSet;
 import '../util/util.dart' show Link;
@@ -342,11 +341,12 @@
   void printOn(StringBuffer sb, String indentation,
       {bool instantiatedOnly: false,
       bool sorted: true,
-      ClassElement withRespectTo}) {
+      ClassEntity withRespectTo}) {
     bool isRelatedTo(ClassEntity _subclass) {
-      ClassElement subclass = _subclass;
-      return subclass == withRespectTo ||
-          subclass.implementsInterface(withRespectTo);
+      return true;
+      // TODO(johnniwinther): Support this for kernel based elements:
+      // return subclass == withRespectTo ||
+      //    subclass.implementsInterface(withRespectTo);
     }
 
     sb.write(indentation);
@@ -406,7 +406,7 @@
   String dump(
       {String indentation: '',
       bool instantiatedOnly: false,
-      ClassElement withRespectTo}) {
+      ClassEntity withRespectTo}) {
     StringBuffer sb = new StringBuffer();
     printOn(sb, indentation,
         instantiatedOnly: instantiatedOnly, withRespectTo: withRespectTo);
diff --git a/pkg/compiler/lib/src/universe/codegen_world_builder.dart b/pkg/compiler/lib/src/universe/codegen_world_builder.dart
index 12c547a0..2476b2b 100644
--- a/pkg/compiler/lib/src/universe/codegen_world_builder.dart
+++ b/pkg/compiler/lib/src/universe/codegen_world_builder.dart
@@ -637,104 +637,6 @@
   }
 }
 
-class ElementCodegenWorldBuilderImpl extends CodegenWorldBuilderImpl {
-  final JavaScriptConstantCompiler _constants;
-
-  ElementCodegenWorldBuilderImpl(
-      this._constants,
-      ElementEnvironment elementEnvironment,
-      NativeBasicData nativeBasicData,
-      ClosedWorld world,
-      SelectorConstraintsStrategy selectorConstraintsStrategy)
-      : super(elementEnvironment, nativeBasicData, world,
-            selectorConstraintsStrategy);
-
-  @override
-  bool hasConstantFieldInitializer(FieldElement field) {
-    return field.constant != null;
-  }
-
-  @override
-  ConstantValue getConstantFieldInitializer(FieldElement field) {
-    assert(field.constant != null,
-        failedAt(field, "Field $field doesn't have a constant initial value."));
-    return _constants.getConstantValue(field.constant);
-  }
-
-  /// Calls [f] with every instance field, together with its declarer, in an
-  /// instance of [cls].
-  void forEachInstanceField(
-      ClassElement cls, void f(ClassEntity declarer, FieldEntity field)) {
-    cls.implementation
-        .forEachInstanceField(f, includeSuperAndInjectedMembers: true);
-  }
-
-  /// Calls [f] with every instance field of the immediate class [cls].
-  void forEachDirectInstanceField(ClassElement cls, void f(FieldEntity field)) {
-    cls.implementation.forEachInstanceField((ClassEntity _, FieldEntity field) {
-      f(field);
-    }, includeSuperAndInjectedMembers: false);
-  }
-
-  @override
-  void forEachParameter(MethodElement function,
-      void f(DartType type, String name, ConstantValue defaultValue)) {
-    if (!function.hasFunctionSignature) return;
-    function = function.implementation;
-    FunctionSignature parameters = function.functionSignature;
-    parameters.orderedForEachParameter((_parameter) {
-      ParameterElement parameter = _parameter;
-      ConstantValue value;
-      if (parameter.isOptional) {
-        value = _constants.getConstantValue(parameter.constant);
-      }
-      f(parameter.type, parameter.name, value);
-    });
-  }
-
-  @override
-  void forEachParameterAsLocal(
-      MethodElement function, void f(Local parameter)) {
-    if (!function.hasFunctionSignature) return;
-    function = function.implementation;
-    FunctionSignature parameters = function.functionSignature;
-    parameters.orderedForEachParameter((_parameter) {
-      ParameterElement parameter = _parameter;
-      f(parameter);
-    });
-  }
-
-  @override
-  void _processInstantiatedClassMember(
-      ClassEntity cls, MemberElement member, MemberUsedCallback memberUsed) {
-    assert(member.isDeclaration, failedAt(member));
-    if (member.isMalformed) return;
-    super._processInstantiatedClassMember(cls, member, memberUsed);
-  }
-
-  @override
-  _MemberUsage _getMemberUsage(
-      MemberElement member, MemberUsedCallback memberUsed) {
-    assert(member.isDeclaration, failedAt(member));
-    return super._getMemberUsage(member, memberUsed);
-  }
-
-  void registerStaticUse(StaticUse staticUse, MemberUsedCallback memberUsed) {
-    Element element = staticUse.element;
-    assert(element.isDeclaration,
-        failedAt(element, "Element ${element} is not the declaration."));
-    super.registerStaticUse(staticUse, memberUsed);
-  }
-
-  void registerIsCheck(ResolutionDartType type) {
-    // Even in checked mode, type annotations for return type and argument
-    // types do not imply type checks, so there should never be a check
-    // against the type variable of a typedef.
-    assert(!type.isTypeVariable || !type.element.enclosingElement.isTypedef);
-    super.registerIsCheck(type);
-  }
-}
-
 class KernelCodegenWorldBuilder extends CodegenWorldBuilderImpl {
   final KernelToWorldBuilder _elementMap;
   final GlobalLocalsMap _globalLocalsMap;
diff --git a/pkg/compiler/lib/src/universe/element_world_builder.dart b/pkg/compiler/lib/src/universe/element_world_builder.dart
deleted file mode 100644
index 5b25897..0000000
--- a/pkg/compiler/lib/src/universe/element_world_builder.dart
+++ /dev/null
@@ -1,178 +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.
-
-part of world_builder;
-
-/// [ResolutionEnqueuerWorldBuilder] based on the [Element] model.
-class ElementResolutionWorldBuilder extends ResolutionWorldBuilderBase {
-  /// Used for testing the new more precise computation of instantiated types
-  /// and classes.
-  static bool useInstantiationMap = false;
-
-  final Resolution _resolution;
-
-  ElementResolutionWorldBuilder(
-      JavaScriptBackend backend,
-      this._resolution,
-      NativeBasicData nativeBasicData,
-      NativeDataBuilder nativeDataBuilder,
-      InterceptorDataBuilder interceptorDataBuilder,
-      BackendUsageBuilder backendUsageBuilder,
-      RuntimeTypesNeedBuilder rtiNeedBuilder,
-      NativeResolutionEnqueuer nativeResolutionEnqueuer,
-      NoSuchMethodRegistry noSuchMethodRegistry,
-      SelectorConstraintsStrategy selectorConstraintsStrategy,
-      ClassHierarchyBuilder classHierarchyBuilder,
-      ClassQueries classQueries)
-      : super(
-            backend.compiler.options,
-            _resolution.elementEnvironment,
-            _resolution.types,
-            _resolution.commonElements,
-            backend.constantSystem,
-            nativeBasicData,
-            nativeDataBuilder,
-            interceptorDataBuilder,
-            backendUsageBuilder,
-            rtiNeedBuilder,
-            nativeResolutionEnqueuer,
-            noSuchMethodRegistry,
-            selectorConstraintsStrategy,
-            classHierarchyBuilder,
-            classQueries);
-
-  bool isImplemented(ClassElement cls) {
-    return super.isImplemented(cls.declaration);
-  }
-
-  void registerTypeInstantiation(
-      InterfaceType type, ClassUsedCallback classUsed,
-      {ConstructorEntity constructor,
-      bool byMirrors: false,
-      bool isRedirection: false}) {
-    ClassElement cls = type.element;
-    cls.ensureResolved(_resolution);
-    super.registerTypeInstantiation(type, classUsed,
-        constructor: constructor,
-        byMirrors: byMirrors,
-        isRedirection: isRedirection);
-  }
-
-  /// Returns the instantiation map used for computing the closed world.
-  ///
-  /// If [useInstantiationMap] is `true`, redirections are removed and
-  /// redirecting factories are converted to their effective target and type.
-  Map<ClassEntity, InstantiationInfo> getInstantiationMap() {
-    if (!useInstantiationMap) return _instantiationInfo;
-
-    Map<ClassEntity, InstantiationInfo> instantiationMap =
-        <ClassEntity, InstantiationInfo>{};
-
-    InstantiationInfo infoFor(ClassEntity cls) {
-      return instantiationMap.putIfAbsent(cls, () => new InstantiationInfo());
-    }
-
-    _instantiationInfo.forEach((cls, info) {
-      if (info.instantiationMap != null) {
-        info.instantiationMap.forEach((_constructor, Set<Instance> set) {
-          ConstructorElement constructor = _constructor;
-          for (Instance instance in set) {
-            if (instance.isRedirection) {
-              continue;
-            }
-            if (constructor == null || !constructor.isRedirectingFactory) {
-              infoFor(cls)
-                  .addInstantiation(constructor, instance.type, instance.kind);
-            } else {
-              ConstructorElement target = constructor.effectiveTarget;
-              ResolutionDartType targetType =
-                  constructor.computeEffectiveTargetType(instance.type);
-              ClassElement cls = target.enclosingClass;
-              bool isNative = _nativeBasicData.isNativeClass(cls);
-              Instantiation kind;
-              if (isNative) {
-                kind = Instantiation.ABSTRACTLY_INSTANTIATED;
-              } else if (cls.isAbstract) {
-                kind = Instantiation.UNINSTANTIATED;
-              } else {
-                kind = Instantiation.DIRECTLY_INSTANTIATED;
-              }
-              if (targetType is ResolutionInterfaceType) {
-                infoFor(targetType.element)
-                    .addInstantiation(target, targetType, kind);
-              }
-            }
-          }
-        });
-      }
-    });
-    return instantiationMap;
-  }
-
-  void registerIsCheck(ResolutionDartType type) {
-    type.computeUnaliased(_resolution);
-    type = type.unaliased;
-    // Even in checked mode, type annotations for return type and argument
-    // types do not imply type checks, so there should never be a check
-    // against the type variable of a typedef.
-    assert(!type.isTypeVariable || !type.element.enclosingElement.isTypedef);
-    super.registerIsCheck(type);
-  }
-
-  void registerStaticUse(StaticUse staticUse, MemberUsedCallback memberUsed) {
-    Element element = staticUse.element;
-    assert(element.isDeclaration,
-        failedAt(element, "Element ${element} is not the declaration."));
-    super.registerStaticUse(staticUse, memberUsed);
-  }
-
-  _ClassUsage _createClassUsage(ClassElement cls) {
-    cls.ensureResolved(_resolution);
-    _resolution.ensureClassMembers(cls);
-    return super._createClassUsage(cls);
-  }
-
-  void _processInstantiatedClassMember(
-      ClassEntity cls, MemberElement member, MemberUsedCallback memberUsed) {
-    assert(member.isDeclaration, failedAt(member));
-    member.computeType(_resolution);
-    super._processInstantiatedClassMember(cls, member, memberUsed);
-  }
-
-  ClosedWorld closeWorld() {
-    Map<ClassEntity, Set<ClassEntity>> typesImplementedBySubclasses =
-        populateHierarchyNodes();
-    _closed = true;
-
-    return _closedWorldCache = new ClosedWorldImpl(
-        options: _options,
-        elementEnvironment: _elementEnvironment,
-        dartTypes: _dartTypes,
-        commonElements: _commonElements,
-        constantSystem: _constantSystem,
-        nativeData: _nativeDataBuilder.close(),
-        interceptorData: _interceptorDataBuilder.close(),
-        backendUsage: _backendUsageBuilder.close(),
-        noSuchMethodData: _noSuchMethodRegistry.close(),
-        resolutionWorldBuilder: this,
-        rtiNeedBuilder: _rtiNeedBuilder,
-        implementedClasses: _implementedClasses,
-        liveNativeClasses: _nativeResolutionEnqueuer.liveNativeClasses,
-        liveInstanceMembers: _liveInstanceMembers,
-        assignedInstanceMembers: computeAssignedInstanceMembers(),
-        processedMembers: _processedMembers,
-        allTypedefs: _allTypedefs,
-        mixinUses: classHierarchyBuilder.mixinUses,
-        typesImplementedBySubclasses: typesImplementedBySubclasses,
-        classHierarchyNodes: classHierarchyBuilder.classHierarchyNodes,
-        classSets: classHierarchyBuilder.classSets);
-  }
-
-  @override
-  void forEachLocalFunction(void f(MemberEntity member, Local localFunction)) {
-    for (LocalFunctionElement local in localFunctions) {
-      f(local.memberContext, local);
-    }
-  }
-}
diff --git a/pkg/compiler/lib/src/universe/function_set.dart b/pkg/compiler/lib/src/universe/function_set.dart
index 01f27b2..aee80f5 100644
--- a/pkg/compiler/lib/src/universe/function_set.dart
+++ b/pkg/compiler/lib/src/universe/function_set.dart
@@ -6,11 +6,9 @@
 
 import '../common/names.dart' show Identifiers, Selectors;
 import '../elements/entities.dart';
-import '../types/types.dart';
+import '../types/abstract_value_domain.dart';
 import '../util/util.dart' show Hashing, Setlet;
-import '../world.dart' show ClosedWorld;
 import 'selector.dart' show Selector;
-import 'world_builder.dart' show ReceiverConstraint;
 
 // TODO(kasperl): This actually holds getters and setters just fine
 // too and stricly they aren't functions. Maybe this needs a better
@@ -41,9 +39,9 @@
   /// receiver with the given [constraint]. The returned elements may include
   /// noSuchMethod handlers that are potential targets indirectly through the
   /// noSuchMethod mechanism.
-  Iterable<MemberEntity> filter(Selector selector,
-      ReceiverConstraint constraint, ClosedWorld closedWorld) {
-    return query(selector, constraint, closedWorld).functions;
+  Iterable<MemberEntity> filter(
+      Selector selector, AbstractValue receiver, AbstractValueDomain domain) {
+    return query(selector, receiver, domain).functions;
   }
 
   /// Returns the mask for the potential receivers of a dynamic call to
@@ -52,43 +50,38 @@
   /// This will narrow the constraints of [constraint] to a [TypeMask] of the
   /// set of classes that actually implement the selected member or implement
   /// the handling 'noSuchMethod' where the selected member is unimplemented.
-  TypeMask receiverType(Selector selector, ReceiverConstraint constraint,
-      ClosedWorld closedWorld) {
-    return query(selector, constraint, closedWorld).computeMask(closedWorld);
+  AbstractValue receiverType(
+      Selector selector, AbstractValue receiver, AbstractValueDomain domain) {
+    return query(selector, receiver, domain).computeMask(domain);
   }
 
-  SelectorMask _createSelectorMask(Selector selector,
-      ReceiverConstraint constraint, ClosedWorld closedWorld) {
-    return constraint != null
-        ? new SelectorMask(selector, constraint)
-        : new SelectorMask(
-            selector,
-            new TypeMask.subclass(
-                closedWorld.commonElements.objectClass, closedWorld));
+  SelectorMask _createSelectorMask(
+      Selector selector, AbstractValue receiver, AbstractValueDomain domain) {
+    return receiver != null
+        ? new SelectorMask(selector, receiver)
+        : new SelectorMask(selector, domain.dynamicType);
   }
 
   /// Returns the set of functions that can be the target of a call to
   /// [selector] on a receiver constrained by [constraint] including
   /// 'noSuchMethod' methods where applicable.
-  FunctionSetQuery query(Selector selector, ReceiverConstraint constraint,
-      ClosedWorld closedWorld) {
+  FunctionSetQuery query(
+      Selector selector, AbstractValue receiver, AbstractValueDomain domain) {
     String name = selector.name;
-    SelectorMask selectorMask =
-        _createSelectorMask(selector, constraint, closedWorld);
+    SelectorMask selectorMask = _createSelectorMask(selector, receiver, domain);
     SelectorMask noSuchMethodMask =
-        new SelectorMask(Selectors.noSuchMethod_, selectorMask.constraint);
+        new SelectorMask(Selectors.noSuchMethod_, selectorMask.receiver);
     FunctionSetNode node = _nodes[name];
     FunctionSetNode noSuchMethods = _nodes[Identifiers.noSuchMethod_];
     if (node != null) {
-      return node.query(
-          selectorMask, closedWorld, noSuchMethods, noSuchMethodMask);
+      return node.query(selectorMask, domain, noSuchMethods, noSuchMethodMask);
     }
     // If there is no method that matches [selector] we know we can
     // only hit [:noSuchMethod:].
     if (noSuchMethods == null) {
       return const EmptyFunctionSetQuery();
     }
-    return noSuchMethods.query(noSuchMethodMask, closedWorld);
+    return noSuchMethods.query(noSuchMethodMask, domain);
   }
 
   void forEach(void action(MemberEntity member)) {
@@ -102,34 +95,32 @@
 /// on a receiver constrained by [constraint].
 class SelectorMask {
   final Selector selector;
-  final ReceiverConstraint constraint;
+  final AbstractValue receiver;
   final int hashCode;
 
-  SelectorMask(Selector selector, ReceiverConstraint constraint)
-      : this.selector = selector,
-        this.constraint = constraint,
-        this.hashCode =
-            Hashing.mixHashCodeBits(selector.hashCode, constraint.hashCode) {
-    assert(constraint != null);
+  SelectorMask(this.selector, this.receiver)
+      : this.hashCode =
+            Hashing.mixHashCodeBits(selector.hashCode, receiver.hashCode) {
+    assert(receiver != null);
   }
 
   String get name => selector.name;
 
-  bool applies(MemberEntity element, ClosedWorld closedWorld) {
+  bool applies(MemberEntity element, AbstractValueDomain domain) {
     if (!selector.appliesUnnamed(element)) return false;
-    return constraint.canHit(element, selector, closedWorld);
+    return domain.canHit(receiver, element, selector);
   }
 
-  bool needsNoSuchMethodHandling(ClosedWorld closedWorld) {
-    return constraint.needsNoSuchMethodHandling(selector, closedWorld);
+  bool needsNoSuchMethodHandling(AbstractValueDomain domain) {
+    return domain.needsNoSuchMethodHandling(receiver, selector);
   }
 
   bool operator ==(other) {
     if (identical(this, other)) return true;
-    return selector == other.selector && constraint == other.constraint;
+    return selector == other.selector && receiver == other.receiver;
   }
 
-  String toString() => '($selector,$constraint)';
+  String toString() => '($selector,$receiver)';
 }
 
 /// A node in the [FunctionSet] caching all [FunctionSetQuery] object for
@@ -202,7 +193,7 @@
 
   /// Returns the set of functions that can be the target of [selectorMask]
   /// including no such method handling where applicable.
-  FunctionSetQuery query(SelectorMask selectorMask, ClosedWorld closedWorld,
+  FunctionSetQuery query(SelectorMask selectorMask, AbstractValueDomain domain,
       [FunctionSetNode noSuchMethods, SelectorMask noSuchMethodMask]) {
     assert(selectorMask.name == name);
     FunctionSetQuery result = cache[selectorMask];
@@ -210,7 +201,7 @@
 
     Setlet<MemberEntity> functions;
     for (MemberEntity element in elements) {
-      if (selectorMask.applies(element, closedWorld)) {
+      if (selectorMask.applies(element, domain)) {
         if (functions == null) {
           // Defer the allocation of the functions set until we are
           // sure we need it. This allows us to return immutable empty
@@ -225,9 +216,9 @@
     // add [noSuchMethod] implementations that apply to [mask] as
     // potential targets.
     if (noSuchMethods != null &&
-        selectorMask.needsNoSuchMethodHandling(closedWorld)) {
+        selectorMask.needsNoSuchMethodHandling(domain)) {
       FunctionSetQuery noSuchMethodQuery =
-          noSuchMethods.query(noSuchMethodMask, closedWorld);
+          noSuchMethods.query(noSuchMethodMask, domain);
       if (!noSuchMethodQuery.functions.isEmpty) {
         if (functions == null) {
           functions =
@@ -263,7 +254,7 @@
   const FunctionSetQuery();
 
   /// Compute the type of all potential receivers of this function set.
-  TypeMask computeMask(ClosedWorld closedWorld);
+  AbstractValue computeMask(AbstractValueDomain domain);
 
   /// Returns all potential targets of this function set.
   Iterable<MemberEntity> get functions;
@@ -273,8 +264,7 @@
   const EmptyFunctionSetQuery();
 
   @override
-  TypeMask computeMask(ClosedWorld closedWorld) =>
-      const TypeMask.nonNullEmpty();
+  AbstractValue computeMask(AbstractValueDomain domain) => domain.emptyType;
 
   @override
   Iterable<MemberEntity> get functions => const <MemberEntity>[];
@@ -286,31 +276,14 @@
   @override
   final Iterable<MemberEntity> functions;
 
-  TypeMask _mask;
+  AbstractValue _receiver;
 
   FullFunctionSetQuery(this.functions);
 
   @override
-  TypeMask computeMask(ClosedWorld closedWorld) {
-    assert(closedWorld
-        .hasAnyStrictSubclass(closedWorld.commonElements.objectClass));
-    if (_mask != null) return _mask;
-    return _mask = new TypeMask.unionOf(
-        functions.expand((MemberEntity element) {
-          ClassEntity cls = element.enclosingClass;
-          return [cls]..addAll(closedWorld.mixinUsesOf(cls));
-        }).map((cls) {
-          if (closedWorld.commonElements.jsNullClass == cls) {
-            return const TypeMask.empty();
-          } else if (closedWorld.isInstantiated(cls)) {
-            return new TypeMask.nonNullSubclass(cls, closedWorld);
-          } else {
-            // TODO(johnniwinther): Avoid the need for this case.
-            return const TypeMask.empty();
-          }
-        }),
-        closedWorld);
+  AbstractValue computeMask(AbstractValueDomain domain) {
+    return _receiver ??= domain.computeReceiver(functions);
   }
 
-  String toString() => '$_mask:$functions';
+  String toString() => '$_receiver:$functions';
 }
diff --git a/pkg/compiler/lib/src/universe/selector.dart b/pkg/compiler/lib/src/universe/selector.dart
index 3d03614..d4af193 100644
--- a/pkg/compiler/lib/src/universe/selector.dart
+++ b/pkg/compiler/lib/src/universe/selector.dart
@@ -6,8 +6,8 @@
 
 import '../common.dart';
 import '../common/names.dart' show Names;
-import '../elements/elements.dart' show Elements;
 import '../elements/entities.dart';
+import '../elements/entity_utils.dart' as utils;
 import '../elements/names.dart';
 import '../elements/operators.dart';
 import '../util/util.dart' show Hashing;
@@ -153,12 +153,12 @@
 
   factory Selector.unaryOperator(String name) => new Selector(
       SelectorKind.OPERATOR,
-      new PublicName(Elements.constructOperatorName(name, true)),
+      new PublicName(utils.constructOperatorName(name, true)),
       CallStructure.NO_ARGS);
 
   factory Selector.binaryOperator(String name) => new Selector(
       SelectorKind.OPERATOR,
-      new PublicName(Elements.constructOperatorName(name, false)),
+      new PublicName(utils.constructOperatorName(name, false)),
       CallStructure.ONE_ARG);
 
   factory Selector.index() =>
diff --git a/pkg/compiler/lib/src/universe/use.dart b/pkg/compiler/lib/src/universe/use.dart
index d5c894e..0fcec7e 100644
--- a/pkg/compiler/lib/src/universe/use.dart
+++ b/pkg/compiler/lib/src/universe/use.dart
@@ -16,11 +16,9 @@
 /// program.
 library dart2js.universe.use;
 
-import '../closure.dart' show BoxFieldElement;
 import '../common.dart';
 import '../constants/values.dart';
 import '../elements/types.dart';
-import '../elements/elements.dart' show Element;
 import '../elements/entities.dart';
 import '../js_model/closure.dart';
 import '../util/util.dart' show equalElements, Hashing;
@@ -43,6 +41,29 @@
 
   DynamicUse(this.selector);
 
+  /// Short textual representation use for testing.
+  String get shortText {
+    StringBuffer sb = new StringBuffer();
+    sb.write(selector.name);
+    if (typeArguments != null && typeArguments.isNotEmpty) {
+      sb.write('<');
+      sb.write(typeArguments.join(','));
+      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(')');
+    } else if (selector.isSetter) {
+      sb.write('=');
+    }
+    return sb.toString();
+  }
+
   bool appliesUnnamed(MemberEntity element, World world) {
     return selector.appliesUnnamed(element) &&
         (mask == null || mask.canHit(element, selector, world));
@@ -149,11 +170,52 @@
       {this.type, this.callStructure, typeArgumentsHash: 0})
       : this.element = element,
         this.hashCode = Hashing.objectsHash(
-            element, kind, type, typeArgumentsHash, callStructure) {
-    assert(
-        !(element is Element && !element.isDeclaration),
-        failedAt(element,
-            "Static use element $element must be the declaration element."));
+            element, kind, type, typeArgumentsHash, callStructure);
+
+  /// Short textual representation use for testing.
+  String get shortText {
+    StringBuffer sb = new StringBuffer();
+    switch (kind) {
+      case StaticUseKind.FIELD_SET:
+      case StaticUseKind.SUPER_FIELD_SET:
+      case StaticUseKind.SET:
+        sb.write('set:');
+        break;
+      case StaticUseKind.INIT:
+        sb.write('init:');
+        break;
+      case StaticUseKind.CLOSURE:
+        sb.write('def:');
+        break;
+      default:
+    }
+    if (element is MemberEntity) {
+      MemberEntity member = element;
+      if (member.enclosingClass != null) {
+        sb.write(member.enclosingClass.name);
+        sb.write('.');
+      }
+    }
+    if (element.name == null) {
+      sb.write('<anonymous>');
+    } else {
+      sb.write(element.name);
+    }
+    if (typeArguments != null && typeArguments.isNotEmpty) {
+      sb.write('<');
+      sb.write(typeArguments.join(','));
+      sb.write('>');
+    }
+    if (callStructure != null) {
+      sb.write('(');
+      sb.write(callStructure.positionalArgumentCount);
+      if (callStructure.namedArgumentCount > 0) {
+        sb.write(',');
+        sb.write(callStructure.getOrderedNamedArguments().join(','));
+      }
+      sb.write(')');
+    }
+    return sb.toString();
   }
 
   List<DartType> get typeArguments => null;
@@ -417,9 +479,7 @@
   /// Read access of an instance field or boxed field [element].
   factory StaticUse.fieldGet(FieldEntity element) {
     assert(
-        element.isInstanceMember ||
-            element is BoxFieldElement ||
-            element is JRecordField,
+        element.isInstanceMember || element is JRecordField,
         failedAt(element,
             "Field init element $element must be an instance or boxed field."));
     return new StaticUse.internal(element, StaticUseKind.FIELD_GET);
@@ -428,9 +488,7 @@
   /// Write access of an instance field or boxed field [element].
   factory StaticUse.fieldSet(FieldEntity element) {
     assert(
-        element.isInstanceMember ||
-            element is BoxFieldElement ||
-            element is JRecordField,
+        element.isInstanceMember || element is JRecordField,
         failedAt(element,
             "Field init element $element must be an instance or boxed field."));
     return new StaticUse.internal(element, StaticUseKind.FIELD_SET);
@@ -533,6 +591,45 @@
         this.kind = kind,
         this.hashCode = Hashing.objectHash(type, Hashing.objectHash(kind));
 
+  /// Short textual representation use for testing.
+  String get shortText {
+    StringBuffer sb = new StringBuffer();
+    switch (kind) {
+      case TypeUseKind.IS_CHECK:
+        sb.write('is:');
+        break;
+      case TypeUseKind.AS_CAST:
+        sb.write('as:');
+        break;
+      case TypeUseKind.CHECKED_MODE_CHECK:
+        sb.write('check:');
+        break;
+      case TypeUseKind.CATCH_TYPE:
+        sb.write('catch:');
+        break;
+      case TypeUseKind.TYPE_LITERAL:
+        sb.write('lit:');
+        break;
+      case TypeUseKind.INSTANTIATION:
+        sb.write('inst:');
+        break;
+      case TypeUseKind.MIRROR_INSTANTIATION:
+        sb.write('mirror:');
+        break;
+      case TypeUseKind.NATIVE_INSTANTIATION:
+        sb.write('native:');
+        break;
+      case TypeUseKind.IMPLICIT_CAST:
+        sb.write('impl:');
+        break;
+      case TypeUseKind.PARAMETER_CHECK:
+        sb.write('param:');
+        break;
+    }
+    sb.write(type);
+    return sb.toString();
+  }
+
   /// [type] used in an is check, like `e is T` or `e is! T`.
   factory TypeUse.isCheck(DartType type) {
     return new TypeUse.internal(type, TypeUseKind.IS_CHECK);
@@ -616,6 +713,11 @@
   ConstantUse._(this.value, this.kind)
       : this.hashCode = Hashing.objectHash(value, kind.hashCode);
 
+  /// Short textual representation use for testing.
+  String get shortText {
+    return value.toDartText();
+  }
+
   /// Constant used as the initial value of a field.
   ConstantUse.init(ConstantValue value) : this._(value, ConstantUseKind.DIRECT);
 
diff --git a/pkg/compiler/lib/src/universe/world_builder.dart b/pkg/compiler/lib/src/universe/world_builder.dart
index fdac83d..44d098b 100644
--- a/pkg/compiler/lib/src/universe/world_builder.dart
+++ b/pkg/compiler/lib/src/universe/world_builder.dart
@@ -8,18 +8,12 @@
 
 import '../common.dart';
 import '../common/names.dart' show Identifiers, Names;
-import '../common/resolution.dart' show Resolution;
 import '../common_elements.dart';
 import '../constants/constant_system.dart';
 import '../constants/values.dart';
-import '../elements/elements.dart';
 import '../elements/entities.dart';
-import '../elements/resolution_types.dart';
 import '../elements/types.dart';
-import '../js_backend/backend.dart' show JavaScriptBackend;
 import '../js_backend/backend_usage.dart' show BackendUsageBuilder;
-import '../js_backend/constant_handler_javascript.dart'
-    show JavaScriptConstantCompiler;
 import '../js_backend/interceptor_data.dart' show InterceptorDataBuilder;
 import '../js_backend/native_data.dart' show NativeBasicData, NativeDataBuilder;
 import '../js_backend/no_such_method_registry.dart';
@@ -32,7 +26,7 @@
 import '../universe/class_set.dart';
 import '../util/enumset.dart';
 import '../util/util.dart';
-import '../world.dart' show World, ClosedWorld, ClosedWorldImpl, OpenWorld;
+import '../world.dart' show World, ClosedWorld, OpenWorld;
 import 'class_hierarchy_builder.dart' show ClassHierarchyBuilder, ClassQueries;
 import 'selector.dart' show Selector;
 import 'use.dart'
@@ -45,7 +39,6 @@
         StaticUseKind;
 
 part 'codegen_world_builder.dart';
-part 'element_world_builder.dart';
 part 'member_usage.dart';
 part 'resolution_world_builder.dart';
 
diff --git a/pkg/compiler/lib/src/use_unused_api.dart b/pkg/compiler/lib/src/use_unused_api.dart
deleted file mode 100644
index 6edbf01..0000000
--- a/pkg/compiler/lib/src/use_unused_api.dart
+++ /dev/null
@@ -1,303 +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.
-
-/// This file use methods that aren't used by dart2js.dart, but that we wish to
-/// keep anyway. This might be general API that isn't currently in use,
-/// debugging aids, or API only used for testing (see TODO below).
-
-library dart2js.use_unused_api;
-
-import '../compiler.dart' as api;
-import 'colors.dart' as colors;
-import 'compiler.dart' as compiler;
-import 'constants/constant_system.dart' as constants;
-import 'constants/constructors.dart' as constants;
-import 'constants/evaluation.dart' as constants;
-import 'constants/expressions.dart' as constants;
-import 'constants/values.dart' as constants;
-import 'dart2js.dart' as dart2js;
-import 'elements/resolution_types.dart' as dart_types;
-import 'deferred_load.dart' as deferred_load;
-import 'diagnostics/source_span.dart' as diagnostics;
-import 'elements/elements.dart' as elements;
-import 'elements/modelx.dart' as modelx;
-import 'elements/names.dart' as names;
-import 'elements/operators.dart' as operators;
-import 'elements/visitor.dart' as elements_visitor;
-import 'filenames.dart' as filenames;
-import 'inferrer/type_graph_inferrer.dart' as type_graph_inferrer;
-import 'io/location_provider.dart' as io;
-import 'io/source_map_builder.dart' as io;
-import 'js/js.dart' as js;
-import 'js_backend/js_backend.dart' as js_backend;
-import 'parser/partial_elements.dart'
-    show PartialClassElement, PartialFunctionElement;
-import 'resolution/semantic_visitor.dart' as semantic_visitor;
-import 'script.dart';
-import 'source_file_provider.dart' as source_file_provider;
-import 'ssa/nodes.dart' as ssa;
-import 'tree/tree.dart' as tree;
-import 'util/util.dart' as util;
-import 'world.dart';
-
-class ElementVisitor extends elements_visitor.BaseElementVisitor {
-  visitElement(e, a) {}
-}
-
-void main(List<String> arguments) {
-  useApi(null);
-  dart2js.main(arguments);
-  names.Name.isPublicName(null);
-  useConstant();
-  useNode(null);
-  useUtil(null);
-  useSetlet(null);
-  useImmutableEmptySet(null);
-  useElementVisitor(new ElementVisitor());
-  useJsNode(new js.Program(null));
-  useJsNode(new js.NamedFunction(null, null));
-  useJsNode(new js.ArrayHole());
-  useJsOther(new js.SimpleJavaScriptPrintingContext());
-  useJsBackend(null);
-  useColor();
-  useFilenames();
-  useSsa(null);
-  useIo();
-  usedByTests();
-  useElements();
-  useCompiler(null);
-  useTypes();
-  useScript(null);
-  useSemanticVisitor();
-  useDeferred();
-}
-
-useApi([api.ReadStringFromUri uri, compiler.Compiler compiler]) {
-  compiler.analyzeUri(null);
-  new diagnostics.SourceSpan.fromNode(null, null);
-}
-
-class NullConstantConstructorVisitor
-    extends constants.ConstantConstructorVisitor {
-  @override
-  visitGenerative(constants.GenerativeConstantConstructor constructor, arg) {}
-
-  @override
-  visitRedirectingFactory(
-      constants.RedirectingFactoryConstantConstructor constructor, arg) {}
-
-  @override
-  visitRedirectingGenerative(
-      constants.RedirectingGenerativeConstantConstructor constructor, arg) {}
-
-  @override
-  visitErroneous(constants.ErroneousConstantConstructor constructor, arg) {}
-}
-
-void useConstant(
-    [constants.ConstantValue constant,
-    constants.ConstantExpression expression,
-    constants.ConstructedConstantExpression constructedConstant,
-    constants.ConstantSystem cs,
-    constants.EvaluationEnvironment env]) {
-  constant.isObject;
-  cs.isBool(constant);
-  constructedConstant.computeInstanceType(null);
-  constructedConstant.computeInstanceData(null);
-  expression.evaluate(null, null);
-  new NullConstantConstructorVisitor()
-    ..visit(null, null)
-    ..visitGenerative(null, null)
-    ..visitRedirectingFactory(null, null)
-    ..visitRedirectingGenerative(null, null);
-}
-
-void useNode(tree.Node node) {
-  node
-    ..asAsyncModifier()
-    ..asAsyncForIn()
-    ..asAwait()
-    ..asBreakStatement()
-    ..asCascade()
-    ..asCatchBlock()
-    ..asClassNode()
-    ..asCombinator()
-    ..asConditional()
-    ..asContinueStatement()
-    ..asEnum()
-    ..asErrorExpression()
-    ..asExport()
-    ..asFor()
-    ..asFunctionDeclaration()
-    ..asIf()
-    ..asImport()
-    ..asLabeledStatement()
-    ..asLibraryDependency()
-    ..asLibraryName()
-    ..asLiteralDouble()
-    ..asLiteralList()
-    ..asLiteralMap()
-    ..asLiteralMapEntry()
-    ..asLiteralNull()
-    ..asLiteralSymbol()
-    ..asMetadata()
-    ..asModifiers()
-    ..asPart()
-    ..asPartOf()
-    ..asRethrow()
-    ..asReturn()
-    ..asStatement()
-    ..asStringInterpolation()
-    ..asStringInterpolationPart()
-    ..asStringJuxtaposition()
-    ..asStringNode()
-    ..asSwitchCase()
-    ..asSwitchStatement()
-    ..asSyncForIn()
-    ..asTryStatement()
-    ..asNominalTypeAnnotation()
-    ..asTypeVariable()
-    ..asTypedef()
-    ..asWhile()
-    ..asYield();
-}
-
-void useUtil(util.Link link) {
-  link.reversePrependAll(link);
-  link.copyWithout(link);
-  util.longestCommonPrefixLength(null, null);
-  new util.Pair(null, null);
-}
-
-void useSetlet(util.Setlet setlet) {
-  setlet.difference(setlet);
-  setlet.retainWhere(null);
-}
-
-void useImmutableEmptySet(util.ImmutableEmptySet set) {
-  set.retainWhere(null);
-}
-
-void useElementVisitor(ElementVisitor visitor) {
-  visitor
-    ..visit(null, null)
-    ..visitAbstractFieldElement(null, null)
-    ..visitAmbiguousElement(null, null)
-    ..visitBoxFieldElement(null, null)
-    ..visitClassElement(null, null)
-    ..visitClosureClassElement(null, null)
-    ..visitClosureFieldElement(null, null)
-    ..visitCompilationUnitElement(null, null)
-    ..visitConstructorBodyElement(null, null)
-    ..visitElement(null, null)
-    ..visitErroneousElement(null, null)
-    ..visitFieldParameterElement(null, null)
-    ..visitFunctionElement(null, null)
-    ..visitLibraryElement(null, null)
-    ..visitMixinApplicationElement(null, null)
-    ..visitPrefixElement(null, null)
-    ..visitScopeContainerElement(null, null)
-    ..visitTypeDeclarationElement(null, null)
-    ..visitTypeVariableElement(null, null)
-    ..visitTypedefElement(null, null)
-    ..visitVariableElement(null, null)
-    ..visitWarnOnUseElement(null, null);
-}
-
-useJsNode(js.Node node) {
-  node.asVariableUse();
-}
-
-useJsOther(js.SimpleJavaScriptPrintingContext context) {
-  context.getText();
-}
-
-useJsBackend(js_backend.JavaScriptBackend backend) {
-  backend.getGeneratedCode(null);
-}
-
-useColor() {
-  colors.white(null);
-  colors.blue(null);
-  colors.yellow(null);
-  colors.black(null);
-}
-
-useFilenames() {
-  filenames.appendSlash(null);
-}
-
-useSsa(ssa.HInstruction instruction) {
-  instruction.isConstantNumber();
-  new ssa.HAndOrBlockInformation(null, null, null);
-  new ssa.HStatementSequenceInformation(null);
-}
-
-useIo([io.LineColumnMap map, io.LocationProvider provider]) {
-  map
-    ..addFirst(null, null, null)
-    ..forEachLine(null)
-    ..getFirstElementsInLine(null)
-    ..forEachColumn(null, null);
-}
-
-usedByTests() {
-  // TODO(ahe): We should try to avoid including API used only for tests. In
-  // most cases, such API can be moved to a test library.
-  ClosedWorldImpl closedWorld = null;
-  type_graph_inferrer.TypeGraphInferrer typeGraphInferrer = null;
-  source_file_provider.SourceFileProvider sourceFileProvider = null;
-  sourceFileProvider.getUtf8SourceFile(null);
-  closedWorld.hasAnyUserDefinedGetter(null, null);
-  closedWorld.subclassesOf(null);
-  closedWorld.getClassHierarchyNode(null);
-  closedWorld.getClassSet(null);
-  closedWorld.haveAnyCommonSubtypes(null, null);
-  typeGraphInferrer.getCallersOfForTesting(null);
-  dart_types.Types.sorted(null);
-  new dart_types.Types(null).copy(null);
-}
-
-useElements(
-    [elements.ClassElement e,
-    names.Name n,
-    modelx.FieldElementX f,
-    PartialClassElement pce,
-    PartialFunctionElement pfe,
-    elements.LibraryElement l]) {
-  e.lookupClassMember(null);
-  e.lookupInterfaceMember(null);
-  n.isAccessibleFrom(null);
-  f.reuseElement();
-  pce.copyWithEnclosing(null);
-  pfe.copyWithEnclosing(null);
-  l.forEachImport(null);
-}
-
-useCompiler(compiler.Compiler c) {
-  c.libraryLoader
-    ..reset()
-    ..resetAsync(null)
-    ..lookupLibrary(null);
-  c.backend.constantCompilerTask.copyConstantValues(null);
-  c.currentlyInUserCode();
-}
-
-useTypes() {}
-
-useScript(Script script) {
-  script.copyWithFile(null);
-}
-
-useSemanticVisitor() {
-  operators.UnaryOperator.fromKind(null);
-  operators.BinaryOperator.fromKind(null);
-  new semantic_visitor.BulkSendVisitor()..apply(null, null);
-  new semantic_visitor.TraversalVisitor(null).apply(null, null);
-  new semantic_visitor.BulkDeclarationVisitor().apply(null, null);
-}
-
-useDeferred([deferred_load.DeferredLoadTask task]) {
-  task.dump();
-}
diff --git a/pkg/compiler/lib/src/world.dart b/pkg/compiler/lib/src/world.dart
index c781eb0..523bca7 100644
--- a/pkg/compiler/lib/src/world.dart
+++ b/pkg/compiler/lib/src/world.dart
@@ -5,20 +5,11 @@
 library dart2js.world;
 
 import 'dart:collection' show Queue;
-import 'closure.dart';
 import 'common.dart';
 import 'common/names.dart';
 import 'common_elements.dart' show CommonElements, ElementEnvironment;
 import 'constants/constant_system.dart';
 import 'elements/entities.dart';
-import 'elements/elements.dart'
-    show
-        ClassElement,
-        Element,
-        MemberElement,
-        MethodElement,
-        MixinApplicationElement;
-import 'elements/resolution_types.dart';
 import 'elements/types.dart';
 import 'js_backend/backend_usage.dart' show BackendUsage;
 import 'js_backend/interceptor_data.dart' show InterceptorData;
@@ -29,7 +20,7 @@
 import 'ordered_typeset.dart';
 import 'options.dart';
 import 'types/abstract_value_domain.dart';
-import 'types/masks.dart' show CommonMasks, FlatTypeMask, TypeMask;
+import 'types/masks.dart' show CommonMasks, TypeMask;
 import 'universe/class_set.dart';
 import 'universe/function_set.dart' show FunctionSet;
 import 'universe/selector.dart' show Selector;
@@ -288,11 +279,6 @@
   /// methods defined in [ClosedWorld].
   ClassSet getClassSet(ClassEntity cls);
 
-  /// Return the cached mask for [base] with the given flags, or
-  /// calls [createMask] to create the mask and cache it.
-  // TODO(johnniwinther): Find a better strategy for caching these?
-  TypeMask getCachedMask(ClassEntity base, int flags, TypeMask createMask());
-
   /// Returns `true` if the field [element] is known to be effectively final.
   bool fieldNeverChanges(MemberEntity element);
 
@@ -523,21 +509,10 @@
   @override
   ClosedWorld get closedWorld => this;
 
-  /// Cache of [FlatTypeMask]s grouped by the 8 possible values of the
-  /// `FlatTypeMask.flags` property.
-  final List<Map<ClassEntity, TypeMask>> _canonicalizedTypeMasks =
-      new List<Map<ClassEntity, TypeMask>>.filled(8, null);
-
   CommonMasks get abstractValueDomain {
     return _commonMasks;
   }
 
-  TypeMask getCachedMask(ClassEntity base, int flags, TypeMask createMask()) {
-    Map<ClassEntity, TypeMask> cachedMasks =
-        _canonicalizedTypeMasks[flags] ??= <ClassEntity, TypeMask>{};
-    return cachedMasks.putIfAbsent(base, createMask);
-  }
-
   bool checkEntity(covariant Entity element);
 
   bool checkClass(covariant ClassEntity cls);
@@ -1079,18 +1054,18 @@
     if (includesClosureCall(selector, mask)) {
       return abstractValueDomain.dynamicType;
     }
-    return _allFunctions.receiverType(selector, mask, this);
+    return _allFunctions.receiverType(selector, mask, abstractValueDomain);
   }
 
   Iterable<MemberEntity> locateMembers(Selector selector, TypeMask mask) {
     _ensureFunctionSet();
-    return _allFunctions.filter(selector, mask, this);
+    return _allFunctions.filter(selector, mask, abstractValueDomain);
   }
 
   bool hasAnyUserDefinedGetter(Selector selector, TypeMask mask) {
     _ensureFunctionSet();
     return _allFunctions
-        .filter(selector, mask, this)
+        .filter(selector, mask, abstractValueDomain)
         .any((each) => each.isGetter);
   }
 
@@ -1142,7 +1117,8 @@
     }
     SideEffects sideEffects = new SideEffects.empty();
     _ensureFunctionSet();
-    for (MemberEntity e in _allFunctions.filter(selector, mask, this)) {
+    for (MemberEntity e
+        in _allFunctions.filter(selector, mask, abstractValueDomain)) {
       if (e.isField) {
         if (selector.isGetter) {
           if (!fieldNeverChanges(e)) {
@@ -1268,10 +1244,6 @@
 
   @override
   String dump([ClassEntity cls]) {
-    if (cls is! ClassElement) {
-      // TODO(johnniwinther): Support [cls] as a [ClassEntity].
-      cls = null;
-    }
     StringBuffer sb = new StringBuffer();
     if (cls != null) {
       sb.write("Classes in the closed world related to $cls:\n");
@@ -1294,178 +1266,6 @@
   }
 }
 
-class ClosedWorldImpl extends ClosedWorldBase with ClosedWorldRtiNeedMixin {
-  final List<MemberEntity> liveInstanceMembers;
-
-  ClosedWorldImpl(
-      {CompilerOptions options,
-      ElementEnvironment elementEnvironment,
-      DartTypes dartTypes,
-      CommonElements commonElements,
-      ConstantSystem constantSystem,
-      NativeData nativeData,
-      InterceptorData interceptorData,
-      BackendUsage backendUsage,
-      NoSuchMethodData noSuchMethodData,
-      ResolutionWorldBuilder resolutionWorldBuilder,
-      RuntimeTypesNeedBuilder rtiNeedBuilder,
-      Set<ClassEntity> implementedClasses,
-      Iterable<ClassEntity> liveNativeClasses,
-      Iterable<MemberEntity> liveInstanceMembers,
-      Iterable<MemberEntity> assignedInstanceMembers,
-      Iterable<MemberEntity> processedMembers,
-      Set<TypedefEntity> allTypedefs,
-      Map<ClassEntity, Set<ClassEntity>> mixinUses,
-      Map<ClassEntity, Set<ClassEntity>> typesImplementedBySubclasses,
-      Map<ClassEntity, ClassHierarchyNode> classHierarchyNodes,
-      Map<ClassEntity, ClassSet> classSets})
-      : this.liveInstanceMembers =
-            new List<MemberEntity>.from(liveInstanceMembers),
-        super(
-            elementEnvironment,
-            dartTypes,
-            commonElements,
-            constantSystem,
-            nativeData,
-            interceptorData,
-            backendUsage,
-            noSuchMethodData,
-            implementedClasses,
-            liveNativeClasses,
-            liveInstanceMembers,
-            assignedInstanceMembers,
-            processedMembers,
-            allTypedefs,
-            mixinUses,
-            typesImplementedBySubclasses,
-            classHierarchyNodes,
-            classSets) {
-    computeRtiNeed(resolutionWorldBuilder, rtiNeedBuilder, options);
-  }
-
-  bool checkClass(ClassElement cls) => cls.isDeclaration;
-
-  bool checkEntity(Element element) => element.isDeclaration;
-
-  bool checkInvariants(ClassElement cls, {bool mustBeInstantiated: true}) {
-    assert(cls.isDeclaration, failedAt(cls, '$cls must be the declaration.'));
-    assert(cls.isResolved, failedAt(cls, '$cls must be resolved.'));
-
-    // TODO(johnniwinther): Reinsert this or similar invariant. Currently
-    // various call sites use uninstantiated classes for isSubtypeOf or
-    // isSubclassOf. Some are valid, some are not. Work out better invariants
-    // to catch the latter.
-    // if (mustBeInstantiated) {
-    //  assert(isInstantiated(cls), failedAt(cls, '$cls is not instantiated.'));
-    // }
-    return true;
-  }
-
-  OrderedTypeSet getOrderedTypeSet(ClassElement cls) =>
-      cls.allSupertypesAndSelf;
-
-  int getHierarchyDepth(ClassElement cls) => cls.hierarchyDepth;
-
-  ClassEntity getSuperClass(ClassElement cls) => cls.superclass;
-
-  Iterable<ClassEntity> getInterfaces(ClassElement cls) sync* {
-    for (Link link = cls.interfaces; !link.isEmpty; link = link.tail) {
-      yield link.head.element;
-    }
-  }
-
-  bool isNamedMixinApplication(ClassElement cls) => cls.isNamedMixinApplication;
-
-  ClassEntity getAppliedMixin(ClassElement cls) {
-    if (cls.isMixinApplication) {
-      MixinApplicationElement application = cls;
-      return application.mixin;
-    }
-    return null;
-  }
-
-  @override
-  bool hasElementIn(ClassEntity cls, Selector selector, Element element) {
-    // Use [:implementation:] of [element]
-    // because our function set only stores declarations.
-    Element result = findMatchIn(cls, selector);
-    return result == null
-        ? false
-        : result.implementation == element.implementation;
-  }
-
-  MemberElement findMatchIn(ClassElement cls, Selector selector,
-      {ClassElement stopAtSuperclass}) {
-    // Use the [:implementation] of [cls] in case the found [element]
-    // is in the patch class.
-    return cls.implementation
-        .lookupByName(selector.memberName, stopAt: stopAtSuperclass);
-  }
-
-  /// Returns whether a [selector] call on an instance of [cls]
-  /// will hit a method at runtime, and not go through [noSuchMethod].
-  bool hasConcreteMatch(ClassElement cls, Selector selector,
-      {ClassElement stopAtSuperclass}) {
-    assert(
-        isInstantiated(cls), failedAt(cls, '$cls has not been instantiated.'));
-    MemberElement element = findMatchIn(cls, selector);
-    if (element == null) return false;
-
-    if (element.isAbstract) {
-      ClassElement enclosingClass = element.enclosingClass;
-      return hasConcreteMatch(enclosingClass.superclass, selector);
-    }
-    return selector.appliesUntyped(element);
-  }
-
-  void registerClosureClass(covariant ClosureClassElement cls) {
-    ClassHierarchyNode parentNode = getClassHierarchyNode(cls.superclass);
-    ClassHierarchyNode node = _classHierarchyNodes[cls] =
-        new ClassHierarchyNode(parentNode, cls, cls.hierarchyDepth);
-    for (ResolutionInterfaceType type in cls.allSupertypes) {
-      ClassSet subtypeSet = getClassSet(type.element);
-      subtypeSet.addSubtype(node);
-    }
-    _classSets[cls] = new ClassSet(node);
-    _updateSuperClassHierarchyNodeForClass(node);
-    node.isDirectlyInstantiated = true;
-    MethodElement callMethod = cls.callMethod;
-    assert(callMethod != null, failedAt(cls, "No call method in $cls"));
-    assert(_allFunctions == null,
-        failedAt(cls, "Function set has already be created."));
-    // TODO(johnniwinther): Include the call method when we can also represent
-    // the synthesized call methods for static and instance method
-    // closurizations.
-    //liveInstanceMembers.add(callMethod);
-  }
-
-  void _updateSuperClassHierarchyNodeForClass(ClassHierarchyNode node) {
-    // Ensure that classes implicitly implementing `Function` are in its
-    // subtype set.
-    ClassElement cls = node.cls;
-    if (cls != commonElements.functionClass &&
-        cls.implementsFunction(commonElements)) {
-      ClassSet subtypeSet = getClassSet(commonElements.functionClass);
-      subtypeSet.addSubtype(node);
-    }
-    if (!node.isInstantiated && node.parentNode != null) {
-      _updateSuperClassHierarchyNodeForClass(node.parentNode);
-    }
-  }
-
-  SideEffects getSideEffectsOfElement(covariant MethodElement element) {
-    // The type inferrer (where the side effects are being computed),
-    // does not see generative constructor bodies because they are
-    // created by the backend. Also, it does not make any distinction
-    // between a constructor and its body for side effects. This
-    // implies that currently, the side effects of a constructor body
-    // contain the side effects of the initializers.
-    assert(!element.isGenerativeConstructorBody);
-    assert(!element.isField);
-    return super.getSideEffectsOfElement(element);
-  }
-}
-
 abstract class ClosedWorldRtiNeedMixin implements ClosedWorld {
   RuntimeTypesNeed _rtiNeed;
 
diff --git a/pkg/dev_compiler/lib/src/analyzer/code_generator.dart b/pkg/dev_compiler/lib/src/analyzer/code_generator.dart
index c2acf4f..c53371c 100644
--- a/pkg/dev_compiler/lib/src/analyzer/code_generator.dart
+++ b/pkg/dev_compiler/lib/src/analyzer/code_generator.dart
@@ -16,7 +16,8 @@
 import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/dart/element/type.dart';
 import 'package:analyzer/src/dart/sdk/sdk.dart';
-import 'package:analyzer/src/generated/constant.dart' show DartObjectImpl;
+import 'package:analyzer/src/generated/constant.dart'
+    show DartObject, DartObjectImpl;
 import 'package:analyzer/src/generated/engine.dart' show AnalysisContext;
 import 'package:analyzer/src/generated/resolver.dart'
     show TypeProvider, NamespaceBuilder;
@@ -76,7 +77,7 @@
         ClosureAnnotator,
         JSTypeRefCodegen,
         NullableTypeInference,
-        SharedCompiler
+        SharedCompiler<LibraryElement>
     implements AstVisitor<JS.Node> {
   final AnalysisContext context;
   final SummaryDataStore summaryData;
@@ -99,9 +100,6 @@
   /// in the SDK to be generated before anything else.
   final _internalSdkFunctions = <JS.ModuleItem>[];
 
-  /// The list of output module items, in the order they need to be emitted in.
-  final _moduleItems = <JS.ModuleItem>[];
-
   /// Table of named and possibly hoisted types.
   TypeTable _typeTable;
 
@@ -120,9 +118,6 @@
   /// In an async* function, this represents the stream controller parameter.
   JS.TemporaryId _asyncStarController;
 
-  // TODO(jmesserly): fuse this with notNull check.
-  final _privateNames =
-      new HashMap<LibraryElement, HashMap<String, JS.TemporaryId>>();
   final _initializingFormalTemps =
       new HashMap<ParameterElement, JS.TemporaryId>();
 
@@ -319,7 +314,7 @@
   }
 
   JS.Program _emitModule(List<CompilationUnit> compilationUnits, String name) {
-    if (_moduleItems.isNotEmpty) {
+    if (moduleItems.isNotEmpty) {
       throw new StateError('Can only call emitModule once.');
     }
 
@@ -423,7 +418,7 @@
     items.addAll(_internalSdkFunctions);
 
     // Add the module's code (produced by visiting compilation units, above)
-    _copyAndFlattenBlocks(items, _moduleItems);
+    _copyAndFlattenBlocks(items, moduleItems);
 
     // Build the module.
     return new JS.Program(items, name: _buildUnit.name);
@@ -441,7 +436,7 @@
 
     // Track the module name for each library in the module.
     // This data is only required for debugging.
-    _moduleItems.add(js
+    moduleItems.add(js
         .statement('#.trackLibraries(#, #, ${JSModuleFile.sourceMapHoleID});', [
       runtimeModule,
       js.string(name),
@@ -603,7 +598,7 @@
     // only run this on the outermost function, and not any closures.
     inferNullableTypes(node);
 
-    _moduleItems.add(node.accept(this) as JS.ModuleItem);
+    moduleItems.add(node.accept(this) as JS.ModuleItem);
 
     _currentElement = savedElement;
   }
@@ -666,7 +661,7 @@
       if (isInternalSdk && element is FunctionElement) {
         _internalSdkFunctions.add(item);
       } else {
-        _moduleItems.add(item);
+        moduleItems.add(item);
       }
     }
 
@@ -727,7 +722,7 @@
       if (currentNames.containsKey(export.name)) return null;
 
       var name = _emitTopLevelName(export);
-      _moduleItems.add(js.statement(
+      moduleItems.add(js.statement(
           '#.# = #;', [emitLibraryName(currentLibrary), name.selector, name]));
     }
   }
@@ -917,14 +912,17 @@
     var jsTypeDef = _emitJSType(classElem);
     if (jsTypeDef != null) return jsTypeDef;
 
-    JS.Expression className;
-    if (classElem.typeParameters.isNotEmpty) {
-      // Generic classes will be defined inside a function that closes over the
-      // type parameter. So we can use their local variable name directly.
-      className = new JS.Identifier(classElem.name);
-    } else {
-      className = _emitTopLevelName(classElem);
-    }
+    // Generic classes will be defined inside a function that closes over the
+    // type parameter. So we can use their local variable name directly.
+    //
+    // TODO(jmesserly): the special case for JSArray is to support its special
+    // type-tagging factory constructors. Those will go away once we fix:
+    // https://github.com/dart-lang/sdk/issues/31003
+    var className = classElem.typeParameters.isNotEmpty
+        ? (classElem == _jsArray
+            ? new JS.Identifier(classElem.name)
+            : new JS.TemporaryId(classElem.name))
+        : _emitTopLevelName(classElem);
 
     var savedClassProperties = _classProperties;
     _classProperties = new ClassPropertyModel.build(
@@ -1183,7 +1181,7 @@
       // TODO(jmesserly): we could export these symbols, if we want to mark
       // implemented interfaces for user-defined classes.
       var id = new JS.TemporaryId("_is_${classElem.name}_default");
-      _moduleItems.add(
+      moduleItems.add(
           js.statement('const # = Symbol(#);', [id, js.string(id.name, "'")]));
       isClassSymbol = id;
     }
@@ -1274,20 +1272,21 @@
       JS.Expression className,
       JS.Expression heritage,
       List<JS.Method> methods) {
-    String name = classElem.name;
     var typeParams = _emitTypeFormals(classElem.typeParameters);
 
     var jsFields = options.closure
         ? classElem.fields.map(_emitTypeScriptField).toList()
         : null;
-    var classExpr = new JS.ClassExpression(
-        new JS.Identifier(name), heritage, methods,
-        typeParams: typeParams, fields: jsFields);
     if (classElem.typeParameters.isNotEmpty) {
-      return classExpr.toStatement();
-    } else {
-      return js.statement('# = #;', [className, classExpr]);
+      return new JS.ClassExpression(
+              className as JS.Identifier, heritage, methods,
+              typeParams: typeParams, fields: jsFields)
+          .toStatement();
     }
+    var classExpr = new JS.ClassExpression(
+        new JS.TemporaryId(classElem.name), heritage, methods,
+        typeParams: typeParams, fields: jsFields);
+    return js.statement('# = #;', [className, classExpr]);
   }
 
   void _defineClass(
@@ -1719,9 +1718,9 @@
   ///
   /// It will generate an `eatFood` that looks like:
   ///
-  ///     eatFood(...args) {
+  ///     eatFood(food) {
   ///       return core.bool.as(this.noSuchMethod(
-  ///           new dart.InvocationImpl.new('eatFood', args)));
+  ///           new dart.InvocationImpl.new('eatFood', [food])));
   ///     }
   JS.Method _implementMockMember(ExecutableElement method, InterfaceType type) {
     var invocationProps = <JS.Property>[];
@@ -1731,52 +1730,40 @@
 
     var typeParams = _emitTypeFormals(method.type.typeFormals);
     var fnArgs = new List<JS.Parameter>.from(typeParams);
-    JS.Expression positionalArgs;
+    var args = _emitParametersForElement(method);
+    fnArgs.addAll(args);
+    var argInit = _emitArgumentInitializers(method);
 
     if (method is PropertyAccessorElement) {
       if (method.isGetter) {
         addProperty('isGetter', js.boolean(true));
-        positionalArgs = new JS.ArrayInitializer([]);
       } else {
         assert(method.isSetter);
         addProperty('isSetter', js.boolean(true));
-        var valueArg = new JS.TemporaryId('value');
-        positionalArgs = new JS.ArrayInitializer([valueArg]);
-        fnArgs.add(valueArg);
       }
     } else {
       addProperty('isMethod', js.boolean(true));
-      if (method.type.namedParameterTypes.isNotEmpty) {
-        // Named parameters need to be emitted in the correct position (after
-        // positional arguments) so we can detect them reliably.
-        var args = _emitParametersForElement(method);
-        fnArgs.addAll(args);
-        addProperty('namedArguments', args.removeLast());
-        positionalArgs = new JS.ArrayInitializer(args);
-      } else {
-        // In case we have optional parameters, we need to use rest args,
-        // because sometimes mocks want to detect whether optional arguments
-        // were passed, and this does not work reliably with undefined (should
-        // not normally appear in DDC, but it can result from JS interop).
-        //
-        // TODO(jmesserly): perhaps we need to use rest args or destructuring
-        // to get reliable optional argument passing in other scenarios? It
-        // doesn't seem to occur outside of tests, perhaps due to the
-        // combination of mockito and protobufs.
-        positionalArgs = new JS.TemporaryId('args');
-        fnArgs.add(new JS.RestParameter(positionalArgs));
-      }
     }
 
+    var positionalArgs = args;
+    var namedParameterTypes = method.type.namedParameterTypes;
+    if (namedParameterTypes.isNotEmpty) {
+      // Sort the names to match dart2js order.
+      var sortedNames = (namedParameterTypes.keys.toList())..sort();
+      var named = sortedNames
+          .map((n) => new JS.Property(_propertyName(n), new JS.Identifier(n)));
+      addProperty('namedArguments', new JS.ObjectInitializer(named.toList()));
+      positionalArgs.removeLast();
+    }
     if (typeParams.isNotEmpty) {
       addProperty('typeArguments', new JS.ArrayInitializer(typeParams));
     }
 
     var fnBody =
-        js.call('this.noSuchMethod(new #.InvocationImpl.new(#, #, #))', [
+        js.call('this.noSuchMethod(new #.InvocationImpl.new(#, [#], #))', [
       runtimeModule,
       _declareMemberName(method),
-      positionalArgs,
+      args,
       new JS.ObjectInitializer(invocationProps)
     ]);
 
@@ -1784,13 +1771,14 @@
       fnBody = js.call('#._check(#)', [_emitType(method.returnType), fnBody]);
     }
 
-    var fn =
-        new JS.Fun(fnArgs, fnBody.toReturn().toBlock(), typeParams: typeParams);
+    var fnBlock = argInit != null
+        ? new JS.Block([argInit, fnBody.toReturn()])
+        : fnBody.toReturn().toBlock();
 
     return new JS.Method(
         _declareMemberName(method,
             useExtension: _extensionTypes.isNativeClass(type.element)),
-        fn,
+        new JS.Fun(fnArgs, fnBlock, typeParams: typeParams),
         isGetter: method is PropertyAccessorElement && method.isGetter,
         isSetter: method is PropertyAccessorElement && method.isSetter,
         isStatic: false);
@@ -1911,9 +1899,8 @@
       return _emitInstanceCreationExpression(
           element,
           element.returnType as InterfaceType,
-          node.constructorName,
-          node.arguments,
-          true);
+          () => _emitArgumentList(node.arguments),
+          isConst: true);
     } else {
       return _visitExpression(node.name);
     }
@@ -2518,25 +2505,44 @@
 
   /// Emits argument initializers, which handles optional/named args, as well
   /// as generic type checks needed due to our covariance.
-  JS.Statement _emitArgumentInitializers(
-      ExecutableElement element, FormalParameterList parameters) {
-    if (parameters == null) return null;
-
+  JS.Statement _emitArgumentInitializers(ExecutableElement element,
+      [FormalParameterList parameterNodes]) {
     var body = <JS.Statement>[];
 
     _emitCovarianceBoundsCheck(
         element.typeParameters, _classProperties?.covariantParameters, body);
-    for (var param in parameters.parameters) {
-      var element = param.identifier.staticElement as ParameterElement;
-      var jsParam = _emitParameter(element)
-        ..sourceInformation = _nodeStart(param.identifier);
+    for (int i = 0, n = element.parameters.length; i < n; i++) {
+      var param = element.parameters[i];
+      var paramNode =
+          parameterNodes != null ? parameterNodes.parameters[i] : null;
+      var jsParam = _emitParameter(param);
+      if (parameterNodes != null) {
+        jsParam.sourceInformation = _nodeStart(paramNode.identifier);
+      }
 
       if (param.isOptional) {
+        JS.Expression defaultValue;
+        if (paramNode != null) {
+          var paramDefault = (paramNode as DefaultFormalParameter).defaultValue;
+          if (paramDefault == null) {
+            defaultValue = new JS.LiteralNull();
+          } else if (_isJSUndefined(paramDefault)) {
+            defaultValue = null;
+          } else {
+            defaultValue = _visitExpression(paramDefault);
+          }
+        } else {
+          // TODO(jmesserly): it would be cleaner to emit the initializer
+          // Expression AST, but it does not seem to be fully resolved
+          // (for example, a list literal will not have the list type).
+          //
+          // So instead we use constant evaluation and emit the constant.
+          defaultValue = _emitDartObject(param.computeConstantValue());
+        }
         if (param.isNamed) {
           // Parameters will be passed using their real names, not the (possibly
           // renamed) local variable.
-          var paramName = js.string(param.identifier.name, "'");
-          var defaultValue = _defaultParamValue(param);
+          var paramName = js.string(param.name, "'");
           if (defaultValue != null) {
             // TODO(ochafik): Fix `'prop' in obj` to please Closure's renaming.
             body.add(js.statement('let # = # && # in # ? #.# : #;', [
@@ -2558,7 +2564,6 @@
           }
         } else {
           assert(param.isOptionalPositional);
-          var defaultValue = _defaultParamValue(param);
           if (defaultValue != null) {
             body.add(js.statement(
                 'if (# === void 0) # = #;', [jsParam, jsParam, defaultValue]));
@@ -2566,12 +2571,11 @@
         }
       }
 
-      var paramElement = resolutionMap.elementDeclaredByFormalParameter(param);
-      if (_isCovariant(paramElement)) {
-        var castType = _emitType(paramElement.type);
+      if (_isCovariant(param)) {
+        var castType = _emitType(param.type);
         body.add(js.statement('#._check(#);', [castType, jsParam]));
       }
-      if (_annotatedNullCheck(paramElement)) {
+      if (_annotatedNullCheck(param)) {
         body.add(_nullParameterCheck(jsParam));
       }
     }
@@ -2583,17 +2587,6 @@
         (_classProperties?.covariantParameters?.contains(p) ?? false);
   }
 
-  JS.Expression _defaultParamValue(FormalParameter param) {
-    if (param is DefaultFormalParameter && param.defaultValue != null) {
-      var defaultValue = param.defaultValue;
-      return _isJSUndefined(defaultValue)
-          ? null
-          : _visitExpression(defaultValue);
-    } else {
-      return new JS.LiteralNull();
-    }
-  }
-
   bool _isJSUndefined(Expression expr) {
     expr = expr is AsExpression ? expr.expression : expr;
     if (expr is Identifier) {
@@ -3049,10 +3042,8 @@
     // Directly emit constants.
     if (element is VariableElement && element.isStatic && element.isConst) {
       var val = element.computeConstantValue() as DartObjectImpl;
-      var result = _emitDartObject(val);
-      if (result != null) {
-        return result;
-      }
+      var result = val.isBoolNumStringOrNull ? _emitDartObject(val) : null;
+      if (result != null) return result;
     }
 
     // type literal
@@ -3071,65 +3062,71 @@
 
     // library member
     if (element.enclosingElement is CompilationUnitElement) {
-      var result = _emitTopLevelName(accessor);
-      if (element is FunctionElement &&
-          _reifyTearoff(element, prefix ?? node)) {
-        return _emitFunctionTagged(result, element.type);
-      }
-      return result;
+      return _emitLibraryMemberElement(accessor, prefix ?? node);
     }
 
-    var name = element.name;
-
     // Unqualified class member. This could mean implicit-this, or implicit
     // call to a static from the same class.
     if (element is ClassMemberElement && element is! ConstructorElement) {
-      bool isStatic = element.isStatic;
-      var classElem = element.enclosingElement;
-      var type = classElem.type;
-      var member = _emitMemberName(name,
-          isStatic: isStatic, type: type, element: accessor);
-
-      // A static native element should just forward directly to the
-      // JS type's member.
-      //
-      // TODO(jmesserly): this code path seems broken. It doesn't exist
-      // elsewhere, such as [_emitAccess], so it will only take affect for
-      // unqualified static access inside of the the same class.
-      //
-      // If we want this feature to work, we'll need to implement it in the
-      // standard [_emitStaticClassName] code path, which will need to know the
-      // member we're calling so it can determine whether to use the Dart class
-      // name or the native JS class name.
-      if (isStatic && _isExternal(element)) {
-        var nativeName = _extensionTypes.getNativePeers(classElem);
-        if (nativeName.isNotEmpty) {
-          var memberName = getAnnotationName(element, isJSName) ?? member;
-          return runtimeCall('global.#.#', [nativeName[0], memberName]);
-        }
-      }
-
-      // For instance members, we add implicit-this.
-      // For method tear-offs, we ensure it's a bound method.
-      var target = isStatic ? _emitStaticClassName(classElem) : new JS.This();
-      if (element is MethodElement && _reifyTearoff(element, prefix ?? node)) {
-        if (isStatic) {
-          // TODO(jmesserly): we could tag static/top-level function types once
-          // in the module initialization, rather than at the point where they
-          // escape.
-          return _emitFunctionTagged(
-              new JS.PropertyAccess(target, member), element.type);
-        }
-        return runtimeCall('bind(#, #)', [target, member]);
-      }
-      return new JS.PropertyAccess(target, member);
+      return _emitClassMemberElement(element, accessor, prefix ?? node);
     }
 
     if (element is ParameterElement) {
       return _emitParameter(element);
     }
 
-    return new JS.Identifier(name);
+    return new JS.Identifier(element.name);
+  }
+
+  JS.Expression _emitLibraryMemberElement(Element element, Expression node) {
+    var result = _emitTopLevelName(element);
+    if (element is FunctionElement && _reifyTearoff(element, node)) {
+      return _emitFunctionTagged(result, element.type);
+    }
+    return result;
+  }
+
+  JS.Expression _emitClassMemberElement(
+      ClassMemberElement element, Element accessor, Expression node) {
+    bool isStatic = element.isStatic;
+    var classElem = element.enclosingElement;
+    var type = classElem.type;
+    var member = _emitMemberName(element.name,
+        isStatic: isStatic, type: type, element: accessor);
+
+    // A static native element should just forward directly to the
+    // JS type's member.
+    //
+    // TODO(jmesserly): this code path seems broken. It doesn't exist
+    // elsewhere, such as [_emitAccess], so it will only take affect for
+    // unqualified static access inside of the the same class.
+    //
+    // If we want this feature to work, we'll need to implement it in the
+    // standard [_emitStaticClassName] code path, which will need to know the
+    // member we're calling so it can determine whether to use the Dart class
+    // name or the native JS class name.
+    if (isStatic && _isExternal(element)) {
+      var nativeName = _extensionTypes.getNativePeers(classElem);
+      if (nativeName.isNotEmpty) {
+        var memberName = getAnnotationName(element, isJSName) ?? member;
+        return runtimeCall('global.#.#', [nativeName[0], memberName]);
+      }
+    }
+
+    // For instance members, we add implicit-this.
+    // For method tear-offs, we ensure it's a bound method.
+    var target = isStatic ? _emitStaticClassName(classElem) : new JS.This();
+    if (element is MethodElement && _reifyTearoff(element, node)) {
+      if (isStatic) {
+        // TODO(jmesserly): we could tag static/top-level function types once
+        // in the module initialization, rather than at the point where they
+        // escape.
+        return _emitFunctionTagged(
+            new JS.PropertyAccess(target, member), element.type);
+      }
+      return runtimeCall('bind(#, #)', [target, member]);
+    }
+    return new JS.PropertyAccess(target, member);
   }
 
   JS.Identifier _emitVariableDef(SimpleIdentifier id, {JS.TypeRef type}) {
@@ -4053,33 +4050,10 @@
       source = (code as StringLiteral).stringValue;
     }
 
-    // TODO(vsm): Constructors in dart:html and friends are trying to
-    // allocate a type defined on window/self, but this often conflicts a
-    // with the generated extension class in scope.  We really should
-    // qualify explicitly in dart:html itself.
-    var constructorPattern = new RegExp("new [A-Z][A-Za-z]+\\(");
-    if (constructorPattern.matchAsPrefix(source) != null) {
-      var containingClass = node.parent;
-      while (containingClass != null && containingClass is! ClassDeclaration) {
-        containingClass = containingClass.parent;
-      }
-      if (containingClass is ClassDeclaration &&
-          _extensionTypes.isNativeClass(containingClass.element)) {
-        var constructorName = source.substring(4, source.indexOf('('));
-        var className = containingClass.name.name;
-        if (className == constructorName) {
-          source =
-              source.replaceFirst('new $className(', 'new self.$className(');
-        }
-      }
-    }
-
-    // TODO(rnystrom): The JS() calls are almost never nested, and probably
-    // really shouldn't be, but there are at least a couple of calls in the
-    // HTML library where an argument to JS() is itself a JS() call. If those
-    // go away, this can just assert(!_isInForeignJS).
-    // Inside JS(), type names evaluate to the raw runtime type, not the
-    // wrapped Type object.
+    // TODO(jmesserly): arguments to JS() that contain type literals evaluate to
+    // the raw runtime type instead of the wrapped Type object.
+    // We can clean this up by switching to `unwrapType(<type literal>)`, which
+    // the compiler will then optimize.
     var wasInForeignJS = _isInForeignJS;
     _isInForeignJS = true;
     var jsArgs = templateArgs.map(_visitExpression).toList();
@@ -4130,7 +4104,7 @@
       if (p.isPositional) {
         jsParams.add(new JS.Identifier(p.name));
       } else {
-        jsParams.add(new JS.TemporaryId('namedArgs'));
+        jsParams.add(namedArgumentTemp);
         break;
       }
     }
@@ -4304,7 +4278,7 @@
 
   /// Emits a list of top-level field.
   void _emitTopLevelFields(List<VariableDeclaration> fields) {
-    _moduleItems.add(_emitLazyFields(
+    moduleItems.add(_emitLazyFields(
         emitLibraryName(currentLibrary), fields, _emitTopLevelMemberName));
   }
 
@@ -4324,7 +4298,7 @@
           _isJSInvocation(init) ||
           init is InstanceCreationExpression &&
               isSdkInternalRuntime(init.staticElement.library)) {
-        _moduleItems.add(closureAnnotate(
+        moduleItems.add(closureAnnotate(
             js.statement('# = #;', [
               _emitTopLevelName(field.element),
               _visitInitializer(field.initializer, field.element)
@@ -4391,46 +4365,43 @@
     return null;
   }
 
-  JS.Expression _emitConstructorName(
-      ConstructorElement element, DartType type) {
+  JS.Expression _emitConstructorName(DartType type, String name) {
     return _emitJSInterop(type.element) ??
         new JS.PropertyAccess(
-            _emitConstructorAccess(type), _constructorName(element.name));
+            _emitConstructorAccess(type), _constructorName(name));
   }
 
   @override
   JS.Expression visitConstructorName(ConstructorName node) {
-    return _emitConstructorName(node.staticElement, node.type.type);
+    return _emitConstructorName(node.type.type, node.staticElement.name);
   }
 
-  JS.Expression _emitInstanceCreationExpression(
-      ConstructorElement element,
-      InterfaceType type,
-      SimpleIdentifier name,
-      ArgumentList argumentList,
-      bool isConst,
-      [ConstructorName ctorNode]) {
+  JS.Expression _emitInstanceCreationExpression(ConstructorElement element,
+      InterfaceType type, List<JS.Expression> Function() emitArguments,
+      {bool isConst = false, ConstructorName ctorNode}) {
     if (element == null) {
       return _throwUnsafe('unresolved constructor: ${type?.name ?? '<null>'}'
-          '.${name?.name ?? '<unnamed>'}');
+          '.${ctorNode?.name?.name ?? '<unnamed>'}');
     }
 
-    var classElem = element.enclosingElement;
+    var classElem = type.element;
     if (_isObjectLiteral(classElem)) {
-      return _emitObjectLiteral(argumentList);
+      var args = emitArguments();
+      return args.isEmpty ? js.call('{}') : args.single as JS.ObjectInitializer;
     }
 
+    var name = element.name;
     JS.Expression emitNew() {
-      var args = _emitArgumentList(argumentList);
-      if (argumentList.arguments.isEmpty && element.source.isInSystemLibrary) {
+      var args = emitArguments();
+      if (args.isEmpty && classElem.source.isInSystemLibrary) {
         // Skip the slow SDK factory constructors when possible.
         switch (classElem.name) {
           case 'Map':
           case 'HashMap':
           case 'LinkedHashMap':
-            if (element.name == '') {
+            if (name == '') {
               return js.call('new #.new()', _emitMapImplType(type));
-            } else if (element.name == 'identity') {
+            } else if (name == 'identity') {
               return js.call(
                   'new #.new()', _emitMapImplType(type, identity: true));
             }
@@ -4438,22 +4409,22 @@
           case 'Set':
           case 'HashSet':
           case 'LinkedHashSet':
-            if (element.name == '') {
+            if (name == '') {
               return js.call('new #.new()', _emitSetImplType(type));
-            } else if (element.name == 'identity') {
+            } else if (name == 'identity') {
               return js.call(
                   'new #.new()', _emitSetImplType(type, identity: true));
             }
             break;
           case 'List':
-            if (element.name == '' && type is InterfaceType) {
+            if (name == '' && type is InterfaceType) {
               return _emitList(type.typeArguments[0], []);
             }
             break;
         }
       }
       // Native factory constructors are JS constructors - use new here.
-      var ctor = _emitConstructorName(element, type);
+      var ctor = _emitConstructorName(type, name);
       if (ctorNode != null) ctor.sourceInformation = _nodeSpan(ctorNode);
       return element.isFactory && !_hasJSInteropAnnotation(classElem)
           ? new JS.Call(ctor, args)
@@ -4482,57 +4453,99 @@
   bool _hasJSInteropAnnotation(Element e) =>
       findAnnotation(e, isPublicJSAnnotation) != null;
 
-  JS.Expression _emitObjectLiteral(ArgumentList argumentList) {
-    var args = _emitArgumentList(argumentList);
-    if (args.isEmpty) {
-      return js.call('{}');
-    }
-    assert(args.single is JS.ObjectInitializer);
-    return args.single;
-  }
-
   /// If the constant [value] is primitive, directly emit the
   /// corresponding JavaScript.  Otherwise, return null.
-  JS.Expression _emitDartObject(DartObjectImpl value,
-      {bool handleUnknown: false}) {
+  JS.Expression _emitDartObject(DartObject value, {bool handleUnknown: false}) {
     if (value == null || value.isNull) {
       return new JS.LiteralNull();
     }
+    var type = value.type;
     // Handle unknown value: when the declared variable wasn't found, and no
     // explicit default value was passed either.
     // TODO(jmesserly): ideally Analyzer would simply resolve this to the
     // default value that is specified in the SDK. Instead we implement that
     // here. `bool.fromEnvironment` defaults to `false`, the others to `null`:
     // https://api.dartlang.org/stable/1.20.1/dart-core/bool/bool.fromEnvironment.html
-    if (value.isUnknown) {
-      if (!handleUnknown) {
-        return null;
-      } else {
-        return value.type == types.boolType
-            ? js.boolean(false)
-            : new JS.LiteralNull();
-      }
+    if (!value.hasKnownValue) {
+      if (!handleUnknown) return null;
+      return type == types.boolType ? js.boolean(false) : new JS.LiteralNull();
     }
-    if (value.type == types.boolType) {
-      var boolValue = value.toBoolValue();
-      return js.boolean(boolValue);
+    if (type == types.boolType) {
+      return js.boolean(value.toBoolValue());
     }
-    if (value.type == types.intType) {
-      var intValue = value.toIntValue();
-      return js.number(intValue);
+    if (type == types.intType) {
+      return js.number(value.toIntValue());
     }
-    if (value.type == types.stringType) {
+    if (type == types.doubleType) {
+      return js.number(value.toDoubleValue());
+    }
+    if (type == types.stringType) {
       var stringValue = value.toStringValue();
       return js.escapedString(stringValue);
     }
-    return null;
+    if (type == types.symbolType) {
+      return _emitDartSymbol(value.toSymbolValue());
+    }
+    if (type == types.typeType) {
+      return _emitType(value.toTypeValue());
+    }
+    if (type is InterfaceType) {
+      if (type.element == types.listType.element) {
+        return _cacheConst(() => _emitConstList(type.typeArguments[0],
+            value.toListValue().map(_emitDartObject).toList()));
+      }
+      if (type.element == types.mapType.element) {
+        return _cacheConst(() {
+          var entries = <JS.Expression>[];
+          value.toMapValue().forEach((key, value) {
+            entries.add(_emitDartObject(key));
+            entries.add(_emitDartObject(value));
+          });
+          return _emitConstMap(type, entries);
+        });
+      }
+      if (value is DartObjectImpl && value.isUserDefinedObject) {
+        var ctor = value.getInvocation();
+        var classElem = type.element;
+        if (classElem.isEnum) {
+          // TODO(jmesserly): we should be able to use `getField('index')` but
+          // in some cases Analyzer uses the name of the static field that
+          // contains the enum, rather than the `index` field, due to a bug.
+          //
+          // So we just grab the one instance field, regardless of its name.
+          var index = value.fields.values.single.toIntValue();
+          var field =
+              classElem.fields.where((f) => f.type == type).elementAt(index);
+          return _emitClassMemberElement(field, field.getter, null);
+        }
+        return _emitInstanceCreationExpression(ctor.constructor, type, () {
+          var args = ctor.positionalArguments.map(_emitDartObject).toList();
+          var named = <JS.Property>[];
+          ctor.namedArguments.forEach((name, value) {
+            named.add(
+                new JS.Property(_propertyName(name), _emitDartObject(value)));
+          });
+          if (named.isNotEmpty) args.add(new JS.ObjectInitializer(named));
+          return args;
+        }, isConst: true);
+      }
+    }
+    if (value is DartObjectImpl && type is FunctionType) {
+      Element element = value.toFunctionValue();
+      if (element.enclosingElement is CompilationUnitElement) {
+        return _emitLibraryMemberElement(element, null);
+      }
+      if (element is ClassMemberElement) {
+        return _emitClassMemberElement(element, element, null);
+      }
+    }
+    return _unreachable(value);
   }
 
   @override
   visitInstanceCreationExpression(InstanceCreationExpression node) {
     var element = resolutionMap.staticElementForConstructorReference(node);
     var constructor = node.constructorName;
-    var name = constructor.name;
     if (node.isConst &&
         element?.name == 'fromEnvironment' &&
         element.library.isDartCore) {
@@ -4561,10 +4574,9 @@
     return _emitInstanceCreationExpression(
         element,
         getType(constructor.type) as InterfaceType,
-        name,
-        node.argumentList,
-        node.isConst,
-        constructor);
+        () => _emitArgumentList(node.argumentList),
+        isConst: node.isConst,
+        ctorNode: constructor);
   }
 
   bool isPrimitiveType(DartType t) => _typeRep.isPrimitive(t);
@@ -4968,7 +4980,7 @@
     if (_currentFunction == null || usesTypeParams) return jsExpr;
 
     var temp = new JS.TemporaryId('const');
-    _moduleItems.add(js.statement('let #;', [temp]));
+    moduleItems.add(js.statement('let #;', [temp]));
     return js.call('# || (# = #)', [temp, temp, jsExpr]);
   }
 
@@ -5504,9 +5516,7 @@
     var createStreamIter = _emitInstanceCreationExpression(
         streamIterator.element.unnamedConstructor,
         streamIterator,
-        null,
-        ast.argumentList([node.iterable]),
-        false);
+        () => [_visitExpression(node.iterable)]);
     var iter = new JS.TemporaryId('iter');
     var variable = node.identifier ?? node.loopVariable.identifier;
     var init = _visitExpression(node.identifier);
@@ -5702,24 +5712,24 @@
 
   @override
   visitSymbolLiteral(SymbolLiteral node) {
-    JS.Expression emitSymbol() {
-      // TODO(vsm): Handle qualified symbols correctly.
-      var last = node.components.last.toString();
-      var name = js.string(node.components.join('.'), "'");
-      if (last.startsWith('_')) {
-        var nativeSymbol = _emitPrivateNameSymbol(currentLibrary, last);
-        return js.call('new #.new(#, #)', [
-          _emitConstructorAccess(privateSymbolClass.type),
-          name,
-          nativeSymbol
-        ]);
-      } else {
-        return js
-            .call('#.new(#)', [_emitConstructorAccess(types.symbolType), name]);
-      }
-    }
+    return _emitConst(() => _emitDartSymbol(node.components.join('.')));
+  }
 
-    return _emitConst(emitSymbol);
+  JS.Expression _emitDartSymbol(String name) {
+    // TODO(vsm): Handle qualified symbols correctly.
+    var last = name.substring(name.lastIndexOf('.') + 1);
+    var jsName = js.string(name, "'");
+    if (last.startsWith('_')) {
+      var nativeSymbol = emitPrivateNameSymbol(currentLibrary, last);
+      return js.call('new #.new(#, #)', [
+        _emitConstructorAccess(privateSymbolClass.type),
+        jsName,
+        nativeSymbol
+      ]);
+    } else {
+      return js
+          .call('#.new(#)', [_emitConstructorAccess(types.symbolType), jsName]);
+    }
   }
 
   @override
@@ -5760,7 +5770,7 @@
         entries.add(_visitExpression(e.key));
         entries.add(_visitExpression(e.value));
       }
-      return new JS.ArrayInitializer(entries);
+      return entries;
     }
 
     var type = node.staticType as InterfaceType;
@@ -5769,11 +5779,15 @@
       if (node.entries.isEmpty) {
         return js.call('new #.new()', [mapType]);
       }
-      return js.call('new #.from(#)', [mapType, emitEntries()]);
+      return js.call('new #.from([#])', [mapType, emitEntries()]);
     }
+    return _cacheConst(() => _emitConstMap(type, emitEntries()));
+  }
+
+  JS.Expression _emitConstMap(InterfaceType type, List<JS.Expression> entries) {
     var typeArgs = type.typeArguments;
-    return _cacheConst(() => runtimeCall('constMap(#, #, #)',
-        [_emitType(typeArgs[0]), _emitType(typeArgs[1]), emitEntries()]));
+    return runtimeCall('constMap(#, #, [#])',
+        [_emitType(typeArgs[0]), _emitType(typeArgs[1]), entries]);
   }
 
   JS.Expression _emitMapImplType(InterfaceType type, {bool identity}) {
@@ -6063,7 +6077,7 @@
     }
 
     if (name.startsWith('_')) {
-      return _emitPrivateNameSymbol(currentLibrary, name);
+      return emitPrivateNameSymbol(currentLibrary, name);
     }
 
     useExtension ??= _isSymbolizedMember(type, name);
@@ -6185,17 +6199,6 @@
     return false;
   }
 
-  JS.TemporaryId _emitPrivateNameSymbol(LibraryElement library, String name) {
-    return _privateNames
-        .putIfAbsent(library, () => new HashMap())
-        .putIfAbsent(name, () {
-      var id = new JS.TemporaryId(name);
-      _moduleItems.add(
-          js.statement('const # = Symbol(#);', [id, js.string(id.name, "'")]));
-      return id;
-    });
-  }
-
   /// Returns the canonical name to refer to the Dart library.
   JS.Identifier emitLibraryName(LibraryElement library) {
     // It's either one of the libraries in this module, or it's an import.
@@ -6277,7 +6280,7 @@
   JS.Expression _throwUnsafe(String message) => runtimeCall(
       'throw(Error(#))', js.escapedString("compile error: $message"));
 
-  JS.Node _unreachable(AstNode node) {
+  JS.Node _unreachable(Object node) {
     throw new UnsupportedError(
         'tried to generate an unreachable node: `$node`');
   }
diff --git a/pkg/dev_compiler/lib/src/analyzer/element_helpers.dart b/pkg/dev_compiler/lib/src/analyzer/element_helpers.dart
index d855eb6..928e5e4 100644
--- a/pkg/dev_compiler/lib/src/analyzer/element_helpers.dart
+++ b/pkg/dev_compiler/lib/src/analyzer/element_helpers.dart
@@ -76,6 +76,7 @@
 /// inDeclarationContext, this method returns true if [node] is used in an
 /// invocation context such as a MethodInvocation.
 bool inInvocationContext(Expression node) {
+  if (node == null) return false;
   var parent = node.parent;
   while (parent is ParenthesizedExpression) {
     node = parent;
diff --git a/pkg/dev_compiler/lib/src/analyzer/module_compiler.dart b/pkg/dev_compiler/lib/src/analyzer/module_compiler.dart
index deb7004..22d64ab 100644
--- a/pkg/dev_compiler/lib/src/analyzer/module_compiler.dart
+++ b/pkg/dev_compiler/lib/src/analyzer/module_compiler.dart
@@ -7,15 +7,17 @@
 import 'dart:io' show File;
 
 import 'package:analyzer/analyzer.dart'
-    show AnalysisError, CompilationUnit, ErrorSeverity;
+    show AnalysisError, CompilationUnit, ErrorSeverity, ErrorType;
 import 'package:analyzer/dart/analysis/declared_variables.dart';
-import 'package:analyzer/dart/element/element.dart' show LibraryElement;
+import 'package:analyzer/dart/element/element.dart'
+    show LibraryElement, UriReferencedElement;
 import 'package:analyzer/file_system/file_system.dart' show ResourceProvider;
 import 'package:analyzer/file_system/physical_file_system.dart'
     show PhysicalResourceProvider;
 import 'package:analyzer/src/context/builder.dart' show ContextBuilder;
 import 'package:analyzer/src/context/context.dart' show AnalysisContextImpl;
-import 'package:analyzer/src/error/codes.dart' show StaticTypeWarningCode;
+import 'package:analyzer/src/error/codes.dart'
+    show StaticTypeWarningCode, StrongModeCode;
 import 'package:analyzer/src/generated/engine.dart'
     show AnalysisContext, AnalysisEngine;
 import 'package:analyzer/src/generated/sdk.dart' show DartSdkManager;
@@ -192,6 +194,16 @@
       librariesToCompile.addAll(library.importedLibraries);
       librariesToCompile.addAll(library.exportedLibraries);
 
+      // TODO(jmesserly): remove "dart:mirrors" from DDC's SDK, and then remove
+      // this special case error message.
+      if (!compilingSdk && !options.emitMetadata) {
+        var node = _getDartMirrorsImport(library);
+        if (node != null) {
+          errors.add(new AnalysisError(library.source, node.uriOffset,
+              node.uriEnd, invalidImportDartMirrors));
+        }
+      }
+
       var tree = context.resolveCompilationUnit(library.source, library);
       trees.add(tree);
       errors.addAll(context.computeErrors(library.source));
@@ -231,6 +243,15 @@
   }
 }
 
+UriReferencedElement _getDartMirrorsImport(LibraryElement library) {
+  return library.imports.firstWhere(_isDartMirrorsImort, orElse: () => null) ??
+      library.exports.firstWhere(_isDartMirrorsImort, orElse: () => null);
+}
+
+bool _isDartMirrorsImort(UriReferencedElement import) {
+  return import.uri == 'dart:mirrors';
+}
+
 class CompilerOptions {
   /// Whether to emit the source mapping file.
   ///
@@ -588,3 +609,8 @@
       return new Uri.file(path.absolute(source));
   }
 }
+
+const invalidImportDartMirrors = const StrongModeCode(
+    ErrorType.COMPILE_TIME_ERROR,
+    'IMPORT_DART_MIRRORS',
+    'Cannot import "dart:mirrors" in web applications (https://goo.gl/R1anEs).');
diff --git a/pkg/dev_compiler/lib/src/compiler/js_names.dart b/pkg/dev_compiler/lib/src/compiler/js_names.dart
index 0310d63..5c212f1 100644
--- a/pkg/dev_compiler/lib/src/compiler/js_names.dart
+++ b/pkg/dev_compiler/lib/src/compiler/js_names.dart
@@ -72,8 +72,8 @@
     return node.name;
   }
 
-  void enterScope(FunctionExpression node) {
-    scope = scope.functions[node];
+  void enterScope(Node node) {
+    scope = scope.childScopes[node];
   }
 
   void leaveScope() {
@@ -83,8 +83,7 @@
 
 /// Represents a complete function scope in JS.
 ///
-/// We don't currently track ES6 block scopes, because we don't represent them
-/// in js_ast yet.
+/// We don't currently track ES6 block scopes.
 class _FunctionScope {
   /// The parent scope.
   final _FunctionScope parent;
@@ -97,9 +96,9 @@
   /// not collide with inside this scope.
   final used = new HashSet<String>();
 
-  /// Nested functions, these are visited after everything else so the names
+  /// Nested scopes, these are visited after everything else so the names
   /// they might need are in scope.
-  final functions = new Map<FunctionExpression, _FunctionScope>();
+  final childScopes = new Map<Node, _FunctionScope>();
 
   /// New names assigned for temps and identifiers.
   final renames = new HashMap<Object, String>();
@@ -118,7 +117,7 @@
   _RenameVisitor.build(Node root) {
     scope = rootScope;
     root.accept(this);
-    _finishFunctions();
+    _finishScopes();
     _finishNames();
   }
 
@@ -166,14 +165,22 @@
 
   visitFunctionExpression(FunctionExpression node) {
     // Visit nested functions after all identifiers are declared.
-    scope.functions[node] = new _FunctionScope(scope);
+    scope.childScopes[node] = new _FunctionScope(scope);
   }
 
-  void _finishFunctions() {
-    scope.functions.forEach((FunctionExpression f, _FunctionScope s) {
+  visitClassExpression(ClassExpression node) {
+    scope.childScopes[node] = new _FunctionScope(scope);
+  }
+
+  void _finishScopes() {
+    scope.childScopes.forEach((node, s) {
       scope = s;
-      super.visitFunctionExpression(f);
-      _finishFunctions();
+      if (node is FunctionExpression) {
+        super.visitFunctionExpression(node);
+      } else {
+        super.visitClassExpression(node);
+      }
+      _finishScopes();
       scope = scope.parent;
     });
   }
diff --git a/pkg/dev_compiler/lib/src/compiler/shared_compiler.dart b/pkg/dev_compiler/lib/src/compiler/shared_compiler.dart
index 10e9782..d2fa9c5 100644
--- a/pkg/dev_compiler/lib/src/compiler/shared_compiler.dart
+++ b/pkg/dev_compiler/lib/src/compiler/shared_compiler.dart
@@ -2,6 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+import 'dart:collection';
 import '../compiler/js_metalet.dart' as JS;
 import '../compiler/js_names.dart' as JS;
 import '../compiler/js_utils.dart' as JS;
@@ -12,7 +13,7 @@
 ///
 /// This class should only implement functionality that depends purely on JS
 /// classes, rather than on Analyzer/Kernel types.
-abstract class SharedCompiler {
+abstract class SharedCompiler<Library> {
   /// When inside a `[]=` operator, this will be a non-null value that should be
   /// returned by any `return;` statement.
   ///
@@ -22,6 +23,11 @@
   JS.Identifier runtimeModule;
   final namedArgumentTemp = new JS.TemporaryId('opts');
 
+  final _privateNames = new HashMap<Library, HashMap<String, JS.TemporaryId>>();
+
+  /// The list of output module items, in the order they need to be emitted in.
+  final moduleItems = <JS.ModuleItem>[];
+
   /// When compiling the body of a `operator []=` method, this will be non-null
   /// and will indicate the the value that should be returned from any `return;`
   /// statements.
@@ -122,4 +128,19 @@
   JS.Statement runtimeStatement(String code, [args]) {
     return runtimeCall(code, args).toStatement();
   }
+
+  JS.TemporaryId emitPrivateNameSymbol(Library library, String name) {
+    return _privateNames
+        .putIfAbsent(library, () => new HashMap())
+        .putIfAbsent(name, () {
+      var idName = name;
+      if (idName.endsWith('=')) {
+        idName = idName.replaceAll('=', '_');
+      }
+      var id = new JS.TemporaryId(idName);
+      moduleItems.add(
+          js.statement('const # = Symbol(#);', [id, js.string(name, "'")]));
+      return id;
+    });
+  }
 }
diff --git a/pkg/dev_compiler/lib/src/js_ast/printer.dart b/pkg/dev_compiler/lib/src/js_ast/printer.dart
index ea97d34..58c8bbb 100644
--- a/pkg/dev_compiler/lib/src/js_ast/printer.dart
+++ b/pkg/dev_compiler/lib/src/js_ast/printer.dart
@@ -1130,6 +1130,7 @@
   }
 
   visitClassExpression(ClassExpression node) {
+    localNamer.enterScope(node);
     out('class ');
     visit(node.name);
     outTypeParams(node.typeParams);
@@ -1161,6 +1162,7 @@
     } else {
       out('{}');
     }
+    localNamer.leaveScope();
   }
 
   visitMethod(Method node) {
@@ -1545,13 +1547,13 @@
 
 abstract class LocalNamer {
   String getName(Identifier node);
-  void enterScope(FunctionExpression node);
+  void enterScope(Node node);
   void leaveScope();
 }
 
 class IdentityNamer implements LocalNamer {
   String getName(Identifier node) => node.name;
-  void enterScope(FunctionExpression node) {}
+  void enterScope(Node node) {}
   void leaveScope() {}
 }
 
@@ -1562,7 +1564,7 @@
   int parameterNumber = 0;
   int variableNumber = 0;
 
-  void enterScope(FunctionExpression node) {
+  void enterScope(Node node) {
     var vars = new VarCollector();
     node.accept(vars);
     maps.add(new Map<String, String>());
@@ -1688,10 +1690,11 @@
   }
 
   _scanVariableBinding(VariableBinding d) {
-    if (d is Identifier)
+    if (d is Identifier) {
       declare(d);
-    else
+    } else {
       d.accept(this);
+    }
   }
 
   visitRestParameter(RestParameter node) {
diff --git a/pkg/dev_compiler/lib/src/kernel/command.dart b/pkg/dev_compiler/lib/src/kernel/command.dart
index 0510037..b2b01e9 100644
--- a/pkg/dev_compiler/lib/src/kernel/command.dart
+++ b/pkg/dev_compiler/lib/src/kernel/command.dart
@@ -198,20 +198,25 @@
     return new CompilerResult(compilerState, false);
   }
 
+  var component = result.component;
+  var emitMetadata = argResults['emit-metadata'] as bool;
+  if (!emitMetadata && _checkForDartMirrorsImport(component)) {
+    return new CompilerResult(compilerState, false);
+  }
+
   String output = argResults['out'];
   var file = new File(output);
   if (!file.parent.existsSync()) file.parent.createSync(recursive: true);
 
-  // Useful for debugging:
-  writeComponentToText(result.component, path: output + '.txt');
-
   // TODO(jmesserly): Save .dill file so other modules can link in this one.
   //await writeComponentToBinary(component, output);
-  var component = result.component;
+
+  // Useful for debugging:
+  writeComponentToText(component, path: output + '.txt');
 
   var compiler = new ProgramCompiler(component,
       declaredVariables: declaredVariables,
-      emitMetadata: argResults['emit-metadata'] as bool,
+      emitMetadata: emitMetadata,
       enableAsserts: argResults['enable-asserts'] as bool);
   var jsModule =
       compiler.emitModule(component, result.inputSummaries, summaryUris);
@@ -385,3 +390,18 @@
     'lib',
     '_internal',
     'ddc_sdk.dill');
+
+bool _checkForDartMirrorsImport(Component component) {
+  for (var library in component.libraries) {
+    if (library.isExternal) continue;
+    for (var dep in library.dependencies) {
+      var uri = dep.targetLibrary.importUri;
+      if (uri.scheme == 'dart' && uri.path == 'mirrors') {
+        print('${library.importUri}: Error: Cannot import "dart:mirrors" '
+            'in web applications (https://goo.gl/R1anEs).');
+        return true;
+      }
+    }
+  }
+  return false;
+}
diff --git a/pkg/dev_compiler/lib/src/kernel/compiler.dart b/pkg/dev_compiler/lib/src/kernel/compiler.dart
index 819227d..0a66690 100644
--- a/pkg/dev_compiler/lib/src/kernel/compiler.dart
+++ b/pkg/dev_compiler/lib/src/kernel/compiler.dart
@@ -8,7 +8,8 @@
 import 'package:front_end/src/fasta/type_inference/type_schema_environment.dart';
 import 'package:kernel/class_hierarchy.dart';
 import 'package:kernel/core_types.dart';
-import 'package:kernel/kernel.dart' hide ConstantVisitor;
+import 'package:kernel/kernel.dart';
+import 'package:kernel/library_index.dart';
 import 'package:kernel/type_algebra.dart';
 import 'package:kernel/type_environment.dart';
 import 'package:source_span/source_span.dart' show SourceLocation;
@@ -20,6 +21,7 @@
 import '../js_ast/js_ast.dart' as JS;
 import '../js_ast/js_ast.dart' show js;
 import '../js_ast/source_map_printer.dart' show NodeEnd, NodeSpan, HoverComment;
+import 'constants.dart';
 import 'js_interop.dart';
 import 'js_typerep.dart';
 import 'kernel_helpers.dart';
@@ -29,14 +31,12 @@
 import 'type_table.dart';
 
 class ProgramCompiler extends Object
-    with SharedCompiler
+    with SharedCompiler<Library>
     implements
         StatementVisitor<JS.Statement>,
         ExpressionVisitor<JS.Expression>,
-        DartTypeVisitor<JS.Expression> {
-  /// The list of output module items, in the order they need to be emitted in.
-  final _moduleItems = <JS.ModuleItem>[];
-
+        DartTypeVisitor<JS.Expression>,
+        ConstantVisitor<JS.Expression> {
   /// The set of libraries we are currently compiling, and the temporaries used
   /// to refer to them.
   ///
@@ -60,9 +60,6 @@
   /// In an async* function, this represents the stream controller parameter.
   JS.TemporaryId _asyncStarController;
 
-  // TODO(jmesserly): fuse this with notNull check.
-  final _privateNames = new HashMap<Library, HashMap<String, JS.TemporaryId>>();
-
   JS.Identifier _extensionSymbolsModule;
   final _extensionSymbols = new Map<String, JS.TemporaryId>();
 
@@ -134,8 +131,6 @@
   final bool enableAsserts;
   final bool replCompile;
 
-  final Map<String, String> declaredVariables;
-
   // Compilation of Kernel's [BreakStatement].
   //
   // Kernel represents Dart's `break` and `continue` uniformly as
@@ -199,7 +194,7 @@
   /// The dart:async `StreamIterator<T>` type.
   final Class _asyncStreamIteratorClass;
 
-  final ConstantVisitor _constants;
+  final DevCompilerConstants _constants;
 
   final NullableInference _nullableInference;
 
@@ -208,48 +203,36 @@
       bool replCompile: false,
       bool enableAsserts: true,
       Map<String, String> declaredVariables: const {}}) {
-    var nativeTypes = new NativeTypeSet(component);
+    var coreTypes = new CoreTypes(component);
     var types = new TypeSchemaEnvironment(
-        nativeTypes.coreTypes, new ClassHierarchy(component), true);
-    return new ProgramCompiler._(
-        nativeTypes, new JSTypeRep(types, nativeTypes.sdk),
+        coreTypes, new ClassHierarchy(component), true);
+    var constants = new DevCompilerConstants(types, declaredVariables);
+    var nativeTypes = new NativeTypeSet(coreTypes, constants);
+    var jsTypeRep = new JSTypeRep(types);
+    return new ProgramCompiler._(coreTypes, coreTypes.index, nativeTypes,
+        constants, types, jsTypeRep, new NullableInference(jsTypeRep),
         emitMetadata: emitMetadata,
         enableAsserts: enableAsserts,
-        replCompile: replCompile,
-        declaredVariables: declaredVariables);
+        replCompile: replCompile);
   }
 
-  ProgramCompiler._(NativeTypeSet nativeTypes, this._typeRep,
-      {this.emitMetadata,
-      this.enableAsserts,
-      this.replCompile,
-      this.declaredVariables})
-      : _extensionTypes = nativeTypes,
-        types = _typeRep.types,
-        coreTypes = nativeTypes.coreTypes,
-        _constants = new ConstantVisitor(nativeTypes.coreTypes),
-        _jsArrayClass =
-            nativeTypes.sdk.getClass('dart:_interceptors', 'JSArray'),
-        _jsBoolClass = nativeTypes.sdk.getClass('dart:_interceptors', 'JSBool'),
-        _jsNumberClass =
-            nativeTypes.sdk.getClass('dart:_interceptors', 'JSNumber'),
-        _jsStringClass =
-            nativeTypes.sdk.getClass('dart:_interceptors', 'JSString'),
+  ProgramCompiler._(this.coreTypes, LibraryIndex sdk, this._extensionTypes,
+      this._constants, this.types, this._typeRep, this._nullableInference,
+      {this.emitMetadata, this.enableAsserts, this.replCompile})
+      : _jsArrayClass = sdk.getClass('dart:_interceptors', 'JSArray'),
+        _jsBoolClass = sdk.getClass('dart:_interceptors', 'JSBool'),
+        _jsNumberClass = sdk.getClass('dart:_interceptors', 'JSNumber'),
+        _jsStringClass = sdk.getClass('dart:_interceptors', 'JSString'),
         _asyncStreamIteratorClass =
-            nativeTypes.sdk.getClass('dart:async', 'StreamIterator'),
-        privateSymbolClass =
-            nativeTypes.sdk.getClass('dart:_js_helper', 'PrivateSymbol'),
-        linkedHashMapImplClass =
-            nativeTypes.sdk.getClass('dart:_js_helper', 'LinkedMap'),
+            sdk.getClass('dart:async', 'StreamIterator'),
+        privateSymbolClass = sdk.getClass('dart:_js_helper', 'PrivateSymbol'),
+        linkedHashMapImplClass = sdk.getClass('dart:_js_helper', 'LinkedMap'),
         identityHashMapImplClass =
-            nativeTypes.sdk.getClass('dart:_js_helper', 'IdentityMap'),
-        linkedHashSetImplClass =
-            nativeTypes.sdk.getClass('dart:collection', '_HashSet'),
+            sdk.getClass('dart:_js_helper', 'IdentityMap'),
+        linkedHashSetImplClass = sdk.getClass('dart:collection', '_HashSet'),
         identityHashSetImplClass =
-            nativeTypes.sdk.getClass('dart:collection', '_IdentityHashSet'),
-        syncIterableClass =
-            nativeTypes.sdk.getClass('dart:_js_helper', 'SyncIterable'),
-        _nullableInference = new NullableInference(_typeRep);
+            sdk.getClass('dart:collection', '_IdentityHashSet'),
+        syncIterableClass = sdk.getClass('dart:_js_helper', 'SyncIterable');
 
   ClassHierarchy get hierarchy => types.hierarchy;
 
@@ -257,7 +240,7 @@
 
   JS.Program emitModule(
       Component buildUnit, List<Component> summaries, List<Uri> summaryUris) {
-    if (_moduleItems.isNotEmpty) {
+    if (moduleItems.isNotEmpty) {
       throw new StateError('Can only call emitModule once.');
     }
     _component = buildUnit;
@@ -352,7 +335,7 @@
     items.addAll(_typeTable.discharge());
 
     // Add the module's code (produced by visiting compilation units, above)
-    _copyAndFlattenBlocks(items, _moduleItems);
+    _copyAndFlattenBlocks(items, moduleItems);
 
     // Build the module.
     return new JS.Program(items, name: buildUnit.root.name);
@@ -491,7 +474,7 @@
     if (node is Procedure && node.name.name == 'main') {
       // Don't allow redefining names from this library.
       var name = _emitTopLevelName(export.node);
-      _moduleItems.add(js.statement(
+      moduleItems.add(js.statement(
           '#.# = #;', [emitLibraryName(library), name.selector, name]));
     }
   }
@@ -515,7 +498,7 @@
     _currentLibrary = c.enclosingLibrary;
     _currentUri = c.fileUri;
 
-    _moduleItems.add(_emitClassDeclaration(c));
+    moduleItems.add(_emitClassDeclaration(c));
 
     _currentClass = savedClass;
     types.thisType = savedClass?.thisType;
@@ -548,14 +531,17 @@
     var jsTypeDef = _emitJSType(c);
     if (jsTypeDef != null) return jsTypeDef;
 
-    JS.Expression className;
-    if (c.typeParameters.isNotEmpty) {
-      // Generic classes will be defined inside a function that closes over the
-      // type parameter. So we can use their local variable name directly.
-      className = new JS.Identifier(getLocalClassName(c));
-    } else {
-      className = _emitTopLevelName(c);
-    }
+    // Generic classes will be defined inside a function that closes over the
+    // type parameter. So we can use their local variable name directly.
+    //
+    // TODO(jmesserly): the special case for JSArray is to support its special
+    // type-tagging factory constructors. Those will go away once we fix:
+    // https://github.com/dart-lang/sdk/issues/31003
+    var className = c.typeParameters.isNotEmpty
+        ? (c == _jsArrayClass
+            ? new JS.Identifier(c.name)
+            : new JS.TemporaryId(getLocalClassName(c)))
+        : _emitTopLevelName(c);
 
     var savedClassProperties = _classProperties;
     _classProperties =
@@ -636,14 +622,14 @@
 
   JS.Statement _emitClassStatement(Class c, JS.Expression className,
       JS.Expression heritage, List<JS.Method> methods) {
-    var name = getLocalClassName(c);
-    var classExpr =
-        new JS.ClassExpression(new JS.Identifier(name), heritage, methods);
     if (c.typeParameters.isNotEmpty) {
-      return classExpr.toStatement();
-    } else {
-      return js.statement('# = #;', [className, classExpr]);
+      return new JS.ClassExpression(
+              className as JS.Identifier, heritage, methods)
+          .toStatement();
     }
+    var classExpr = new JS.ClassExpression(
+        new JS.TemporaryId(getLocalClassName(c)), heritage, methods);
+    return js.statement('# = #;', [className, classExpr]);
   }
 
   void _defineClass(Class c, JS.Expression className, List<JS.Method> methods,
@@ -1059,7 +1045,7 @@
       // TODO(jmesserly): we could export these symbols, if we want to mark
       // implemented interfaces for user-defined classes.
       var id = new JS.TemporaryId("_is_${getLocalClassName(c)}_default");
-      _moduleItems.add(
+      moduleItems.add(
           js.statement('const # = Symbol(#);', [id, js.string(id.name, "'")]));
       isClassSymbol = id;
     }
@@ -1219,9 +1205,6 @@
     }
 
     var classProcedures = c.procedures.where((p) => !p.isAbstract).toList();
-    for (var m in _classProperties.mockMembers.values) {
-      if (m is Procedure) classProcedures.add(m);
-    }
     for (var member in classProcedures) {
       // Static getters/setters/methods cannot be called with dynamic dispatch,
       // nor can they be torn off.
@@ -1276,9 +1259,6 @@
     var staticFields = <JS.Property>[];
 
     var classFields = c.fields.toList();
-    for (var m in _classProperties.mockMembers.values) {
-      if (m is Field) classFields.add(m);
-    }
     for (var field in classFields) {
       // Only instance fields need to be saved for dynamic dispatch.
       var isStatic = field.isStatic;
@@ -1644,11 +1624,6 @@
     }
     _currentUri = savedUri;
 
-    _classProperties.mockMembers.forEach((String name, Member member) {
-      jsMethods
-          .add(_implementMockMember(member, c, isSetter: name.endsWith('=')));
-    });
-
     // If the type doesn't have an `iterator`, but claims to implement Iterable,
     // we inject the adaptor method here, as it's less code size to put the
     // helper on a parent class. This pattern is common in the core libraries
@@ -1674,7 +1649,7 @@
     }
 
     JS.Fun fn;
-    if (member.isExternal) {
+    if (member.isExternal && !member.isNoSuchMethodForwarder) {
       if (member.isStatic) {
         // TODO(vsm): Do we need to handle this case?
         return null;
@@ -1820,122 +1795,6 @@
     return _emitJSInterop(type.classNode) ?? visitInterfaceType(type);
   }
 
-  /// Given a class C that implements method M from interface I, but does not
-  /// declare M, this will generate an implementation that forwards to
-  /// noSuchMethod.
-  ///
-  /// For example:
-  ///
-  ///     class Cat {
-  ///       bool eatFood(String food) => true;
-  ///     }
-  ///     class MockCat implements Cat {
-  ///        noSuchMethod(Invocation invocation) => 3;
-  ///     }
-  ///
-  /// It will generate an `eatFood` that looks like:
-  ///
-  ///     eatFood(...args) {
-  ///       return core.bool.as(this.noSuchMethod(
-  ///           new dart.InvocationImpl.new('eatFood', args)));
-  ///     }
-  ///
-  /// Same technique is applied if interface I has fields, and C doesn't declare
-  /// neither the fields nor the corresponding getters and setters.
-  JS.Method _implementMockMember(Member member, Class c, {bool isSetter}) {
-    JS.Method implementMockMember(
-        ProcedureKind procedureKind, DartType returnType,
-        [List<TypeParameter> typeParameters,
-        List<JS.Parameter> positionalParameters,
-        List<VariableDeclaration> namedParameters]) {
-      assert(procedureKind != ProcedureKind.Factory);
-
-      var invocationProps = <JS.Property>[];
-      addProperty(String name, JS.Expression value) {
-        invocationProps.add(new JS.Property(js.string(name), value));
-      }
-
-      var typeParams = _emitTypeFormals(typeParameters ?? []);
-      var fnArgs = new List<JS.Parameter>.from(typeParams);
-      JS.Expression positionalArgs;
-      if (procedureKind == ProcedureKind.Getter) {
-        addProperty('isGetter', js.boolean(true));
-        positionalArgs = new JS.ArrayInitializer([]);
-      } else if (procedureKind == ProcedureKind.Setter) {
-        addProperty('isSetter', js.boolean(true));
-        var valueArg = new JS.TemporaryId('value');
-        positionalArgs = new JS.ArrayInitializer([valueArg]);
-        fnArgs.add(valueArg);
-      } else {
-        addProperty('isMethod', js.boolean(true));
-        if (namedParameters.isNotEmpty) {
-          // Named parameters need to be emitted in the correct position (after
-          // positional arguments) so we can detect them reliably.
-          addProperty('namedArguments', namedArgumentTemp);
-          positionalArgs = new JS.ArrayInitializer(positionalParameters);
-          fnArgs.addAll(positionalParameters);
-          fnArgs.add(namedArgumentTemp);
-        } else {
-          // In case we have optional parameters, we need to use rest args,
-          // because sometimes mocks want to detect whether optional arguments
-          // were passed, and this does not work reliably with undefined (should
-          // not normally appear in DDC, but it can result from JS interop).
-          //
-          // TODO(jmesserly): perhaps we need to use rest args or destructuring
-          // to get reliable optional argument passing in other scenarios? It
-          // doesn't seem to occur outside of tests, perhaps due to the
-          // combination of mockito and protobufs.
-          positionalArgs = new JS.TemporaryId('args');
-          fnArgs.add(new JS.RestParameter(positionalArgs));
-        }
-      }
-
-      if (typeParams.isNotEmpty) {
-        addProperty('typeArguments', new JS.ArrayInitializer(typeParams));
-      }
-
-      var fnBody =
-          js.call('this.noSuchMethod(new #.InvocationImpl.new(#, #, #))', [
-        runtimeModule,
-        _declareMemberName(member),
-        positionalArgs,
-        new JS.ObjectInitializer(invocationProps)
-      ]);
-
-      returnType = _getTypeFromClass(returnType, member.enclosingClass, c);
-      fnBody = _emitImplicitCast(fnBody, returnType);
-
-      var fn = new JS.Fun(fnArgs, fnBody.toReturn().toBlock(),
-          typeParams: typeParams);
-
-      return new JS.Method(
-          _declareMemberName(member,
-              useExtension: _extensionTypes.isNativeClass(c)),
-          fn,
-          isGetter: procedureKind == ProcedureKind.Getter,
-          isSetter: procedureKind == ProcedureKind.Setter,
-          isStatic: false);
-    }
-
-    if (member is Field) {
-      if (isSetter) {
-        return implementMockMember(ProcedureKind.Setter, new VoidType());
-      } else {
-        return implementMockMember(ProcedureKind.Getter, member.type);
-      }
-    } else {
-      var procedure = member as Procedure;
-      var f = procedure.function;
-      assert(procedure.isSetter == isSetter);
-      return implementMockMember(
-          procedure.kind,
-          f.returnType,
-          f.typeParameters,
-          f.positionalParameters.map(_emitVariableRef).toList(),
-          f.namedParameters);
-    }
-  }
-
   /// This is called whenever a derived class needs to introduce a new field,
   /// shadowing a field or getter/setter pair on its parent.
   ///
@@ -1945,34 +1804,27 @@
   /// wrong behavior if a new field was declared.
   List<JS.Method> _emitVirtualFieldAccessor(Field field) {
     var virtualField = _classProperties.virtualFields[field];
-    var result = <JS.Method>[];
     var name = _declareMemberName(field);
 
-    var mocks = _classProperties.mockMembers;
-    if (!mocks.containsKey(field.name.name)) {
-      var getter = js.fun('function() { return this[#]; }', [virtualField]);
-      result.add(new JS.Method(name, getter, isGetter: true)
-        ..sourceInformation = _nodeStart(field));
+    var getter = js.fun('function() { return this[#]; }', [virtualField]);
+    var jsGetter = new JS.Method(name, getter, isGetter: true)
+      ..sourceInformation = _nodeStart(field);
+
+    var args =
+        field.isFinal ? [new JS.Super(), name] : [new JS.This(), virtualField];
+
+    JS.Expression value = new JS.Identifier('value');
+    if (!field.isFinal && field.isGenericCovariantImpl) {
+      value = _emitImplicitCast(value, field.type);
     }
+    args.add(value);
 
-    if (!mocks.containsKey(field.name.name + '=')) {
-      var args = field.isFinal
-          ? [new JS.Super(), name]
-          : [new JS.This(), virtualField];
+    var jsSetter = new JS.Method(
+        name, js.fun('function(value) { #[#] = #; }', args),
+        isSetter: true)
+      ..sourceInformation = _nodeStart(field);
 
-      JS.Expression value = new JS.Identifier('value');
-      if (!field.isFinal && field.isGenericCovariantImpl) {
-        value = _emitImplicitCast(value, field.type);
-      }
-      args.add(value);
-
-      result.add(new JS.Method(
-          name, js.fun('function(value) { #[#] = #; }', args),
-          isSetter: true)
-        ..sourceInformation = _nodeStart(field));
-    }
-
-    return result;
+    return [jsGetter, jsSetter];
   }
 
   /// Provide Dart getters and setters that forward to the underlying native
@@ -2111,7 +1963,7 @@
     }
 
     _currentUri = savedUri;
-    _moduleItems.add(result);
+    moduleItems.add(result);
   }
 
   void _emitTopLevelFields(List<Field> fields) {
@@ -2129,7 +1981,7 @@
             init is BasicLiteral ||
             init is StaticInvocation && isInlineJS(init.target)) {
           _currentUri = field.fileUri;
-          _moduleItems.add(js.statement('# = #;', [
+          moduleItems.add(js.statement('# = #;', [
             _emitTopLevelName(field),
             _visitInitializer(init, field.annotations)
           ]));
@@ -2143,7 +1995,7 @@
     }
 
     if (fields.isEmpty) return;
-    _moduleItems.add(_emitLazyFields(
+    moduleItems.add(_emitLazyFields(
         emitLibraryName(_currentLibrary), fields, _emitTopLevelMemberName));
   }
 
@@ -2291,7 +2143,7 @@
     }
 
     if (name.startsWith('_')) {
-      return _emitPrivateNameSymbol(_currentLibrary, name);
+      return emitPrivateNameSymbol(_currentLibrary, name);
     }
 
     useExtension ??= _isSymbolizedMember(type, name);
@@ -2372,17 +2224,6 @@
             hierarchy.getDispatchTarget(c, new Name(name), setter: true));
   }
 
-  JS.TemporaryId _emitPrivateNameSymbol(Library library, String name) {
-    return _privateNames
-        .putIfAbsent(library, () => new HashMap())
-        .putIfAbsent(name, () {
-      var id = new JS.TemporaryId(name);
-      _moduleItems.add(
-          js.statement('const # = Symbol(#);', [id, js.string(id.name, "'")]));
-      return id;
-    });
-  }
-
   JS.Expression _emitStaticMemberName(String name, [NamedNode member]) {
     if (member != null) {
       var jsName = _emitJSInteropStaticMemberName(member);
@@ -2474,7 +2315,7 @@
     var procedures = library.procedures
         .where((p) => !p.isExternal && !p.isAbstract)
         .toList();
-    _moduleItems.addAll(procedures
+    moduleItems.addAll(procedures
         .where((p) => !p.isAccessor)
         .map(_emitLibraryFunction)
         .toList());
@@ -2483,7 +2324,7 @@
 
   void _emitLibraryAccessors(Iterable<Procedure> accessors) {
     if (accessors.isEmpty) return;
-    _moduleItems.add(runtimeStatement('copyProperties(#, { # })', [
+    moduleItems.add(runtimeStatement('copyProperties(#, { # })', [
       emitLibraryName(_currentLibrary),
       accessors.map(_emitLibraryAccessor).toList()
     ]));
@@ -3720,10 +3561,9 @@
   @override
   visitInvalidExpression(InvalidExpression node) => defaultExpression(node);
 
-  // [ConstantExpression] is produced by the Kernel constant evaluator, which
-  // we do not use.
   @override
-  visitConstantExpression(ConstantExpression node) => defaultExpression(node);
+  visitConstantExpression(ConstantExpression node) =>
+      node.constant.accept(this);
 
   @override
   visitVariableGet(VariableGet node) {
@@ -3867,6 +3707,11 @@
   @override
   visitStaticGet(StaticGet node) {
     var target = node.target;
+    if (target is Field && target.isConst) {
+      var value = _constants.evaluate(target.initializer, cache: true);
+      if (value is PrimitiveConstant) return value.accept(this);
+    }
+
     var result = _emitStaticTarget(target);
     if (_reifyTearoff(target)) {
       // TODO(jmesserly): we could tag static/top-level function types once
@@ -4069,7 +3914,10 @@
       if (expr.value >= low && expr.value <= high) return expr.value;
       return null;
     }
-    // TODO(jmesserly): other constant evaluation here once kernel supports it.
+    if (_constants.isConstant(expr)) {
+      var c = _constants.evaluate(expr);
+      if (c is IntConstant && c.value >= low && c.value <= high) return c.value;
+    }
     return null;
   }
 
@@ -4520,33 +4368,10 @@
       source = (code as StringLiteral).value;
     }
 
-    // TODO(vsm): Constructors in dart:html and friends are trying to
-    // allocate a type defined on window/self, but this often conflicts a
-    // with the generated extension class in scope.  We really should
-    // qualify explicitly in dart:html itself.
-    var constructorPattern = new RegExp("new [A-Z][A-Za-z]+\\(");
-    if (constructorPattern.matchAsPrefix(source) != null) {
-      var enclosingClass = node.parent;
-      while (enclosingClass != null && enclosingClass is! Class) {
-        enclosingClass = enclosingClass.parent;
-      }
-      if (enclosingClass is Class &&
-          _extensionTypes.isNativeClass(enclosingClass)) {
-        var constructorName = source.substring(4, source.indexOf('('));
-        var className = enclosingClass.name;
-        if (className == constructorName) {
-          source =
-              source.replaceFirst('new $className(', 'new self.$className(');
-        }
-      }
-    }
-
-    // TODO(rnystrom): The JS() calls are almost never nested, and probably
-    // really shouldn't be, but there are at least a couple of calls in the
-    // HTML library where an argument to JS() is itself a JS() call. If those
-    // go away, this can just assert(!_isInForeignJS).
-    // Inside JS(), type names evaluate to the raw runtime type, not the
-    // wrapped Type object.
+    // TODO(jmesserly): arguments to JS() that contain type literals evaluate to
+    // the raw runtime type instead of the wrapped Type object.
+    // We can clean this up by switching to `unwrapType(<type literal>)`, which
+    // the compiler will then optimize.
     var wasInForeignJS = _isInForeignJS;
     _isInForeignJS = true;
     var jsArgs = templateArgs.map(_visitExpression).toList();
@@ -4644,31 +4469,11 @@
         ? ctorClass.rawType
         : new InterfaceType(ctorClass, args.types);
 
-    if (node.isConst &&
-        ctor.name.name == 'fromEnvironment' &&
-        ctor.enclosingLibrary == coreTypes.coreLibrary &&
-        args.positional.length == 1 &&
-        // TODO(jmesserly): this does not correctly handle when the arguments to
-        // fromEnvironment are constant non-literal values.
-        args.positional[0] is BasicLiteral) {
-      var varName = (args.positional[0] as StringLiteral).value;
-      var value = declaredVariables[varName];
-      var defaultArg = args.named.isNotEmpty ? args.named[0].value : null;
-      if (ctorClass == coreTypes.stringClass) {
-        if (value != null) return js.escapedString(value);
-        return _visitExpression(defaultArg) ?? new JS.LiteralNull();
-      } else if (ctorClass == coreTypes.intClass) {
-        var intValue = int.parse(value ?? '', onError: (_) => null);
-        if (intValue != null) return js.number(intValue);
-        return _visitExpression(defaultArg) ?? new JS.LiteralNull();
-      } else if (ctorClass == coreTypes.boolClass) {
-        if (value == "true") return js.boolean(true);
-        if (value == "false") return js.boolean(false);
-        return _visitExpression(defaultArg) ?? js.boolean(false);
-      } else {
-        return _emitInvalidNode(node, '$ctorClass.fromEnvironment constant');
-      }
+    if (isFromEnvironmentInvocation(coreTypes, node)) {
+      var value = _constants.evaluate(node);
+      if (value is PrimitiveConstant) return value.accept(this);
     }
+
     if (args.positional.isEmpty &&
         args.named.isEmpty &&
         ctorClass.enclosingLibrary.importUri.scheme == 'dart') {
@@ -4908,7 +4713,7 @@
       var last = node.value.split('.').last;
       var name = js.escapedString(node.value, "'");
       if (last.startsWith('_')) {
-        var nativeSymbol = _emitPrivateNameSymbol(_currentLibrary, last);
+        var nativeSymbol = emitPrivateNameSymbol(_currentLibrary, last);
         return js.call('new #.new(#, #)', [
           _emitConstructorAccess(privateSymbolClass.rawType),
           name,
@@ -4938,7 +4743,7 @@
     if (_currentFunction == null || usesTypeParams) return jsExpr;
 
     var temp = new JS.TemporaryId('const');
-    _moduleItems.add(js.statement('let #;', [temp]));
+    moduleItems.add(js.statement('let #;', [temp]));
     return js.call('# || (# = #)', [temp, temp, jsExpr]);
   }
 
@@ -5161,6 +4966,52 @@
   bool _isObjectMemberCall(Expression target, String memberName) {
     return isObjectMember(memberName) && isNullable(target);
   }
+
+  /// Returns the name value of the `JSExportName` annotation (when compiling
+  /// the SDK), or `null` if there's none. This is used to control the name
+  /// under which functions are compiled and exported.
+  String getJSExportName(NamedNode n) {
+    var library = getLibrary(n);
+    if (library == null || library.importUri.scheme != 'dart') return null;
+
+    return getAnnotationName(n, isJSExportNameAnnotation);
+  }
+
+  /// If [node] has annotation matching [test] and the first argument is a
+  /// string, this returns the string value.
+  ///
+  /// Calls [findAnnotation] followed by [getNameFromAnnotation].
+  String getAnnotationName(NamedNode node, bool test(Expression value)) {
+    return _constants.getNameFromAnnotation(findAnnotation(node, test));
+  }
+
+  @override
+  visitNullConstant(NullConstant node) => new JS.LiteralNull();
+  @override
+  visitBoolConstant(BoolConstant node) => js.boolean(node.value);
+  @override
+  visitIntConstant(IntConstant node) => js.number(node.value);
+  @override
+  visitDoubleConstant(DoubleConstant node) => js.number(node.value);
+  @override
+  visitStringConstant(StringConstant node) => js.escapedString(node.value, '"');
+
+  // DDC does not currently use the non-primivite constant nodes; rather these
+  // are emitted via their normal expression nodes.
+  @override
+  defaultConstant(Constant node) => _emitInvalidNode(node);
+  @override
+  visitMapConstant(node) => defaultConstant(node);
+  @override
+  visitListConstant(node) => defaultConstant(node);
+  @override
+  visitInstanceConstant(node) => defaultConstant(node);
+  @override
+  visitTearOffConstant(node) => defaultConstant(node);
+  @override
+  visitTypeLiteralConstant(node) => defaultConstant(node);
+  @override
+  visitPartialInstantiationConstant(node) => defaultConstant(node);
 }
 
 bool isSdkInternalRuntime(Library l) =>
diff --git a/pkg/dev_compiler/lib/src/kernel/constants.dart b/pkg/dev_compiler/lib/src/kernel/constants.dart
new file mode 100644
index 0000000..fb88289
--- /dev/null
+++ b/pkg/dev_compiler/lib/src/kernel/constants.dart
@@ -0,0 +1,332 @@
+// 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:kernel/core_types.dart';
+import 'package:kernel/kernel.dart';
+import 'package:kernel/transformations/constants.dart';
+import 'package:kernel/type_environment.dart';
+import 'kernel_helpers.dart';
+
+/// Implements constant evaluation for dev compiler:
+///
+/// [isConstant] determines if an expression is constant.
+/// [evaluate] computes the value of a constant expression, if available.
+class DevCompilerConstants {
+  final _ConstantVisitor _visitor;
+  final _ConstantEvaluator _evaluator;
+
+  DevCompilerConstants(
+      TypeEnvironment types, Map<String, String> declaredVariables)
+      : _visitor = new _ConstantVisitor(types.coreTypes),
+        _evaluator = new _ConstantEvaluator(types, declaredVariables);
+
+  /// Determines if an expression is constant.
+  bool isConstant(Expression e) => _visitor.isConstant(e);
+
+  /// Evaluates [e] to find its constant value, returning `null` if evaluation
+  /// failed, or if the constant was unavailable.
+  ///
+  /// Returns [NullConstant] to represent the `null` value.
+  ///
+  /// To avoid performance costs associated with try+catch on invalid constant
+  /// evaluation, call this after [isConstant] is known to be true.
+  Constant evaluate(Expression e, {bool cache: false}) {
+    if (e == null) return null;
+
+    try {
+      var result = cache ? _evaluator.evaluate(e) : e.accept(_evaluator);
+      return identical(result, _evaluator.unavailableConstant) ? 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.
+      //
+      // It can also be caused by methods in the evaluator that don't understand
+      // unavailable constants.
+      return null;
+    }
+  }
+
+  /// If [node] is an annotation with a field named `name`, returns that field's
+  /// value.
+  ///
+  /// This assumes the `name` field is populated from a named argument `name:`
+  /// or from the first positional argument.
+  ///
+  /// For example:
+  ///
+  ///     class MyAnnotation {
+  ///       final String name;
+  ///       // ...
+  ///       const MyAnnotation(this.name/*, ... other params ... */);
+  ///     }
+  ///
+  ///     @MyAnnotation('FooBar')
+  ///     main() { ... }
+  ///
+  /// Given the node for `@MyAnnotation('FooBar')` this will return `'FooBar'`.
+  String getNameFromAnnotation(ConstructorInvocation node) {
+    if (node == null) return null;
+
+    // TODO(jmesserly): this does not use the normal evaluation engine, because
+    // it won't work if we don't have the const constructor body available.
+    //
+    // We may need to address this in the kernel outline files.
+    Expression first;
+    var named = node.arguments.named;
+    if (named.isNotEmpty) {
+      first =
+          named.firstWhere((n) => n.name == 'name', orElse: () => null)?.value;
+    }
+    var positional = node.arguments.positional;
+    if (positional.isNotEmpty) first ??= positional[0];
+    if (first != null) {
+      first = _followConstFields(first);
+      if (first is StringLiteral) return first.value;
+    }
+    return null;
+  }
+
+  Expression _followConstFields(Expression expr) {
+    if (expr is StaticGet) {
+      var target = expr.target;
+      if (target is Field) {
+        return _followConstFields(target.initializer);
+      }
+    }
+    return expr;
+  }
+}
+
+/// Finds constant expressions as defined in Dart language spec 4th ed,
+/// 16.1 Constants.
+class _ConstantVisitor extends ExpressionVisitor<bool> {
+  final CoreTypes coreTypes;
+  _ConstantVisitor(this.coreTypes);
+
+  bool isConstant(Expression e) => e.accept(this);
+
+  defaultExpression(node) => false;
+  defaultBasicLiteral(node) => true;
+  visitTypeLiteral(node) => true; // TODO(jmesserly): deferred libraries?
+  visitSymbolLiteral(node) => true;
+  visitListLiteral(node) => node.isConst;
+  visitMapLiteral(node) => node.isConst;
+  visitStaticInvocation(node) {
+    return node.isConst ||
+        node.target == coreTypes.identicalProcedure &&
+            node.arguments.positional.every(isConstant) ||
+        isFromEnvironmentInvocation(coreTypes, node) &&
+            node.arguments.positional.every(isConstant) &&
+            node.arguments.named.every((n) => isConstant(n.value));
+  }
+
+  visitDirectMethodInvocation(node) {
+    return node.receiver is BasicLiteral &&
+        isOperatorMethodName(node.name.name) &&
+        node.arguments.positional.every((p) => p is BasicLiteral);
+  }
+
+  visitMethodInvocation(node) {
+    return node.receiver is BasicLiteral &&
+        isOperatorMethodName(node.name.name) &&
+        node.arguments.positional.every((p) => p is BasicLiteral);
+  }
+
+  visitConstructorInvocation(node) => node.isConst;
+  visitStringConcatenation(node) =>
+      node.expressions.every((e) => e is BasicLiteral);
+  visitStaticGet(node) {
+    var target = node.target;
+    return target is Procedure || target is Field && target.isConst;
+  }
+
+  visitVariableGet(node) => node.variable.isConst;
+  visitNot(node) {
+    var operand = node.operand;
+    return operand is BoolLiteral ||
+        operand is DirectMethodInvocation &&
+            visitDirectMethodInvocation(operand) ||
+        operand is MethodInvocation && visitMethodInvocation(operand);
+  }
+
+  visitLogicalExpression(node) =>
+      node.left is BoolLiteral && node.right is BoolLiteral;
+  visitConditionalExpression(node) =>
+      node.condition is BoolLiteral &&
+      node.then is BoolLiteral &&
+      node.otherwise is BoolLiteral;
+
+  visitLet(Let node) {
+    var init = node.variable.initializer;
+    return (init == null || isConstant(init)) && isConstant(node.body);
+  }
+}
+
+/// 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})
+      : unavailableConstant = new InstanceConstant(
+            types.coreTypes.index
+                .getClass('dart:core', '_ConstantExpressionError')
+                .reference,
+            [],
+            {}),
+        super(new _ConstantsBackend(types.coreTypes), types, types.coreTypes,
+            true, enableAsserts, const _ErrorReporter()) {
+    env = new EvaluationEnvironment();
+  }
+
+  @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(new StringConstant(value));
+        return defaultArg ?? nullConstant;
+      } else if (targetClass == coreTypes.intClass) {
+        var intValue = int.parse(value ?? '', onError: (_) => null);
+        if (intValue != null) return canonicalize(new 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) {
+    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(new 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) =>
+      throw new StateError('unreachable'); // DDC does not use VM native syntax
+
+  @override
+  buildSymbolConstant(StringConstant value) {
+    return new InstanceConstant(
+        coreTypes.internalSymbolClass.reference,
+        const <DartType>[],
+        <Reference, Constant>{symbolNameField.reference: value});
+  }
+
+  @override
+  lowerMapConstant(constant) => constant;
+
+  @override
+  lowerListConstant(constant) => constant;
+}
+
+class _ErrorReporter extends ErrorReporterBase {
+  const _ErrorReporter();
+
+  @override
+  report(context, message, node) => throw const _AbortCurrentEvaluation();
+}
+
+// TODO(jmesserly): this class is private in Kernel constants library, so
+// we have our own version.
+class _AbortCurrentEvaluation {
+  const _AbortCurrentEvaluation();
+}
diff --git a/pkg/dev_compiler/lib/src/kernel/js_interop.dart b/pkg/dev_compiler/lib/src/kernel/js_interop.dart
index 890edab..95145f6 100644
--- a/pkg/dev_compiler/lib/src/kernel/js_interop.dart
+++ b/pkg/dev_compiler/lib/src/kernel/js_interop.dart
@@ -110,13 +110,3 @@
       (n is Procedure && n.isExternal ||
           n is Class && n.annotations.any(isPublicJSAnnotation));
 }
-
-/// Returns the name value of the `JSExportName` annotation (when compiling
-/// the SDK), or `null` if there's none. This is used to control the name
-/// under which functions are compiled and exported.
-String getJSExportName(NamedNode n) {
-  var library = getLibrary(n);
-  if (library == null || library.importUri.scheme != 'dart') return null;
-
-  return getAnnotationName(n, isJSExportNameAnnotation);
-}
diff --git a/pkg/dev_compiler/lib/src/kernel/js_typerep.dart b/pkg/dev_compiler/lib/src/kernel/js_typerep.dart
index 8b6500b..103e981 100644
--- a/pkg/dev_compiler/lib/src/kernel/js_typerep.dart
+++ b/pkg/dev_compiler/lib/src/kernel/js_typerep.dart
@@ -4,7 +4,6 @@
 
 import 'package:kernel/core_types.dart';
 import 'package:kernel/kernel.dart';
-import 'package:kernel/library_index.dart';
 import 'package:kernel/type_environment.dart';
 
 /// An abstraction of the JS types
@@ -89,17 +88,19 @@
 class JSTypeRep {
   final TypeEnvironment types;
   final CoreTypes coreTypes;
-  final LibraryIndex sdk;
 
   final Class _jsBool;
   final Class _jsNumber;
-
   final Class _jsString;
-  JSTypeRep(this.types, this.sdk)
+
+  JSTypeRep(this.types)
       : coreTypes = types.coreTypes,
-        _jsBool = sdk.getClass('dart:_interceptors', 'JSBool'),
-        _jsNumber = sdk.getClass('dart:_interceptors', 'JSNumber'),
-        _jsString = sdk.getClass('dart:_interceptors', 'JSString');
+        _jsBool =
+            types.coreTypes.index.getClass('dart:_interceptors', 'JSBool'),
+        _jsNumber =
+            types.coreTypes.index.getClass('dart:_interceptors', 'JSNumber'),
+        _jsString =
+            types.coreTypes.index.getClass('dart:_interceptors', 'JSString');
 
   JSType typeFor(DartType type) {
     while (type is TypeParameterType) {
diff --git a/pkg/dev_compiler/lib/src/kernel/kernel_helpers.dart b/pkg/dev_compiler/lib/src/kernel/kernel_helpers.dart
index d0043bb..dc11518 100644
--- a/pkg/dev_compiler/lib/src/kernel/kernel_helpers.dart
+++ b/pkg/dev_compiler/lib/src/kernel/kernel_helpers.dart
@@ -89,120 +89,6 @@
   return false;
 }
 
-/// If [node] has annotation matching [test] and the first argument is a
-/// string, this returns the string value.
-///
-/// Calls [findAnnotation] followed by [getNameFromAnnotation].
-String getAnnotationName(NamedNode node, bool test(Expression value)) {
-  return getNameFromAnnotation(findAnnotation(node, test));
-}
-
-/// If [node] is an annotation and the first argument is a string, this returns
-/// the string value.
-///
-/// For example
-///
-///     class MyAnnotation {
-///       final String name;
-///       // ...
-///       const MyAnnotation(this.name/*, ... other params ... */);
-///     }
-///
-///     @MyAnnotation('FooBar')
-///     main() { ... }
-///
-/// Given teh node for `@MyAnnotation('FooBar')` this will return `'FooBar'`.
-String getNameFromAnnotation(ConstructorInvocation node) {
-  if (node != null) {
-    Expression first;
-    if (node.arguments.named.isNotEmpty) {
-      first = node.arguments.named
-          .firstWhere((n) => n.name == 'name', orElse: () => null)
-          ?.value;
-    }
-    if (node.arguments.positional.isNotEmpty) {
-      first ??= node.arguments.positional[0];
-    }
-    if (first != null) {
-      first = _followConstFields(first);
-      if (first is StringLiteral) return first.value;
-    }
-  }
-  return null;
-}
-
-Expression _followConstFields(Expression expr) {
-  if (expr is StaticGet) {
-    var target = expr.target;
-    if (target is Field) {
-      return _followConstFields(target.initializer);
-    }
-  }
-  return expr;
-}
-
-/// Finds constant expressions as defined in Dart language spec 4th ed,
-/// 16.1 Constants
-class ConstantVisitor extends ExpressionVisitor<bool> {
-  final CoreTypes coreTypes;
-  ConstantVisitor(this.coreTypes);
-
-  bool isConstant(Expression e) => e.accept(this) as bool;
-
-  defaultExpression(node) => false;
-  defaultBasicLiteral(node) => true;
-  visitTypeLiteral(node) => true; // TODO(jmesserly): deferred libraries?
-  visitSymbolLiteral(node) => true;
-  visitListLiteral(node) => node.isConst;
-  visitMapLiteral(node) => node.isConst;
-  visitStaticInvocation(node) {
-    return node.isConst ||
-        node.target == coreTypes.identicalProcedure &&
-            node.arguments.positional.every(isConstant);
-  }
-
-  visitDirectMethodInvocation(node) {
-    return node.receiver is BasicLiteral &&
-        isOperatorMethodName(node.name.name) &&
-        node.arguments.positional.every((p) => p is BasicLiteral);
-  }
-
-  visitMethodInvocation(node) {
-    return node.receiver is BasicLiteral &&
-        isOperatorMethodName(node.name.name) &&
-        node.arguments.positional.every((p) => p is BasicLiteral);
-  }
-
-  visitConstructorInvocation(node) => node.isConst;
-  visitStringConcatenation(node) =>
-      node.expressions.every((e) => e is BasicLiteral);
-  visitStaticGet(node) {
-    var target = node.target;
-    return target is Procedure || target is Field && target.isConst;
-  }
-
-  visitVariableGet(node) => node.variable.isConst;
-  visitNot(node) {
-    var operand = node.operand;
-    return operand is BoolLiteral ||
-        operand is DirectMethodInvocation &&
-            visitDirectMethodInvocation(operand) ||
-        operand is MethodInvocation && visitMethodInvocation(operand);
-  }
-
-  visitLogicalExpression(node) =>
-      node.left is BoolLiteral && node.right is BoolLiteral;
-  visitConditionalExpression(node) =>
-      node.condition is BoolLiteral &&
-      node.then is BoolLiteral &&
-      node.otherwise is BoolLiteral;
-
-  visitLet(Let node) {
-    var init = node.variable.initializer;
-    return (init == null || isConstant(init)) && isConstant(node.body);
-  }
-}
-
 /// Returns true if [name] is an operator method that is available on primitive
 /// types (`int`, `double`, `num`, `String`, `bool`).
 ///
@@ -233,6 +119,13 @@
   return false;
 }
 
+bool isFromEnvironmentInvocation(CoreTypes coreTypes, StaticInvocation node) {
+  var target = node.target;
+  return node.isConst &&
+      target.name.name == 'fromEnvironment' &&
+      target.enclosingLibrary == coreTypes.coreLibrary;
+}
+
 /// Returns true if this class is of the form:
 /// `class C = Object with M [implements I1, I2 ...];`
 ///
diff --git a/pkg/dev_compiler/lib/src/kernel/native_types.dart b/pkg/dev_compiler/lib/src/kernel/native_types.dart
index 1ac42bb..78876b4 100644
--- a/pkg/dev_compiler/lib/src/kernel/native_types.dart
+++ b/pkg/dev_compiler/lib/src/kernel/native_types.dart
@@ -5,8 +5,7 @@
 import 'dart:collection';
 import 'package:kernel/core_types.dart';
 import 'package:kernel/kernel.dart';
-import 'package:kernel/library_index.dart';
-import 'kernel_helpers.dart' show getNameFromAnnotation;
+import 'constants.dart';
 
 /// Contains information about native JS types (those types provided by the
 /// implementation) that are also provided by the Dart SDK.
@@ -27,7 +26,7 @@
 /// `first` to the `Array.prototype`.
 class NativeTypeSet {
   final CoreTypes coreTypes;
-  final LibraryIndex sdk;
+  final DevCompilerConstants constants;
 
   // Abstract types that may be implemented by both native and non-native
   // classes.
@@ -37,9 +36,7 @@
   final _nativeTypes = new HashSet<Class>.identity();
   final _pendingLibraries = new HashSet<Library>.identity();
 
-  NativeTypeSet(Component component)
-      : sdk = new LibraryIndex.coreLibraries(component),
-        coreTypes = new CoreTypes(component) {
+  NativeTypeSet(this.coreTypes, this.constants) {
     // First, core types:
     // TODO(vsm): If we're analyzing against the main SDK, those
     // types are not explicitly annotated.
@@ -48,6 +45,8 @@
     _addExtensionType(coreTypes.doubleClass, true);
     _addExtensionType(coreTypes.boolClass, true);
     _addExtensionType(coreTypes.stringClass, true);
+
+    var sdk = coreTypes.index;
     _addExtensionTypes(sdk.getLibrary('dart:_interceptors'));
     _addExtensionTypes(sdk.getLibrary('dart:_native_typed_data'));
 
@@ -82,6 +81,7 @@
   }
 
   void _addExtensionTypesForLibrary(String library, List<String> classNames) {
+    var sdk = coreTypes.index;
     for (var className in classNames) {
       _addExtensionType(sdk.getClass(library, className), true);
     }
@@ -125,7 +125,7 @@
   /// referring to the JavaScript built-in `Array` type.
   List<String> getNativePeers(Class c) {
     if (c == coreTypes.objectClass) return ['Object'];
-    var names = getNameFromAnnotation(_getNativeAnnotation(c));
+    var names = constants.getNameFromAnnotation(_getNativeAnnotation(c));
     if (names == null) return const [];
 
     // Omit the special name "!nonleaf" and any future hacks starting with "!"
diff --git a/pkg/dev_compiler/lib/src/kernel/property_model.dart b/pkg/dev_compiler/lib/src/kernel/property_model.dart
index 51cad84..e630821 100644
--- a/pkg/dev_compiler/lib/src/kernel/property_model.dart
+++ b/pkg/dev_compiler/lib/src/kernel/property_model.dart
@@ -196,8 +196,6 @@
   /// super.
   final inheritedSetters = new HashSet<String>();
 
-  final mockMembers = <String, Member>{};
-
   final extensionMethods = new Set<String>();
 
   final extensionAccessors = new Set<String>();
@@ -231,14 +229,12 @@
       }
     }
 
-    _collectMockMembers(class_);
     _collectExtensionMembers(class_);
 
     var virtualAccessorNames = new HashSet<String>()
       ..addAll(inheritedGetters)
       ..addAll(inheritedSetters)
-      ..addAll(extensionAccessors)
-      ..addAll(mockMembers.values.map((m) => m.name.name));
+      ..addAll(extensionAccessors);
 
     // Visit accessors in the current class, and see if they need to be
     // generated differently based on the inherited fields/accessors.
@@ -258,62 +254,6 @@
 
   CoreTypes get coreTypes => extensionTypes.coreTypes;
 
-  void _collectMockMembers(Class class_) {
-    // TODO(jmesserly): every type with nSM will generate new stubs for all
-    // abstract members. For example:
-    //
-    //     class C { m(); noSuchMethod(...) { ... } }
-    //     class D extends C { m(); noSuchMethod(...) { ... } }
-    //
-    // We'll generate D.m even though it is not necessary.
-    //
-    // Doing better is a bit tricky, as our current codegen strategy for the
-    // mock methods encodes information about the number of arguments (and type
-    // arguments) that D expects.
-    if (!_hasNoSuchMethod(class_)) return;
-
-    // Collect all unimplemented members.
-    //
-    // Initially, we track abstract and concrete members separately, then
-    // remove concrete from the abstract set. This is done because abstract
-    // members are allowed to "override" concrete ones in Dart.
-    // (In that case, it will still be treated as a concrete member and can be
-    // called at runtime.)
-    var concreteMembers = new HashSet<String>();
-
-    void addMember(Member m, bool classIsAbstract, {bool isSetter: false}) {
-      var name = m.name.name;
-      if (isSetter) name += '=';
-      if (classIsAbstract || m.isAbstract) {
-        mockMembers[name] = m;
-      } else {
-        concreteMembers.add(name);
-      }
-    }
-
-    void visit(Class c, bool classIsAbstract) {
-      if (c == null) return;
-      visit(c.superclass, classIsAbstract);
-      visit(c.mixedInClass, classIsAbstract);
-      for (var i in c.implementedTypes) visit(i.classNode, true);
-
-      for (var m in c.members) {
-        if (m is Field) {
-          if (m.isStatic) continue;
-          addMember(m, classIsAbstract);
-          if (m.hasSetter) addMember(m, classIsAbstract, isSetter: true);
-        } else if (m is Procedure) {
-          if (m.isStatic) continue;
-          addMember(m, classIsAbstract, isSetter: m.isSetter);
-        }
-      }
-    }
-
-    visit(class_, false);
-
-    concreteMembers.forEach(mockMembers.remove);
-  }
-
   void _collectExtensionMembers(Class class_) {
     if (extensionTypes.isNativeClass(class_)) return;
 
@@ -327,17 +267,6 @@
     // For members on this class, check them against all generic interfaces.
     var seenConcreteMembers = new HashSet<String>();
     _findExtensionMembers(class_, seenConcreteMembers, allNatives);
-    // Add mock members. These are compiler-generated concrete members that
-    // forward to `noSuchMethod`.
-    for (var m in mockMembers.values) {
-      var name = m.name.name;
-      if (seenConcreteMembers.add(name) && allNatives.contains(name)) {
-        var extMembers = m is Procedure && !m.isAccessor
-            ? extensionMethods
-            : extensionAccessors;
-        extMembers.add(name);
-      }
-    }
 
     // For members of the superclass, we may need to add checks because this
     // class adds a new unsafe interface. Collect those checks.
@@ -421,17 +350,4 @@
     var s = c.superclass;
     if (s != null) _collectNativeMembers(s, members);
   }
-
-  /// Return `true` if the given [classElement] has a noSuchMethod() method
-  /// distinct from the one declared in class Object, as per the Dart Language
-  /// Specification (section 10.4).
-  // TODO(jmesserly): this was taken from error_verifier.dart
-  bool _hasNoSuchMethod(Class c) {
-    // TODO(jmesserly): is this lookup fast in Kernel?
-    // TODO(jmesserly): our old code may have matched an abstract nSM, but
-    // that seems incorrect. So we now look for a dispatch target.
-    var method = types.hierarchy.getDispatchTarget(c, new Name('noSuchMethod'));
-    var definingClass = method?.enclosingClass;
-    return definingClass != null && definingClass != coreTypes.objectClass;
-  }
 }
diff --git a/pkg/dev_compiler/lib/src/kernel/target.dart b/pkg/dev_compiler/lib/src/kernel/target.dart
index b1888c6..26dbc21 100644
--- a/pkg/dev_compiler/lib/src/kernel/target.dart
+++ b/pkg/dev_compiler/lib/src/kernel/target.dart
@@ -2,6 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+import 'dart:core' hide MapEntry;
 import 'package:kernel/kernel.dart';
 import 'package:kernel/core_types.dart';
 import 'package:kernel/class_hierarchy.dart';
@@ -57,6 +58,9 @@
   bool get nativeExtensionExpectsString => false;
 
   @override
+  bool get enableNoSuchMethodForwarders => true;
+
+  @override
   void performModularTransformationsOnLibraries(
       CoreTypes coreTypes, ClassHierarchy hierarchy, List<Library> libraries,
       {void logger(String msg)}) {}
@@ -68,8 +72,40 @@
   @override
   Expression instantiateInvocation(CoreTypes coreTypes, Expression receiver,
       String name, Arguments arguments, int offset, bool isSuper) {
-    // TODO(sigmund): implement;
-    return new InvalidExpression(null);
+    // TODO(jmesserly): preserve source information?
+    // (These method are synthetic. Also unclear if the offset will correspond
+    // to the file where the class resides, or the file where the method we're
+    // mocking resides).
+    Expression createInvocation(String name, List<Expression> positional) {
+      var ctor = coreTypes.invocationClass.procedures
+          .firstWhere((c) => c.name.name == name);
+      return new StaticInvocation(ctor, new Arguments(positional));
+    }
+
+    if (name.startsWith('get:')) {
+      return createInvocation('getter', [new SymbolLiteral(name.substring(4))]);
+    }
+    if (name.startsWith('set:')) {
+      return createInvocation('setter', [
+        new SymbolLiteral(name.substring(4) + '='),
+        arguments.positional.single
+      ]);
+    }
+    var ctorArgs = <Expression>[new SymbolLiteral(name)];
+    bool isGeneric = arguments.types.isNotEmpty;
+    if (isGeneric) {
+      ctorArgs.add(new ListLiteral(
+          arguments.types.map((t) => new TypeLiteral(t)).toList()));
+    }
+    ctorArgs.add(new ListLiteral(arguments.positional));
+    if (arguments.named.isNotEmpty) {
+      ctorArgs.add(new MapLiteral(
+          arguments.named
+              .map((n) => new MapEntry(new SymbolLiteral(n.name), n.value))
+              .toList(),
+          keyType: coreTypes.symbolClass.rawType));
+    }
+    return createInvocation(isGeneric ? 'genericMethod' : 'method', ctorArgs);
   }
 
   @override
diff --git a/pkg/dev_compiler/test/nullable_inference_test.dart b/pkg/dev_compiler/test/nullable_inference_test.dart
index be94da4..dadc9018 100644
--- a/pkg/dev_compiler/test/nullable_inference_test.dart
+++ b/pkg/dev_compiler/test/nullable_inference_test.dart
@@ -9,7 +9,6 @@
 import 'package:front_end/src/fasta/type_inference/type_schema_environment.dart';
 import 'package:kernel/core_types.dart';
 import 'package:kernel/kernel.dart';
-import 'package:kernel/library_index.dart';
 import 'package:kernel/class_hierarchy.dart';
 import 'package:test/test.dart';
 
@@ -491,9 +490,9 @@
   @override
   visitComponent(Component node) {
     inference ??= new NullableInference(new JSTypeRep(
-        new TypeSchemaEnvironment(
-            new CoreTypes(node), new ClassHierarchy(node), true),
-        new LibraryIndex.coreLibraries(node)));
+      new TypeSchemaEnvironment(
+          new CoreTypes(node), new ClassHierarchy(node), true),
+    ));
 
     if (useAnnotations) {
       inference.allowNotNullDeclarations = useAnnotations;
diff --git a/pkg/dev_compiler/tool/ddb b/pkg/dev_compiler/tool/ddb
index b42781e..493b103 100755
--- a/pkg/dev_compiler/tool/ddb
+++ b/pkg/dev_compiler/tool/ddb
@@ -55,7 +55,7 @@
   ProcessResult runDdc(String command, List<String> args) {
     if (debug) {
       // Use unbuilt script.  This only works from a source checkout.
-      args.insertAll(0, ['-c', path.join(ddcPath, 'bin', '${command}.dart')]);
+      args.insertAll(0, ['--preview-dart-2', '-c', path.join(ddcPath, 'bin', '${command}.dart')]);
       command = dartBinary;
     } else {
       // Use built snapshot.
diff --git a/pkg/dev_compiler/tool/ddc b/pkg/dev_compiler/tool/ddc
index cc8f410..aa6f9d8 100755
--- a/pkg/dev_compiler/tool/ddc
+++ b/pkg/dev_compiler/tool/ddc
@@ -74,7 +74,7 @@
     exit 1
   fi
 
-  dart -c $SDK_DIR/pkg/dev_compiler/bin/dartdevk.dart --modules=node \
+  $SDK_DIR/sdk/bin/dartdevk --modules=node \
       --dart-sdk-summary=$GEN_DIR/kernel/ddc_sdk.dill \
       -o $LIBROOT/$BASENAME.js $*
 else
@@ -86,7 +86,7 @@
     exit 1
   fi
 
-  dart -c $SDK_DIR/pkg/dev_compiler/bin/dartdevc.dart --modules=node \
+  $SDK_DIR/sdk/bin/dartdevc --modules=node \
       --library-root=$LIBROOT --dart-sdk-summary=$GEN_DIR/ddc_sdk.sum \
       -o $LIBROOT/$BASENAME.js $*
 fi
diff --git a/pkg/dev_compiler/tool/input_sdk/patch/core_patch.dart b/pkg/dev_compiler/tool/input_sdk/patch/core_patch.dart
index 7ae52ae..24d3768 100644
--- a/pkg/dev_compiler/tool/input_sdk/patch/core_patch.dart
+++ b/pkg/dev_compiler/tool/input_sdk/patch/core_patch.dart
@@ -602,6 +602,12 @@
 
 @patch
 class NoSuchMethodError {
+  final Object _receiver;
+  final Symbol _memberName;
+  final List _arguments;
+  final Map<Symbol, dynamic> _namedArguments;
+  final List _existingArgumentNames;
+
   @patch
   NoSuchMethodError(Object receiver, Symbol memberName,
       List positionalArguments, Map<Symbol, dynamic> namedArguments,
diff --git a/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/operations.dart b/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/operations.dart
index ca353ba..b8b88e2 100644
--- a/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/operations.dart
+++ b/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/operations.dart
@@ -6,6 +6,7 @@
 /// generator.
 part of dart._runtime;
 
+// TODO(jmesserly): remove this in favor of _Invocation.
 class InvocationImpl extends Invocation {
   final Symbol memberName;
   final List positionalArguments;
diff --git a/pkg/dev_compiler/tool/input_sdk/private/js_array.dart b/pkg/dev_compiler/tool/input_sdk/private/js_array.dart
index 3cac8a5..e392cfb 100644
--- a/pkg/dev_compiler/tool/input_sdk/private/js_array.dart
+++ b/pkg/dev_compiler/tool/input_sdk/private/js_array.dart
@@ -20,7 +20,9 @@
    */
   factory JSArray.of(list) {
     // TODO(sra): Move this to core.List for better readability.
-    // Capture the parameterized ES6 'JSArray' class.
+    //
+    // TODO(jmesserly): this uses special compiler magic to close over the
+    // parameterized ES6 'JSArray' class.
     JS('', '#.__proto__ = JSArray.prototype', list);
     return JS('-dynamic', '#', list);
   }
diff --git a/pkg/front_end/README.md b/pkg/front_end/README.md
index fd5aed2..6c4e0ed 100644
--- a/pkg/front_end/README.md
+++ b/pkg/front_end/README.md
@@ -13,4 +13,6 @@
 [analyzer] package.
 
 _Note:_ The APIs in this package are in an early state; developers should be
-careful about depending on this package.
+careful about depending on this package.  In particular, there is no semver
+contract for release versions of this package.  Please depend directly on individual
+versions.
diff --git a/pkg/front_end/lib/src/api_prototype/incremental_kernel_generator.dart b/pkg/front_end/lib/src/api_prototype/incremental_kernel_generator.dart
index 76e4075..f10c806 100644
--- a/pkg/front_end/lib/src/api_prototype/incremental_kernel_generator.dart
+++ b/pkg/front_end/lib/src/api_prototype/incremental_kernel_generator.dart
@@ -19,10 +19,10 @@
 
 abstract class IncrementalKernelGenerator {
   factory IncrementalKernelGenerator(CompilerOptions options, Uri entryPoint,
-      [Uri bootstrapDill]) {
+      [Uri initializeFromDillUri]) {
     return new IncrementalCompiler(
         new CompilerContext(new ProcessedOptions(options, false, [entryPoint])),
-        bootstrapDill);
+        initializeFromDillUri);
   }
 
   /// Returns a component whose libraries are the recompiled libraries,
@@ -61,6 +61,7 @@
       String expression,
       Map<String, DartType> definitions,
       List<TypeParameter> typeDefinitions,
+      String syntheticProcedureName,
       Uri libraryUri,
       [String className,
       bool isStatic = false]);
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 5407f55..1815328 100644
--- a/pkg/front_end/lib/src/fasta/builder/library_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/library_builder.dart
@@ -176,7 +176,7 @@
   /// where they were omitted by the programmer and not provided by the type
   /// inference.  The method returns the number of distinct type variables
   /// that were instantiated in this library.
-  int instantiateToBound(TypeBuilder dynamicType, TypeBuilder bottomType,
+  int computeDefaultTypes(TypeBuilder dynamicType, TypeBuilder bottomType,
       ClassBuilder objectClass) {
     return 0;
   }
diff --git a/pkg/front_end/lib/src/fasta/deprecated_problems.dart b/pkg/front_end/lib/src/fasta/deprecated_problems.dart
index 8ec0ce2..fd2e6dd 100644
--- a/pkg/front_end/lib/src/fasta/deprecated_problems.dart
+++ b/pkg/front_end/lib/src/fasta/deprecated_problems.dart
@@ -94,13 +94,14 @@
   hasCrashed = false;
 }
 
-Future reportCrash(error, StackTrace trace, [Uri uri, int charOffset]) async {
+Future<T> reportCrash<T>(error, StackTrace trace,
+    [Uri uri, int charOffset]) async {
   note(String note) async {
     stderr.write(note);
     await stderr.flush();
   }
 
-  if (hasCrashed) return new Future.error(error, trace);
+  if (hasCrashed) return new Future<T>.error(error, trace);
   if (error is Crash) {
     trace = error.trace ?? trace;
     uri = error.uri ?? uri;
@@ -126,7 +127,8 @@
     } on SocketException {
       // Assume the crash logger isn't running.
       await client.close(force: true);
-      return new Future.error(new Crash(uri, charOffset, error, trace), trace);
+      return new Future<T>.error(
+          new Crash(uri, charOffset, error, trace), trace);
     }
     if (request != null) {
       await note("\nSending crash report data");
@@ -147,7 +149,7 @@
   }
   await client.close(force: true);
   await note("\n");
-  return new Future.error(error, trace);
+  return new Future<T>.error(error, trace);
 }
 
 String safeToString(Object object) {
diff --git a/pkg/front_end/lib/src/fasta/fasta_codes.dart b/pkg/front_end/lib/src/fasta/fasta_codes.dart
index 3d1368d..6e7dbc1 100644
--- a/pkg/front_end/lib/src/fasta/fasta_codes.dart
+++ b/pkg/front_end/lib/src/fasta/fasta_codes.dart
@@ -4,7 +4,7 @@
 
 library fasta.codes;
 
-import 'package:kernel/ast.dart' show DartType;
+import 'package:kernel/ast.dart' show Constant, DartType;
 
 import 'package:kernel/text/ast_to_text.dart' show NameSystem, Printer;
 
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 ae67c8e..e65d55b 100644
--- a/pkg/front_end/lib/src/fasta/fasta_codes_generated.dart
+++ b/pkg/front_end/lib/src/fasta/fasta_codes_generated.dart
@@ -726,6 +726,257 @@
     tip: r"""Try removing either the 'const' keyword or the body.""");
 
 // 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.
+const MessageCode messageConstEvalContext =
+    const MessageCode("ConstEvalContext", message: r"""While analyzing:""");
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Template<
+    Message Function(
+        Constant
+            constant)> templateConstEvalDuplicateKey = const Template<
+        Message Function(Constant constant)>(
+    messageTemplate:
+        r"""The key '#constant' conflicts with another existing key in the map.""",
+    withArguments: _withArgumentsConstEvalDuplicateKey);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Message Function(Constant constant)> codeConstEvalDuplicateKey =
+    const Code<Message Function(Constant constant)>(
+        "ConstEvalDuplicateKey", templateConstEvalDuplicateKey,
+        analyzerCode: "EQUAL_KEYS_IN_MAP");
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+Message _withArgumentsConstEvalDuplicateKey(Constant constant) {
+  return new Message(codeConstEvalDuplicateKey,
+      message:
+          """The key '$constant' conflicts with another existing key in the map.""",
+      arguments: {'constant': constant});
+}
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Null> codeConstEvalFailedAssertion = messageConstEvalFailedAssertion;
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const MessageCode messageConstEvalFailedAssertion = const MessageCode(
+    "ConstEvalFailedAssertion",
+    analyzerCode: "CONST_EVAL_THROWS_EXCEPTION",
+    message: r"""This assertion failed.""");
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Template<Message Function(String string)>
+    templateConstEvalFailedAssertionWithMessage =
+    const Template<Message Function(String string)>(
+        messageTemplate: r"""This assertion failed with message: #string""",
+        withArguments: _withArgumentsConstEvalFailedAssertionWithMessage);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Message Function(String string)>
+    codeConstEvalFailedAssertionWithMessage =
+    const Code<Message Function(String string)>(
+        "ConstEvalFailedAssertionWithMessage",
+        templateConstEvalFailedAssertionWithMessage,
+        analyzerCode: "CONST_EVAL_THROWS_EXCEPTION");
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+Message _withArgumentsConstEvalFailedAssertionWithMessage(String string) {
+  return new Message(codeConstEvalFailedAssertionWithMessage,
+      message: """This assertion failed with message: $string""",
+      arguments: {'string': string});
+}
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Template<
+    Message Function(
+        String string,
+        Constant constant,
+        DartType _type,
+        DartType
+            _type2)> templateConstEvalInvalidBinaryOperandType = const Template<
+        Message Function(String string, Constant constant, DartType _type,
+            DartType _type2)>(
+    messageTemplate:
+        r"""Binary operator '#string' on '#constant' requires operand of type '#type', but was of type '#type2'.""",
+    withArguments: _withArgumentsConstEvalInvalidBinaryOperandType);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<
+        Message Function(
+            String string, Constant constant, DartType _type, DartType _type2)>
+    codeConstEvalInvalidBinaryOperandType = const Code<
+        Message Function(
+            String string, Constant constant, DartType _type, DartType _type2)>(
+  "ConstEvalInvalidBinaryOperandType",
+  templateConstEvalInvalidBinaryOperandType,
+);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+Message _withArgumentsConstEvalInvalidBinaryOperandType(
+    String string, Constant constant, DartType _type, DartType _type2) {
+  NameSystem nameSystem = new NameSystem();
+  StringBuffer buffer = new StringBuffer();
+  new Printer(buffer, syntheticNames: nameSystem).writeNode(_type);
+  String type = '$buffer';
+
+  buffer = new StringBuffer();
+  new Printer(buffer, syntheticNames: nameSystem).writeNode(_type2);
+  String type2 = '$buffer';
+
+  return new Message(codeConstEvalInvalidBinaryOperandType,
+      message:
+          """Binary operator '$string' on '$constant' requires operand of type '$type', but was of type '$type2'.""",
+      arguments: {
+        'string': string,
+        'constant': constant,
+        'type': _type,
+        'type2': _type2
+      });
+}
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Template<
+    Message Function(
+        String string,
+        Constant
+            constant)> templateConstEvalInvalidMethodInvocation = const Template<
+        Message Function(String string, Constant constant)>(
+    messageTemplate:
+        r"""The method '#string' can't be invoked on '#constant' within a const context.""",
+    withArguments: _withArgumentsConstEvalInvalidMethodInvocation);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Message Function(String string, Constant constant)>
+    codeConstEvalInvalidMethodInvocation =
+    const Code<Message Function(String string, Constant constant)>(
+        "ConstEvalInvalidMethodInvocation",
+        templateConstEvalInvalidMethodInvocation,
+        analyzerCode: "UNDEFINED_OPERATOR");
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+Message _withArgumentsConstEvalInvalidMethodInvocation(
+    String string, Constant constant) {
+  return new Message(codeConstEvalInvalidMethodInvocation,
+      message:
+          """The method '$string' can't be invoked on '$constant' within a const context.""",
+      arguments: {'string': string, 'constant': constant});
+}
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Template<
+    Message Function(
+        String
+            name)> templateConstEvalInvalidStaticInvocation = const Template<
+        Message Function(String name)>(
+    messageTemplate:
+        r"""The invocation of '#name' is not allowed within a const context.""",
+    withArguments: _withArgumentsConstEvalInvalidStaticInvocation);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Message Function(String name)> codeConstEvalInvalidStaticInvocation =
+    const Code<Message Function(String name)>(
+        "ConstEvalInvalidStaticInvocation",
+        templateConstEvalInvalidStaticInvocation,
+        analyzerCode: "CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE");
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+Message _withArgumentsConstEvalInvalidStaticInvocation(String name) {
+  return new Message(codeConstEvalInvalidStaticInvocation,
+      message:
+          """The invocation of '$name' is not allowed within a const context.""",
+      arguments: {'name': name});
+}
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Template<Message Function(Constant constant)>
+    templateConstEvalInvalidStringInterpolationOperand =
+    const Template<Message Function(Constant constant)>(
+        messageTemplate:
+            r"""The '#constant' can't be used as part of a string interpolation within a const context, only values of type 'null', 'bool', 'int', 'double', or 'String' can be used.""",
+        withArguments:
+            _withArgumentsConstEvalInvalidStringInterpolationOperand);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Message Function(Constant constant)>
+    codeConstEvalInvalidStringInterpolationOperand =
+    const Code<Message Function(Constant constant)>(
+        "ConstEvalInvalidStringInterpolationOperand",
+        templateConstEvalInvalidStringInterpolationOperand,
+        analyzerCode: "CONST_EVAL_TYPE_BOOL_NUM_STRING");
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+Message _withArgumentsConstEvalInvalidStringInterpolationOperand(
+    Constant constant) {
+  return new Message(codeConstEvalInvalidStringInterpolationOperand,
+      message:
+          """The '$constant' can't be used as part of a string interpolation within a const context, only values of type 'null', 'bool', 'int', 'double', or 'String' can be used.""",
+      arguments: {'constant': constant});
+}
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Template<
+    Message Function(
+        Constant constant,
+        DartType _type,
+        DartType
+            _type2)> templateConstEvalInvalidType = const Template<
+        Message Function(Constant constant, DartType _type, DartType _type2)>(
+    messageTemplate:
+        r"""Expected constant '#constant' to be of type '#type', but was of type '#type2'.""",
+    withArguments: _withArgumentsConstEvalInvalidType);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Message Function(Constant constant, DartType _type, DartType _type2)>
+    codeConstEvalInvalidType = const Code<
+        Message Function(Constant constant, DartType _type, DartType _type2)>(
+  "ConstEvalInvalidType",
+  templateConstEvalInvalidType,
+);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+Message _withArgumentsConstEvalInvalidType(
+    Constant constant, DartType _type, DartType _type2) {
+  NameSystem nameSystem = new NameSystem();
+  StringBuffer buffer = new StringBuffer();
+  new Printer(buffer, syntheticNames: nameSystem).writeNode(_type);
+  String type = '$buffer';
+
+  buffer = new StringBuffer();
+  new Printer(buffer, syntheticNames: nameSystem).writeNode(_type2);
+  String type2 = '$buffer';
+
+  return new Message(codeConstEvalInvalidType,
+      message:
+          """Expected constant '$constant' to be of type '$type', but was of type '$type2'.""",
+      arguments: {'constant': constant, 'type': _type, 'type2': _type2});
+}
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Template<
+    Message Function(
+        String
+            string)> templateConstEvalNonConstantLiteral = const Template<
+        Message Function(String string)>(
+    messageTemplate:
+        r"""Can't have a non-constant #string literal within a const context.""",
+    withArguments: _withArgumentsConstEvalNonConstantLiteral);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Message Function(String string)> codeConstEvalNonConstantLiteral =
+    const Code<Message Function(String string)>(
+        "ConstEvalNonConstantLiteral", templateConstEvalNonConstantLiteral,
+        analyzerCode: "NON_CONSTANT_DEFAULT_VALUE");
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+Message _withArgumentsConstEvalNonConstantLiteral(String string) {
+  return new Message(codeConstEvalNonConstantLiteral,
+      message:
+          """Can't have a non-constant $string literal within a const context.""",
+      arguments: {'string': string});
+}
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
 const Code<Null> codeConstFactory = messageConstFactory;
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
@@ -2141,7 +2392,7 @@
     Read the SDK platform from <file>, which should be in Dill/Kernel IR format
     and contain the Dart SDK.
 
-  --target=none|vm|vmcc|vmreify|flutter
+  --target=dart2js|dart2js_server|dart_runner|flutter|flutter_runner|none|vm
     Specify the target configuration.
 
   --verify
@@ -2288,6 +2539,26 @@
 }
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Null> codeForInLoopExactlyOneVariable =
+    messageForInLoopExactlyOneVariable;
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const MessageCode messageForInLoopExactlyOneVariable = const MessageCode(
+    "ForInLoopExactlyOneVariable",
+    severity: Severity.error,
+    message: r"""A for-in loop can't have more than one loop variable.""");
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Null> codeForInLoopNotAssignable = messageForInLoopNotAssignable;
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const MessageCode messageForInLoopNotAssignable = const MessageCode(
+    "ForInLoopNotAssignable",
+    severity: Severity.error,
+    message:
+        r"""Can't assign to this, so it can't be used in a for-in loop.""");
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
 const Template<
         Message Function(String name)> templateFunctionHasNoSuchNamedParameter =
     const Template<Message Function(String name)>(
@@ -5657,6 +5928,8 @@
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
 const MessageCode messageTypedefNotFunction = const MessageCode(
     "TypedefNotFunction",
+    analyzerCode: "INVALID_GENERIC_FUNCTION_TYPE",
+    dart2jsCode: "*fatal*",
     message: r"""Can't create typedef from non-function type.""");
 
 // 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 f23b510..0cfc1d8a 100644
--- a/pkg/front_end/lib/src/fasta/incremental_compiler.dart
+++ b/pkg/front_end/lib/src/fasta/incremental_compiler.dart
@@ -8,6 +8,8 @@
 
 import 'package:kernel/binary/ast_from_binary.dart' show BinaryBuilder;
 
+import 'package:kernel/class_hierarchy.dart' show ClassHierarchy;
+
 import '../api_prototype/file_system.dart' show FileSystemEntity;
 
 import 'package:kernel/kernel.dart'
@@ -75,6 +77,7 @@
   Map<Uri, LibraryBuilder> userBuilders;
   final Uri initializeFromDillUri;
   bool initializedFromDill = false;
+  bool hasToCheckPackageUris = false;
 
   KernelIncrementalTarget userCode;
 
@@ -93,6 +96,7 @@
       if (this.invalidatedUris.contains(c.options.packagesUri)) {
         bypassCache = true;
       }
+      hasToCheckPackageUris = hasToCheckPackageUris || bypassCache;
       UriTranslator uriTranslator =
           await c.options.getUriTranslator(bypassCache: bypassCache);
       ticker.logMs("Read packages file");
@@ -138,13 +142,18 @@
       }
 
       Set<Uri> invalidatedUris = this.invalidatedUris.toSet();
-      this.invalidatedUris.clear();
       if (fullComponent) {
         invalidatedUris.add(entryPoint);
       }
 
-      List<LibraryBuilder> reusedLibraries =
-          computeReusedLibraries(invalidatedUris, uriTranslator);
+      ClassHierarchy hierarchy = userCode?.loader?.hierarchy;
+      Set<LibraryBuilder> notReusedLibraries;
+      if (hierarchy != null) {
+        notReusedLibraries = new Set<LibraryBuilder>();
+      }
+      List<LibraryBuilder> reusedLibraries = computeReusedLibraries(
+          invalidatedUris, uriTranslator,
+          notReused: notReusedLibraries);
       Set<Uri> reusedLibraryUris =
           new Set<Uri>.from(reusedLibraries.map((b) => b.uri));
       for (Uri uri in new Set<Uri>.from(dillLoadedData.loader.builders.keys)
@@ -153,6 +162,15 @@
         userBuilders?.remove(uri);
       }
 
+      if (hierarchy != null) {
+        List<Class> removedClasses = new List<Class>();
+        for (LibraryBuilder builder in notReusedLibraries) {
+          Library lib = builder.target;
+          removedClasses.addAll(lib.classes);
+        }
+        hierarchy.applyTreeChanges(removedClasses, const []);
+      }
+
       if (userCode != null) {
         ticker.logMs("Decided to reuse ${reusedLibraries.length}"
             " of ${userCode.loader.builders.length} libraries");
@@ -170,6 +188,7 @@
           dillLoadedData,
           uriTranslator,
           uriToSource: c.uriToSource);
+      userCode.loader.hierarchy = hierarchy;
 
       for (LibraryBuilder library in reusedLibraries) {
         userCode.loader.builders[library.uri] = library;
@@ -201,6 +220,8 @@
             libraries: compiledLibraries, uriToSource: <Uri, Source>{});
       }
       if (componentWithDill != null) {
+        this.invalidatedUris.clear();
+        hasToCheckPackageUris = false;
         userCodeOld?.loader?.releaseAncillaryResources();
         userCodeOld?.loader?.builders?.clear();
         userCodeOld = null;
@@ -217,9 +238,11 @@
 
       List<Library> outputLibraries;
       if (data.includeUserLoadedLibraries || fullComponent) {
-        outputLibraries = computeTransitiveClosure(
-            compiledLibraries, mainMethod, entryPoint, reusedLibraries, data);
+        outputLibraries = computeTransitiveClosure(compiledLibraries,
+            mainMethod, entryPoint, reusedLibraries, data, hierarchy);
       } else {
+        computeTransitiveClosure(compiledLibraries, mainMethod, entryPoint,
+            reusedLibraries, data, hierarchy);
         outputLibraries = compiledLibraries;
       }
 
@@ -239,7 +262,8 @@
       Procedure mainMethod,
       Uri entry,
       List<LibraryBuilder> reusedLibraries,
-      IncrementalCompilerData data) {
+      IncrementalCompilerData data,
+      ClassHierarchy hierarchy) {
     List<Library> result = new List<Library>.from(inputLibraries);
     Map<Uri, Library> libraryMap = <Uri, Library>{};
     for (Library library in inputLibraries) {
@@ -274,10 +298,16 @@
       }
     }
 
+    List<Class> removedClasses = new List<Class>();
     for (Uri uri in potentiallyReferencedLibraries.keys) {
       if (uri.scheme == "package") continue;
-      userCode.loader.builders.remove(uri);
+      LibraryBuilder builder = userCode.loader.builders.remove(uri);
+      if (builder != null) {
+        Library lib = builder.target;
+        removedClasses.addAll(lib.classes);
+      }
     }
+    hierarchy?.applyTreeChanges(removedClasses, const []);
 
     return result;
   }
@@ -360,6 +390,7 @@
       String expression,
       Map<String, DartType> definitions,
       List<TypeParameter> typeDefinitions,
+      String syntheticProcedureName,
       Uri libraryUri,
       [String className,
       bool isStatic = false]) async {
@@ -440,7 +471,7 @@
           debugLibrary, className, className != null && !isStatic, parameters);
 
       Procedure procedure = new Procedure(
-          new Name("debugExpr"), ProcedureKind.Method, parameters,
+          new Name(syntheticProcedureName), ProcedureKind.Method, parameters,
           isStatic: isStatic);
 
       parameters.body = new ReturnStatement(compiledExpression)
@@ -459,11 +490,14 @@
   }
 
   List<LibraryBuilder> computeReusedLibraries(
-      Set<Uri> invalidatedUris, UriTranslator uriTranslator) {
+      Set<Uri> invalidatedUris, UriTranslator uriTranslator,
+      {Set<LibraryBuilder> notReused}) {
     if (userCode == null && userBuilders == null) {
       return <LibraryBuilder>[];
     }
 
+    List<LibraryBuilder> result = <LibraryBuilder>[];
+
     // Maps all non-platform LibraryBuilders from their import URI.
     Map<Uri, LibraryBuilder> builders = <Uri, LibraryBuilder>{};
 
@@ -476,7 +510,8 @@
           (importUri != fileUri && invalidatedUris.contains(fileUri))) {
         return true;
       }
-      if (importUri.scheme == "package" &&
+      if (hasToCheckPackageUris &&
+          importUri.scheme == "package" &&
           uriTranslator.translate(importUri, false) != fileUri) {
         return true;
       }
@@ -484,6 +519,10 @@
     }
 
     addBuilderAndInvalidateUris(Uri uri, LibraryBuilder library) {
+      if (uri.scheme == "dart") {
+        result.add(library);
+        return;
+      }
       builders[uri] = library;
       if (isInvalidated(uri, library.target.fileUri)) {
         invalidatedImportUris.add(uri);
@@ -547,13 +586,13 @@
             workList.add(dependency);
           }
         }
+        notReused?.add(current);
       }
     }
 
     // Builders contain mappings from part uri to builder, meaning the same
     // builder can exist multiple times in the values list.
     Set<Uri> seenUris = new Set<Uri>();
-    List<LibraryBuilder> result = <LibraryBuilder>[];
     for (LibraryBuilder builder in builders.values) {
       if (builder.isPart) continue;
       // TODO(jensj/ahe): This line can probably go away once
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 252270f..66003ca 100644
--- a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
@@ -12,10 +12,30 @@
 
 import '../fasta_codes.dart' show LocatedMessage, Message, noLength, Template;
 
+import 'forest.dart' show Forest;
+
 import '../messages.dart' as messages show getLocationFromUri;
 
 import '../modifier.dart' show Modifier, constMask, covariantMask, finalMask;
 
+import '../names.dart'
+    show
+        ampersandName,
+        barName,
+        callName,
+        caretName,
+        divisionName,
+        emptyName,
+        indexGetName,
+        indexSetName,
+        leftShiftName,
+        minusName,
+        multiplyName,
+        mustacheName,
+        percentName,
+        plusName,
+        rightShiftName;
+
 import '../parser.dart'
     show
         Assert,
@@ -62,7 +82,32 @@
 
 import 'constness.dart' show Constness;
 
-import 'frontend_accessors.dart' show buildIsNull;
+import 'expression_generator.dart'
+    show
+        BuilderHelper,
+        CalleeDesignation,
+        DeferredAccessGenerator,
+        ErroneousExpressionGenerator,
+        FastaAccessor,
+        FunctionTypeAccessor,
+        GeneratorImpl,
+        IncompleteError,
+        IncompletePropertyAccessor,
+        IncompleteSend,
+        IndexedAccessGenerator,
+        LargeIntAccessGenerator,
+        LoadLibraryGenerator,
+        ParenthesizedExpression,
+        ReadOnlyAccessGenerator,
+        SendAccessor,
+        StaticAccessGenerator,
+        SuperIndexedAccessGenerator,
+        ThisAccessGenerator,
+        ThisPropertyAccessGenerator,
+        TypeDeclarationAccessor,
+        UnresolvedAccessor,
+        VariableUseGenerator,
+        buildIsNull;
 
 import 'redirecting_factory_body.dart'
     show
@@ -71,10 +116,6 @@
         getRedirectingFactoryBody,
         getRedirectionTarget;
 
-import '../names.dart';
-
-import 'fasta_accessors.dart';
-
 import 'kernel_api.dart';
 
 import 'kernel_ast_api.dart' hide Expression, Statement;
@@ -83,6 +124,8 @@
 
 import 'kernel_builder.dart';
 
+import 'type_algorithms.dart' show calculateBounds;
+
 // TODO(ahe): Remove this and ensure all nodes have a location.
 const noLocation = null;
 
@@ -201,8 +244,8 @@
         ignoreMainInGetMainClosure = library.uri.scheme == 'dart' &&
             (library.uri.path == "_builtin" || library.uri.path == "ui"),
         needsImplicitSuperInitializer =
-            coreTypes.objectClass != classBuilder?.cls,
-        typePromoter = _typeInferrer.typePromoter,
+            coreTypes?.objectClass != classBuilder?.cls,
+        typePromoter = _typeInferrer?.typePromoter,
         super(scope);
 
   bool get hasParserError => recoverableErrors.isNotEmpty;
@@ -271,39 +314,18 @@
     return list;
   }
 
-  Block popBlock(int count, Token beginToken) {
-    List<dynamic /*kernel.Statement | List<kernel.Statement>*/ > statements =
-        popList(count) ?? <kernel.Statement>[];
-    List<kernel.Statement> copy;
-    for (int i = 0; i < statements.length; i++) {
-      var statement = statements[i];
-      if (statement is List) {
-        copy ??= new List<kernel.Statement>.from(statements.getRange(0, i));
-        // TODO(sigmund): remove this assignment (issue #28651)
-        Iterable subStatements = statement;
-        copy.addAll(subStatements);
-      } else if (copy != null) {
-        copy.add(statement);
-      }
-    }
-    return new ShadowBlock(copy ?? statements)
-      ..fileOffset = offsetForToken(beginToken);
+  Statement popBlock(int count, Token openBrace, Token closeBrace) {
+    List<Statement> statements =
+        new List<Statement>.filled(count, null, growable: true);
+    popList(count, statements);
+    return forest.block(openBrace, statements, closeBrace);
   }
 
-  kernel.Statement popStatementIfNotNull(Object value) {
+  Statement popStatementIfNotNull(Object value) {
     return value == null ? null : popStatement();
   }
 
-  kernel.Statement popStatement() {
-    var statement = pop();
-    if (statement is List) {
-      return new Block(new List<kernel.Statement>.from(statement));
-    } else if (statement is VariableDeclaration) {
-      return new Block(<kernel.Statement>[statement]);
-    } else {
-      return statement;
-    }
-  }
+  Statement popStatement() => forest.wrapVariables(pop());
 
   void ignore(Unhandled value) {
     pop();
@@ -388,7 +410,8 @@
 
   @override
   JumpTarget createJumpTarget(JumpTargetKind kind, int charOffset) {
-    return new JumpTarget(kind, functionNestingLevel, member, charOffset);
+    return new JumpTarget<Statement>(
+        kind, functionNestingLevel, member, charOffset);
   }
 
   @override
@@ -415,7 +438,7 @@
       if (expression is Identifier) {
         Identifier identifier = expression;
         expression = new UnresolvedAccessor(
-            this, new Name(identifier.name, library.library), identifier.token);
+            this, identifier.token, new Name(identifier.name, library.library));
       }
       if (name?.isNotEmpty ?? false) {
         Token period = periodBeforeName ?? beginToken.next;
@@ -428,7 +451,7 @@
       }
 
       ConstantContext savedConstantContext = pop();
-      if (expression is! StaticAccessor) {
+      if (expression is! StaticAccessGenerator) {
         push(wrapInCompileTimeError(
             toValue(expression), fasta.messageExpressionNotMetadata));
       } else {
@@ -512,13 +535,13 @@
   }
 
   @override
-  void endBlockFunctionBody(int count, Token beginToken, Token endToken) {
+  void endBlockFunctionBody(int count, Token openBrace, Token closeBrace) {
     debugEvent("BlockFunctionBody");
-    if (beginToken == null) {
+    if (openBrace == null) {
       assert(count == 0);
       push(NullValue.Block);
     } else {
-      Block block = popBlock(count, beginToken);
+      Statement block = popBlock(count, openBrace, closeBrace);
       exitLocalScope();
       push(block);
     }
@@ -633,7 +656,7 @@
   }
 
   @override
-  void finishFunction(List annotations, FormalParameters formals,
+  void finishFunction(List annotations, FormalParameters<Arguments> formals,
       AsyncMarker asyncModifier, kernel.Statement body) {
     debugEvent("finishFunction");
     typePromoter.finished();
@@ -673,18 +696,23 @@
         if (builder.formals != null) {
           // Illegal parameters were removed by the function builder.
           // Add them as local variable to put them in scope of the body.
-          List<kernel.Statement> statements = <kernel.Statement>[];
+          List<Statement> statements = <Statement>[];
           for (KernelFormalParameterBuilder parameter in builder.formals) {
-            statements.add(parameter.target);
+            statements.add(toStatement(parameter.target));
           }
-          statements.add(body);
-          body = new Block(statements)..fileOffset = charOffset;
+          statements.add(toStatement(body));
+          body = toKernelStatement(
+              storeOffset(forest.block(null, statements, null), charOffset));
         }
         body = wrapInCompileTimeErrorStatement(
             body, fasta.messageSetterWithWrongNumberOfFormals);
       }
     }
-    if (!builder.isExternal) {
+    // No-such-method forwarders get their bodies injected during outline
+    // buliding, so we should skip them here.
+    bool isNoSuchMethodForwarder = (builder.function.parent is Procedure &&
+        (builder.function.parent as Procedure).isNoSuchMethodForwarder);
+    if (!builder.isExternal && !isNoSuchMethodForwarder) {
       builder.body = body;
     } else {
       if (body != null) {
@@ -727,7 +755,8 @@
 
     enterLocalScope(
         null,
-        new FormalParameters(parameters.positionalParameters, null, -1)
+        new FormalParameters<Arguments>(
+                parameters.positionalParameters, null, -1)
             .computeFormalParameterScope(scope, member, this));
 
     token = parser.parseExpression(parser.syntheticPreviousToken(token));
@@ -806,7 +835,7 @@
   @override
   void endExpressionStatement(Token token) {
     debugEvent("ExpressionStatement");
-    push(new ShadowExpressionStatement(toKernelExpression(popForEffect())));
+    push(forest.expressionStatement(popForEffect(), token));
   }
 
   @override
@@ -872,10 +901,16 @@
   }
 
   @override
+  void handleParenthesizedCondition(Token token) {
+    debugEvent("ParenthesizedCondition");
+    push(forest.parenthesizedCondition(token, popForValue(), token.endGroup));
+  }
+
+  @override
   void handleParenthesizedExpression(Token token) {
     debugEvent("ParenthesizedExpression");
     push(new ParenthesizedExpression(
-        this, toKernelExpression(popForValue()), token.endGroup));
+        this, token.endGroup, toKernelExpression(popForValue())));
   }
 
   @override
@@ -921,13 +956,13 @@
     Expression expression = popForValue();
     if (expression is ShadowCascadeExpression) {
       push(expression);
-      push(new VariableAccessor(this, token, expression.variable));
+      push(new VariableUseGenerator(this, token, expression.variable));
       expression.extend();
     } else {
       VariableDeclaration variable = new ShadowVariableDeclaration.forValue(
           toKernelExpression(expression), functionNestingLevel);
       push(new ShadowCascadeExpression(variable));
-      push(new VariableAccessor(this, token, variable));
+      push(new VariableUseGenerator(this, token, variable));
     }
   }
 
@@ -979,8 +1014,8 @@
     Expression argument = popForValue();
     var receiver = pop();
     bool isSuper = false;
-    if (receiver is ThisAccessor && receiver.isSuper) {
-      ThisAccessor thisAccessorReceiver = receiver;
+    if (receiver is ThisAccessGenerator && receiver.isSuper) {
+      ThisAccessGenerator thisAccessorReceiver = receiver;
       isSuper = true;
       receiver = forest.thisExpression(thisAccessorReceiver.token);
     }
@@ -1030,11 +1065,13 @@
         new VariableDeclaration.forValue(toKernelExpression(a));
     push(new ShadowIfNullExpression(
         variable,
-        new ConditionalExpression(
-            buildIsNull(new VariableGet(variable), offsetForToken(token)),
-            toKernelExpression(b),
-            new VariableGet(variable),
-            null))
+        toKernelExpression(forest.conditionalExpression(
+            toExpression(buildIsNull(
+                new VariableGet(variable), offsetForToken(token), this)),
+            token,
+            b,
+            null,
+            toExpression(new VariableGet(variable)))))
       ..fileOffset = offsetForToken(token));
   }
 
@@ -1319,8 +1356,8 @@
 
   /// Look up [name] in [scope] using [token] as location information (both to
   /// report problems and as the file offset in the generated kernel code).
-  /// [isQualified] should be true if [name] is a qualified access
-  /// (which implies that it shouldn't be turned into a [ThisPropertyAccessor]
+  /// [isQualified] should be true if [name] is a qualified access (which
+  /// implies that it shouldn't be turned into a [ThisPropertyAccessGenerator]
   /// if the name doesn't resolve in the scope).
   @override
   scopeLookup(Scope scope, String name, Token token,
@@ -1341,16 +1378,16 @@
       if (!isQualified && isInstanceContext) {
         assert(builder == null);
         if (constantContext != ConstantContext.none || member.isField) {
-          return new UnresolvedAccessor(this, n, token);
+          return new UnresolvedAccessor(this, token, n);
         }
-        return new ThisPropertyAccessor(this, token, n, lookupInstanceMember(n),
-            lookupInstanceMember(n, isSetter: true));
+        return new ThisPropertyAccessGenerator(this, token, n,
+            lookupInstanceMember(n), lookupInstanceMember(n, isSetter: true));
       } else if (ignoreMainInGetMainClosure &&
           name == "main" &&
           member?.name == "_getMainClosure") {
         return storeOffset(forest.literalNull(null), charOffset);
       } else {
-        return new UnresolvedAccessor(this, n, token);
+        return new UnresolvedAccessor(this, token, n);
       }
     } else if (builder.isTypeDeclaration) {
       if (constantContext != ConstantContext.none &&
@@ -1360,9 +1397,9 @@
             charOffset, "Not a constant expression.");
       }
       TypeDeclarationAccessor accessor = new TypeDeclarationAccessor(
-          this, prefix, charOffset, builder, name, token);
+          this, token, prefix, charOffset, builder, name);
       return (prefix?.deferred == true)
-          ? new DeferredAccessor(this, token, prefix, accessor)
+          ? new DeferredAccessGenerator(this, token, prefix, accessor)
           : accessor;
     } else if (builder.isLocal) {
       if (constantContext != ConstantContext.none &&
@@ -1374,19 +1411,19 @@
       // An initializing formal parameter might be final without its
       // VariableDeclaration being final. See
       // [ProcedureBuilder.computeFormalParameterInitializerScope]. If that
-      // wasn't the case, we could always use VariableAccessor.
+      // wasn't the case, we could always use [VariableUseGenerator].
       if (builder.isFinal) {
         var fact =
             typePromoter.getFactForAccess(builder.target, functionNestingLevel);
         var scope = typePromoter.currentScope;
-        return new ReadOnlyAccessor(
+        return new ReadOnlyAccessGenerator(
             this,
+            token,
             new ShadowVariableGet(builder.target, fact, scope)
               ..fileOffset = charOffset,
-            name,
-            token);
+            name);
       } else {
-        return new VariableAccessor(this, token, builder.target);
+        return new VariableUseGenerator(this, token, builder.target);
       }
     } else if (builder.isInstanceMember) {
       if (constantContext != ConstantContext.none &&
@@ -1409,13 +1446,13 @@
         getter = builder.target;
         setter = lookupInstanceMember(n, isSetter: true);
       }
-      return new ThisPropertyAccessor(this, token, n, getter, setter);
+      return new ThisPropertyAccessGenerator(this, token, n, getter, setter);
     } else if (builder.isRegularMethod) {
       assert(builder.isStatic || builder.isTopLevel);
-      StaticAccessor accessor =
-          new StaticAccessor(this, token, builder.target, null);
+      StaticAccessGenerator accessor =
+          new StaticAccessGenerator(this, token, builder.target, null);
       return (prefix?.deferred == true)
-          ? new DeferredAccessor(this, token, prefix, accessor)
+          ? new DeferredAccessGenerator(this, token, prefix, accessor)
           : accessor;
     } else if (builder is PrefixBuilder) {
       if (constantContext != ConstantContext.none && builder.deferred) {
@@ -1429,7 +1466,7 @@
       }
       return builder;
     } else if (builder is LoadLibraryBuilder) {
-      return new LoadLibraryAccessor(this, token, builder);
+      return new LoadLibraryGenerator(this, token, builder);
     } else {
       if (builder.hasProblem && builder is! AccessErrorBuilder) return builder;
       Builder setter;
@@ -1440,8 +1477,8 @@
       } else if (builder.isField && !builder.isFinal) {
         setter = builder;
       }
-      StaticAccessor accessor =
-          new StaticAccessor.fromBuilder(this, builder, token, setter);
+      StaticAccessGenerator accessor =
+          new StaticAccessGenerator.fromBuilder(this, builder, token, setter);
       if (constantContext != ConstantContext.none) {
         Member readTarget = accessor.readTarget;
         if (!(readTarget is Field && readTarget.isConst ||
@@ -1452,7 +1489,7 @@
         }
       }
       return (prefix?.deferred == true)
-          ? new DeferredAccessor(this, token, prefix, accessor)
+          ? new DeferredAccessGenerator(this, token, prefix, accessor)
           : accessor;
     }
   }
@@ -1561,7 +1598,7 @@
     debugEvent("LiteralInt");
     int value = int.parse(token.lexeme, onError: (_) => null);
     if (value == null) {
-      push(new LargeIntAccessor(this, token));
+      push(new LargeIntAccessGenerator(this, token));
     } else {
       push(forest.literalInt(value, token));
     }
@@ -1588,15 +1625,14 @@
       push(deprecated_buildCompileTimeErrorStatement(
           "Can't return from a constructor.", beginToken.charOffset));
     } else {
-      push(new ShadowReturnStatement(toKernelExpression(expression))
-        ..fileOffset = beginToken.charOffset);
+      push(forest.returnStatement(beginToken, expression, endToken));
     }
   }
 
   @override
   void beginThenStatement(Token token) {
     Expression condition = popForValue();
-    typePromoter.enterThen(toKernelExpression(condition));
+    enterThenForTypePromotion(condition);
     push(condition);
     super.beginThenStatement(token);
   }
@@ -1609,13 +1645,11 @@
 
   @override
   void endIfStatement(Token ifToken, Token elseToken) {
-    kernel.Statement elsePart = popStatementIfNotNull(elseToken);
-    kernel.Statement thenPart = popStatement();
+    Statement elsePart = popStatementIfNotNull(elseToken);
+    Statement thenPart = popStatement();
     Expression condition = pop();
     typePromoter.exitConditional();
-    push(
-        new ShadowIfStatement(toKernelExpression(condition), thenPart, elsePart)
-          ..fileOffset = ifToken.charOffset);
+    push(forest.ifStatement(ifToken, condition, thenPart, elseToken, elsePart));
   }
 
   @override
@@ -1707,29 +1741,40 @@
   @override
   void endVariablesDeclaration(int count, Token endToken) {
     debugEvent("VariablesDeclaration");
-    List<VariableDeclaration> variables = popList(count);
-    constantContext = pop();
-    currentLocalVariableType = pop();
-    currentLocalVariableModifiers = pop();
-    List<Expression> annotations = pop();
-    if (annotations != null) {
-      for (VariableDeclaration variable in variables) {
+    if (count == 1) {
+      VariableDeclaration variable = pop();
+      constantContext = pop();
+      currentLocalVariableType = pop();
+      currentLocalVariableModifiers = pop();
+      List<Expression> annotations = pop();
+      if (annotations != null) {
         for (Expression annotation in annotations) {
           variable.addAnnotation(toKernelExpression(annotation));
         }
       }
-    }
-    if (variables.length != 1) {
-      push(variables);
+      push(variable);
     } else {
-      push(variables.single);
+      List<VariableDeclaration> variables = popList(count,
+          new List<VariableDeclaration>.filled(count, null, growable: true));
+      constantContext = pop();
+      currentLocalVariableType = pop();
+      currentLocalVariableModifiers = pop();
+      List<Expression> annotations = pop();
+      if (annotations != null) {
+        for (VariableDeclaration variable in variables) {
+          for (Expression annotation in annotations) {
+            variable.addAnnotation(toKernelExpression(annotation));
+          }
+        }
+      }
+      push(forest.variablesDeclaration(variables, uri));
     }
   }
 
   @override
-  void endBlock(int count, Token beginToken, Token endToken) {
+  void endBlock(int count, Token openBrace, Token closeBrace) {
     debugEvent("Block");
-    Block block = popBlock(count, beginToken);
+    Statement block = popBlock(count, openBrace, closeBrace);
     exitLocalScope();
     push(block);
   }
@@ -1766,7 +1811,7 @@
     }
   }
 
-  void exitLoopOrSwitch(kernel.Statement statement) {
+  void exitLoopOrSwitch(Statement statement) {
     if (compileTimeErrorInLoopOrSwitch != null) {
       push(compileTimeErrorInLoopOrSwitch);
       compileTimeErrorInLoopOrSwitch = null;
@@ -1781,14 +1826,6 @@
     }
     if (variableOrExpression is VariableDeclaration) {
       return <VariableDeclaration>[variableOrExpression];
-    } else if (variableOrExpression is List) {
-      List<VariableDeclaration> variables = <VariableDeclaration>[];
-      for (var v in variableOrExpression) {
-        variables.addAll(buildVariableDeclarations(v));
-      }
-      return variables;
-    } else if (variableOrExpression == null) {
-      return <VariableDeclaration>[];
     } else if (variableOrExpression is Expression) {
       VariableDeclaration variable = new ShadowVariableDeclaration.forEffect(
           toKernelExpression(variableOrExpression), functionNestingLevel);
@@ -1797,6 +1834,17 @@
       VariableDeclaration variable = new ShadowVariableDeclaration.forEffect(
           variableOrExpression.expression, functionNestingLevel);
       return <VariableDeclaration>[variable];
+    } else if (forest.isVariablesDeclaration(variableOrExpression)) {
+      return forest
+          .variablesDeclarationExtractDeclarations(variableOrExpression);
+    } else if (variableOrExpression is List) {
+      List<VariableDeclaration> variables = <VariableDeclaration>[];
+      for (var v in variableOrExpression) {
+        variables.addAll(buildVariableDeclarations(v));
+      }
+      return variables;
+    } else if (variableOrExpression == null) {
+      return <VariableDeclaration>[];
     }
     return null;
   }
@@ -1805,14 +1853,16 @@
   void endForStatement(Token forKeyword, Token leftParen, Token leftSeparator,
       int updateExpressionCount, Token endToken) {
     debugEvent("ForStatement");
-    kernel.Statement body = popStatement();
+    Statement body = popStatement();
     List<Expression> updates = popListForEffect(updateExpressionCount);
-    kernel.Statement conditionStatement = popStatement();
+    Statement conditionStatement = popStatement();
+    kernel.Statement kernelConditionStatement =
+        toKernelStatement(conditionStatement);
     Expression condition = null;
-    if (conditionStatement is ExpressionStatement) {
-      condition = toExpression(conditionStatement.expression);
+    if (kernelConditionStatement is ExpressionStatement) {
+      condition = toExpression(kernelConditionStatement.expression);
     } else {
-      assert(conditionStatement is EmptyStatement);
+      assert(kernelConditionStatement is EmptyStatement);
     }
     dynamic variableOrExpression = pop();
     List<VariableDeclaration> variables =
@@ -1824,18 +1874,22 @@
     exitLocalScope();
     JumpTarget continueTarget = exitContinueTarget();
     JumpTarget breakTarget = exitBreakTarget();
+    kernel.Statement kernelBody = toKernelStatement(body);
     if (continueTarget.hasUsers) {
-      body = new ShadowLabeledStatement(body);
-      continueTarget.resolveContinues(body);
+      kernelBody = new ShadowLabeledStatement(kernelBody);
+      continueTarget.resolveContinues(forest, kernelBody);
     }
-    kernel.Statement result = new ShadowForStatement(variables,
-        toKernelExpression(condition), toKernelExpressionList(updates), body)
+    kernel.Statement result = new ShadowForStatement(
+        variables,
+        toKernelExpression(condition),
+        toKernelExpressionList(updates),
+        kernelBody)
       ..fileOffset = forKeyword.charOffset;
     if (breakTarget.hasUsers) {
       result = new ShadowLabeledStatement(result);
-      breakTarget.resolveBreaks(result);
+      breakTarget.resolveBreaks(forest, result);
     }
-    exitLoopOrSwitch(result);
+    exitLoopOrSwitch(toStatement(result));
   }
 
   @override
@@ -1960,15 +2014,18 @@
     debugEvent("LiteralSymbol");
     String value;
     if (identifierCount == 1) {
-      value = symbolPartToString(pop());
+      Object part = pop();
+      value = symbolPartToString(part);
+      push(forest.literalSymbolSingluar(value, hashToken, part));
     } else {
-      List parts = popList(identifierCount);
+      List<Identifier> parts = popList(identifierCount,
+          new List<Identifier>.filled(identifierCount, null, growable: true));
       value = symbolPartToString(parts.first);
       for (int i = 1; i < parts.length; i++) {
         value += ".${symbolPartToString(parts[i])}";
       }
+      push(forest.literalSymbolMultiple(value, hashToken, parts));
     }
-    push(forest.literalSymbol(value, hashToken));
   }
 
   @override
@@ -1986,7 +2043,7 @@
       if (prefix is PrefixBuilder) {
         name = scopeLookup(prefix.exportScope, suffix.name, beginToken,
             isQualified: true, prefix: prefix);
-      } else if (prefix is ErrorAccessor) {
+      } else if (prefix is ErroneousExpressionGenerator) {
         push(prefix.buildErroneousTypeNotAPrefix(suffix));
         return;
       } else {
@@ -2041,7 +2098,7 @@
   @override
   void endFunctionType(Token functionToken, Token endToken) {
     debugEvent("FunctionType");
-    FormalParameters formals = pop();
+    FormalParameters<Arguments> formals = pop();
     DartType returnType = pop();
     List<TypeParameter> typeVariables = typeVariableBuildersToKernel(pop());
     FunctionType type = formals.toFunctionType(returnType, typeVariables);
@@ -2121,9 +2178,10 @@
     if (constantContext != ConstantContext.none) {
       push(deprecated_buildCompileTimeError(
           "Not a constant expression.", throwToken.charOffset));
+      // TODO(brianwilkerson): For analyzer, we need to produce the error above
+      // but then we need to produce the AST as in the `else` clause below.
     } else {
-      push(new ShadowThrow(toKernelExpression(expression))
-        ..fileOffset = offsetForToken(throwToken));
+      push(forest.throwExpression(throwToken, expression));
     }
   }
 
@@ -2214,7 +2272,7 @@
     if (inCatchClause || functionNestingLevel != 0) {
       exitLocalScope();
     }
-    FormalParameters formals = pop();
+    FormalParameters<Arguments> formals = pop();
     DartType returnType = pop();
     List<TypeParameter> typeVariables = typeVariableBuildersToKernel(pop());
     FunctionType type = formals.toFunctionType(returnType, typeVariables);
@@ -2266,8 +2324,12 @@
       optional = pop();
       count--;
     }
-    FormalParameters formals = new FormalParameters(
-        popList(count) ?? <VariableDeclaration>[],
+    FormalParameters<Arguments> formals = new FormalParameters(
+        popList(
+                count,
+                new List<VariableDeclaration>.filled(count, null,
+                    growable: true)) ??
+            <VariableDeclaration>[],
         optional,
         beginToken.charOffset);
     constantContext = pop();
@@ -2303,7 +2365,7 @@
     if (catchKeyword != null) {
       exitLocalScope();
     }
-    FormalParameters catchParameters = popIfNotNull(catchKeyword);
+    FormalParameters<Arguments> catchParameters = popIfNotNull(catchKeyword);
     DartType type = popIfNotNull(onKeyword) ?? const DynamicType();
     VariableDeclaration exception;
     VariableDeclaration stackTrace;
@@ -2318,10 +2380,14 @@
       }
       if (catchParameters.required.length > 2 ||
           catchParameters.optional != null) {
-        body = new Block(<kernel.Statement>[
-          compileTimeErrorInTry ??= deprecated_buildCompileTimeErrorStatement(
-              "Invalid catch arguments.", catchKeyword.next.charOffset)
-        ]);
+        body = toKernelStatement(forest.block(
+            catchKeyword,
+            <Statement>[
+              toStatement(compileTimeErrorInTry ??=
+                  deprecated_buildCompileTimeErrorStatement(
+                      "Invalid catch arguments.", catchKeyword.next.charOffset))
+            ],
+            null));
       }
     }
     push(new Catch(exception, body, guard: type, stackTrace: stackTrace)
@@ -2330,17 +2396,12 @@
 
   @override
   void endTryStatement(int catchCount, Token tryKeyword, Token finallyKeyword) {
-    kernel.Statement finallyBlock = popStatementIfNotNull(finallyKeyword);
-    List<Catch> catches = popList(catchCount);
-    kernel.Statement tryBlock = popStatement();
+    Statement finallyBlock = popStatementIfNotNull(finallyKeyword);
+    Object catches = popList(catchCount);
+    Statement tryBlock = popStatement();
     if (compileTimeErrorInTry == null) {
-      if (catches != null) {
-        tryBlock = new ShadowTryCatch(tryBlock, catches);
-      }
-      if (finallyBlock != null) {
-        tryBlock = new ShadowTryFinally(tryBlock, finallyBlock);
-      }
-      push(tryBlock);
+      push(forest.tryStatement(
+          tryKeyword, tryBlock, catches, finallyKeyword, finallyBlock));
     } else {
       push(compileTimeErrorInTry);
       compileTimeErrorInTry = null;
@@ -2359,15 +2420,15 @@
     debugEvent("IndexedExpression");
     Expression index = popForValue();
     var receiver = pop();
-    if (receiver is ThisAccessor && receiver.isSuper) {
-      push(new SuperIndexAccessor(
+    if (receiver is ThisAccessGenerator && receiver.isSuper) {
+      push(new SuperIndexedAccessGenerator(
           this,
           openSquareBracket,
           toKernelExpression(index),
           lookupInstanceMember(indexGetName, isSuper: true),
           lookupInstanceMember(indexSetName, isSuper: true)));
     } else {
-      push(IndexAccessor.make(
+      push(IndexedAccessGenerator.make<Arguments>(
           this,
           openSquareBracket,
           toKernelExpression(toValue(receiver)),
@@ -2388,7 +2449,7 @@
       if (optional("-", token)) {
         operator = "unary-";
 
-        if (receiver is LargeIntAccessor) {
+        if (receiver is LargeIntAccessGenerator) {
           int value =
               int.parse("-" + receiver.token.lexeme, onError: (_) => null);
           if (value != null) {
@@ -2399,7 +2460,7 @@
       }
       bool isSuper = false;
       Expression receiverValue;
-      if (receiver is ThisAccessor && receiver.isSuper) {
+      if (receiver is ThisAccessGenerator && receiver.isSuper) {
         isSuper = true;
         receiverValue = forest.thisExpression(receiver.token);
       } else {
@@ -2437,7 +2498,7 @@
     debugEvent("UnaryPostfixAssignmentExpression");
     var accessor = pop();
     if (accessor is FastaAccessor) {
-      push(new DelayedPostfixIncrement(
+      push(new DelayedPostfixIncrement<Arguments>(
           this, token, accessor, incrementOperator(token), null));
     } else {
       push(wrapInCompileTimeError(toValue(accessor), fasta.messageNotAnLvalue));
@@ -2504,7 +2565,7 @@
             ? "${prefix.plainNameForRead}.${identifier.name}"
             : "${prefix.plainNameForRead}.${identifier.name}.$suffix";
         type = new UnresolvedAccessor(
-            this, new Name(name, library.library), prefix.token);
+            this, prefix.token, new Name(name, library.library));
       } else {
         unhandled("${prefix.runtimeType}", "pushQualifiedReference",
             start.charOffset, uri);
@@ -2725,8 +2786,8 @@
     var type = pop();
     PrefixBuilder deferredPrefix;
     int checkOffset;
-    if (type is DeferredAccessor) {
-      DeferredAccessor accessor = type;
+    if (type is DeferredAccessGenerator) {
+      DeferredAccessGenerator accessor = type;
       type = accessor.accessor;
       deferredPrefix = accessor.builder;
       checkOffset = accessor.token.charOffset;
@@ -2747,7 +2808,7 @@
       push(deferredPrefix != null
           ? wrapInDeferredCheck(expression, deferredPrefix, checkOffset)
           : expression);
-    } else if (type is ErrorAccessor) {
+    } else if (type is ErroneousExpressionGenerator) {
       push(type.buildError(arguments));
     } else {
       push(throwNoSuchMethodError(storeOffset(forest.literalNull(null), offset),
@@ -2877,7 +2938,7 @@
   void handleThisExpression(Token token, IdentifierContext context) {
     debugEvent("ThisExpression");
     if (context.isScopeReference && isInstanceContext) {
-      push(new ThisAccessor(this, token, inInitializer));
+      push(new ThisAccessGenerator(this, token, inInitializer));
     } else {
       push(new IncompleteError(this, token, fasta.messageThisAsIdentifier));
     }
@@ -2889,7 +2950,7 @@
     if (context.isScopeReference && isInstanceContext) {
       Member member = this.member.target;
       member.transformerFlags |= TransformerFlag.superCalls;
-      push(new ThisAccessor(this, token, inInitializer, isSuper: true));
+      push(new ThisAccessGenerator(this, token, inInitializer, isSuper: true));
     } else {
       push(new IncompleteError(this, token, fasta.messageSuperAsIdentifier));
     }
@@ -2967,10 +3028,10 @@
   }
 
   void pushNamedFunction(Token token, bool isFunctionExpression) {
-    kernel.Statement body = popStatement();
+    Statement body = popStatement();
     AsyncMarker asyncModifier = pop();
     exitLocalScope();
-    FormalParameters formals = pop();
+    FormalParameters<Arguments> formals = pop();
     var declaration = pop();
     var returnType = pop();
     var hasImplicitReturnType = returnType == null;
@@ -2981,7 +3042,8 @@
     if (!isFunctionExpression) {
       annotations = pop(); // Metadata.
     }
-    FunctionNode function = formals.addToFunction(new FunctionNode(body,
+    FunctionNode function = formals.addToFunction(new FunctionNode(
+        toKernelStatement(body),
         typeParameters: typeParameters,
         asyncMarker: asyncModifier,
         returnType: returnType)
@@ -3027,11 +3089,16 @@
           // This must have been a compile-time error.
           assert(isErroneousNode(variable.initializer));
 
-          push(new Block(<kernel.Statement>[
-            new ExpressionStatement(variable.initializer),
-            declaration
-          ])
-            ..fileOffset = declaration.fileOffset);
+          push(storeOffset(
+              forest.block(
+                  null,
+                  <Statement>[
+                    forest.expressionStatement(
+                        toExpression(variable.initializer), token),
+                    toStatement(declaration)
+                  ],
+                  null),
+              declaration.fileOffset));
           variable.initializer = null;
         } else {
           push(declaration);
@@ -3058,14 +3125,16 @@
   @override
   void endFunctionExpression(Token beginToken, Token token) {
     debugEvent("FunctionExpression");
-    kernel.Statement body = popStatement();
+    Statement body = popStatement();
     AsyncMarker asyncModifier = pop();
     exitLocalScope();
-    FormalParameters formals = pop();
+    FormalParameters<Arguments> formals = pop();
     exitFunction();
     List<TypeParameter> typeParameters = typeVariableBuildersToKernel(pop());
-    FunctionNode function = formals.addToFunction(new FunctionNode(body,
-        typeParameters: typeParameters, asyncMarker: asyncModifier)
+    FunctionNode function = formals.addToFunction(new FunctionNode(
+        toKernelStatement(body),
+        typeParameters: typeParameters,
+        asyncMarker: asyncModifier)
       ..fileOffset = beginToken.charOffset
       ..fileEndOffset = token.charOffset);
     if (constantContext != ConstantContext.none) {
@@ -3082,19 +3151,18 @@
       Token doKeyword, Token whileKeyword, Token endToken) {
     debugEvent("DoWhileStatement");
     Expression condition = popForValue();
-    kernel.Statement body = popStatement();
+    Statement body = popStatement();
     JumpTarget continueTarget = exitContinueTarget();
     JumpTarget breakTarget = exitBreakTarget();
     if (continueTarget.hasUsers) {
-      body = new ShadowLabeledStatement(body);
-      continueTarget.resolveContinues(body);
+      body = forest.syntheticLabeledStatement(body);
+      continueTarget.resolveContinues(forest, body);
     }
-    kernel.Statement result =
-        new ShadowDoStatement(body, toKernelExpression(condition))
-          ..fileOffset = doKeyword.charOffset;
+    Statement result =
+        forest.doStatement(doKeyword, body, whileKeyword, condition, endToken);
     if (breakTarget.hasUsers) {
-      result = new ShadowLabeledStatement(result);
-      breakTarget.resolveBreaks(result);
+      result = forest.syntheticLabeledStatement(result);
+      breakTarget.resolveBreaks(forest, result);
     }
     exitLoopOrSwitch(result);
   }
@@ -3116,15 +3184,16 @@
   void endForIn(Token awaitToken, Token forToken, Token leftParenthesis,
       Token inKeyword, Token endToken) {
     debugEvent("ForIn");
-    kernel.Statement body = popStatement();
+    Statement body = popStatement();
     Expression expression = popForValue();
     var lvalue = pop();
     exitLocalScope();
     JumpTarget continueTarget = exitContinueTarget();
     JumpTarget breakTarget = exitBreakTarget();
+    kernel.Statement kernelBody = toKernelStatement(body);
     if (continueTarget.hasUsers) {
-      body = new ShadowLabeledStatement(body);
-      continueTarget.resolveContinues(body);
+      kernelBody = new ShadowLabeledStatement(kernelBody);
+      continueTarget.resolveContinues(forest, kernelBody);
     }
     VariableDeclaration variable;
     bool declaresVariable = false;
@@ -3155,27 +3224,31 @@
           new ShadowVariableGet(variable, fact, scope)
             ..fileOffset = inKeyword.offset,
           voidContext: true);
-      body = combineStatements(
-          new ShadowLoopAssignmentStatement(syntheticAssignment), body);
+      kernelBody = combineStatements(
+          new ShadowLoopAssignmentStatement(syntheticAssignment), kernelBody);
     } else {
+      Message message = forest.isVariablesDeclaration(lvalue)
+          ? fasta.messageForInLoopExactlyOneVariable
+          : fasta.messageForInLoopNotAssignable;
+      Token token = forToken.next.next;
       variable = new VariableDeclaration.forValue(toKernelExpression(
-          deprecated_buildCompileTimeError("Expected lvalue, but got ${lvalue}",
-              forToken.next.next.charOffset)));
+          buildCompileTimeError(
+              message, offsetForToken(token), lengthForToken(token))));
     }
     kernel.Statement result = new ShadowForInStatement(
         variable,
         toKernelExpression(expression),
-        body,
+        kernelBody,
         declaresVariable,
         syntheticAssignment,
         isAsync: awaitToken != null)
       ..fileOffset = awaitToken?.charOffset ?? forToken.charOffset
-      ..bodyOffset = body.fileOffset;
+      ..bodyOffset = kernelBody.fileOffset;
     if (breakTarget.hasUsers) {
       result = new ShadowLabeledStatement(result);
-      breakTarget.resolveBreaks(result);
+      breakTarget.resolveBreaks(forest, result);
     }
-    exitLoopOrSwitch(result);
+    exitLoopOrSwitch(toStatement(result));
   }
 
   @override
@@ -3190,8 +3263,8 @@
     debugEvent("beginLabeledStatement");
     List<Label> labels = popList(labelCount);
     enterLocalScope(null, scope.createNestedLabelScope());
-    LabelTarget target =
-        new LabelTarget(member, functionNestingLevel, token.charOffset);
+    LabelTarget target = new LabelTarget<Statement>(
+        member, functionNestingLevel, token.charOffset);
     for (Label label in labels) {
       scope.declareLabel(label.name, target);
     }
@@ -3201,30 +3274,30 @@
   @override
   void endLabeledStatement(int labelCount) {
     debugEvent("LabeledStatement");
-    kernel.Statement statement = popStatement();
+    Statement statement = popStatement();
     LabelTarget target = pop();
     exitLocalScope();
+    kernel.Statement kernelStatement = toKernelStatement(statement);
     if (target.breakTarget.hasUsers) {
-      if (statement is! LabeledStatement) {
-        statement = new ShadowLabeledStatement(statement);
+      if (kernelStatement is! LabeledStatement) {
+        kernelStatement = new ShadowLabeledStatement(kernelStatement);
       }
-      target.breakTarget.resolveBreaks(statement);
+      target.breakTarget.resolveBreaks(forest, kernelStatement);
     }
     if (target.continueTarget.hasUsers) {
-      if (statement is! LabeledStatement) {
-        statement = new ShadowLabeledStatement(statement);
+      if (kernelStatement is! LabeledStatement) {
+        kernelStatement = new ShadowLabeledStatement(kernelStatement);
       }
-      target.continueTarget.resolveContinues(statement);
+      target.continueTarget.resolveContinues(forest, kernelStatement);
     }
-    push(statement);
+    push(kernelStatement);
   }
 
   @override
   void endRethrowStatement(Token rethrowToken, Token endToken) {
     debugEvent("RethrowStatement");
     if (inCatchBlock) {
-      push(new ShadowExpressionStatement(
-          new ShadowRethrow()..fileOffset = offsetForToken(rethrowToken)));
+      push(forest.rethrowStatement(rethrowToken, endToken));
     } else {
       push(deprecated_buildCompileTimeErrorStatement(
           "'rethrow' can only be used in catch clauses.",
@@ -3241,20 +3314,18 @@
   @override
   void endWhileStatement(Token whileKeyword, Token endToken) {
     debugEvent("WhileStatement");
-    kernel.Statement body = popStatement();
+    Statement body = popStatement();
     Expression condition = popForValue();
     JumpTarget continueTarget = exitContinueTarget();
     JumpTarget breakTarget = exitBreakTarget();
     if (continueTarget.hasUsers) {
-      body = new ShadowLabeledStatement(body);
-      continueTarget.resolveContinues(body);
+      body = forest.syntheticLabeledStatement(body);
+      continueTarget.resolveContinues(forest, body);
     }
-    kernel.Statement result =
-        new ShadowWhileStatement(toKernelExpression(condition), body)
-          ..fileOffset = whileKeyword.charOffset;
+    Statement result = forest.whileStatement(whileKeyword, condition, body);
     if (breakTarget.hasUsers) {
-      result = new ShadowLabeledStatement(result);
-      breakTarget.resolveBreaks(result);
+      result = forest.syntheticLabeledStatement(result);
+      breakTarget.resolveBreaks(forest, result);
     }
     exitLoopOrSwitch(result);
   }
@@ -3262,7 +3333,7 @@
   @override
   void handleEmptyStatement(Token token) {
     debugEvent("EmptyStatement");
-    push(new EmptyStatement());
+    push(forest.emptyStatement(token));
   }
 
   @override
@@ -3341,9 +3412,7 @@
   @override
   void endYieldStatement(Token yieldToken, Token starToken, Token endToken) {
     debugEvent("YieldStatement");
-    push(new ShadowYieldStatement(toKernelExpression(popForValue()),
-        isYieldStar: starToken != null)
-      ..fileOffset = yieldToken.charOffset);
+    push(forest.yieldStatement(yieldToken, starToken, popForValue(), endToken));
   }
 
   @override
@@ -3402,7 +3471,7 @@
     // We always create a block here so that we later know that there's always
     // one synthetic block when we finish compiling the switch statement and
     // check this switch case to see if it falls through to the next case.
-    Block block = popBlock(statementCount, firstToken);
+    Statement block = popBlock(statementCount, firstToken, null);
     exitLocalScope();
     List<Label> labels = pop();
     List<Expression> expressions = pop();
@@ -3410,8 +3479,8 @@
     for (Expression expression in expressions) {
       expressionOffsets.add(forest.readOffset(expression));
     }
-    push(new SwitchCase(
-        toKernelExpressionList(expressions), expressionOffsets, block,
+    push(new SwitchCase(toKernelExpressionList(expressions), expressionOffsets,
+        toKernelStatement(block),
         isDefault: defaultKeyword != null)
       ..fileOffset = firstToken.charOffset);
     push(labels);
@@ -3431,9 +3500,9 @@
           ..fileOffset = switchKeyword.charOffset;
     if (target.hasUsers) {
       result = new ShadowLabeledStatement(result);
-      target.resolveBreaks(result);
+      target.resolveBreaks(forest, result);
     }
-    exitLoopOrSwitch(result);
+    exitLoopOrSwitch(toStatement(result));
   }
 
   @override
@@ -3447,7 +3516,7 @@
       for (Label label in labels) {
         JumpTarget target = switchScope.lookupLabel(label.name);
         if (target != null) {
-          target.resolveGotos(current);
+          target.resolveGotos(forest, current);
         }
       }
     }
@@ -3458,7 +3527,7 @@
       // declarations in the switch case.
       TreeNode lastNode =
           block.statements.isEmpty ? null : block.statements.last;
-      if (lastNode is Block) {
+      if (forest.isBlock(lastNode)) {
         // This is a non-synthetic block.
         Block block = lastNode;
         lastNode = block.statements.isEmpty ? null : block.statements.last;
@@ -3581,9 +3650,25 @@
   void beginTypeVariables(Token token) {
     debugEvent("beginTypeVariables");
     OutlineBuilder listener = new OutlineBuilder(library);
+    // TODO(dmitryas):  [ClassMemberParser] shouldn't be used to parse and build
+    // the type variables for the local function.  It also causes the unresolved
+    // types from the bounds of the type variables to appear in [library.types].
+    // See the code that resolves them below.
     new ClassMemberParser(listener)
         .parseTypeVariablesOpt(new Token.eof(-1)..next = token);
     enterFunctionTypeScope(listener.pop());
+
+    // The invocation of [enterFunctionTypeScope] above has put the type
+    // variables into the scope, and now the possibly unresolved types from
+    // the bounds of the variables can be resolved.  This is needed to apply
+    // instantiate-to-bound later.
+    // TODO(dmitryas):  Move the resolution to the appropriate place once
+    // [ClassMemberParser] is not used to build the type variables for the local
+    // function.  See the comment above.
+    for (UnresolvedType t in library.types) {
+      t.resolveIn(scope);
+    }
+    library.types.clear();
   }
 
   @override
@@ -3616,15 +3701,40 @@
         variable.parameter.addAnnotation(toKernelExpression(annotation));
       }
     }
-    push(variable
-      ..finish(library, library.loader.target.objectClassBuilder,
-          library.loader.target.dynamicType));
+    push(variable);
   }
 
   @override
   void endTypeVariables(int count, Token beginToken, Token endToken) {
     debugEvent("TypeVariables");
-    push(popList(count) ?? NullValue.TypeVariables);
+    List<KernelTypeVariableBuilder> typeVariables = popList(count);
+    if (typeVariables != null) {
+      if (library.loader.target.strongMode) {
+        List<KernelTypeBuilder> calculatedBounds = calculateBounds(
+            typeVariables,
+            library.loader.target.dynamicType,
+            library.loader.target.bottomType,
+            library.loader.target.objectClassBuilder);
+        for (int i = 0; i < typeVariables.length; ++i) {
+          typeVariables[i].defaultType = calculatedBounds[i];
+          typeVariables[i].defaultType.resolveIn(
+              scope, typeVariables[i].charOffset, typeVariables[i].fileUri);
+          typeVariables[i].finish(
+              library,
+              library.loader.target.objectClassBuilder,
+              library.loader.target.dynamicType);
+        }
+      } else {
+        for (int i = 0; i < typeVariables.length; ++i) {
+          typeVariables[i].defaultType = library.loader.target.dynamicType;
+          typeVariables[i].finish(
+              library,
+              library.loader.target.objectClassBuilder,
+              library.loader.target.dynamicType);
+        }
+      }
+    }
+    push(typeVariables ?? NullValue.TypeVariables);
   }
 
   List<TypeParameter> typeVariableBuildersToKernel(List typeVariableBuilders) {
@@ -3871,7 +3981,7 @@
   @override
   void handleOperator(Token token) {
     debugEvent("Operator");
-    push(new Operator(token.stringValue, token.charOffset));
+    push(new Operator(token, token.charOffset));
   }
 
   @override
@@ -3898,10 +4008,13 @@
     if (member.isNative) {
       push(NullValue.FunctionBody);
     } else {
-      push(new Block(<kernel.Statement>[
-        deprecated_buildCompileTimeErrorStatement(
-            "Expected '{'.", token.charOffset)
-      ]));
+      push(forest.block(
+          token,
+          <Statement>[
+            toStatement(deprecated_buildCompileTimeErrorStatement(
+                "Expected '{'.", token.charOffset))
+          ],
+          null));
     }
   }
 
@@ -3960,7 +4073,7 @@
     }
     if (isSuper) {
       // We can ignore [isNullAware] on super sends.
-      assert(receiver is ThisExpression);
+      assert(forest.isThisExpression(receiver));
       Member target = lookupInstanceMember(name, isSuper: true);
 
       if (target == null || (target is Procedure && !target.isAccessor)) {
@@ -3994,14 +4107,17 @@
           new VariableDeclaration.forValue(toKernelExpression(receiver));
       return toExpression(new ShadowNullAwareMethodInvocation(
           variable,
-          new ConditionalExpression(
-              buildIsNull(new VariableGet(variable), offset),
-              toKernelExpression(storeOffset(forest.literalNull(null), offset)),
-              new MethodInvocation(new VariableGet(variable), name,
-                  forest.castArguments(arguments), interfaceTarget)
-                ..fileOffset = offset,
-              null)
-            ..fileOffset = offset)
+          toKernelExpression(storeOffset(
+              forest.conditionalExpression(
+                  toExpression(
+                      buildIsNull(new VariableGet(variable), offset, this)),
+                  null,
+                  storeOffset(forest.literalNull(null), offset),
+                  null,
+                  toExpression(new MethodInvocation(new VariableGet(variable),
+                      name, forest.castArguments(arguments), interfaceTarget)
+                    ..fileOffset = offset)),
+              offset)))
         ..fileOffset = offset);
     } else {
       return toExpression(new ShadowMethodInvocation(
@@ -4079,6 +4195,20 @@
     return expressions as dynamic;
   }
 
+  // TODO(ahe): Remove this method once Forest API is complete.
+  kernel.Statement toKernelStatement(Statement statement) {
+    return statement as dynamic;
+  }
+
+  // TODO(ahe): Remove this method once Forest API is complete.
+  Statement toStatement(kernel.Statement statement) {
+    return statement as dynamic;
+  }
+
+  /// TODO(ahe): This method is temporarily implemented by subclasses. Once type
+  /// promotion is independent of shadow nodes, remove this method.
+  void enterThenForTypePromotion(Expression condition);
+
   bool isErroneousNode(TreeNode node) {
     return library.loader.handledErrors.isNotEmpty &&
         forest.isErroneousNode(node);
@@ -4097,11 +4227,12 @@
 }
 
 class Operator {
-  final String name;
+  final Token token;
+  String get name => token.stringValue;
 
   final int charOffset;
 
-  Operator(this.name, this.charOffset);
+  Operator(this.token, this.charOffset);
 
   String toString() => "operator($name)";
 }
@@ -4123,8 +4254,9 @@
   String toString() => "label($name)";
 }
 
-abstract class ContextAccessor<Arguments> extends FastaAccessor<Arguments> {
-  final BuilderHelper helper;
+abstract class ContextAccessor<Arguments> extends FastaAccessor<Arguments>
+    with GeneratorImpl {
+  final BuilderHelper<dynamic, dynamic, Arguments> helper;
 
   final FastaAccessor accessor;
 
@@ -4194,10 +4326,12 @@
 
   final String assignmentOperator;
 
-  DelayedAssignment(BuilderHelper helper, Token token, FastaAccessor accessor,
-      this.value, this.assignmentOperator)
+  DelayedAssignment(BuilderHelper<dynamic, dynamic, Arguments> helper,
+      Token token, FastaAccessor accessor, this.value, this.assignmentOperator)
       : super(helper, token, accessor);
 
+  String get debugName => "DelayedAssignment";
+
   kernel.Expression buildSimpleRead() {
     return handleAssignment(false);
   }
@@ -4258,13 +4392,20 @@
 
   @override
   Initializer buildFieldInitializer(Map<String, int> initializedFields) {
-    if (!identical("=", assignmentOperator) ||
-        !accessor.isThisPropertyAccessor) {
+    if (!identical("=", assignmentOperator) || !accessor.isThisPropertyAccess) {
       return accessor.buildFieldInitializer(initializedFields);
     }
     return helper.buildFieldInitializer(
         false, accessor.plainNameForRead, offsetForToken(token), value);
   }
+
+  @override
+  void printOn(StringSink sink) {
+    sink.write(", value: ");
+    printNodeOn(value, sink);
+    sink.write(", assignmentOperator: ");
+    sink.write(assignmentOperator);
+  }
 }
 
 class DelayedPostfixIncrement<Arguments> extends ContextAccessor<Arguments> {
@@ -4272,10 +4413,16 @@
 
   final Procedure interfaceTarget;
 
-  DelayedPostfixIncrement(BuilderHelper helper, Token token,
-      FastaAccessor accessor, this.binaryOperator, this.interfaceTarget)
+  DelayedPostfixIncrement(
+      BuilderHelper<dynamic, dynamic, Arguments> helper,
+      Token token,
+      FastaAccessor accessor,
+      this.binaryOperator,
+      this.interfaceTarget)
       : super(helper, token, accessor);
 
+  String get debugName => "DelayedPostfixIncrement";
+
   kernel.Expression buildSimpleRead() {
     return accessor.buildPostfixIncrement(binaryOperator,
         offset: offsetForToken(token),
@@ -4289,10 +4436,18 @@
         voidContext: true,
         interfaceTarget: interfaceTarget);
   }
+
+  @override
+  void printOn(StringSink sink) {
+    sink.write(", binaryOperator: ");
+    sink.write(binaryOperator.name);
+    sink.write(", interfaceTarget: ");
+    printQualifiedNameOn(interfaceTarget, sink);
+  }
 }
 
-class JumpTarget extends Builder {
-  final List<kernel.Statement> users = <kernel.Statement>[];
+class JumpTarget<Statement> extends Builder {
+  final List<Statement> users = <Statement>[];
 
   final JumpTargetKind kind;
 
@@ -4310,41 +4465,44 @@
 
   bool get hasUsers => users.isNotEmpty;
 
-  void addBreak(BreakStatement statement) {
+  void addBreak(Statement statement) {
     assert(isBreakTarget);
     users.add(statement);
   }
 
-  void addContinue(BreakStatement statement) {
+  void addContinue(Statement statement) {
     assert(isContinueTarget);
     users.add(statement);
   }
 
-  void addGoto(ContinueSwitchStatement statement) {
+  void addGoto(Statement statement) {
     assert(isGotoTarget);
     users.add(statement);
   }
 
-  void resolveBreaks(LabeledStatement target) {
+  void resolveBreaks(
+      Forest<dynamic, Statement, dynamic, dynamic> forest, Statement target) {
     assert(isBreakTarget);
-    for (BreakStatement user in users) {
-      user.target = target;
+    for (Statement user in users) {
+      forest.resolveBreak(target, user);
     }
     users.clear();
   }
 
-  void resolveContinues(LabeledStatement target) {
+  void resolveContinues(
+      Forest<dynamic, Statement, dynamic, dynamic> forest, Statement target) {
     assert(isContinueTarget);
-    for (BreakStatement user in users) {
-      user.target = target;
+    for (Statement user in users) {
+      forest.resolveContinue(target, user);
     }
     users.clear();
   }
 
-  void resolveGotos(SwitchCase target) {
+  void resolveGotos(
+      Forest<dynamic, Statement, dynamic, dynamic> forest, Object target) {
     assert(isGotoTarget);
-    for (ContinueSwitchStatement user in users) {
-      user.target = target;
+    for (Statement user in users) {
+      forest.resolveContinueInSwitch(target, user);
     }
     users.clear();
   }
@@ -4353,7 +4511,7 @@
   String get fullNameForErrors => "<jump-target>";
 }
 
-class LabelTarget extends Builder implements JumpTarget {
+class LabelTarget<Statement> extends Builder implements JumpTarget<Statement> {
   final JumpTarget breakTarget;
 
   final JumpTarget continueTarget;
@@ -4361,15 +4519,15 @@
   final int functionNestingLevel;
 
   LabelTarget(MemberBuilder member, this.functionNestingLevel, int charOffset)
-      : breakTarget = new JumpTarget(
+      : breakTarget = new JumpTarget<Statement>(
             JumpTargetKind.Break, functionNestingLevel, member, charOffset),
-        continueTarget = new JumpTarget(
+        continueTarget = new JumpTarget<Statement>(
             JumpTargetKind.Continue, functionNestingLevel, member, charOffset),
         super(member, charOffset, member.fileUri);
 
   bool get hasUsers => breakTarget.hasUsers || continueTarget.hasUsers;
 
-  List<kernel.Statement> get users => unsupported("users", charOffset, fileUri);
+  List<Statement> get users => unsupported("users", charOffset, fileUri);
 
   JumpTargetKind get kind => unsupported("kind", charOffset, fileUri);
 
@@ -4379,27 +4537,30 @@
 
   bool get isGotoTarget => false;
 
-  void addBreak(BreakStatement statement) {
+  void addBreak(Statement statement) {
     breakTarget.addBreak(statement);
   }
 
-  void addContinue(BreakStatement statement) {
+  void addContinue(Statement statement) {
     continueTarget.addContinue(statement);
   }
 
-  void addGoto(ContinueSwitchStatement statement) {
+  void addGoto(Statement statement) {
     unsupported("addGoto", charOffset, fileUri);
   }
 
-  void resolveBreaks(LabeledStatement target) {
-    breakTarget.resolveBreaks(target);
+  void resolveBreaks(
+      Forest<dynamic, Statement, dynamic, dynamic> forest, Statement target) {
+    breakTarget.resolveBreaks(forest, target);
   }
 
-  void resolveContinues(LabeledStatement target) {
-    continueTarget.resolveContinues(target);
+  void resolveContinues(
+      Forest<dynamic, Statement, dynamic, dynamic> forest, Statement target) {
+    continueTarget.resolveContinues(forest, target);
   }
 
-  void resolveGotos(SwitchCase target) {
+  void resolveGotos(
+      Forest<dynamic, Statement, dynamic, dynamic> forest, Object target) {
     unsupported("resolveGotos", charOffset, fileUri);
   }
 
@@ -4415,7 +4576,7 @@
   OptionalFormals(this.kind, this.formals);
 }
 
-class FormalParameters {
+class FormalParameters<Arguments> {
   final List<VariableDeclaration> required;
   final OptionalFormals optional;
   final int charOffset;
@@ -4466,8 +4627,8 @@
         typeParameters: typeParameters);
   }
 
-  Scope computeFormalParameterScope(
-      Scope parent, Builder builder, BuilderHelper helper) {
+  Scope computeFormalParameterScope(Scope parent, Builder builder,
+      BuilderHelper<dynamic, dynamic, Arguments> helper) {
     if (required.length == 0 && optional == null) return parent;
     Map<String, Builder> local = <String, Builder>{};
 
@@ -4521,7 +4682,7 @@
     return node.name;
   } else if (node is Builder) {
     return node.fullNameForErrors;
-  } else if (node is ThisAccessor) {
+  } else if (node is ThisAccessGenerator) {
     return node.isSuper ? "super" : "this";
   } else if (node is FastaAccessor) {
     return node.plainNameForRead;
diff --git a/pkg/front_end/lib/src/fasta/kernel/expression_generator.dart b/pkg/front_end/lib/src/fasta/kernel/expression_generator.dart
new file mode 100644
index 0000000..291cf8a
--- /dev/null
+++ b/pkg/front_end/lib/src/fasta/kernel/expression_generator.dart
@@ -0,0 +1,1752 @@
+// 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.
+
+/// A library to help transform compounds and null-aware accessors into
+/// let expressions.
+library fasta.expression_generator;
+
+import '../../scanner/token.dart' show Token;
+
+import '../constant_context.dart' show ConstantContext;
+
+import '../fasta_codes.dart'
+    show
+        LocatedMessage,
+        messageInvalidInitializer,
+        messageLoadLibraryTakesNoArguments,
+        messageSuperAsExpression,
+        templateDeferredTypeAnnotation,
+        templateIntegerLiteralIsOutOfRange,
+        templateNotAPrefixInTypeAnnotation,
+        templateNotAType,
+        templateUnresolvedPrefixInTypeAnnotation;
+
+import '../messages.dart' show Message, noLength;
+
+import '../names.dart'
+    show callName, equalsName, indexGetName, indexSetName, lengthName;
+
+import '../parser.dart' show lengthForToken, lengthOfSpan, offsetForToken;
+
+import '../problems.dart' show unhandled, unimplemented, unsupported;
+
+import '../scope.dart' show AccessErrorBuilder, ProblemBuilder, Scope;
+
+import '../type_inference/type_promotion.dart' show TypePromoter;
+
+import 'body_builder.dart' show Identifier, noLocation;
+
+import 'constness.dart' show Constness;
+
+import 'forest.dart' show Forest;
+
+import 'kernel_builder.dart' show LoadLibraryBuilder, PrefixBuilder;
+
+import 'kernel_api.dart' show NameSystem, printNodeOn, printQualifiedNameOn;
+
+import 'kernel_ast_api.dart'
+    show
+        Constructor,
+        DartType,
+        Field,
+        FunctionNode,
+        FunctionType,
+        Initializer,
+        InvalidType,
+        Let,
+        Member,
+        Name,
+        Procedure,
+        PropertySet,
+        ShadowComplexAssignment,
+        ShadowIllegalAssignment,
+        ShadowIndexAssign,
+        ShadowMethodInvocation,
+        ShadowNullAwarePropertyGet,
+        ShadowPropertyAssign,
+        ShadowPropertyGet,
+        ShadowStaticAssignment,
+        ShadowSuperMethodInvocation,
+        ShadowSuperPropertyGet,
+        ShadowVariableAssignment,
+        ShadowVariableDeclaration,
+        ShadowVariableGet,
+        StaticGet,
+        StaticSet,
+        SuperMethodInvocation,
+        SuperPropertySet,
+        Throw,
+        TreeNode,
+        TypeParameter,
+        TypeParameterType,
+        VariableDeclaration,
+        VariableGet,
+        VariableSet;
+
+import 'kernel_ast_api.dart' as kernel show Expression, Node, Statement;
+
+import 'kernel_builder.dart'
+    show
+        Builder,
+        BuiltinTypeBuilder,
+        FunctionTypeAliasBuilder,
+        KernelClassBuilder,
+        KernelFunctionTypeAliasBuilder,
+        KernelInvalidTypeBuilder,
+        KernelPrefixBuilder,
+        KernelTypeVariableBuilder,
+        LibraryBuilder,
+        LoadLibraryBuilder,
+        PrefixBuilder,
+        TypeDeclarationBuilder;
+
+part 'expression_generator_impl.dart';
+
+/// An [Accessor] represents a subexpression for which we can't yet build a
+/// kernel [kernel.Expression] because we don't yet know the context in which
+/// it is used.
+///
+/// Once the context is known, an [Accessor] can be converted into an
+/// [kernel.Expression] by calling a "build" method.
+///
+/// For example, when building a kernel representation for `a[x] = b`, after
+/// parsing `a[x]` but before parsing `= b`, we don't yet know whether to
+/// generate an invocation of `operator[]` or `operator[]=`, so we generate an
+/// [Accessor] object.  Later, after `= b` is parsed, [buildAssignment] will be
+/// called.
+// TODO(ahe): Move this into [Generator] when all uses have been updated.
+abstract class Accessor<Arguments> {
+  final BuilderHelper<dynamic, dynamic, Arguments> helper;
+  final Token token;
+
+  Accessor(this.helper, this.token);
+
+  Forest<kernel.Expression, kernel.Statement, Token, Arguments> get forest =>
+      helper.forest;
+
+  /// Builds an [kernel.Expression] representing a read from the accessor.
+  kernel.Expression buildSimpleRead() {
+    return _finish(_makeSimpleRead(), null);
+  }
+
+  /// Builds an [kernel.Expression] representing an assignment with the
+  /// accessor on the LHS and [value] on the RHS.
+  ///
+  /// The returned expression evaluates to the assigned value, unless
+  /// [voidContext] is true, in which case it may evaluate to anything.
+  kernel.Expression buildAssignment(kernel.Expression value,
+      {bool voidContext: false}) {
+    var complexAssignment = startComplexAssignment(value);
+    return _finish(_makeSimpleWrite(value, voidContext, complexAssignment),
+        complexAssignment);
+  }
+
+  /// Returns an [kernel.Expression] representing a null-aware assignment
+  /// (`??=`) with the accessor on the LHS and [value] on the RHS.
+  ///
+  /// The returned expression evaluates to the assigned value, unless
+  /// [voidContext] is true, in which case it may evaluate to anything.
+  ///
+  /// [type] is the static type of the RHS.
+  kernel.Expression buildNullAwareAssignment(
+      kernel.Expression value, DartType type, int offset,
+      {bool voidContext: false}) {
+    var complexAssignment = startComplexAssignment(value);
+    if (voidContext) {
+      var nullAwareCombiner = helper.storeOffset(
+          forest.conditionalExpression(
+              buildIsNull(_makeRead(complexAssignment), offset, helper),
+              null,
+              _makeWrite(value, false, complexAssignment),
+              null,
+              helper.storeOffset(forest.literalNull(null), offset)),
+          offset);
+      complexAssignment?.nullAwareCombiner = nullAwareCombiner;
+      return _finish(nullAwareCombiner, complexAssignment);
+    }
+    var tmp = new VariableDeclaration.forValue(_makeRead(complexAssignment));
+    var nullAwareCombiner = helper.storeOffset(
+        forest.conditionalExpression(
+            buildIsNull(new VariableGet(tmp), offset, helper),
+            null,
+            _makeWrite(value, false, complexAssignment),
+            null,
+            new VariableGet(tmp)),
+        offset);
+    complexAssignment?.nullAwareCombiner = nullAwareCombiner;
+    return _finish(makeLet(tmp, nullAwareCombiner), complexAssignment);
+  }
+
+  /// Returns an [kernel.Expression] representing a compound assignment
+  /// (e.g. `+=`) with the accessor on the LHS and [value] on the RHS.
+  kernel.Expression buildCompoundAssignment(
+      Name binaryOperator, kernel.Expression value,
+      {int offset: TreeNode.noOffset,
+      bool voidContext: false,
+      Procedure interfaceTarget,
+      bool isPreIncDec: false}) {
+    var complexAssignment = startComplexAssignment(value);
+    complexAssignment?.isPreIncDec = isPreIncDec;
+    var combiner = makeBinary(_makeRead(complexAssignment), binaryOperator,
+        interfaceTarget, value, helper,
+        offset: offset);
+    complexAssignment?.combiner = combiner;
+    return _finish(_makeWrite(combiner, voidContext, complexAssignment),
+        complexAssignment);
+  }
+
+  /// Returns an [kernel.Expression] representing a pre-increment or
+  /// pre-decrement of the accessor.
+  kernel.Expression buildPrefixIncrement(Name binaryOperator,
+      {int offset: TreeNode.noOffset,
+      bool voidContext: false,
+      Procedure interfaceTarget}) {
+    return buildCompoundAssignment(
+        binaryOperator, helper.storeOffset(forest.literalInt(1, null), offset),
+        offset: offset,
+        voidContext: voidContext,
+        interfaceTarget: interfaceTarget,
+        isPreIncDec: true);
+  }
+
+  /// Returns an [kernel.Expression] representing a post-increment or
+  /// post-decrement of the accessor.
+  kernel.Expression buildPostfixIncrement(Name binaryOperator,
+      {int offset: TreeNode.noOffset,
+      bool voidContext: false,
+      Procedure interfaceTarget}) {
+    if (voidContext) {
+      return buildPrefixIncrement(binaryOperator,
+          offset: offset, voidContext: true, interfaceTarget: interfaceTarget);
+    }
+    var rhs = helper.storeOffset(forest.literalInt(1, null), offset);
+    var complexAssignment = startComplexAssignment(rhs);
+    var value = new VariableDeclaration.forValue(_makeRead(complexAssignment));
+    valueAccess() => new VariableGet(value);
+    var combiner = makeBinary(
+        valueAccess(), binaryOperator, interfaceTarget, rhs, helper,
+        offset: offset);
+    complexAssignment?.combiner = combiner;
+    complexAssignment?.isPostIncDec = true;
+    var dummy = new ShadowVariableDeclaration.forValue(
+        _makeWrite(combiner, true, complexAssignment),
+        helper.functionNestingLevel);
+    return _finish(
+        makeLet(value, makeLet(dummy, valueAccess())), complexAssignment);
+  }
+
+  kernel.Expression _makeSimpleRead() => _makeRead(null);
+
+  kernel.Expression _makeSimpleWrite(kernel.Expression value, bool voidContext,
+      ShadowComplexAssignment complexAssignment) {
+    return _makeWrite(value, voidContext, complexAssignment);
+  }
+
+  kernel.Expression _makeRead(ShadowComplexAssignment complexAssignment);
+
+  kernel.Expression _makeWrite(kernel.Expression value, bool voidContext,
+      ShadowComplexAssignment complexAssignment);
+
+  kernel.Expression _finish(
+      kernel.Expression body, ShadowComplexAssignment complexAssignment) {
+    if (complexAssignment != null) {
+      complexAssignment.desugared = body;
+      return complexAssignment;
+    } else {
+      return body;
+    }
+  }
+
+  /// Returns an [kernel.Expression] representing a compile-time error.
+  ///
+  /// At runtime, an exception will be thrown.
+  makeInvalidRead() {
+    return unhandled("compile-time error", "$runtimeType",
+        offsetForToken(token), helper.uri);
+  }
+
+  /// Returns an [kernel.Expression] representing a compile-time error wrapping
+  /// [value].
+  ///
+  /// At runtime, [value] will be evaluated before throwing an exception.
+  makeInvalidWrite(kernel.Expression value) {
+    return unhandled("compile-time error", "$runtimeType",
+        offsetForToken(token), helper.uri);
+  }
+
+  /// Creates a data structure for tracking the desugaring of a complex
+  /// assignment expression whose right hand side is [rhs].
+  ShadowComplexAssignment startComplexAssignment(kernel.Expression rhs) =>
+      new ShadowIllegalAssignment(rhs);
+}
+
+// TODO(ahe): Merge classes [Accessor] and [FastaAccessor] into this.
+abstract class Generator<Arguments> = Accessor<Arguments>
+    with FastaAccessor<Arguments>;
+
+class VariableUseGenerator<Arguments> extends Generator<Arguments> {
+  final VariableDeclaration variable;
+
+  final DartType promotedType;
+
+  VariableUseGenerator(BuilderHelper<dynamic, dynamic, Arguments> helper,
+      Token token, this.variable,
+      [this.promotedType])
+      : super(helper, token);
+
+  String get plainNameForRead => variable.name;
+
+  String get debugName => "VariableUseGenerator";
+
+  kernel.Expression _makeRead(ShadowComplexAssignment complexAssignment) {
+    var fact = helper.typePromoter
+        .getFactForAccess(variable, helper.functionNestingLevel);
+    var scope = helper.typePromoter.currentScope;
+    var read = new ShadowVariableGet(variable, fact, scope)
+      ..fileOffset = offsetForToken(token);
+    complexAssignment?.read = read;
+    return read;
+  }
+
+  kernel.Expression _makeWrite(kernel.Expression value, bool voidContext,
+      ShadowComplexAssignment 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;
+    return write;
+  }
+
+  @override
+  kernel.Expression doInvocation(int offset, Arguments arguments) {
+    return helper.buildMethodInvocation(buildSimpleRead(), callName, arguments,
+        adjustForImplicitCall(plainNameForRead, offset),
+        isImplicitCall: true);
+  }
+
+  @override
+  ShadowComplexAssignment startComplexAssignment(kernel.Expression rhs) =>
+      new ShadowVariableAssignment(rhs);
+
+  @override
+  void printOn(StringSink sink) {
+    NameSystem syntheticNames = new NameSystem();
+    sink.write(", variable: ");
+    printNodeOn(variable, sink, syntheticNames: syntheticNames);
+    sink.write(", promotedType: ");
+    printNodeOn(promotedType, sink, syntheticNames: syntheticNames);
+  }
+}
+
+class PropertyAccessGenerator<Arguments> extends Generator<Arguments> {
+  final kernel.Expression receiver;
+
+  final Name name;
+
+  final Member getter;
+
+  final Member setter;
+
+  VariableDeclaration _receiverVariable;
+
+  PropertyAccessGenerator.internal(
+      BuilderHelper<dynamic, dynamic, Arguments> helper,
+      Token token,
+      this.receiver,
+      this.name,
+      this.getter,
+      this.setter)
+      : super(helper, token);
+
+  static FastaAccessor<Arguments> make<Arguments>(
+      BuilderHelper<dynamic, dynamic, Arguments> helper,
+      Token token,
+      kernel.Expression receiver,
+      Name name,
+      Member getter,
+      Member setter,
+      bool isNullAware) {
+    if (helper.forest.isThisExpression(receiver)) {
+      return unsupported("ThisExpression", offsetForToken(token), helper.uri);
+    } else {
+      return isNullAware
+          ? new NullAwarePropertyAccessGenerator(
+              helper, token, receiver, name, getter, setter, null)
+          : new PropertyAccessGenerator.internal(
+              helper, token, receiver, name, getter, setter);
+    }
+  }
+
+  String get plainNameForRead => name.name;
+
+  String get debugName => "PropertyAccessGenerator";
+
+  bool get isThisPropertyAccess => forest.isThisExpression(receiver);
+
+  kernel.Expression _makeSimpleRead() =>
+      new ShadowPropertyGet(receiver, name, getter)
+        ..fileOffset = offsetForToken(token);
+
+  kernel.Expression _makeSimpleWrite(kernel.Expression value, bool voidContext,
+      ShadowComplexAssignment complexAssignment) {
+    var write = new PropertySet(receiver, name, value, setter)
+      ..fileOffset = offsetForToken(token);
+    complexAssignment?.write = write;
+    return write;
+  }
+
+  receiverAccess() {
+    _receiverVariable ??= new VariableDeclaration.forValue(receiver);
+    return new VariableGet(_receiverVariable)
+      ..fileOffset = offsetForToken(token);
+  }
+
+  kernel.Expression _makeRead(ShadowComplexAssignment complexAssignment) {
+    var read = new ShadowPropertyGet(receiverAccess(), name, getter)
+      ..fileOffset = offsetForToken(token);
+    complexAssignment?.read = read;
+    return read;
+  }
+
+  kernel.Expression _makeWrite(kernel.Expression value, bool voidContext,
+      ShadowComplexAssignment complexAssignment) {
+    var write = new PropertySet(receiverAccess(), name, value, setter)
+      ..fileOffset = offsetForToken(token);
+    complexAssignment?.write = write;
+    return write;
+  }
+
+  kernel.Expression _finish(
+      kernel.Expression body, ShadowComplexAssignment complexAssignment) {
+    return super._finish(makeLet(_receiverVariable, body), complexAssignment);
+  }
+
+  kernel.Expression doInvocation(int offset, Arguments arguments) {
+    return helper.buildMethodInvocation(receiver, name, arguments, offset);
+  }
+
+  @override
+  ShadowComplexAssignment startComplexAssignment(kernel.Expression rhs) =>
+      new ShadowPropertyAssign(receiver, rhs);
+
+  @override
+  void printOn(StringSink sink) {
+    NameSystem syntheticNames = new NameSystem();
+    sink.write(", _receiverVariable: ");
+    printNodeOn(_receiverVariable, sink, syntheticNames: syntheticNames);
+    sink.write(", receiver: ");
+    printNodeOn(receiver, sink, syntheticNames: syntheticNames);
+    sink.write(", name: ");
+    sink.write(name.name);
+    sink.write(", getter: ");
+    printQualifiedNameOn(getter, sink, syntheticNames: syntheticNames);
+    sink.write(", setter: ");
+    printQualifiedNameOn(setter, sink, syntheticNames: syntheticNames);
+  }
+}
+
+/// Special case of [PropertyAccessGenerator] to avoid creating an indirect
+/// access to 'this'.
+class ThisPropertyAccessGenerator<Arguments> extends Generator<Arguments> {
+  final Name name;
+
+  final Member getter;
+
+  final Member setter;
+
+  ThisPropertyAccessGenerator(BuilderHelper<dynamic, dynamic, Arguments> helper,
+      Token token, this.name, this.getter, this.setter)
+      : super(helper, token);
+
+  String get plainNameForRead => name.name;
+
+  String get debugName => "ThisPropertyAccessGenerator";
+
+  bool get isThisPropertyAccess => true;
+
+  kernel.Expression _makeRead(ShadowComplexAssignment complexAssignment) {
+    if (getter == null) {
+      helper.warnUnresolvedGet(name, offsetForToken(token));
+    }
+    var read = new ShadowPropertyGet(forest.thisExpression(token), name, getter)
+      ..fileOffset = offsetForToken(token);
+    complexAssignment?.read = read;
+    return read;
+  }
+
+  kernel.Expression _makeWrite(kernel.Expression value, bool voidContext,
+      ShadowComplexAssignment complexAssignment) {
+    if (setter == null) {
+      helper.warnUnresolvedSet(name, offsetForToken(token));
+    }
+    var write =
+        new PropertySet(forest.thisExpression(token), name, value, setter)
+          ..fileOffset = offsetForToken(token);
+    complexAssignment?.write = write;
+    return write;
+  }
+
+  kernel.Expression doInvocation(int offset, Arguments arguments) {
+    Member interfaceTarget = getter;
+    if (interfaceTarget == null) {
+      helper.warnUnresolvedMethod(name, offset);
+    }
+    if (interfaceTarget is Field) {
+      // TODO(ahe): In strong mode we should probably rewrite this to
+      // `this.name.call(arguments)`.
+      interfaceTarget = null;
+    }
+    return helper.buildMethodInvocation(
+        forest.thisExpression(null), name, arguments, offset,
+        interfaceTarget: interfaceTarget);
+  }
+
+  @override
+  ShadowComplexAssignment startComplexAssignment(kernel.Expression rhs) =>
+      new ShadowPropertyAssign(null, rhs);
+
+  @override
+  void printOn(StringSink sink) {
+    NameSystem syntheticNames = new NameSystem();
+    sink.write(", name: ");
+    sink.write(name.name);
+    sink.write(", getter: ");
+    printQualifiedNameOn(getter, sink, syntheticNames: syntheticNames);
+    sink.write(", setter: ");
+    printQualifiedNameOn(setter, sink, syntheticNames: syntheticNames);
+  }
+}
+
+class NullAwarePropertyAccessGenerator<Arguments> extends Generator<Arguments> {
+  final VariableDeclaration receiver;
+
+  final kernel.Expression receiverExpression;
+
+  final Name name;
+
+  final Member getter;
+
+  final Member setter;
+
+  final DartType type;
+
+  NullAwarePropertyAccessGenerator(
+      BuilderHelper<dynamic, dynamic, Arguments> helper,
+      Token token,
+      this.receiverExpression,
+      this.name,
+      this.getter,
+      this.setter,
+      this.type)
+      : this.receiver = makeOrReuseVariable(receiverExpression),
+        super(helper, token);
+
+  String get plainNameForRead => name.name;
+
+  String get debugName => "NullAwarePropertyAccessGenerator";
+
+  kernel.Expression receiverAccess() => new VariableGet(receiver);
+
+  kernel.Expression _makeRead(ShadowComplexAssignment complexAssignment) {
+    var read = new ShadowPropertyGet(receiverAccess(), name, getter)
+      ..fileOffset = offsetForToken(token);
+    complexAssignment?.read = read;
+    return read;
+  }
+
+  kernel.Expression _makeWrite(kernel.Expression value, bool voidContext,
+      ShadowComplexAssignment complexAssignment) {
+    var write = new PropertySet(receiverAccess(), name, value, setter)
+      ..fileOffset = offsetForToken(token);
+    complexAssignment?.write = write;
+    return write;
+  }
+
+  kernel.Expression _finish(
+      kernel.Expression body, ShadowComplexAssignment complexAssignment) {
+    var offset = offsetForToken(token);
+    var nullAwareGuard = helper.storeOffset(
+        forest.conditionalExpression(
+            buildIsNull(receiverAccess(), offset, helper),
+            null,
+            helper.storeOffset(forest.literalNull(null), offset),
+            null,
+            body),
+        offset);
+    if (complexAssignment != null) {
+      body = makeLet(receiver, nullAwareGuard);
+      ShadowPropertyAssign kernelPropertyAssign = complexAssignment;
+      kernelPropertyAssign.nullAwareGuard = nullAwareGuard;
+      kernelPropertyAssign.desugared = body;
+      return kernelPropertyAssign;
+    } else {
+      return new ShadowNullAwarePropertyGet(receiver, nullAwareGuard)
+        ..fileOffset = offset;
+    }
+  }
+
+  kernel.Expression doInvocation(int offset, Arguments arguments) {
+    return unimplemented("doInvocation", offset, uri);
+  }
+
+  @override
+  ShadowComplexAssignment startComplexAssignment(kernel.Expression rhs) =>
+      new ShadowPropertyAssign(receiverExpression, rhs);
+
+  @override
+  void printOn(StringSink sink) {
+    NameSystem syntheticNames = new NameSystem();
+    sink.write(", receiver: ");
+    printNodeOn(receiver, sink, syntheticNames: syntheticNames);
+    sink.write(", receiverExpression: ");
+    printNodeOn(receiverExpression, sink, syntheticNames: syntheticNames);
+    sink.write(", name: ");
+    sink.write(name.name);
+    sink.write(", getter: ");
+    printQualifiedNameOn(getter, sink, syntheticNames: syntheticNames);
+    sink.write(", setter: ");
+    printQualifiedNameOn(setter, sink, syntheticNames: syntheticNames);
+    sink.write(", type: ");
+    printNodeOn(type, sink, syntheticNames: syntheticNames);
+  }
+}
+
+class SuperPropertyAccessGenerator<Arguments> extends Generator<Arguments> {
+  final Name name;
+
+  final Member getter;
+
+  final Member setter;
+
+  SuperPropertyAccessGenerator(
+      BuilderHelper<dynamic, dynamic, Arguments> helper,
+      Token token,
+      this.name,
+      this.getter,
+      this.setter)
+      : super(helper, token);
+
+  String get plainNameForRead => name.name;
+
+  String get debugName => "SuperPropertyAccessGenerator";
+
+  kernel.Expression _makeRead(ShadowComplexAssignment complexAssignment) {
+    if (getter == null) {
+      helper.warnUnresolvedGet(name, offsetForToken(token), isSuper: true);
+    }
+    // TODO(ahe): Use [DirectPropertyGet] when possible.
+    var read = new ShadowSuperPropertyGet(name, getter)
+      ..fileOffset = offsetForToken(token);
+    complexAssignment?.read = read;
+    return read;
+  }
+
+  kernel.Expression _makeWrite(kernel.Expression value, bool voidContext,
+      ShadowComplexAssignment complexAssignment) {
+    if (setter == null) {
+      helper.warnUnresolvedSet(name, offsetForToken(token), isSuper: true);
+    }
+    // TODO(ahe): Use [DirectPropertySet] when possible.
+    var write = new SuperPropertySet(name, value, setter)
+      ..fileOffset = offsetForToken(token);
+    complexAssignment?.write = write;
+    return write;
+  }
+
+  kernel.Expression doInvocation(int offset, Arguments arguments) {
+    if (helper.constantContext != ConstantContext.none) {
+      helper.deprecated_addCompileTimeError(
+          offset, "Not a constant expression.");
+    }
+    if (getter == null || isFieldOrGetter(getter)) {
+      return helper.buildMethodInvocation(
+          buildSimpleRead(), callName, arguments, offset,
+          // This isn't a constant expression, but we have checked if a
+          // constant expression error should be emitted already.
+          isConstantExpression: true,
+          isImplicitCall: true);
+    } else {
+      // TODO(ahe): This could be something like "super.property(...)" where
+      // property is a setter.
+      return unhandled("${getter.runtimeType}", "doInvocation", offset, uri);
+    }
+  }
+
+  @override
+  ShadowComplexAssignment startComplexAssignment(kernel.Expression rhs) =>
+      new ShadowPropertyAssign(null, rhs, isSuper: true);
+
+  @override
+  void printOn(StringSink sink) {
+    NameSystem syntheticNames = new NameSystem();
+    sink.write(", name: ");
+    sink.write(name.name);
+    sink.write(", getter: ");
+    printQualifiedNameOn(getter, sink, syntheticNames: syntheticNames);
+    sink.write(", setter: ");
+    printQualifiedNameOn(setter, sink, syntheticNames: syntheticNames);
+  }
+}
+
+class IndexedAccessGenerator<Arguments> extends Generator<Arguments> {
+  final kernel.Expression receiver;
+
+  final kernel.Expression index;
+
+  final Procedure getter;
+
+  final Procedure setter;
+
+  VariableDeclaration receiverVariable;
+
+  VariableDeclaration indexVariable;
+
+  IndexedAccessGenerator.internal(
+      BuilderHelper<dynamic, dynamic, Arguments> helper,
+      Token token,
+      this.receiver,
+      this.index,
+      this.getter,
+      this.setter)
+      : super(helper, token);
+
+  static FastaAccessor<Arguments> make<Arguments>(
+      BuilderHelper<dynamic, dynamic, Arguments> helper,
+      Token token,
+      kernel.Expression receiver,
+      kernel.Expression index,
+      Procedure getter,
+      Procedure setter) {
+    if (helper.forest.isThisExpression(receiver)) {
+      return new ThisIndexedAccessGenerator(
+          helper, token, index, getter, setter);
+    } else {
+      return new IndexedAccessGenerator.internal(
+          helper, token, receiver, index, getter, setter);
+    }
+  }
+
+  String get plainNameForRead => "[]";
+
+  String get plainNameForWrite => "[]=";
+
+  String get debugName => "IndexedAccessGenerator";
+
+  kernel.Expression _makeSimpleRead() {
+    var read = new ShadowMethodInvocation(
+        receiver,
+        indexGetName,
+        forest
+            .castArguments(forest.arguments(<kernel.Expression>[index], token)),
+        interfaceTarget: getter)
+      ..fileOffset = offsetForToken(token);
+    return read;
+  }
+
+  kernel.Expression _makeSimpleWrite(kernel.Expression value, bool voidContext,
+      ShadowComplexAssignment complexAssignment) {
+    if (!voidContext) return _makeWriteAndReturn(value, complexAssignment);
+    var write = new ShadowMethodInvocation(
+        receiver,
+        indexSetName,
+        forest.castArguments(
+            forest.arguments(<kernel.Expression>[index, value], token)),
+        interfaceTarget: setter)
+      ..fileOffset = offsetForToken(token);
+    complexAssignment?.write = write;
+    return write;
+  }
+
+  receiverAccess() {
+    // We cannot reuse the receiver if it is a variable since it might be
+    // reassigned in the index expression.
+    receiverVariable ??= new VariableDeclaration.forValue(receiver);
+    return new VariableGet(receiverVariable)
+      ..fileOffset = offsetForToken(token);
+  }
+
+  indexAccess() {
+    indexVariable ??= new VariableDeclaration.forValue(index);
+    return new VariableGet(indexVariable)..fileOffset = offsetForToken(token);
+  }
+
+  kernel.Expression _makeRead(ShadowComplexAssignment complexAssignment) {
+    var read = new ShadowMethodInvocation(
+        receiverAccess(),
+        indexGetName,
+        forest.castArguments(
+            forest.arguments(<kernel.Expression>[indexAccess()], token)),
+        interfaceTarget: getter)
+      ..fileOffset = offsetForToken(token);
+    complexAssignment?.read = read;
+    return read;
+  }
+
+  kernel.Expression _makeWrite(kernel.Expression value, bool voidContext,
+      ShadowComplexAssignment complexAssignment) {
+    if (!voidContext) return _makeWriteAndReturn(value, complexAssignment);
+    var write = new ShadowMethodInvocation(
+        receiverAccess(),
+        indexSetName,
+        forest.castArguments(
+            forest.arguments(<kernel.Expression>[indexAccess(), value], token)),
+        interfaceTarget: setter)
+      ..fileOffset = offsetForToken(token);
+    complexAssignment?.write = write;
+    return write;
+  }
+
+  // TODO(dmitryas): remove this method after the "[]=" operator of the Context
+  // class is made to return a value.
+  _makeWriteAndReturn(
+      kernel.Expression value, ShadowComplexAssignment complexAssignment) {
+    // The call to []= does not return the value like direct-style assignments
+    // do.  We need to bind the value in a let.
+    var valueVariable = new VariableDeclaration.forValue(value);
+    var write = new ShadowMethodInvocation(
+        receiverAccess(),
+        indexSetName,
+        forest.castArguments(forest.arguments(
+            <kernel.Expression>[indexAccess(), new VariableGet(valueVariable)],
+            token)),
+        interfaceTarget: setter)
+      ..fileOffset = offsetForToken(token);
+    complexAssignment?.write = write;
+    var dummy = new ShadowVariableDeclaration.forValue(
+        write, helper.functionNestingLevel);
+    return makeLet(
+        valueVariable, makeLet(dummy, new VariableGet(valueVariable)));
+  }
+
+  kernel.Expression _finish(
+      kernel.Expression body, ShadowComplexAssignment complexAssignment) {
+    return super._finish(
+        makeLet(receiverVariable, makeLet(indexVariable, body)),
+        complexAssignment);
+  }
+
+  kernel.Expression doInvocation(int offset, Arguments arguments) {
+    return helper.buildMethodInvocation(
+        buildSimpleRead(), callName, arguments, forest.readOffset(arguments),
+        isImplicitCall: true);
+  }
+
+  @override
+  ShadowComplexAssignment startComplexAssignment(kernel.Expression rhs) =>
+      new ShadowIndexAssign(receiver, index, rhs);
+
+  @override
+  void printOn(StringSink sink) {
+    NameSystem syntheticNames = new NameSystem();
+    sink.write(", receiver: ");
+    printNodeOn(receiver, sink, syntheticNames: syntheticNames);
+    sink.write(", index: ");
+    printNodeOn(index, sink, syntheticNames: syntheticNames);
+    sink.write(", getter: ");
+    printQualifiedNameOn(getter, sink, syntheticNames: syntheticNames);
+    sink.write(", setter: ");
+    printQualifiedNameOn(setter, sink, syntheticNames: syntheticNames);
+    sink.write(", receiverVariable: ");
+    printNodeOn(receiverVariable, sink, syntheticNames: syntheticNames);
+    sink.write(", indexVariable: ");
+    printNodeOn(indexVariable, sink, syntheticNames: syntheticNames);
+  }
+}
+
+/// Special case of [IndexedAccessGenerator] to avoid creating an indirect
+/// access to 'this'.
+class ThisIndexedAccessGenerator<Arguments> extends Generator<Arguments> {
+  final kernel.Expression index;
+
+  final Procedure getter;
+
+  final Procedure setter;
+
+  VariableDeclaration indexVariable;
+
+  ThisIndexedAccessGenerator(BuilderHelper<dynamic, dynamic, Arguments> helper,
+      Token token, this.index, this.getter, this.setter)
+      : super(helper, token);
+
+  String get plainNameForRead => "[]";
+
+  String get plainNameForWrite => "[]=";
+
+  String get debugName => "ThisIndexedAccessGenerator";
+
+  kernel.Expression _makeSimpleRead() {
+    return new ShadowMethodInvocation(
+        forest.thisExpression(token),
+        indexGetName,
+        forest
+            .castArguments(forest.arguments(<kernel.Expression>[index], token)),
+        interfaceTarget: getter)
+      ..fileOffset = offsetForToken(token);
+  }
+
+  kernel.Expression _makeSimpleWrite(kernel.Expression value, bool voidContext,
+      ShadowComplexAssignment complexAssignment) {
+    if (!voidContext) return _makeWriteAndReturn(value, complexAssignment);
+    var write = new ShadowMethodInvocation(
+        forest.thisExpression(token),
+        indexSetName,
+        forest.castArguments(
+            forest.arguments(<kernel.Expression>[index, value], token)),
+        interfaceTarget: setter)
+      ..fileOffset = offsetForToken(token);
+    complexAssignment?.write = write;
+    return write;
+  }
+
+  indexAccess() {
+    indexVariable ??= new VariableDeclaration.forValue(index);
+    return new VariableGet(indexVariable);
+  }
+
+  kernel.Expression _makeRead(ShadowComplexAssignment complexAssignment) {
+    var read = new ShadowMethodInvocation(
+        forest.thisExpression(token),
+        indexGetName,
+        forest.castArguments(
+            forest.arguments(<kernel.Expression>[indexAccess()], token)),
+        interfaceTarget: getter)
+      ..fileOffset = offsetForToken(token);
+    complexAssignment?.read = read;
+    return read;
+  }
+
+  kernel.Expression _makeWrite(kernel.Expression value, bool voidContext,
+      ShadowComplexAssignment complexAssignment) {
+    if (!voidContext) return _makeWriteAndReturn(value, complexAssignment);
+    var write = new ShadowMethodInvocation(
+        forest.thisExpression(token),
+        indexSetName,
+        forest.castArguments(
+            forest.arguments(<kernel.Expression>[indexAccess(), value], token)),
+        interfaceTarget: setter)
+      ..fileOffset = offsetForToken(token);
+    complexAssignment?.write = write;
+    return write;
+  }
+
+  _makeWriteAndReturn(
+      kernel.Expression value, ShadowComplexAssignment complexAssignment) {
+    var valueVariable = new VariableDeclaration.forValue(value);
+    var write = new ShadowMethodInvocation(
+        forest.thisExpression(token),
+        indexSetName,
+        forest.castArguments(forest.arguments(
+            <kernel.Expression>[indexAccess(), new VariableGet(valueVariable)],
+            token)),
+        interfaceTarget: setter)
+      ..fileOffset = offsetForToken(token);
+    complexAssignment?.write = write;
+    var dummy = new VariableDeclaration.forValue(write);
+    return makeLet(
+        valueVariable, makeLet(dummy, new VariableGet(valueVariable)));
+  }
+
+  kernel.Expression _finish(
+      kernel.Expression body, ShadowComplexAssignment complexAssignment) {
+    return super._finish(makeLet(indexVariable, body), complexAssignment);
+  }
+
+  kernel.Expression doInvocation(int offset, Arguments arguments) {
+    return helper.buildMethodInvocation(
+        buildSimpleRead(), callName, arguments, offset,
+        isImplicitCall: true);
+  }
+
+  @override
+  ShadowComplexAssignment startComplexAssignment(kernel.Expression rhs) =>
+      new ShadowIndexAssign(null, index, rhs);
+
+  @override
+  void printOn(StringSink sink) {
+    NameSystem syntheticNames = new NameSystem();
+    sink.write(", index: ");
+    printNodeOn(index, sink, syntheticNames: syntheticNames);
+    sink.write(", getter: ");
+    printQualifiedNameOn(getter, sink, syntheticNames: syntheticNames);
+    sink.write(", setter: ");
+    printQualifiedNameOn(setter, sink, syntheticNames: syntheticNames);
+    sink.write(", indexVariable: ");
+    printNodeOn(indexVariable, sink, syntheticNames: syntheticNames);
+  }
+}
+
+class SuperIndexedAccessGenerator<Arguments> extends Generator<Arguments> {
+  final kernel.Expression index;
+
+  final Member getter;
+
+  final Member setter;
+
+  VariableDeclaration indexVariable;
+
+  SuperIndexedAccessGenerator(BuilderHelper<dynamic, dynamic, Arguments> helper,
+      Token token, this.index, this.getter, this.setter)
+      : super(helper, token);
+
+  String get plainNameForRead => "[]";
+
+  String get plainNameForWrite => "[]=";
+
+  String get debugName => "SuperIndexedAccessGenerator";
+
+  indexAccess() {
+    indexVariable ??= new VariableDeclaration.forValue(index);
+    return new VariableGet(indexVariable);
+  }
+
+  kernel.Expression _makeSimpleRead() {
+    if (getter == null) {
+      helper.warnUnresolvedMethod(indexGetName, offsetForToken(token),
+          isSuper: true);
+    }
+    // TODO(ahe): Use [DirectMethodInvocation] when possible.
+    return new ShadowSuperMethodInvocation(
+        indexGetName,
+        forest
+            .castArguments(forest.arguments(<kernel.Expression>[index], token)),
+        getter)
+      ..fileOffset = offsetForToken(token);
+  }
+
+  kernel.Expression _makeSimpleWrite(kernel.Expression value, bool voidContext,
+      ShadowComplexAssignment complexAssignment) {
+    if (!voidContext) return _makeWriteAndReturn(value, complexAssignment);
+    if (setter == null) {
+      helper.warnUnresolvedMethod(indexSetName, offsetForToken(token),
+          isSuper: true);
+    }
+    var write = new SuperMethodInvocation(
+        indexSetName,
+        forest.castArguments(
+            forest.arguments(<kernel.Expression>[index, value], token)),
+        setter)
+      ..fileOffset = offsetForToken(token);
+    complexAssignment?.write = write;
+    return write;
+  }
+
+  kernel.Expression _makeRead(ShadowComplexAssignment complexAssignment) {
+    if (getter == null) {
+      helper.warnUnresolvedMethod(indexGetName, offsetForToken(token),
+          isSuper: true);
+    }
+    var read = new SuperMethodInvocation(
+        indexGetName,
+        forest.castArguments(
+            forest.arguments(<kernel.Expression>[indexAccess()], token)),
+        getter)
+      ..fileOffset = offsetForToken(token);
+    complexAssignment?.read = read;
+    return read;
+  }
+
+  kernel.Expression _makeWrite(kernel.Expression value, bool voidContext,
+      ShadowComplexAssignment complexAssignment) {
+    if (!voidContext) return _makeWriteAndReturn(value, complexAssignment);
+    if (setter == null) {
+      helper.warnUnresolvedMethod(indexSetName, offsetForToken(token),
+          isSuper: true);
+    }
+    var write = new SuperMethodInvocation(
+        indexSetName,
+        forest.castArguments(
+            forest.arguments(<kernel.Expression>[indexAccess(), value], token)),
+        setter)
+      ..fileOffset = offsetForToken(token);
+    complexAssignment?.write = write;
+    return write;
+  }
+
+  _makeWriteAndReturn(
+      kernel.Expression value, ShadowComplexAssignment complexAssignment) {
+    var valueVariable = new VariableDeclaration.forValue(value);
+    if (setter == null) {
+      helper.warnUnresolvedMethod(indexSetName, offsetForToken(token),
+          isSuper: true);
+    }
+    var write = new SuperMethodInvocation(
+        indexSetName,
+        forest.castArguments(forest.arguments(
+            <kernel.Expression>[indexAccess(), new VariableGet(valueVariable)],
+            token)),
+        setter)
+      ..fileOffset = offsetForToken(token);
+    complexAssignment?.write = write;
+    var dummy = new VariableDeclaration.forValue(write);
+    return makeLet(
+        valueVariable, makeLet(dummy, new VariableGet(valueVariable)));
+  }
+
+  kernel.Expression _finish(
+      kernel.Expression body, ShadowComplexAssignment complexAssignment) {
+    return super._finish(makeLet(indexVariable, body), complexAssignment);
+  }
+
+  kernel.Expression doInvocation(int offset, Arguments arguments) {
+    return helper.buildMethodInvocation(
+        buildSimpleRead(), callName, arguments, offset,
+        isImplicitCall: true);
+  }
+
+  @override
+  ShadowComplexAssignment startComplexAssignment(kernel.Expression rhs) =>
+      new ShadowIndexAssign(null, index, rhs, isSuper: true);
+
+  @override
+  void printOn(StringSink sink) {
+    NameSystem syntheticNames = new NameSystem();
+    sink.write(", index: ");
+    printNodeOn(index, sink, syntheticNames: syntheticNames);
+    sink.write(", getter: ");
+    printQualifiedNameOn(getter, sink, syntheticNames: syntheticNames);
+    sink.write(", setter: ");
+    printQualifiedNameOn(setter, sink, syntheticNames: syntheticNames);
+    sink.write(", indexVariable: ");
+    printNodeOn(indexVariable, sink, syntheticNames: syntheticNames);
+  }
+}
+
+class StaticAccessGenerator<Arguments> extends Generator<Arguments> {
+  final Member readTarget;
+
+  final Member writeTarget;
+
+  StaticAccessGenerator(BuilderHelper<dynamic, dynamic, Arguments> helper,
+      Token token, this.readTarget, this.writeTarget)
+      : assert(readTarget != null || writeTarget != null),
+        super(helper, token);
+
+  factory StaticAccessGenerator.fromBuilder(
+      BuilderHelper<dynamic, dynamic, Arguments> helper,
+      Builder builder,
+      Token token,
+      Builder builderSetter) {
+    if (builder is AccessErrorBuilder) {
+      AccessErrorBuilder error = builder;
+      builder = error.builder;
+      // We should only see an access error here if we've looked up a setter
+      // when not explicitly looking for a setter.
+      assert(builder.isSetter);
+    } else if (builder.target == null) {
+      return unhandled(
+          "${builder.runtimeType}",
+          "StaticAccessGenerator.fromBuilder",
+          offsetForToken(token),
+          helper.uri);
+    }
+    Member getter = builder.target.hasGetter ? builder.target : null;
+    Member setter = builder.target.hasSetter ? builder.target : null;
+    if (setter == null) {
+      if (builderSetter?.target?.hasSetter ?? false) {
+        setter = builderSetter.target;
+      }
+    }
+    return new StaticAccessGenerator(helper, token, getter, setter);
+  }
+
+  String get plainNameForRead => (readTarget ?? writeTarget).name.name;
+
+  String get debugName => "StaticAccessGenerator";
+
+  kernel.Expression _makeRead(ShadowComplexAssignment complexAssignment) {
+    if (readTarget == null) {
+      return makeInvalidRead();
+    } else {
+      var read = helper.makeStaticGet(readTarget, token);
+      complexAssignment?.read = read;
+      return read;
+    }
+  }
+
+  kernel.Expression _makeWrite(kernel.Expression value, bool voidContext,
+      ShadowComplexAssignment complexAssignment) {
+    kernel.Expression write;
+    if (writeTarget == null) {
+      write = makeInvalidWrite(value);
+    } else {
+      write = new StaticSet(writeTarget, value);
+      complexAssignment?.write = write;
+    }
+    write.fileOffset = offsetForToken(token);
+    return write;
+  }
+
+  kernel.Expression doInvocation(int offset, Arguments arguments) {
+    if (helper.constantContext != ConstantContext.none &&
+        !helper.isIdentical(readTarget)) {
+      helper.deprecated_addCompileTimeError(
+          offset, "Not a constant expression.");
+    }
+    if (readTarget == null || isFieldOrGetter(readTarget)) {
+      return helper.buildMethodInvocation(buildSimpleRead(), callName,
+          arguments, offset + (readTarget?.name?.name?.length ?? 0),
+          // This isn't a constant expression, but we have checked if a
+          // constant expression error should be emitted already.
+          isConstantExpression: true,
+          isImplicitCall: true);
+    } else {
+      return helper.buildStaticInvocation(readTarget, arguments,
+          charOffset: offset);
+    }
+  }
+
+  @override
+  ShadowComplexAssignment startComplexAssignment(kernel.Expression rhs) =>
+      new ShadowStaticAssignment(rhs);
+
+  @override
+  void printOn(StringSink sink) {
+    NameSystem syntheticNames = new NameSystem();
+    sink.write(", readTarget: ");
+    printQualifiedNameOn(readTarget, sink, syntheticNames: syntheticNames);
+    sink.write(", writeTarget: ");
+    printQualifiedNameOn(writeTarget, sink, syntheticNames: syntheticNames);
+  }
+}
+
+class LoadLibraryGenerator<Arguments> extends Generator<Arguments> {
+  final LoadLibraryBuilder builder;
+
+  LoadLibraryGenerator(BuilderHelper<dynamic, dynamic, Arguments> helper,
+      Token token, this.builder)
+      : super(helper, token);
+
+  String get plainNameForRead => 'loadLibrary';
+
+  String get debugName => "LoadLibraryGenerator";
+
+  kernel.Expression _makeRead(ShadowComplexAssignment complexAssignment) {
+    var read =
+        helper.makeStaticGet(builder.createTearoffMethod(helper.forest), token);
+    complexAssignment?.read = read;
+    return read;
+  }
+
+  kernel.Expression _makeWrite(kernel.Expression value, bool voidContext,
+      ShadowComplexAssignment complexAssignment) {
+    kernel.Expression write = makeInvalidWrite(value);
+    write.fileOffset = offsetForToken(token);
+    return write;
+  }
+
+  kernel.Expression doInvocation(int offset, Arguments arguments) {
+    if (forest.argumentsPositional(arguments).length > 0 ||
+        forest.argumentsNamed(arguments).length > 0) {
+      helper.addProblemErrorIfConst(
+          messageLoadLibraryTakesNoArguments, offset, 'loadLibrary'.length);
+    }
+    return builder.createLoadLibrary(offset, forest);
+  }
+
+  @override
+  void printOn(StringSink sink) {
+    sink.write(", builder: ");
+    sink.write(builder);
+  }
+}
+
+class DeferredAccessGenerator<Arguments> extends Generator<Arguments> {
+  final PrefixBuilder builder;
+
+  final FastaAccessor accessor;
+
+  DeferredAccessGenerator(BuilderHelper<dynamic, dynamic, Arguments> helper,
+      Token token, this.builder, this.accessor)
+      : super(helper, token);
+
+  String get plainNameForRead {
+    return unsupported(
+        "deferredAccessor.plainNameForRead", offsetForToken(token), uri);
+  }
+
+  String get debugName => "DeferredAccessGenerator";
+
+  kernel.Expression _makeSimpleRead() {
+    return helper.wrapInDeferredCheck(
+        accessor._makeSimpleRead(), builder, token.charOffset);
+  }
+
+  kernel.Expression _makeRead(ShadowComplexAssignment complexAssignment) {
+    return helper.wrapInDeferredCheck(
+        accessor._makeRead(complexAssignment), builder, token.charOffset);
+  }
+
+  kernel.Expression _makeWrite(kernel.Expression value, bool voidContext,
+      ShadowComplexAssignment complexAssignment) {
+    return helper.wrapInDeferredCheck(
+        accessor._makeWrite(value, voidContext, complexAssignment),
+        builder,
+        token.charOffset);
+  }
+
+  buildPropertyAccess(
+      IncompleteSend send, int operatorOffset, bool isNullAware) {
+    var propertyAccess =
+        accessor.buildPropertyAccess(send, operatorOffset, isNullAware);
+    if (propertyAccess is FastaAccessor) {
+      return new DeferredAccessGenerator(
+          helper, token, builder, propertyAccess);
+    } else {
+      kernel.Expression expression = propertyAccess;
+      return helper.wrapInDeferredCheck(expression, builder, token.charOffset);
+    }
+  }
+
+  @override
+  DartType buildTypeWithBuiltArguments(List<DartType> arguments,
+      {bool nonInstanceAccessIsError: false}) {
+    helper.addProblem(
+        templateDeferredTypeAnnotation.withArguments(
+            accessor.buildTypeWithBuiltArguments(arguments,
+                nonInstanceAccessIsError: nonInstanceAccessIsError),
+            builder.name),
+        offsetForToken(token),
+        lengthForToken(token));
+    return const InvalidType();
+  }
+
+  kernel.Expression doInvocation(int offset, Arguments arguments) {
+    return helper.wrapInDeferredCheck(
+        accessor.doInvocation(offset, arguments), builder, token.charOffset);
+  }
+
+  @override
+  void printOn(StringSink sink) {
+    sink.write(", builder: ");
+    sink.write(builder);
+    sink.write(", accessor: ");
+    sink.write(accessor);
+  }
+}
+
+class ReadOnlyAccessGenerator<Arguments> extends Generator<Arguments> {
+  final String plainNameForRead;
+
+  kernel.Expression expression;
+
+  VariableDeclaration value;
+
+  ReadOnlyAccessGenerator(BuilderHelper<dynamic, dynamic, Arguments> helper,
+      Token token, this.expression, this.plainNameForRead)
+      : super(helper, token);
+
+  String get debugName => "ReadOnlyAccessGenerator";
+
+  kernel.Expression _makeSimpleRead() => expression;
+
+  kernel.Expression _makeRead(ShadowComplexAssignment complexAssignment) {
+    value ??= new VariableDeclaration.forValue(expression);
+    return new VariableGet(value);
+  }
+
+  kernel.Expression _makeWrite(kernel.Expression value, bool voidContext,
+      ShadowComplexAssignment complexAssignment) {
+    var write = makeInvalidWrite(value);
+    complexAssignment?.write = write;
+    return write;
+  }
+
+  kernel.Expression _finish(
+          kernel.Expression body, ShadowComplexAssignment complexAssignment) =>
+      super._finish(makeLet(value, body), complexAssignment);
+
+  kernel.Expression doInvocation(int offset, Arguments arguments) {
+    return helper.buildMethodInvocation(buildSimpleRead(), callName, arguments,
+        adjustForImplicitCall(plainNameForRead, offset),
+        isImplicitCall: true);
+  }
+
+  @override
+  void printOn(StringSink sink) {
+    NameSystem syntheticNames = new NameSystem();
+    sink.write(", expression: ");
+    printNodeOn(expression, sink, syntheticNames: syntheticNames);
+    sink.write(", plainNameForRead: ");
+    sink.write(plainNameForRead);
+    sink.write(", value: ");
+    printNodeOn(value, sink, syntheticNames: syntheticNames);
+  }
+}
+
+class LargeIntAccessGenerator<Arguments> extends Generator<Arguments> {
+  LargeIntAccessGenerator(
+      BuilderHelper<dynamic, dynamic, Arguments> helper, Token token)
+      : super(helper, token);
+
+  // TODO(ahe): This should probably be calling unhandled.
+  String get plainNameForRead => null;
+
+  String get debugName => "LargeIntAccessGenerator";
+
+  @override
+  kernel.Expression _makeSimpleRead() => buildError();
+
+  @override
+  kernel.Expression _makeSimpleWrite(kernel.Expression value, bool voidContext,
+      ShadowComplexAssignment complexAssignment) {
+    return buildError();
+  }
+
+  @override
+  kernel.Expression _makeRead(ShadowComplexAssignment complexAssignment) {
+    return buildError();
+  }
+
+  @override
+  kernel.Expression _makeWrite(kernel.Expression value, bool voidContext,
+      ShadowComplexAssignment complexAssignment) {
+    return buildError();
+  }
+
+  kernel.Expression buildError() {
+    return helper.buildCompileTimeError(
+        templateIntegerLiteralIsOutOfRange.withArguments(token),
+        offsetForToken(token),
+        lengthForToken(token));
+  }
+
+  @override
+  kernel.Expression doInvocation(int offset, Arguments arguments) {
+    return buildError();
+  }
+
+  @override
+  void printOn(StringSink sink) {
+    sink.write(", lexeme: ");
+    sink.write(token.lexeme);
+  }
+}
+
+abstract class ErroneousExpressionGenerator<Arguments>
+    implements Generator<Arguments> {
+  /// Pass [arguments] that must be evaluated before throwing an error.  At
+  /// most one of [isGetter] and [isSetter] should be true and they're passed
+  /// to [BuilderHelper.buildThrowNoSuchMethodError] if it is used.
+  kernel.Expression buildError(Arguments arguments,
+      {bool isGetter: false, bool isSetter: false, int offset});
+
+  DartType buildErroneousTypeNotAPrefix(Identifier suffix);
+
+  Name get name => unsupported("name", offsetForToken(token), uri);
+
+  @override
+  String get plainNameForRead => name.name;
+
+  withReceiver(Object receiver, int operatorOffset, {bool isNullAware}) => this;
+
+  @override
+  Initializer buildFieldInitializer(Map<String, int> initializedFields) {
+    return helper.buildInvalidInitializer(
+        buildError(forest.argumentsEmpty(noLocation), isSetter: true));
+  }
+
+  @override
+  doInvocation(int offset, Arguments arguments) {
+    return buildError(arguments, offset: offset);
+  }
+
+  @override
+  buildPropertyAccess(
+      IncompleteSend send, int operatorOffset, bool isNullAware) {
+    return this;
+  }
+
+  @override
+  buildThrowNoSuchMethodError(kernel.Expression receiver, Arguments arguments,
+      {bool isSuper: false,
+      bool isGetter: false,
+      bool isSetter: false,
+      bool isStatic: false,
+      String name,
+      int offset,
+      LocatedMessage argMessage}) {
+    return this;
+  }
+
+  @override
+  kernel.Expression buildAssignment(kernel.Expression value,
+      {bool voidContext: false}) {
+    return buildError(forest.arguments(<kernel.Expression>[value], noLocation),
+        isSetter: true);
+  }
+
+  @override
+  kernel.Expression buildCompoundAssignment(
+      Name binaryOperator, kernel.Expression value,
+      {int offset: TreeNode.noOffset,
+      bool voidContext: false,
+      Procedure interfaceTarget,
+      bool isPreIncDec: false}) {
+    return buildError(forest.arguments(<kernel.Expression>[value], token),
+        isGetter: true);
+  }
+
+  @override
+  kernel.Expression buildPrefixIncrement(Name binaryOperator,
+      {int offset: TreeNode.noOffset,
+      bool voidContext: false,
+      Procedure interfaceTarget}) {
+    // TODO(ahe): For the Analyzer, we probably need to build a prefix
+    // increment node that wraps an error.
+    return buildError(
+        forest.arguments(<kernel.Expression>[
+          storeOffset(forest.literalInt(1, null), offset)
+        ], noLocation),
+        isGetter: true);
+  }
+
+  @override
+  kernel.Expression buildPostfixIncrement(Name binaryOperator,
+      {int offset: TreeNode.noOffset,
+      bool voidContext: false,
+      Procedure interfaceTarget}) {
+    // TODO(ahe): For the Analyzer, we probably need to build a post increment
+    // node that wraps an error.
+    return buildError(
+        forest.arguments(<kernel.Expression>[
+          storeOffset(forest.literalInt(1, null), offset)
+        ], noLocation),
+        isGetter: true);
+  }
+
+  @override
+  kernel.Expression buildNullAwareAssignment(
+      kernel.Expression value, DartType type, int offset,
+      {bool voidContext: false}) {
+    return buildError(forest.arguments(<kernel.Expression>[value], noLocation),
+        isSetter: true);
+  }
+
+  @override
+  kernel.Expression buildSimpleRead() =>
+      buildError(forest.argumentsEmpty(noLocation), isGetter: true);
+
+  @override
+  kernel.Expression makeInvalidRead() =>
+      buildError(forest.argumentsEmpty(noLocation), isGetter: true);
+
+  @override
+  kernel.Expression makeInvalidWrite(kernel.Expression value) {
+    return buildError(forest.arguments(<kernel.Expression>[value], noLocation),
+        isSetter: true);
+  }
+}
+
+class ThisAccessGenerator<Arguments> extends Generator<Arguments> {
+  final bool isInitializer;
+
+  final bool isSuper;
+
+  ThisAccessGenerator(BuilderHelper<dynamic, dynamic, Arguments> helper,
+      Token token, this.isInitializer,
+      {this.isSuper: false})
+      : super(helper, token);
+
+  String get plainNameForRead {
+    return unsupported("${isSuper ? 'super' : 'this'}.plainNameForRead",
+        offsetForToken(token), uri);
+  }
+
+  String get debugName => "ThisAccessGenerator";
+
+  kernel.Expression buildSimpleRead() {
+    if (!isSuper) {
+      return forest.thisExpression(token);
+    } else {
+      return helper.buildCompileTimeError(messageSuperAsExpression,
+          offsetForToken(token), lengthForToken(token));
+    }
+  }
+
+  @override
+  Initializer buildFieldInitializer(Map<String, int> initializedFields) {
+    String keyword = isSuper ? "super" : "this";
+    int offset = offsetForToken(token);
+    return helper.buildInvalidInitializer(
+        helper.deprecated_buildCompileTimeError(
+            "Can't use '$keyword' here, did you mean '$keyword()'?", offset),
+        offset);
+  }
+
+  buildPropertyAccess(
+      IncompleteSend send, int operatorOffset, bool isNullAware) {
+    Name name = send.name;
+    Arguments arguments = send.arguments;
+    int offset = offsetForToken(send.token);
+    if (isInitializer && send is SendAccessor) {
+      if (isNullAware) {
+        helper.deprecated_addCompileTimeError(
+            operatorOffset, "Expected '.'\nTry removing '?'.");
+      }
+      return buildConstructorInitializer(offset, name, arguments);
+    }
+    Member getter = helper.lookupInstanceMember(name, isSuper: isSuper);
+    if (send is SendAccessor) {
+      // Notice that 'this' or 'super' can't be null. So we can ignore the
+      // value of [isNullAware].
+      if (getter == null) {
+        helper.warnUnresolvedMethod(name, offsetForToken(send.token),
+            isSuper: isSuper);
+      }
+      return helper.buildMethodInvocation(forest.thisExpression(null), name,
+          send.arguments, offsetForToken(send.token),
+          isSuper: isSuper, interfaceTarget: getter);
+    } else {
+      Member setter =
+          helper.lookupInstanceMember(name, isSuper: isSuper, isSetter: true);
+      if (isSuper) {
+        return new SuperPropertyAccessGenerator(
+            helper, send.token, name, getter, setter);
+      } else {
+        return new ThisPropertyAccessGenerator(
+            helper, send.token, name, getter, setter);
+      }
+    }
+  }
+
+  doInvocation(int offset, Arguments arguments) {
+    if (isInitializer) {
+      return buildConstructorInitializer(offset, new Name(""), arguments);
+    } else if (isSuper) {
+      return helper.buildCompileTimeError(
+          messageSuperAsExpression, offset, noLength);
+    } else {
+      return helper.buildMethodInvocation(
+          forest.thisExpression(null), callName, arguments, offset,
+          isImplicitCall: true);
+    }
+  }
+
+  Initializer buildConstructorInitializer(
+      int offset, Name name, Arguments arguments) {
+    Constructor constructor = helper.lookupConstructor(name, isSuper: isSuper);
+    LocatedMessage argMessage;
+    if (constructor != null) {
+      argMessage = helper.checkArguments(
+          new FunctionTypeAccessor.fromNode(constructor.function),
+          arguments,
+          CalleeDesignation.Constructor,
+          offset, <TypeParameter>[]);
+    }
+    if (constructor == null || argMessage != null) {
+      return helper.buildInvalidInitializer(
+          buildThrowNoSuchMethodError(
+              storeOffset(forest.literalNull(null), offset), arguments,
+              isSuper: isSuper,
+              name: name.name,
+              offset: offset,
+              argMessage: argMessage),
+          offset);
+    } else if (isSuper) {
+      return helper.buildSuperInitializer(
+          false, constructor, arguments, offset);
+    } else {
+      return helper.buildRedirectingInitializer(constructor, arguments, offset);
+    }
+  }
+
+  kernel.Expression buildAssignment(kernel.Expression value,
+      {bool voidContext: false}) {
+    return buildAssignmentError();
+  }
+
+  kernel.Expression buildNullAwareAssignment(
+      kernel.Expression value, DartType type, int offset,
+      {bool voidContext: false}) {
+    return buildAssignmentError();
+  }
+
+  kernel.Expression buildCompoundAssignment(
+      Name binaryOperator, kernel.Expression value,
+      {int offset: TreeNode.noOffset,
+      bool voidContext: false,
+      Procedure interfaceTarget,
+      bool isPreIncDec: false}) {
+    return buildAssignmentError();
+  }
+
+  kernel.Expression buildPrefixIncrement(Name binaryOperator,
+      {int offset: TreeNode.noOffset,
+      bool voidContext: false,
+      Procedure interfaceTarget}) {
+    return buildAssignmentError();
+  }
+
+  kernel.Expression buildPostfixIncrement(Name binaryOperator,
+      {int offset: TreeNode.noOffset,
+      bool voidContext: false,
+      Procedure interfaceTarget}) {
+    return buildAssignmentError();
+  }
+
+  kernel.Expression buildAssignmentError() {
+    String message =
+        isSuper ? "Can't assign to 'super'." : "Can't assign to 'this'.";
+    return helper.deprecated_buildCompileTimeError(
+        message, offsetForToken(token));
+  }
+
+  @override
+  kernel.Expression _makeRead(ShadowComplexAssignment complexAssignment) {
+    return unimplemented("_makeRead", offsetForToken(token), uri);
+  }
+
+  @override
+  kernel.Expression _makeWrite(kernel.Expression value, bool voidContext,
+      ShadowComplexAssignment complexAssignment) {
+    return unimplemented("_makeWrite", offsetForToken(token), uri);
+  }
+
+  @override
+  void printOn(StringSink sink) {
+    sink.write(", isInitializer: ");
+    sink.write(isInitializer);
+    sink.write(", isSuper: ");
+    sink.write(isSuper);
+  }
+}
+
+kernel.Expression makeLet(
+    VariableDeclaration variable, kernel.Expression body) {
+  if (variable == null) return body;
+  return new Let(variable, body);
+}
+
+kernel.Expression makeBinary<Arguments>(
+    kernel.Expression left,
+    Name operator,
+    Procedure interfaceTarget,
+    kernel.Expression right,
+    BuilderHelper<dynamic, dynamic, Arguments> helper,
+    {int offset: TreeNode.noOffset}) {
+  return new ShadowMethodInvocation(
+      left,
+      operator,
+      helper.storeOffset(
+          helper.forest.castArguments(
+              helper.forest.arguments(<kernel.Expression>[right], null)),
+          offset),
+      interfaceTarget: interfaceTarget)
+    ..fileOffset = offset;
+}
+
+kernel.Expression buildIsNull<Arguments>(kernel.Expression value, int offset,
+    BuilderHelper<dynamic, dynamic, Arguments> helper) {
+  return makeBinary(value, equalsName, null,
+      helper.storeOffset(helper.forest.literalNull(null), offset), helper,
+      offset: offset);
+}
+
+VariableDeclaration makeOrReuseVariable(kernel.Expression value) {
+  // TODO: Devise a way to remember if a variable declaration was reused
+  // or is fresh (hence needs a let binding).
+  return new VariableDeclaration.forValue(value);
+}
diff --git a/pkg/front_end/lib/src/fasta/kernel/expression_generator_impl.dart b/pkg/front_end/lib/src/fasta/kernel/expression_generator_impl.dart
new file mode 100644
index 0000000..603841f
--- /dev/null
+++ b/pkg/front_end/lib/src/fasta/kernel/expression_generator_impl.dart
@@ -0,0 +1,730 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+part of 'expression_generator.dart';
+
+abstract class BuilderHelper<Expression, Statement, Arguments> {
+  LibraryBuilder get library;
+
+  Uri get uri;
+
+  TypePromoter get typePromoter;
+
+  int get functionNestingLevel;
+
+  ConstantContext get constantContext;
+
+  Forest<Expression, Statement, Token, Arguments> get forest;
+
+  Constructor lookupConstructor(Name name, {bool isSuper});
+
+  Expression toValue(node);
+
+  Member lookupInstanceMember(Name name, {bool isSetter, bool isSuper});
+
+  scopeLookup(Scope scope, String name, Token token,
+      {bool isQualified: false, PrefixBuilder prefix});
+
+  finishSend(Object receiver, Arguments arguments, int offset);
+
+  Expression buildCompileTimeError(Message message, int charOffset, int length,
+      {List<LocatedMessage> context});
+
+  Expression wrapInCompileTimeError(Expression expression, Message message);
+
+  Expression deprecated_buildCompileTimeError(String error, [int offset]);
+
+  Initializer buildInvalidInitializer(Expression expression, [int offset]);
+
+  Initializer buildFieldInitializer(
+      bool isSynthetic, String name, int offset, Expression expression);
+
+  Initializer buildSuperInitializer(
+      bool isSynthetic, Constructor constructor, Arguments arguments,
+      [int offset]);
+
+  Initializer buildRedirectingInitializer(
+      Constructor constructor, Arguments arguments,
+      [int charOffset = -1]);
+
+  Expression buildStaticInvocation(Procedure target, Arguments arguments,
+      {Constness constness, int charOffset, Member initialTarget});
+
+  Expression buildProblemExpression(
+      ProblemBuilder builder, int offset, int length);
+
+  Expression throwNoSuchMethodError(
+      Expression receiver, String name, Arguments arguments, int offset,
+      {Member candidate,
+      bool isSuper,
+      bool isGetter,
+      bool isSetter,
+      bool isStatic,
+      LocatedMessage argMessage});
+
+  LocatedMessage checkArguments(FunctionTypeAccessor function,
+      Arguments arguments, CalleeDesignation calleeKind, int offset,
+      [List<TypeParameter> typeParameters]);
+
+  StaticGet makeStaticGet(Member readTarget, Token token);
+
+  Expression wrapInDeferredCheck(
+      Expression expression, KernelPrefixBuilder prefix, int charOffset);
+
+  dynamic deprecated_addCompileTimeError(int charOffset, String message);
+
+  bool isIdentical(Member member);
+
+  Expression buildMethodInvocation(
+      Expression receiver, Name name, Arguments arguments, int offset,
+      {bool isConstantExpression,
+      bool isNullAware,
+      bool isImplicitCall,
+      bool isSuper,
+      Member interfaceTarget});
+
+  Expression buildConstructorInvocation(
+      TypeDeclarationBuilder type,
+      Token nameToken,
+      Arguments arguments,
+      String name,
+      List<DartType> typeArguments,
+      int charOffset,
+      Constness constness);
+
+  DartType validatedTypeVariableUse(
+      TypeParameterType type, int offset, bool nonInstanceAccessIsError);
+
+  void addProblem(Message message, int charOffset, int length);
+
+  void addProblemErrorIfConst(Message message, int charOffset, int length);
+
+  Message warnUnresolvedGet(Name name, int charOffset, {bool isSuper});
+
+  Message warnUnresolvedSet(Name name, int charOffset, {bool isSuper});
+
+  Message warnUnresolvedMethod(Name name, int charOffset, {bool isSuper});
+
+  void warnTypeArgumentsMismatch(String name, int expected, int charOffset);
+
+  T storeOffset<T>(T node, int offset);
+}
+
+// The name used to refer to a call target kind
+enum CalleeDesignation { Function, Method, Constructor }
+
+// Abstraction over FunctionNode and FunctionType to access the
+// number and names of parameters.
+class FunctionTypeAccessor {
+  int requiredParameterCount;
+  int positionalParameterCount;
+
+  List _namedParameters;
+
+  Set<String> get namedParameterNames {
+    return new Set.from(_namedParameters.map((a) => a.name));
+  }
+
+  factory FunctionTypeAccessor.fromNode(FunctionNode node) {
+    return new FunctionTypeAccessor._(node.requiredParameterCount,
+        node.positionalParameters.length, node.namedParameters);
+  }
+
+  factory FunctionTypeAccessor.fromType(FunctionType type) {
+    return new FunctionTypeAccessor._(type.requiredParameterCount,
+        type.positionalParameters.length, type.namedParameters);
+  }
+
+  FunctionTypeAccessor._(this.requiredParameterCount,
+      this.positionalParameterCount, this._namedParameters);
+}
+
+// TODO(ahe): Merge this into [Generator] when all uses have been updated.
+abstract class FastaAccessor<Arguments> implements Accessor<Arguments> {
+  BuilderHelper<dynamic, dynamic, Arguments> get helper;
+
+  // TODO(ahe): Change type arguments.
+  Forest<kernel.Expression, kernel.Statement, Token, Arguments> get forest =>
+      helper.forest;
+
+  String get plainNameForRead;
+
+  String get debugName;
+
+  Uri get uri => helper.uri;
+
+  String get plainNameForWrite => plainNameForRead;
+
+  bool get isInitializer => false;
+
+  T storeOffset<T>(T node, int offset) {
+    return helper.storeOffset(node, offset);
+  }
+
+  kernel.Expression buildForEffect() => buildSimpleRead();
+
+  Initializer buildFieldInitializer(Map<String, int> initializedFields) {
+    int offset = offsetForToken(token);
+    return helper.buildInvalidInitializer(
+        helper.buildCompileTimeError(
+            messageInvalidInitializer, offset, lengthForToken(token)),
+        offset);
+  }
+
+  kernel.Expression makeInvalidRead() {
+    return buildThrowNoSuchMethodError(
+        forest.literalNull(token), forest.argumentsEmpty(noLocation),
+        isGetter: true);
+  }
+
+  kernel.Expression makeInvalidWrite(kernel.Expression value) {
+    return buildThrowNoSuchMethodError(forest.literalNull(token),
+        forest.arguments(<kernel.Expression>[value], noLocation),
+        isSetter: true);
+  }
+
+  /* kernel.Expression | FastaAccessor | Initializer */ doInvocation(
+      int offset, Arguments arguments);
+
+  /* kernel.Expression | FastaAccessor */ buildPropertyAccess(
+      IncompleteSend send, int operatorOffset, bool isNullAware) {
+    if (send is SendAccessor) {
+      return helper.buildMethodInvocation(buildSimpleRead(), send.name,
+          send.arguments, offsetForToken(send.token),
+          isNullAware: isNullAware);
+    } else {
+      if (helper.constantContext != ConstantContext.none &&
+          send.name != lengthName) {
+        helper.deprecated_addCompileTimeError(
+            offsetForToken(token), "Not a constant expression.");
+      }
+      return PropertyAccessGenerator.make(helper, send.token, buildSimpleRead(),
+          send.name, null, null, isNullAware);
+    }
+  }
+
+  DartType buildTypeWithBuiltArguments(List<DartType> arguments,
+      {bool nonInstanceAccessIsError: false}) {
+    helper.addProblem(templateNotAType.withArguments(token.lexeme),
+        offsetForToken(token), lengthForToken(token));
+    return const InvalidType();
+  }
+
+  /* kernel.Expression | FastaAccessor */ buildThrowNoSuchMethodError(
+      kernel.Expression receiver, Arguments arguments,
+      {bool isSuper: false,
+      bool isGetter: false,
+      bool isSetter: false,
+      bool isStatic: false,
+      String name,
+      int offset,
+      LocatedMessage argMessage}) {
+    return helper.throwNoSuchMethodError(receiver, name ?? plainNameForWrite,
+        arguments, offset ?? offsetForToken(this.token),
+        isGetter: isGetter,
+        isSetter: isSetter,
+        isSuper: isSuper,
+        isStatic: isStatic,
+        argMessage: argMessage);
+  }
+
+  bool get isThisPropertyAccess => false;
+
+  @override
+  ShadowComplexAssignment startComplexAssignment(kernel.Expression rhs) =>
+      new ShadowIllegalAssignment(rhs);
+
+  void printOn(StringSink sink);
+
+  String toString() {
+    StringBuffer buffer = new StringBuffer();
+    buffer.write(debugName);
+    buffer.write("(offset: ");
+    buffer.write("${offsetForToken(token)}");
+    printOn(buffer);
+    buffer.write(")");
+    return "$buffer";
+  }
+}
+
+abstract class GeneratorImpl {
+  Token get token;
+
+  Uri get uri;
+
+  kernel.Expression _finish(
+      kernel.Expression body, ShadowComplexAssignment complexAssignment) {
+    return unimplemented("_finish", offsetForToken(token), uri);
+  }
+
+  kernel.Expression _makeSimpleRead() {
+    return unimplemented("_makeSimpleRead", offsetForToken(token), uri);
+  }
+
+  kernel.Expression _makeSimpleWrite(kernel.Expression value, bool voidContext,
+      ShadowComplexAssignment complexAssignment) {
+    return unimplemented("_makeSimpleWrite", offsetForToken(token), uri);
+  }
+
+  kernel.Expression _makeRead(ShadowComplexAssignment complexAssignment) {
+    return unimplemented("_makeRead", offsetForToken(token), uri);
+  }
+
+  kernel.Expression _makeWrite(kernel.Expression value, bool voidContext,
+      ShadowComplexAssignment complexAssignment) {
+    return unimplemented("_makeWrite", offsetForToken(token), uri);
+  }
+}
+
+abstract class IncompleteSend<Arguments> extends FastaAccessor<Arguments>
+    with GeneratorImpl {
+  final BuilderHelper<dynamic, dynamic, Arguments> helper;
+
+  @override
+  final Token token;
+
+  final Name name;
+
+  IncompleteSend(this.helper, this.token, this.name);
+
+  withReceiver(Object receiver, int operatorOffset, {bool isNullAware});
+
+  Arguments get arguments => null;
+
+  @override
+  void printOn(StringSink sink) {
+    sink.write(", name: ");
+    sink.write(name.name);
+  }
+}
+
+class IncompleteError<Arguments> extends IncompleteSend<Arguments>
+    with ErroneousExpressionGenerator<Arguments> {
+  final Message message;
+
+  IncompleteError(BuilderHelper<dynamic, dynamic, Arguments> helper,
+      Token token, this.message)
+      : super(helper, token, null);
+
+  String get debugName => "IncompleteError";
+
+  @override
+  kernel.Expression buildError(Arguments arguments,
+      {bool isGetter: false, bool isSetter: false, int offset}) {
+    int length = noLength;
+    if (offset == null) {
+      offset = offsetForToken(token);
+      length = lengthForToken(token);
+    }
+    return helper.buildCompileTimeError(message, offset, length);
+  }
+
+  @override
+  DartType buildErroneousTypeNotAPrefix(Identifier suffix) {
+    helper.addProblem(
+        templateNotAPrefixInTypeAnnotation.withArguments(
+            token.lexeme, suffix.name),
+        offsetForToken(token),
+        lengthOfSpan(token, suffix.token));
+    return const InvalidType();
+  }
+
+  @override
+  doInvocation(int offset, Arguments arguments) => this;
+
+  @override
+  void printOn(StringSink sink) {
+    sink.write(", message: ");
+    sink.write(message.code.name);
+  }
+}
+
+class SendAccessor<Arguments> extends IncompleteSend<Arguments> {
+  @override
+  final Arguments arguments;
+
+  SendAccessor(BuilderHelper<dynamic, dynamic, Arguments> helper, Token token,
+      Name name, this.arguments)
+      : super(helper, token, name) {
+    assert(arguments != null);
+  }
+
+  String get plainNameForRead => name.name;
+
+  String get debugName => "SendAccessor";
+
+  kernel.Expression buildSimpleRead() {
+    return unsupported("buildSimpleRead", offsetForToken(token), uri);
+  }
+
+  kernel.Expression buildAssignment(kernel.Expression value,
+      {bool voidContext: false}) {
+    return unsupported("buildAssignment", offsetForToken(token), uri);
+  }
+
+  withReceiver(Object receiver, int operatorOffset, {bool isNullAware: false}) {
+    if (receiver is FastaAccessor) {
+      return receiver.buildPropertyAccess(this, operatorOffset, isNullAware);
+    }
+    if (receiver is PrefixBuilder) {
+      PrefixBuilder prefix = receiver;
+      if (isNullAware) {
+        helper.deprecated_addCompileTimeError(
+            offsetForToken(token),
+            "Library prefix '${prefix.name}' can't be used with null-aware "
+            "operator.\nTry removing '?'.");
+      }
+      receiver = helper.scopeLookup(prefix.exportScope, name.name, token,
+          isQualified: true, prefix: prefix);
+      return helper.finishSend(receiver, arguments, offsetForToken(token));
+    }
+    return helper.buildMethodInvocation(
+        helper.toValue(receiver), name, arguments, offsetForToken(token),
+        isNullAware: isNullAware);
+  }
+
+  kernel.Expression buildNullAwareAssignment(
+      kernel.Expression value, DartType type, int offset,
+      {bool voidContext: false}) {
+    return unsupported("buildNullAwareAssignment", offset, uri);
+  }
+
+  kernel.Expression buildCompoundAssignment(
+      Name binaryOperator, kernel.Expression value,
+      {int offset,
+      bool voidContext: false,
+      Procedure interfaceTarget,
+      bool isPreIncDec: false}) {
+    return unsupported(
+        "buildCompoundAssignment", offset ?? offsetForToken(token), uri);
+  }
+
+  kernel.Expression buildPrefixIncrement(Name binaryOperator,
+      {int offset, bool voidContext: false, Procedure interfaceTarget}) {
+    return unsupported(
+        "buildPrefixIncrement", offset ?? offsetForToken(token), uri);
+  }
+
+  kernel.Expression buildPostfixIncrement(Name binaryOperator,
+      {int offset, bool voidContext: false, Procedure interfaceTarget}) {
+    return unsupported(
+        "buildPostfixIncrement", offset ?? offsetForToken(token), uri);
+  }
+
+  kernel.Expression doInvocation(int offset, Arguments arguments) {
+    return unsupported("doInvocation", offset, uri);
+  }
+
+  @override
+  void printOn(StringSink sink) {
+    super.printOn(sink);
+    sink.write(", arguments: ");
+    var node = arguments;
+    if (node is kernel.Node) {
+      printNodeOn(node, sink);
+    } else {
+      sink.write(node);
+    }
+  }
+}
+
+class IncompletePropertyAccessor<Arguments> extends IncompleteSend<Arguments> {
+  IncompletePropertyAccessor(
+      BuilderHelper<dynamic, dynamic, Arguments> helper, Token token, Name name)
+      : super(helper, token, name);
+
+  String get plainNameForRead => name.name;
+
+  String get debugName => "IncompletePropertyAccessor";
+
+  kernel.Expression buildSimpleRead() {
+    return unsupported("buildSimpleRead", offsetForToken(token), uri);
+  }
+
+  kernel.Expression buildAssignment(kernel.Expression value,
+      {bool voidContext: false}) {
+    return unsupported("buildAssignment", offsetForToken(token), uri);
+  }
+
+  withReceiver(Object receiver, int operatorOffset, {bool isNullAware: false}) {
+    if (receiver is FastaAccessor) {
+      return receiver.buildPropertyAccess(this, operatorOffset, isNullAware);
+    }
+    if (receiver is PrefixBuilder) {
+      PrefixBuilder prefix = receiver;
+      if (isNullAware) {
+        helper.deprecated_addCompileTimeError(
+            offsetForToken(token),
+            "Library prefix '${prefix.name}' can't be used with null-aware "
+            "operator.\nTry removing '?'.");
+      }
+      return helper.scopeLookup(prefix.exportScope, name.name, token,
+          isQualified: true, prefix: prefix);
+    }
+
+    return PropertyAccessGenerator.make(
+        helper, token, helper.toValue(receiver), name, null, null, isNullAware);
+  }
+
+  kernel.Expression buildNullAwareAssignment(
+      kernel.Expression value, DartType type, int offset,
+      {bool voidContext: false}) {
+    return unsupported("buildNullAwareAssignment", offset, uri);
+  }
+
+  kernel.Expression buildCompoundAssignment(
+      Name binaryOperator, kernel.Expression value,
+      {int offset,
+      bool voidContext: false,
+      Procedure interfaceTarget,
+      bool isPreIncDec: false}) {
+    return unsupported(
+        "buildCompoundAssignment", offset ?? offsetForToken(token), uri);
+  }
+
+  kernel.Expression buildPrefixIncrement(Name binaryOperator,
+      {int offset, bool voidContext: false, Procedure interfaceTarget}) {
+    return unsupported(
+        "buildPrefixIncrement", offset ?? offsetForToken(token), uri);
+  }
+
+  kernel.Expression buildPostfixIncrement(Name binaryOperator,
+      {int offset, bool voidContext: false, Procedure interfaceTarget}) {
+    return unsupported(
+        "buildPostfixIncrement", offset ?? offsetForToken(token), uri);
+  }
+
+  kernel.Expression doInvocation(int offset, Arguments arguments) {
+    return unsupported("doInvocation", offset, uri);
+  }
+}
+
+int adjustForImplicitCall(String name, int offset) {
+  // Normally the offset is at the start of the token, but in this case,
+  // because we insert a '.call', we want it at the end instead.
+  return offset + (name?.length ?? 0);
+}
+
+class ParenthesizedExpression<Arguments>
+    extends ReadOnlyAccessGenerator<Arguments> {
+  ParenthesizedExpression(BuilderHelper<dynamic, dynamic, Arguments> helper,
+      Token token, kernel.Expression expression)
+      : super(helper, token, expression, null);
+
+  String get debugName => "ParenthesizedExpression";
+
+  kernel.Expression makeInvalidWrite(kernel.Expression value) {
+    return helper.deprecated_buildCompileTimeError(
+        "Can't assign to a parenthesized expression.", offsetForToken(token));
+  }
+}
+
+class TypeDeclarationAccessor<Arguments>
+    extends ReadOnlyAccessGenerator<Arguments> {
+  /// The import prefix preceding the [declaration] reference, or `null` if
+  /// the reference is not prefixed.
+  final PrefixBuilder prefix;
+
+  /// The offset at which the [declaration] is referenced by this accessor,
+  /// or `-1` if the reference is implicit.
+  final int declarationReferenceOffset;
+
+  final TypeDeclarationBuilder declaration;
+
+  TypeDeclarationAccessor(
+      BuilderHelper<dynamic, dynamic, Arguments> helper,
+      Token token,
+      this.prefix,
+      this.declarationReferenceOffset,
+      this.declaration,
+      String plainNameForRead)
+      : super(helper, token, null, plainNameForRead);
+
+  String get debugName => "TypeDeclarationAccessor";
+
+  kernel.Expression get expression {
+    if (super.expression == null) {
+      int offset = offsetForToken(token);
+      if (declaration is KernelInvalidTypeBuilder) {
+        KernelInvalidTypeBuilder declaration = this.declaration;
+        helper.addProblemErrorIfConst(
+            declaration.message.messageObject, offset, token.length);
+        super.expression =
+            new Throw(forest.literalString(declaration.message.message, token))
+              ..fileOffset = offset;
+      } else {
+        super.expression = forest.literalType(
+            buildTypeWithBuiltArguments(null, nonInstanceAccessIsError: true),
+            token);
+      }
+    }
+    return super.expression;
+  }
+
+  kernel.Expression makeInvalidWrite(kernel.Expression value) {
+    return buildThrowNoSuchMethodError(
+        forest.literalNull(token),
+        storeOffset(forest.arguments(<kernel.Expression>[value], null),
+            value.fileOffset),
+        isSetter: true);
+  }
+
+  @override
+  buildPropertyAccess(
+      IncompleteSend send, int operatorOffset, bool isNullAware) {
+    // `SomeType?.toString` is the same as `SomeType.toString`, not
+    // `(SomeType).toString`.
+    isNullAware = false;
+
+    Name name = send.name;
+    Arguments arguments = send.arguments;
+
+    if (declaration is KernelClassBuilder) {
+      KernelClassBuilder declaration = this.declaration;
+      Builder builder = declaration.findStaticBuilder(
+          name.name, offsetForToken(token), uri, helper.library);
+
+      FastaAccessor accessor;
+      if (builder == null) {
+        // If we find a setter, [builder] is an [AccessErrorBuilder], not null.
+        if (send is IncompletePropertyAccessor) {
+          accessor = new UnresolvedAccessor(helper, send.token, name);
+        } else {
+          return helper.buildConstructorInvocation(declaration, send.token,
+              arguments, name.name, null, token.charOffset, Constness.implicit);
+        }
+      } else {
+        Builder setter;
+        if (builder.isSetter) {
+          setter = builder;
+        } else if (builder.isGetter) {
+          setter = declaration.findStaticBuilder(
+              name.name, offsetForToken(token), uri, helper.library,
+              isSetter: true);
+        } else if (builder.isField && !builder.isFinal) {
+          setter = builder;
+        }
+        accessor = new StaticAccessGenerator.fromBuilder(
+            helper, builder, send.token, setter);
+      }
+
+      return arguments == null
+          ? accessor
+          : accessor.doInvocation(offsetForToken(send.token), arguments);
+    } else {
+      return super.buildPropertyAccess(send, operatorOffset, isNullAware);
+    }
+  }
+
+  @override
+  DartType buildTypeWithBuiltArguments(List<DartType> arguments,
+      {bool nonInstanceAccessIsError: false}) {
+    if (arguments != null) {
+      int expected = 0;
+      if (declaration is KernelClassBuilder) {
+        expected = declaration.target.typeParameters.length;
+      } else if (declaration is FunctionTypeAliasBuilder) {
+        expected = declaration.target.typeParameters.length;
+      } else if (declaration is KernelTypeVariableBuilder) {
+        // Type arguments on a type variable - error reported elsewhere.
+      } else if (declaration is BuiltinTypeBuilder) {
+        // Type arguments on a built-in type, for example, dynamic or void.
+        expected = 0;
+      } else {
+        return unhandled(
+            "${declaration.runtimeType}",
+            "TypeDeclarationAccessor.buildType",
+            offsetForToken(token),
+            helper.uri);
+      }
+      if (arguments.length != expected) {
+        helper.warnTypeArgumentsMismatch(
+            declaration.name, expected, offsetForToken(token));
+        // We ignore the provided arguments, which will in turn return the
+        // raw type below.
+        // TODO(sigmund): change to use an InvalidType and include the raw type
+        // as a recovery node once the IR can represent it (Issue #29840).
+        arguments = null;
+      }
+    }
+
+    DartType type;
+    if (arguments == null) {
+      TypeDeclarationBuilder typeDeclaration = declaration;
+      if (typeDeclaration is KernelClassBuilder) {
+        type = typeDeclaration.buildType(helper.library, null);
+      } else if (typeDeclaration is KernelFunctionTypeAliasBuilder) {
+        type = typeDeclaration.buildType(helper.library, null);
+      }
+    }
+    if (type == null) {
+      type =
+          declaration.buildTypesWithBuiltArguments(helper.library, arguments);
+    }
+    if (type is TypeParameterType) {
+      return helper.validatedTypeVariableUse(
+          type, offsetForToken(token), nonInstanceAccessIsError);
+    }
+    return type;
+  }
+
+  @override
+  kernel.Expression doInvocation(int offset, Arguments arguments) {
+    return helper.buildConstructorInvocation(declaration, token, arguments, "",
+        null, token.charOffset, Constness.implicit);
+  }
+}
+
+class UnresolvedAccessor<Arguments> extends FastaAccessor<Arguments>
+    with GeneratorImpl, ErroneousExpressionGenerator<Arguments> {
+  @override
+  final Token token;
+
+  @override
+  final BuilderHelper<dynamic, dynamic, Arguments> helper;
+
+  @override
+  final Name name;
+
+  UnresolvedAccessor(this.helper, this.token, this.name);
+
+  String get debugName => "UnresolvedAccessor";
+
+  kernel.Expression doInvocation(int charOffset, Arguments arguments) {
+    return buildError(arguments, offset: charOffset);
+  }
+
+  @override
+  DartType buildErroneousTypeNotAPrefix(Identifier suffix) {
+    helper.addProblem(
+        templateUnresolvedPrefixInTypeAnnotation.withArguments(
+            name.name, suffix.name),
+        offsetForToken(token),
+        lengthOfSpan(token, suffix.token));
+    return const InvalidType();
+  }
+
+  @override
+  kernel.Expression buildError(Arguments arguments,
+      {bool isGetter: false, bool isSetter: false, int offset}) {
+    offset ??= offsetForToken(this.token);
+    return helper.throwNoSuchMethodError(
+        storeOffset(forest.literalNull(null), offset),
+        plainNameForRead,
+        arguments,
+        offset,
+        isGetter: isGetter,
+        isSetter: isSetter);
+  }
+
+  @override
+  void printOn(StringSink sink) {
+    sink.write(", name: ");
+    sink.write(name.name);
+  }
+}
+
+bool isFieldOrGetter(Member member) {
+  return member is Field || (member is Procedure && member.isGetter);
+}
diff --git a/pkg/front_end/lib/src/fasta/kernel/fangorn.dart b/pkg/front_end/lib/src/fasta/kernel/fangorn.dart
index 7dbebfe..8f539a0 100644
--- a/pkg/front_end/lib/src/fasta/kernel/fangorn.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/fangorn.dart
@@ -9,20 +9,31 @@
 import 'package:kernel/ast.dart'
     show
         Arguments,
+        BreakStatement,
+        Block,
+        Catch,
+        ContinueSwitchStatement,
         DartType,
+        EmptyStatement,
         Expression,
         ExpressionStatement,
         InvalidExpression,
+        LabeledStatement,
         Let,
         LibraryDependency,
         MapEntry,
         NamedExpression,
         Statement,
+        SwitchCase,
+        ThisExpression,
         TreeNode,
-        VariableDeclaration;
+        VariableDeclaration,
+        setParents;
 
 import '../parser.dart' show offsetForToken;
 
+import '../problems.dart' show unsupported;
+
 import '../scanner.dart' show Token;
 
 import 'kernel_shadow_ast.dart'
@@ -30,24 +41,36 @@
         ShadowArguments,
         ShadowAsExpression,
         ShadowAwaitExpression,
+        ShadowBlock,
         ShadowBoolLiteral,
         ShadowCheckLibraryIsLoaded,
         ShadowConditionalExpression,
+        ShadowDoStatement,
         ShadowDoubleLiteral,
+        ShadowExpressionStatement,
+        ShadowIfStatement,
         ShadowIntLiteral,
         ShadowIsExpression,
         ShadowIsNotExpression,
+        ShadowLabeledStatement,
         ShadowListLiteral,
         ShadowLoadLibrary,
         ShadowMapLiteral,
         ShadowNot,
         ShadowNullLiteral,
+        ShadowRethrow,
+        ShadowReturnStatement,
         ShadowStringConcatenation,
         ShadowStringLiteral,
         ShadowSymbolLiteral,
         ShadowSyntheticExpression,
         ShadowThisExpression,
-        ShadowTypeLiteral;
+        ShadowThrow,
+        ShadowTryCatch,
+        ShadowTryFinally,
+        ShadowTypeLiteral,
+        ShadowWhileStatement,
+        ShadowYieldStatement;
 
 import 'forest.dart' show Forest;
 
@@ -149,8 +172,13 @@
   }
 
   @override
-  ShadowSymbolLiteral literalSymbol(String value, Token token) {
-    return new ShadowSymbolLiteral(value)..fileOffset = offsetForToken(token);
+  ShadowSymbolLiteral literalSymbolMultiple(String value, Token hash, _) {
+    return new ShadowSymbolLiteral(value)..fileOffset = offsetForToken(hash);
+  }
+
+  @override
+  ShadowSymbolLiteral literalSymbolSingluar(String value, Token hash, _) {
+    return new ShadowSymbolLiteral(value)..fileOffset = offsetForToken(hash);
   }
 
   @override
@@ -200,6 +228,23 @@
   }
 
   @override
+  Statement block(
+      Token openBrace, List<Statement> statements, Token closeBrace) {
+    List<Statement> copy;
+    for (int i = 0; i < statements.length; i++) {
+      Statement statement = statements[i];
+      if (statement is _VariablesDeclaration) {
+        copy ??= new List<Statement>.from(statements.getRange(0, i));
+        copy.addAll(statement.declarations);
+      } else if (copy != null) {
+        copy.add(statement);
+      }
+    }
+    return new ShadowBlock(copy ?? statements)
+      ..fileOffset = offsetForToken(openBrace);
+  }
+
+  @override
   Expression conditionalExpression(Expression condition, Token question,
       Expression thenExpression, Token colon, Expression elseExpression) {
     return new ShadowConditionalExpression(
@@ -208,6 +253,29 @@
   }
 
   @override
+  Statement doStatement(Token doKeyword, Statement body, Token whileKeyword,
+      Expression condition, Token semicolon) {
+    return new ShadowDoStatement(body, condition)
+      ..fileOffset = doKeyword.charOffset;
+  }
+
+  Statement expressionStatement(Expression expression, Token semicolon) {
+    return new ShadowExpressionStatement(expression);
+  }
+
+  @override
+  Statement emptyStatement(Token semicolon) {
+    return new EmptyStatement();
+  }
+
+  @override
+  Statement ifStatement(Token ifKeyword, Expression condition,
+      Statement thenStatement, Token elseKeyword, Statement elseStatement) {
+    return new ShadowIfStatement(condition, thenStatement, elseStatement)
+      ..fileOffset = ifKeyword.charOffset;
+  }
+
+  @override
   Expression isExpression(
       Expression operand, isOperator, Token notOperator, covariant type) {
     int offset = offsetForToken(isOperator);
@@ -223,6 +291,25 @@
   }
 
   @override
+  Object parenthesizedCondition(
+      Token leftParenthesis, Expression expression, Token rightParenthesis) {
+    return expression;
+  }
+
+  @override
+  Statement rethrowStatement(Token rethrowKeyword, Token semicolon) {
+    return new ShadowExpressionStatement(
+        new ShadowRethrow()..fileOffset = offsetForToken(rethrowKeyword));
+  }
+
+  @override
+  Statement returnStatement(
+      Token returnKeyword, Expression expression, Token semicolon) {
+    return new ShadowReturnStatement(expression)
+      ..fileOffset = returnKeyword.charOffset;
+  }
+
+  @override
   Expression stringConcatenationExpression(
       List<Expression> expressions, Token token) {
     return new ShadowStringConcatenation(expressions)
@@ -230,12 +317,78 @@
   }
 
   @override
+  Statement syntheticLabeledStatement(Statement statement) {
+    return new ShadowLabeledStatement(statement);
+  }
+
+  @override
   Expression thisExpression(Token token) {
     return new ShadowThisExpression()..fileOffset = offsetForToken(token);
   }
 
   @override
-  bool isErroneousNode(TreeNode node) {
+  Expression throwExpression(Token throwKeyword, Expression expression) {
+    return new ShadowThrow(expression)
+      ..fileOffset = offsetForToken(throwKeyword);
+  }
+
+  @override
+  Statement tryStatement(Token tryKeyword, Statement body,
+      List<Catch> catchClauses, Token finallyKeyword, Statement finallyBlock) {
+    Statement tryStatement = body;
+    if (catchClauses != null) {
+      tryStatement = new ShadowTryCatch(tryStatement, catchClauses);
+    }
+    if (finallyBlock != null) {
+      tryStatement = new ShadowTryFinally(tryStatement, finallyBlock);
+    }
+    return tryStatement;
+  }
+
+  @override
+  _VariablesDeclaration variablesDeclaration(
+      List<VariableDeclaration> declarations, Uri uri) {
+    return new _VariablesDeclaration(declarations, uri);
+  }
+
+  @override
+  List<VariableDeclaration> variablesDeclarationExtractDeclarations(
+      _VariablesDeclaration variablesDeclaration) {
+    return variablesDeclaration.declarations;
+  }
+
+  @override
+  Statement wrapVariables(Statement statement) {
+    if (statement is _VariablesDeclaration) {
+      return new ShadowBlock(statement.declarations)
+        ..fileOffset = statement.fileOffset;
+    } else if (statement is VariableDeclaration) {
+      return new ShadowBlock(<Statement>[statement])
+        ..fileOffset = statement.fileOffset;
+    } else {
+      return statement;
+    }
+  }
+
+  @override
+  Statement whileStatement(
+      Token whileKeyword, Expression condition, Statement body) {
+    return new ShadowWhileStatement(condition, body)
+      ..fileOffset = whileKeyword.charOffset;
+  }
+
+  @override
+  Statement yieldStatement(
+      Token yieldKeyword, Token star, Expression expression, Token semicolon) {
+    return new ShadowYieldStatement(expression, isYieldStar: star != null)
+      ..fileOffset = yieldKeyword.charOffset;
+  }
+
+  @override
+  bool isBlock(Object node) => node is Block;
+
+  @override
+  bool isErroneousNode(Object node) {
     if (node is ExpressionStatement) {
       ExpressionStatement statement = node;
       node = statement.expression;
@@ -254,4 +407,55 @@
     }
     return node is InvalidExpression;
   }
+
+  @override
+  bool isThisExpression(Object node) => node is ThisExpression;
+
+  @override
+  bool isVariablesDeclaration(Object node) => node is _VariablesDeclaration;
+
+  @override
+  void resolveBreak(LabeledStatement target, BreakStatement user) {
+    user.target = target;
+  }
+
+  @override
+  void resolveContinue(LabeledStatement target, BreakStatement user) {
+    user.target = target;
+  }
+
+  @override
+  void resolveContinueInSwitch(
+      SwitchCase target, ContinueSwitchStatement user) {
+    user.target = target;
+  }
+}
+
+class _VariablesDeclaration extends Statement {
+  final List<VariableDeclaration> declarations;
+  final Uri uri;
+
+  _VariablesDeclaration(this.declarations, this.uri) {
+    setParents(declarations, this);
+  }
+
+  @override
+  accept(v) {
+    unsupported("accept", fileOffset, uri);
+  }
+
+  @override
+  accept1(v, arg) {
+    unsupported("accept1", fileOffset, uri);
+  }
+
+  @override
+  visitChildren(v) {
+    unsupported("visitChildren", fileOffset, uri);
+  }
+
+  @override
+  transformChildren(v) {
+    unsupported("transformChildren", fileOffset, uri);
+  }
 }
diff --git a/pkg/front_end/lib/src/fasta/kernel/fasta_accessors.dart b/pkg/front_end/lib/src/fasta/kernel/fasta_accessors.dart
deleted file mode 100644
index 25ddc28..0000000
--- a/pkg/front_end/lib/src/fasta/kernel/fasta_accessors.dart
+++ /dev/null
@@ -1,1391 +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.fasta_accessors;
-
-import '../../scanner/token.dart' show Token;
-
-import '../constant_context.dart' show ConstantContext;
-
-import '../fasta_codes.dart'
-    show
-        LocatedMessage,
-        messageInvalidInitializer,
-        messageLoadLibraryTakesNoArguments,
-        messageSuperAsExpression,
-        templateDeferredTypeAnnotation,
-        templateIntegerLiteralIsOutOfRange,
-        templateNotAPrefixInTypeAnnotation,
-        templateNotAType,
-        templateUnresolvedPrefixInTypeAnnotation;
-
-import '../messages.dart' show Message, noLength;
-
-import '../names.dart' show callName, lengthName;
-
-import '../parser.dart' show lengthForToken, lengthOfSpan, offsetForToken;
-
-import '../problems.dart' show unhandled, unimplemented, unsupported;
-
-import '../scope.dart' show AccessErrorBuilder, ProblemBuilder, Scope;
-
-import '../type_inference/type_promotion.dart' show TypePromoter;
-
-import 'body_builder.dart' show Identifier, noLocation;
-
-import 'constness.dart' show Constness;
-
-import 'forest.dart' show Forest;
-
-import 'frontend_accessors.dart' as kernel
-    show
-        IndexAccessor,
-        NullAwarePropertyAccessor,
-        LoadLibraryAccessor,
-        PropertyAccessor,
-        ReadOnlyAccessor,
-        DeferredAccessor,
-        DelayedErrorAccessor,
-        StaticAccessor,
-        SuperIndexAccessor,
-        SuperPropertyAccessor,
-        ThisIndexAccessor,
-        ThisPropertyAccessor,
-        VariableAccessor;
-
-import 'frontend_accessors.dart' show Accessor;
-
-import 'kernel_ast_api.dart' hide Expression, Statement;
-
-import 'kernel_ast_api.dart' as kernel show Expression, Statement;
-
-import 'kernel_builder.dart'
-    show
-        Builder,
-        BuiltinTypeBuilder,
-        FunctionTypeAliasBuilder,
-        KernelClassBuilder,
-        KernelFunctionTypeAliasBuilder,
-        KernelInvalidTypeBuilder,
-        KernelPrefixBuilder,
-        KernelTypeVariableBuilder,
-        LibraryBuilder,
-        LoadLibraryBuilder,
-        PrefixBuilder,
-        TypeDeclarationBuilder;
-
-abstract class BuilderHelper<Expression, Statement, Arguments> {
-  LibraryBuilder get library;
-
-  Uri get uri;
-
-  TypePromoter get typePromoter;
-
-  int get functionNestingLevel;
-
-  ConstantContext get constantContext;
-
-  Forest<Expression, Statement, Token, Arguments> get forest;
-
-  Constructor lookupConstructor(Name name, {bool isSuper});
-
-  Expression toValue(node);
-
-  Member lookupInstanceMember(Name name, {bool isSetter, bool isSuper});
-
-  scopeLookup(Scope scope, String name, Token token,
-      {bool isQualified: false, PrefixBuilder prefix});
-
-  finishSend(Object receiver, Arguments arguments, int offset);
-
-  Expression buildCompileTimeError(Message message, int charOffset, int length,
-      {List<LocatedMessage> context});
-
-  Expression wrapInCompileTimeError(Expression expression, Message message);
-
-  Expression deprecated_buildCompileTimeError(String error, [int offset]);
-
-  Initializer buildInvalidInitializer(Expression expression, [int offset]);
-
-  Initializer buildFieldInitializer(
-      bool isSynthetic, String name, int offset, Expression expression);
-
-  Initializer buildSuperInitializer(
-      bool isSynthetic, Constructor constructor, Arguments arguments,
-      [int offset]);
-
-  Initializer buildRedirectingInitializer(
-      Constructor constructor, Arguments arguments,
-      [int charOffset = -1]);
-
-  Expression buildStaticInvocation(Procedure target, Arguments arguments,
-      {Constness constness, int charOffset, Member initialTarget});
-
-  Expression buildProblemExpression(
-      ProblemBuilder builder, int offset, int length);
-
-  Expression throwNoSuchMethodError(
-      Expression receiver, String name, Arguments arguments, int offset,
-      {Member candidate,
-      bool isSuper,
-      bool isGetter,
-      bool isSetter,
-      bool isStatic,
-      LocatedMessage argMessage});
-
-  LocatedMessage checkArguments(FunctionTypeAccessor function,
-      Arguments arguments, CalleeDesignation calleeKind, int offset,
-      [List<TypeParameter> typeParameters]);
-
-  StaticGet makeStaticGet(Member readTarget, Token token);
-
-  Expression wrapInDeferredCheck(
-      Expression expression, KernelPrefixBuilder prefix, int charOffset);
-
-  dynamic deprecated_addCompileTimeError(int charOffset, String message);
-
-  bool isIdentical(Member member);
-
-  Expression buildMethodInvocation(
-      Expression receiver, Name name, Arguments arguments, int offset,
-      {bool isConstantExpression,
-      bool isNullAware,
-      bool isImplicitCall,
-      bool isSuper,
-      Member interfaceTarget});
-
-  Expression buildConstructorInvocation(
-      TypeDeclarationBuilder type,
-      Token nameToken,
-      Arguments arguments,
-      String name,
-      List<DartType> typeArguments,
-      int charOffset,
-      Constness constness);
-
-  DartType validatedTypeVariableUse(
-      TypeParameterType type, int offset, bool nonInstanceAccessIsError);
-
-  void addProblem(Message message, int charOffset, int length);
-
-  void addProblemErrorIfConst(Message message, int charOffset, int length);
-
-  Message warnUnresolvedGet(Name name, int charOffset, {bool isSuper});
-
-  Message warnUnresolvedSet(Name name, int charOffset, {bool isSuper});
-
-  Message warnUnresolvedMethod(Name name, int charOffset, {bool isSuper});
-
-  void warnTypeArgumentsMismatch(String name, int expected, int charOffset);
-
-  T storeOffset<T>(T node, int offset);
-}
-
-// The name used to refer to a call target kind
-enum CalleeDesignation { Function, Method, Constructor }
-
-// Abstraction over FunctionNode and FunctionType to access the
-// number and names of parameters.
-class FunctionTypeAccessor {
-  int requiredParameterCount;
-  int positionalParameterCount;
-
-  List _namedParameters;
-
-  Set<String> get namedParameterNames {
-    return new Set.from(_namedParameters.map((a) => a.name));
-  }
-
-  factory FunctionTypeAccessor.fromNode(FunctionNode node) {
-    return new FunctionTypeAccessor._(node.requiredParameterCount,
-        node.positionalParameters.length, node.namedParameters);
-  }
-
-  factory FunctionTypeAccessor.fromType(FunctionType type) {
-    return new FunctionTypeAccessor._(type.requiredParameterCount,
-        type.positionalParameters.length, type.namedParameters);
-  }
-
-  FunctionTypeAccessor._(this.requiredParameterCount,
-      this.positionalParameterCount, this._namedParameters);
-}
-
-abstract class FastaAccessor<Arguments> implements Accessor<Arguments> {
-  BuilderHelper get helper;
-
-  // TODO(ahe): Change type arguments.
-  Forest<kernel.Expression, kernel.Statement, Token, Arguments> get forest =>
-      helper.forest;
-
-  String get plainNameForRead;
-
-  Uri get uri => helper.uri;
-
-  String get plainNameForWrite => plainNameForRead;
-
-  bool get isInitializer => false;
-
-  T storeOffset<T>(T node, int offset) {
-    return helper.storeOffset(node, offset);
-  }
-
-  kernel.Expression buildForEffect() => buildSimpleRead();
-
-  Initializer buildFieldInitializer(Map<String, int> initializedFields) {
-    int offset = offsetForToken(token);
-    return helper.buildInvalidInitializer(
-        helper.buildCompileTimeError(
-            messageInvalidInitializer, offset, lengthForToken(token)),
-        offset);
-  }
-
-  kernel.Expression makeInvalidRead() {
-    return buildThrowNoSuchMethodError(
-        forest.literalNull(token), forest.argumentsEmpty(noLocation),
-        isGetter: true);
-  }
-
-  kernel.Expression makeInvalidWrite(kernel.Expression value) {
-    return buildThrowNoSuchMethodError(forest.literalNull(token),
-        forest.arguments(<kernel.Expression>[value], noLocation),
-        isSetter: true);
-  }
-
-  /* kernel.Expression | FastaAccessor | Initializer */ doInvocation(
-      int offset, Arguments arguments);
-
-  /* kernel.Expression | FastaAccessor */ buildPropertyAccess(
-      IncompleteSend send, int operatorOffset, bool isNullAware) {
-    if (send is SendAccessor) {
-      return helper.buildMethodInvocation(buildSimpleRead(), send.name,
-          send.arguments, offsetForToken(send.token),
-          isNullAware: isNullAware);
-    } else {
-      if (helper.constantContext != ConstantContext.none &&
-          send.name != lengthName) {
-        helper.deprecated_addCompileTimeError(
-            offsetForToken(token), "Not a constant expression.");
-      }
-      return PropertyAccessor.make(helper, send.token, buildSimpleRead(),
-          send.name, null, null, isNullAware);
-    }
-  }
-
-  DartType buildTypeWithBuiltArguments(List<DartType> arguments,
-      {bool nonInstanceAccessIsError: false}) {
-    helper.addProblem(templateNotAType.withArguments(token.lexeme),
-        offsetForToken(token), lengthForToken(token));
-    return const InvalidType();
-  }
-
-  /* kernel.Expression | FastaAccessor */ buildThrowNoSuchMethodError(
-      kernel.Expression receiver, Arguments arguments,
-      {bool isSuper: false,
-      bool isGetter: false,
-      bool isSetter: false,
-      bool isStatic: false,
-      String name,
-      int offset,
-      LocatedMessage argMessage}) {
-    return helper.throwNoSuchMethodError(receiver, name ?? plainNameForWrite,
-        arguments, offset ?? offsetForToken(this.token),
-        isGetter: isGetter,
-        isSetter: isSetter,
-        isSuper: isSuper,
-        isStatic: isStatic,
-        argMessage: argMessage);
-  }
-
-  bool get isThisPropertyAccessor => false;
-
-  @override
-  ShadowComplexAssignment startComplexAssignment(kernel.Expression rhs) =>
-      new ShadowIllegalAssignment(rhs);
-}
-
-abstract class ErrorAccessor<Arguments> implements FastaAccessor<Arguments> {
-  /// Pass [arguments] that must be evaluated before throwing an error.  At
-  /// most one of [isGetter] and [isSetter] should be true and they're passed
-  /// to [BuilderHelper.buildThrowNoSuchMethodError] if it is used.
-  kernel.Expression buildError(Arguments arguments,
-      {bool isGetter: false, bool isSetter: false, int offset});
-
-  DartType buildErroneousTypeNotAPrefix(Identifier suffix);
-
-  Name get name => unsupported("name", offsetForToken(token), uri);
-
-  @override
-  String get plainNameForRead => name.name;
-
-  withReceiver(Object receiver, int operatorOffset, {bool isNullAware}) => this;
-
-  @override
-  Initializer buildFieldInitializer(Map<String, int> initializedFields) {
-    return helper.buildInvalidInitializer(
-        buildError(forest.argumentsEmpty(noLocation), isSetter: true));
-  }
-
-  @override
-  doInvocation(int offset, Arguments arguments) {
-    return buildError(arguments, offset: offset);
-  }
-
-  @override
-  buildPropertyAccess(
-      IncompleteSend send, int operatorOffset, bool isNullAware) {
-    return this;
-  }
-
-  @override
-  buildThrowNoSuchMethodError(kernel.Expression receiver, Arguments arguments,
-      {bool isSuper: false,
-      bool isGetter: false,
-      bool isSetter: false,
-      bool isStatic: false,
-      String name,
-      int offset,
-      LocatedMessage argMessage}) {
-    return this;
-  }
-
-  @override
-  kernel.Expression buildAssignment(kernel.Expression value,
-      {bool voidContext: false}) {
-    return buildError(forest.arguments(<kernel.Expression>[value], noLocation),
-        isSetter: true);
-  }
-
-  @override
-  kernel.Expression buildCompoundAssignment(
-      Name binaryOperator, kernel.Expression value,
-      {int offset: TreeNode.noOffset,
-      bool voidContext: false,
-      Procedure interfaceTarget,
-      bool isPreIncDec: false}) {
-    return buildError(forest.arguments(<kernel.Expression>[value], token),
-        isGetter: true);
-  }
-
-  @override
-  kernel.Expression buildPrefixIncrement(Name binaryOperator,
-      {int offset: TreeNode.noOffset,
-      bool voidContext: false,
-      Procedure interfaceTarget}) {
-    // TODO(ahe): For the Analyzer, we probably need to build a prefix
-    // increment node that wraps an error.
-    return buildError(
-        forest.arguments(<kernel.Expression>[
-          storeOffset(forest.literalInt(1, null), offset)
-        ], noLocation),
-        isGetter: true);
-  }
-
-  @override
-  kernel.Expression buildPostfixIncrement(Name binaryOperator,
-      {int offset: TreeNode.noOffset,
-      bool voidContext: false,
-      Procedure interfaceTarget}) {
-    // TODO(ahe): For the Analyzer, we probably need to build a post increment
-    // node that wraps an error.
-    return buildError(
-        forest.arguments(<kernel.Expression>[
-          storeOffset(forest.literalInt(1, null), offset)
-        ], noLocation),
-        isGetter: true);
-  }
-
-  @override
-  kernel.Expression buildNullAwareAssignment(
-      kernel.Expression value, DartType type, int offset,
-      {bool voidContext: false}) {
-    return buildError(forest.arguments(<kernel.Expression>[value], noLocation),
-        isSetter: true);
-  }
-
-  @override
-  kernel.Expression buildSimpleRead() =>
-      buildError(forest.argumentsEmpty(noLocation), isGetter: true);
-
-  @override
-  kernel.Expression makeInvalidRead() =>
-      buildError(forest.argumentsEmpty(noLocation), isGetter: true);
-
-  @override
-  kernel.Expression makeInvalidWrite(kernel.Expression value) {
-    return buildError(forest.arguments(<kernel.Expression>[value], noLocation),
-        isSetter: true);
-  }
-}
-
-class ThisAccessor<Arguments> extends FastaAccessor<Arguments> {
-  final BuilderHelper helper;
-
-  final Token token;
-
-  final bool isInitializer;
-
-  final bool isSuper;
-
-  ThisAccessor(this.helper, this.token, this.isInitializer,
-      {this.isSuper: false});
-
-  String get plainNameForRead {
-    return unsupported("${isSuper ? 'super' : 'this'}.plainNameForRead",
-        offsetForToken(token), uri);
-  }
-
-  kernel.Expression buildSimpleRead() {
-    if (!isSuper) {
-      return forest.thisExpression(token);
-    } else {
-      return helper.buildCompileTimeError(messageSuperAsExpression,
-          offsetForToken(token), lengthForToken(token));
-    }
-  }
-
-  @override
-  Initializer buildFieldInitializer(Map<String, int> initializedFields) {
-    String keyword = isSuper ? "super" : "this";
-    int offset = offsetForToken(token);
-    return helper.buildInvalidInitializer(
-        helper.deprecated_buildCompileTimeError(
-            "Can't use '$keyword' here, did you mean '$keyword()'?", offset),
-        offset);
-  }
-
-  buildPropertyAccess(
-      IncompleteSend send, int operatorOffset, bool isNullAware) {
-    Name name = send.name;
-    Arguments arguments = send.arguments;
-    int offset = offsetForToken(send.token);
-    if (isInitializer && send is SendAccessor) {
-      if (isNullAware) {
-        helper.deprecated_addCompileTimeError(
-            operatorOffset, "Expected '.'\nTry removing '?'.");
-      }
-      return buildConstructorInitializer(offset, name, arguments);
-    }
-    Member getter = helper.lookupInstanceMember(name, isSuper: isSuper);
-    if (send is SendAccessor) {
-      // Notice that 'this' or 'super' can't be null. So we can ignore the
-      // value of [isNullAware].
-      if (getter == null) {
-        helper.warnUnresolvedMethod(name, offsetForToken(send.token),
-            isSuper: isSuper);
-      }
-      return helper.buildMethodInvocation(forest.thisExpression(null), name,
-          send.arguments, offsetForToken(send.token),
-          isSuper: isSuper, interfaceTarget: getter);
-    } else {
-      Member setter =
-          helper.lookupInstanceMember(name, isSuper: isSuper, isSetter: true);
-      if (isSuper) {
-        return new SuperPropertyAccessor(
-            helper, send.token, name, getter, setter);
-      } else {
-        return new ThisPropertyAccessor(
-            helper, send.token, name, getter, setter);
-      }
-    }
-  }
-
-  doInvocation(int offset, Arguments arguments) {
-    if (isInitializer) {
-      return buildConstructorInitializer(offset, new Name(""), arguments);
-    } else if (isSuper) {
-      return helper.buildCompileTimeError(
-          messageSuperAsExpression, offset, noLength);
-    } else {
-      return helper.buildMethodInvocation(
-          forest.thisExpression(null), callName, arguments, offset,
-          isImplicitCall: true);
-    }
-  }
-
-  Initializer buildConstructorInitializer(
-      int offset, Name name, Arguments arguments) {
-    Constructor constructor = helper.lookupConstructor(name, isSuper: isSuper);
-    LocatedMessage argMessage;
-    if (constructor != null) {
-      argMessage = helper.checkArguments(
-          new FunctionTypeAccessor.fromNode(constructor.function),
-          arguments,
-          CalleeDesignation.Constructor,
-          offset, <TypeParameter>[]);
-    }
-    if (constructor == null || argMessage != null) {
-      return helper.buildInvalidInitializer(
-          buildThrowNoSuchMethodError(
-              storeOffset(forest.literalNull(null), offset), arguments,
-              isSuper: isSuper,
-              name: name.name,
-              offset: offset,
-              argMessage: argMessage),
-          offset);
-    } else if (isSuper) {
-      return helper.buildSuperInitializer(
-          false, constructor, arguments, offset);
-    } else {
-      return helper.buildRedirectingInitializer(constructor, arguments, offset);
-    }
-  }
-
-  kernel.Expression buildAssignment(kernel.Expression value,
-      {bool voidContext: false}) {
-    return buildAssignmentError();
-  }
-
-  kernel.Expression buildNullAwareAssignment(
-      kernel.Expression value, DartType type, int offset,
-      {bool voidContext: false}) {
-    return buildAssignmentError();
-  }
-
-  kernel.Expression buildCompoundAssignment(
-      Name binaryOperator, kernel.Expression value,
-      {int offset: TreeNode.noOffset,
-      bool voidContext: false,
-      Procedure interfaceTarget,
-      bool isPreIncDec: false}) {
-    return buildAssignmentError();
-  }
-
-  kernel.Expression buildPrefixIncrement(Name binaryOperator,
-      {int offset: TreeNode.noOffset,
-      bool voidContext: false,
-      Procedure interfaceTarget}) {
-    return buildAssignmentError();
-  }
-
-  kernel.Expression buildPostfixIncrement(Name binaryOperator,
-      {int offset: TreeNode.noOffset,
-      bool voidContext: false,
-      Procedure interfaceTarget}) {
-    return buildAssignmentError();
-  }
-
-  kernel.Expression buildAssignmentError() {
-    String message =
-        isSuper ? "Can't assign to 'super'." : "Can't assign to 'this'.";
-    return helper.deprecated_buildCompileTimeError(
-        message, offsetForToken(token));
-  }
-
-  toString() {
-    int offset = offsetForToken(token);
-    return "ThisAccessor($offset${isSuper ? ', super' : ''})";
-  }
-}
-
-abstract class IncompleteSend<Arguments> extends FastaAccessor<Arguments> {
-  final BuilderHelper helper;
-
-  @override
-  final Token token;
-
-  final Name name;
-
-  IncompleteSend(this.helper, this.token, this.name);
-
-  withReceiver(Object receiver, int operatorOffset, {bool isNullAware});
-
-  Arguments get arguments => null;
-}
-
-class IncompleteError<Arguments> extends IncompleteSend<Arguments>
-    with ErrorAccessor<Arguments> {
-  final Message message;
-
-  IncompleteError(BuilderHelper helper, Token token, this.message)
-      : super(helper, token, null);
-
-  @override
-  kernel.Expression buildError(Arguments arguments,
-      {bool isGetter: false, bool isSetter: false, int offset}) {
-    int length = noLength;
-    if (offset == null) {
-      offset = offsetForToken(token);
-      length = lengthForToken(token);
-    }
-    return helper.buildCompileTimeError(message, offset, length);
-  }
-
-  @override
-  DartType buildErroneousTypeNotAPrefix(Identifier suffix) {
-    helper.addProblem(
-        templateNotAPrefixInTypeAnnotation.withArguments(
-            token.lexeme, suffix.name),
-        offsetForToken(token),
-        lengthOfSpan(token, suffix.token));
-    return const InvalidType();
-  }
-
-  @override
-  doInvocation(int offset, Arguments arguments) => this;
-}
-
-class SendAccessor<Arguments> extends IncompleteSend<Arguments> {
-  @override
-  final Arguments arguments;
-
-  SendAccessor(BuilderHelper helper, Token token, Name name, this.arguments)
-      : super(helper, token, name) {
-    assert(arguments != null);
-  }
-
-  String get plainNameForRead => name.name;
-
-  kernel.Expression buildSimpleRead() {
-    return unsupported("buildSimpleRead", offsetForToken(token), uri);
-  }
-
-  kernel.Expression buildAssignment(kernel.Expression value,
-      {bool voidContext: false}) {
-    return unsupported("buildAssignment", offsetForToken(token), uri);
-  }
-
-  withReceiver(Object receiver, int operatorOffset, {bool isNullAware: false}) {
-    if (receiver is FastaAccessor) {
-      return receiver.buildPropertyAccess(this, operatorOffset, isNullAware);
-    }
-    if (receiver is PrefixBuilder) {
-      PrefixBuilder prefix = receiver;
-      if (isNullAware) {
-        helper.deprecated_addCompileTimeError(
-            offsetForToken(token),
-            "Library prefix '${prefix.name}' can't be used with null-aware "
-            "operator.\nTry removing '?'.");
-      }
-      receiver = helper.scopeLookup(prefix.exportScope, name.name, token,
-          isQualified: true, prefix: prefix);
-      return helper.finishSend(receiver, arguments, offsetForToken(token));
-    }
-    return helper.buildMethodInvocation(
-        helper.toValue(receiver), name, arguments, offsetForToken(token),
-        isNullAware: isNullAware);
-  }
-
-  kernel.Expression buildNullAwareAssignment(
-      kernel.Expression value, DartType type, int offset,
-      {bool voidContext: false}) {
-    return unsupported("buildNullAwareAssignment", offset, uri);
-  }
-
-  kernel.Expression buildCompoundAssignment(
-      Name binaryOperator, kernel.Expression value,
-      {int offset,
-      bool voidContext: false,
-      Procedure interfaceTarget,
-      bool isPreIncDec: false}) {
-    return unsupported(
-        "buildCompoundAssignment", offset ?? offsetForToken(token), uri);
-  }
-
-  kernel.Expression buildPrefixIncrement(Name binaryOperator,
-      {int offset, bool voidContext: false, Procedure interfaceTarget}) {
-    return unsupported(
-        "buildPrefixIncrement", offset ?? offsetForToken(token), uri);
-  }
-
-  kernel.Expression buildPostfixIncrement(Name binaryOperator,
-      {int offset, bool voidContext: false, Procedure interfaceTarget}) {
-    return unsupported(
-        "buildPostfixIncrement", offset ?? offsetForToken(token), uri);
-  }
-
-  kernel.Expression doInvocation(int offset, Arguments arguments) {
-    return unsupported("doInvocation", offset, uri);
-  }
-
-  toString() {
-    int offset = offsetForToken(token);
-    return "SendAccessor($offset, $name, $arguments)";
-  }
-}
-
-class IncompletePropertyAccessor<Arguments> extends IncompleteSend<Arguments> {
-  IncompletePropertyAccessor(BuilderHelper helper, Token token, Name name)
-      : super(helper, token, name);
-
-  String get plainNameForRead => name.name;
-
-  kernel.Expression buildSimpleRead() {
-    return unsupported("buildSimpleRead", offsetForToken(token), uri);
-  }
-
-  kernel.Expression buildAssignment(kernel.Expression value,
-      {bool voidContext: false}) {
-    return unsupported("buildAssignment", offsetForToken(token), uri);
-  }
-
-  withReceiver(Object receiver, int operatorOffset, {bool isNullAware: false}) {
-    if (receiver is FastaAccessor) {
-      return receiver.buildPropertyAccess(this, operatorOffset, isNullAware);
-    }
-    if (receiver is PrefixBuilder) {
-      PrefixBuilder prefix = receiver;
-      if (isNullAware) {
-        helper.deprecated_addCompileTimeError(
-            offsetForToken(token),
-            "Library prefix '${prefix.name}' can't be used with null-aware "
-            "operator.\nTry removing '?'.");
-      }
-      return helper.scopeLookup(prefix.exportScope, name.name, token,
-          isQualified: true, prefix: prefix);
-    }
-
-    return PropertyAccessor.make(
-        helper, token, helper.toValue(receiver), name, null, null, isNullAware);
-  }
-
-  kernel.Expression buildNullAwareAssignment(
-      kernel.Expression value, DartType type, int offset,
-      {bool voidContext: false}) {
-    return unsupported("buildNullAwareAssignment", offset, uri);
-  }
-
-  kernel.Expression buildCompoundAssignment(
-      Name binaryOperator, kernel.Expression value,
-      {int offset,
-      bool voidContext: false,
-      Procedure interfaceTarget,
-      bool isPreIncDec: false}) {
-    return unsupported(
-        "buildCompoundAssignment", offset ?? offsetForToken(token), uri);
-  }
-
-  kernel.Expression buildPrefixIncrement(Name binaryOperator,
-      {int offset, bool voidContext: false, Procedure interfaceTarget}) {
-    return unsupported(
-        "buildPrefixIncrement", offset ?? offsetForToken(token), uri);
-  }
-
-  kernel.Expression buildPostfixIncrement(Name binaryOperator,
-      {int offset, bool voidContext: false, Procedure interfaceTarget}) {
-    return unsupported(
-        "buildPostfixIncrement", offset ?? offsetForToken(token), uri);
-  }
-
-  kernel.Expression doInvocation(int offset, Arguments arguments) {
-    return unsupported("doInvocation", offset, uri);
-  }
-
-  toString() {
-    int offset = offsetForToken(token);
-    return "IncompletePropertyAccessor($offset, $name)";
-  }
-}
-
-class IndexAccessor<Arguments> extends kernel.IndexAccessor<Arguments>
-    with FastaAccessor<Arguments> {
-  final BuilderHelper helper;
-
-  IndexAccessor.internal(this.helper, Token token, kernel.Expression receiver,
-      kernel.Expression index, Procedure getter, Procedure setter)
-      : super.internal(helper, receiver, index, getter, setter, token);
-
-  String get plainNameForRead => "[]";
-
-  String get plainNameForWrite => "[]=";
-
-  kernel.Expression doInvocation(int offset, Arguments arguments) {
-    return helper.buildMethodInvocation(
-        buildSimpleRead(), callName, arguments, forest.readOffset(arguments),
-        isImplicitCall: true);
-  }
-
-  toString() => "IndexAccessor()";
-
-  static FastaAccessor make(
-      BuilderHelper helper,
-      Token token,
-      kernel.Expression receiver,
-      kernel.Expression index,
-      Procedure getter,
-      Procedure setter) {
-    if (receiver is ThisExpression) {
-      return new ThisIndexAccessor(helper, token, index, getter, setter);
-    } else {
-      return new IndexAccessor.internal(
-          helper, token, receiver, index, getter, setter);
-    }
-  }
-
-  @override
-  ShadowComplexAssignment startComplexAssignment(kernel.Expression rhs) =>
-      new ShadowIndexAssign(receiver, index, rhs);
-}
-
-class PropertyAccessor<Arguments> extends kernel.PropertyAccessor<Arguments>
-    with FastaAccessor<Arguments> {
-  final BuilderHelper helper;
-
-  PropertyAccessor.internal(this.helper, Token token,
-      kernel.Expression receiver, Name name, Member getter, Member setter)
-      : super.internal(helper, receiver, name, getter, setter, token);
-
-  String get plainNameForRead => name.name;
-
-  bool get isThisPropertyAccessor => receiver is ThisExpression;
-
-  kernel.Expression doInvocation(int offset, Arguments arguments) {
-    return helper.buildMethodInvocation(receiver, name, arguments, offset);
-  }
-
-  toString() => "PropertyAccessor()";
-
-  static FastaAccessor make(
-      BuilderHelper helper,
-      Token token,
-      kernel.Expression receiver,
-      Name name,
-      Member getter,
-      Member setter,
-      bool isNullAware) {
-    if (receiver is ThisExpression) {
-      return unsupported("ThisExpression", offsetForToken(token), helper.uri);
-    } else {
-      return isNullAware
-          ? new NullAwarePropertyAccessor(
-              helper, token, receiver, name, getter, setter, null)
-          : new PropertyAccessor.internal(
-              helper, token, receiver, name, getter, setter);
-    }
-  }
-
-  @override
-  ShadowComplexAssignment startComplexAssignment(kernel.Expression rhs) =>
-      new ShadowPropertyAssign(receiver, rhs);
-}
-
-class StaticAccessor<Arguments> extends kernel.StaticAccessor<Arguments>
-    with FastaAccessor<Arguments> {
-  StaticAccessor(
-      BuilderHelper helper, Token token, Member readTarget, Member writeTarget)
-      : super(helper, readTarget, writeTarget, token) {
-    assert(readTarget != null || writeTarget != null);
-  }
-
-  factory StaticAccessor.fromBuilder(BuilderHelper helper, Builder builder,
-      Token token, Builder builderSetter) {
-    if (builder is AccessErrorBuilder) {
-      AccessErrorBuilder error = builder;
-      builder = error.builder;
-      // We should only see an access error here if we've looked up a setter
-      // when not explicitly looking for a setter.
-      assert(builder.isSetter);
-    } else if (builder.target == null) {
-      return unhandled("${builder.runtimeType}", "StaticAccessor.fromBuilder",
-          offsetForToken(token), helper.uri);
-    }
-    Member getter = builder.target.hasGetter ? builder.target : null;
-    Member setter = builder.target.hasSetter ? builder.target : null;
-    if (setter == null) {
-      if (builderSetter?.target?.hasSetter ?? false) {
-        setter = builderSetter.target;
-      }
-    }
-    return new StaticAccessor(helper, token, getter, setter);
-  }
-
-  String get plainNameForRead => (readTarget ?? writeTarget).name.name;
-
-  kernel.Expression doInvocation(int offset, Arguments arguments) {
-    if (helper.constantContext != ConstantContext.none &&
-        !helper.isIdentical(readTarget)) {
-      helper.deprecated_addCompileTimeError(
-          offset, "Not a constant expression.");
-    }
-    if (readTarget == null || isFieldOrGetter(readTarget)) {
-      return helper.buildMethodInvocation(buildSimpleRead(), callName,
-          arguments, offset + (readTarget?.name?.name?.length ?? 0),
-          // This isn't a constant expression, but we have checked if a
-          // constant expression error should be emitted already.
-          isConstantExpression: true,
-          isImplicitCall: true);
-    } else {
-      return helper.buildStaticInvocation(readTarget, arguments,
-          charOffset: offset);
-    }
-  }
-
-  toString() => "StaticAccessor()";
-
-  @override
-  ShadowComplexAssignment startComplexAssignment(kernel.Expression rhs) =>
-      new ShadowStaticAssignment(rhs);
-}
-
-class LoadLibraryAccessor<Arguments> extends kernel
-    .LoadLibraryAccessor<Arguments> with FastaAccessor<Arguments> {
-  LoadLibraryAccessor(
-      BuilderHelper helper, Token token, LoadLibraryBuilder builder)
-      : super(helper, token, builder);
-
-  String get plainNameForRead => 'loadLibrary';
-
-  kernel.Expression doInvocation(int offset, Arguments arguments) {
-    if (forest.argumentsPositional(arguments).length > 0 ||
-        forest.argumentsNamed(arguments).length > 0) {
-      helper.addProblemErrorIfConst(
-          messageLoadLibraryTakesNoArguments, offset, 'loadLibrary'.length);
-    }
-    return builder.createLoadLibrary(offset, forest);
-  }
-}
-
-class DeferredAccessor<Arguments> extends kernel.DeferredAccessor<Arguments>
-    with FastaAccessor<Arguments> {
-  DeferredAccessor(BuilderHelper helper, Token token, PrefixBuilder builder,
-      FastaAccessor expression)
-      : super(helper, token, builder, expression);
-
-  String get plainNameForRead {
-    return unsupported(
-        "deferredAccessor.plainNameForRead", offsetForToken(token), uri);
-  }
-
-  FastaAccessor get accessor => super.accessor;
-
-  buildPropertyAccess(
-      IncompleteSend send, int operatorOffset, bool isNullAware) {
-    var propertyAccess =
-        accessor.buildPropertyAccess(send, operatorOffset, isNullAware);
-    if (propertyAccess is FastaAccessor) {
-      return new DeferredAccessor(helper, token, builder, propertyAccess);
-    } else {
-      kernel.Expression expression = propertyAccess;
-      return helper.wrapInDeferredCheck(expression, builder, token.charOffset);
-    }
-  }
-
-  @override
-  DartType buildTypeWithBuiltArguments(List<DartType> arguments,
-      {bool nonInstanceAccessIsError: false}) {
-    helper.addProblem(
-        templateDeferredTypeAnnotation.withArguments(
-            accessor.buildTypeWithBuiltArguments(arguments,
-                nonInstanceAccessIsError: nonInstanceAccessIsError),
-            builder.name),
-        offsetForToken(token),
-        lengthForToken(token));
-    return const InvalidType();
-  }
-
-  kernel.Expression doInvocation(int offset, Arguments arguments) {
-    return helper.wrapInDeferredCheck(
-        accessor.doInvocation(offset, arguments), builder, token.charOffset);
-  }
-}
-
-class SuperPropertyAccessor<Arguments> extends kernel
-    .SuperPropertyAccessor<Arguments> with FastaAccessor<Arguments> {
-  SuperPropertyAccessor(BuilderHelper helper, Token token, Name name,
-      Member getter, Member setter)
-      : super(helper, name, getter, setter, token);
-
-  String get plainNameForRead => name.name;
-
-  kernel.Expression doInvocation(int offset, Arguments arguments) {
-    if (helper.constantContext != ConstantContext.none) {
-      helper.deprecated_addCompileTimeError(
-          offset, "Not a constant expression.");
-    }
-    if (getter == null || isFieldOrGetter(getter)) {
-      return helper.buildMethodInvocation(
-          buildSimpleRead(), callName, arguments, offset,
-          // This isn't a constant expression, but we have checked if a
-          // constant expression error should be emitted already.
-          isConstantExpression: true,
-          isImplicitCall: true);
-    } else {
-      // TODO(ahe): This could be something like "super.property(...)" where
-      // property is a setter.
-      return unhandled("${getter.runtimeType}", "doInvocation", offset, uri);
-    }
-  }
-
-  toString() => "SuperPropertyAccessor()";
-
-  @override
-  ShadowComplexAssignment startComplexAssignment(kernel.Expression rhs) =>
-      new ShadowPropertyAssign(null, rhs, isSuper: true);
-}
-
-class ThisIndexAccessor<Arguments> extends kernel.ThisIndexAccessor<Arguments>
-    with FastaAccessor<Arguments> {
-  ThisIndexAccessor(BuilderHelper helper, Token token, kernel.Expression index,
-      Procedure getter, Procedure setter)
-      : super(helper, index, getter, setter, token);
-
-  String get plainNameForRead => "[]";
-
-  String get plainNameForWrite => "[]=";
-
-  kernel.Expression doInvocation(int offset, Arguments arguments) {
-    return helper.buildMethodInvocation(
-        buildSimpleRead(), callName, arguments, offset,
-        isImplicitCall: true);
-  }
-
-  toString() => "ThisIndexAccessor()";
-
-  @override
-  ShadowComplexAssignment startComplexAssignment(kernel.Expression rhs) =>
-      new ShadowIndexAssign(null, index, rhs);
-}
-
-class SuperIndexAccessor<Arguments> extends kernel.SuperIndexAccessor<Arguments>
-    with FastaAccessor<Arguments> {
-  SuperIndexAccessor(BuilderHelper helper, Token token, kernel.Expression index,
-      Member getter, Member setter)
-      : super(helper, index, getter, setter, token);
-
-  String get plainNameForRead => "[]";
-
-  String get plainNameForWrite => "[]=";
-
-  kernel.Expression doInvocation(int offset, Arguments arguments) {
-    return helper.buildMethodInvocation(
-        buildSimpleRead(), callName, arguments, offset,
-        isImplicitCall: true);
-  }
-
-  toString() => "SuperIndexAccessor()";
-
-  @override
-  ShadowComplexAssignment startComplexAssignment(kernel.Expression rhs) =>
-      new ShadowIndexAssign(null, index, rhs, isSuper: true);
-}
-
-class ThisPropertyAccessor<Arguments> extends kernel
-    .ThisPropertyAccessor<Arguments> with FastaAccessor<Arguments> {
-  final BuilderHelper helper;
-
-  ThisPropertyAccessor(
-      this.helper, Token token, Name name, Member getter, Member setter)
-      : super(helper, name, getter, setter, token);
-
-  String get plainNameForRead => name.name;
-
-  bool get isThisPropertyAccessor => true;
-
-  kernel.Expression doInvocation(int offset, Arguments arguments) {
-    Member interfaceTarget = getter;
-    if (interfaceTarget == null) {
-      helper.warnUnresolvedMethod(name, offset);
-    }
-    if (interfaceTarget is Field) {
-      // TODO(ahe): In strong mode we should probably rewrite this to
-      // `this.name.call(arguments)`.
-      interfaceTarget = null;
-    }
-    return helper.buildMethodInvocation(
-        forest.thisExpression(null), name, arguments, offset,
-        interfaceTarget: interfaceTarget);
-  }
-
-  toString() => "ThisPropertyAccessor()";
-
-  @override
-  ShadowComplexAssignment startComplexAssignment(kernel.Expression rhs) =>
-      new ShadowPropertyAssign(null, rhs);
-}
-
-class NullAwarePropertyAccessor<Arguments> extends kernel
-    .NullAwarePropertyAccessor<Arguments> with FastaAccessor<Arguments> {
-  final BuilderHelper helper;
-
-  NullAwarePropertyAccessor(
-      this.helper,
-      Token token,
-      kernel.Expression receiver,
-      Name name,
-      Member getter,
-      Member setter,
-      DartType type)
-      : super(helper, receiver, name, getter, setter, type, token);
-
-  String get plainNameForRead => name.name;
-
-  kernel.Expression doInvocation(int offset, Arguments arguments) {
-    return unimplemented("doInvocation", offset, uri);
-  }
-
-  toString() => "NullAwarePropertyAccessor()";
-
-  @override
-  ShadowComplexAssignment startComplexAssignment(kernel.Expression rhs) =>
-      new ShadowPropertyAssign(receiverExpression, rhs);
-}
-
-int adjustForImplicitCall(String name, int offset) {
-  // Normally the offset is at the start of the token, but in this case,
-  // because we insert a '.call', we want it at the end instead.
-  return offset + (name?.length ?? 0);
-}
-
-class VariableAccessor<Arguments> extends kernel.VariableAccessor<Arguments>
-    with FastaAccessor<Arguments> {
-  VariableAccessor(
-      BuilderHelper helper, Token token, VariableDeclaration variable,
-      [DartType promotedType])
-      : super(helper, variable, promotedType, token);
-
-  String get plainNameForRead => variable.name;
-
-  kernel.Expression doInvocation(int offset, Arguments arguments) {
-    return helper.buildMethodInvocation(buildSimpleRead(), callName, arguments,
-        adjustForImplicitCall(plainNameForRead, offset),
-        isImplicitCall: true);
-  }
-
-  toString() => "VariableAccessor()";
-
-  @override
-  ShadowComplexAssignment startComplexAssignment(kernel.Expression rhs) =>
-      new ShadowVariableAssignment(rhs);
-}
-
-class ReadOnlyAccessor<Arguments> extends kernel.ReadOnlyAccessor<Arguments>
-    with FastaAccessor<Arguments> {
-  final String plainNameForRead;
-
-  ReadOnlyAccessor(BuilderHelper helper, kernel.Expression expression,
-      this.plainNameForRead, Token token)
-      : super(helper, expression, token);
-
-  kernel.Expression doInvocation(int offset, Arguments arguments) {
-    return helper.buildMethodInvocation(buildSimpleRead(), callName, arguments,
-        adjustForImplicitCall(plainNameForRead, offset),
-        isImplicitCall: true);
-  }
-}
-
-class LargeIntAccessor<Arguments> extends kernel.DelayedErrorAccessor<Arguments>
-    with FastaAccessor<Arguments> {
-  final String plainNameForRead = null;
-
-  LargeIntAccessor(BuilderHelper helper, Token token) : super(helper, token);
-
-  @override
-  kernel.Expression buildError() {
-    return helper.buildCompileTimeError(
-        templateIntegerLiteralIsOutOfRange.withArguments(token),
-        offsetForToken(token),
-        lengthForToken(token));
-  }
-
-  kernel.Expression doInvocation(int offset, Arguments arguments) =>
-      buildError();
-}
-
-class ParenthesizedExpression<Arguments> extends ReadOnlyAccessor<Arguments> {
-  ParenthesizedExpression(
-      BuilderHelper helper, kernel.Expression expression, Token token)
-      : super(helper, expression, null, token);
-
-  kernel.Expression makeInvalidWrite(kernel.Expression value) {
-    return helper.deprecated_buildCompileTimeError(
-        "Can't assign to a parenthesized expression.", offsetForToken(token));
-  }
-}
-
-class TypeDeclarationAccessor<Arguments> extends ReadOnlyAccessor<Arguments> {
-  /// The import prefix preceding the [declaration] reference, or `null` if
-  /// the reference is not prefixed.
-  final PrefixBuilder prefix;
-
-  /// The offset at which the [declaration] is referenced by this accessor,
-  /// or `-1` if the reference is implicit.
-  final int declarationReferenceOffset;
-
-  final TypeDeclarationBuilder declaration;
-
-  TypeDeclarationAccessor(
-      BuilderHelper helper,
-      this.prefix,
-      this.declarationReferenceOffset,
-      this.declaration,
-      String plainNameForRead,
-      Token token)
-      : super(helper, null, plainNameForRead, token);
-
-  kernel.Expression get expression {
-    if (super.expression == null) {
-      int offset = offsetForToken(token);
-      if (declaration is KernelInvalidTypeBuilder) {
-        KernelInvalidTypeBuilder declaration = this.declaration;
-        helper.addProblemErrorIfConst(
-            declaration.message.messageObject, offset, token.length);
-        super.expression =
-            new Throw(forest.literalString(declaration.message.message, token))
-              ..fileOffset = offset;
-      } else {
-        super.expression = forest.literalType(
-            buildTypeWithBuiltArguments(null, nonInstanceAccessIsError: true),
-            token);
-      }
-    }
-    return super.expression;
-  }
-
-  kernel.Expression makeInvalidWrite(kernel.Expression value) {
-    return buildThrowNoSuchMethodError(
-        forest.literalNull(token),
-        storeOffset(forest.arguments(<kernel.Expression>[value], null),
-            value.fileOffset),
-        isSetter: true);
-  }
-
-  @override
-  buildPropertyAccess(
-      IncompleteSend send, int operatorOffset, bool isNullAware) {
-    // `SomeType?.toString` is the same as `SomeType.toString`, not
-    // `(SomeType).toString`.
-    isNullAware = false;
-
-    Name name = send.name;
-    Arguments arguments = send.arguments;
-
-    if (declaration is KernelClassBuilder) {
-      KernelClassBuilder declaration = this.declaration;
-      Builder builder = declaration.findStaticBuilder(
-          name.name, offsetForToken(token), uri, helper.library);
-
-      FastaAccessor accessor;
-      if (builder == null) {
-        // If we find a setter, [builder] is an [AccessErrorBuilder], not null.
-        if (send is IncompletePropertyAccessor) {
-          accessor = new UnresolvedAccessor(helper, name, send.token);
-        } else {
-          return helper.buildConstructorInvocation(declaration, send.token,
-              arguments, name.name, null, token.charOffset, Constness.implicit);
-        }
-      } else {
-        Builder setter;
-        if (builder.isSetter) {
-          setter = builder;
-        } else if (builder.isGetter) {
-          setter = declaration.findStaticBuilder(
-              name.name, offsetForToken(token), uri, helper.library,
-              isSetter: true);
-        } else if (builder.isField && !builder.isFinal) {
-          setter = builder;
-        }
-        accessor =
-            new StaticAccessor.fromBuilder(helper, builder, send.token, setter);
-      }
-
-      return arguments == null
-          ? accessor
-          : accessor.doInvocation(offsetForToken(send.token), arguments);
-    } else {
-      return super.buildPropertyAccess(send, operatorOffset, isNullAware);
-    }
-  }
-
-  @override
-  DartType buildTypeWithBuiltArguments(List<DartType> arguments,
-      {bool nonInstanceAccessIsError: false}) {
-    if (arguments != null) {
-      int expected = 0;
-      if (declaration is KernelClassBuilder) {
-        expected = declaration.target.typeParameters.length;
-      } else if (declaration is FunctionTypeAliasBuilder) {
-        expected = declaration.target.typeParameters.length;
-      } else if (declaration is KernelTypeVariableBuilder) {
-        // Type arguments on a type variable - error reported elsewhere.
-      } else if (declaration is BuiltinTypeBuilder) {
-        // Type arguments on a built-in type, for example, dynamic or void.
-        expected = 0;
-      } else {
-        return unhandled(
-            "${declaration.runtimeType}",
-            "TypeDeclarationAccessor.buildType",
-            offsetForToken(token),
-            helper.uri);
-      }
-      if (arguments.length != expected) {
-        helper.warnTypeArgumentsMismatch(
-            declaration.name, expected, offsetForToken(token));
-        // We ignore the provided arguments, which will in turn return the
-        // raw type below.
-        // TODO(sigmund): change to use an InvalidType and include the raw type
-        // as a recovery node once the IR can represent it (Issue #29840).
-        arguments = null;
-      }
-    }
-
-    DartType type;
-    if (arguments == null) {
-      TypeDeclarationBuilder typeDeclaration = declaration;
-      if (typeDeclaration is KernelClassBuilder) {
-        type = typeDeclaration.buildType(helper.library, null);
-      } else if (typeDeclaration is KernelFunctionTypeAliasBuilder) {
-        type = typeDeclaration.buildType(helper.library, null);
-      }
-    }
-    if (type == null) {
-      type =
-          declaration.buildTypesWithBuiltArguments(helper.library, arguments);
-    }
-    if (type is TypeParameterType) {
-      return helper.validatedTypeVariableUse(
-          type, offsetForToken(token), nonInstanceAccessIsError);
-    }
-    return type;
-  }
-
-  @override
-  kernel.Expression doInvocation(int offset, Arguments arguments) {
-    return helper.buildConstructorInvocation(declaration, token, arguments, "",
-        null, token.charOffset, Constness.implicit);
-  }
-}
-
-class UnresolvedAccessor<Arguments> extends FastaAccessor<Arguments>
-    with ErrorAccessor<Arguments> {
-  @override
-  final Token token;
-
-  @override
-  final BuilderHelper helper;
-
-  @override
-  final Name name;
-
-  UnresolvedAccessor(this.helper, this.name, this.token);
-
-  kernel.Expression doInvocation(int charOffset, Arguments arguments) {
-    return buildError(arguments, offset: charOffset);
-  }
-
-  @override
-  DartType buildErroneousTypeNotAPrefix(Identifier suffix) {
-    helper.addProblem(
-        templateUnresolvedPrefixInTypeAnnotation.withArguments(
-            name.name, suffix.name),
-        offsetForToken(token),
-        lengthOfSpan(token, suffix.token));
-    return const InvalidType();
-  }
-
-  @override
-  kernel.Expression buildError(Arguments arguments,
-      {bool isGetter: false, bool isSetter: false, int offset}) {
-    offset ??= offsetForToken(this.token);
-    return helper.throwNoSuchMethodError(
-        storeOffset(forest.literalNull(null), offset),
-        plainNameForRead,
-        arguments,
-        offset,
-        isGetter: isGetter,
-        isSetter: isSetter);
-  }
-}
-
-bool isFieldOrGetter(Member member) {
-  return member is Field || (member is Procedure && member.isGetter);
-}
diff --git a/pkg/front_end/lib/src/fasta/kernel/forest.dart b/pkg/front_end/lib/src/fasta/kernel/forest.dart
index c194492..99375a3 100644
--- a/pkg/front_end/lib/src/fasta/kernel/forest.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/forest.dart
@@ -7,6 +7,8 @@
 // TODO(ahe): Remove this import.
 import 'package:kernel/ast.dart' as kernel show Arguments, DartType;
 
+import 'body_builder.dart' show Identifier;
+
 /// A tree factory.
 ///
 /// For now, the [Location] is always a token.
@@ -91,7 +93,16 @@
   /// either adjacent strings or interpolated strings.
   Expression literalString(String value, Location location);
 
-  Expression literalSymbol(String value, Location location);
+  /// Return a representation of a symbol literal defined by the [hash] and the
+  /// list of [components]. The [value] is the string value of the symbol.
+  Expression literalSymbolMultiple(
+      String value, Location hash, List<Identifier> components);
+
+  /// Return a representation of a symbol literal defined by the [hash] and the
+  /// single [component]. The component can be either an [Identifier] or an
+  /// [Operator]. The [value] is the string value of the symbol.
+  Expression literalSymbolSingluar(
+      String value, Location hash, Object component);
 
   Expression literalType(covariant type, Location location);
 
@@ -124,6 +135,11 @@
 
   Expression awaitExpression(Expression operand, Location location);
 
+  /// Return a representation of a block of [statements] enclosed between the
+  /// [openBracket] and [closeBracket].
+  Statement block(
+      Location openBrace, List<Statement> statements, Location closeBrace);
+
   /// Return a representation of a conditional expression. The [condition] is
   /// the expression preceding the question mark. The [question] is the `?`. The
   /// [thenExpression] is the expression following the question mark. The
@@ -132,6 +148,26 @@
   Expression conditionalExpression(Expression condition, Location question,
       Expression thenExpression, Location colon, Expression elseExpression);
 
+  /// Return a representation of a do statement.
+  Statement doStatement(
+      Location doKeyword,
+      Statement body,
+      Location whileKeyword,
+      covariant Expression condition,
+      Location semicolon);
+
+  /// Return a representation of an expression statement composed from the
+  /// [expression] and [semicolon].
+  Statement expressionStatement(Expression expression, Location semicolon);
+
+  /// Return a representation of an empty statement consisting of the given
+  /// [semicolon].
+  Statement emptyStatement(Location semicolon);
+
+  /// Return a representation of an `if` statement.
+  Statement ifStatement(Location ifKeyword, covariant Expression condition,
+      Statement thenStatement, Location elseKeyword, Statement elseStatement);
+
   /// Return a representation of an `is` expression. The [operand] is the
   /// representation of the left operand. The [isOperator] is the `is` operator.
   /// The [notOperator] is either the `!` or `null` if the test is not negated.
@@ -141,12 +177,82 @@
 
   Expression notExpression(Expression operand, Location location);
 
+  /// Return a representation of a parenthesized condition consisting of the
+  /// given [expression] between the [leftParenthesis] and [rightParenthesis].
+  Object parenthesizedCondition(Location leftParenthesis, Expression expression,
+      Location rightParenthesis);
+
+  /// Return a representation of a rethrow statement consisting of the
+  /// [rethrowKeyword] followed by the [semicolon].
+  Statement rethrowStatement(Location rethrowKeyword, Location semicolon);
+
+  /// Return a representation of a return statement.
+  Statement returnStatement(
+      Location returnKeyword, Expression expression, Location semicolon);
+
   Expression stringConcatenationExpression(
       List<Expression> expressions, Location location);
 
+  /// The given [statement] is being used as the target of either a break or
+  /// continue statement. Return the statement that should be used as the actual
+  /// target.
+  Statement syntheticLabeledStatement(Statement statement);
+
   Expression thisExpression(Location location);
 
-  bool isErroneousNode(covariant node);
+  /// Return a representation of a throw expression consisting of the
+  /// [throwKeyword].
+  Expression throwExpression(Location throwKeyword, Expression expression);
+
+  /// Return a representation of a try statement. The statement is introduced by
+  /// the [tryKeyword] and the given [body]. If catch clauses were included,
+  /// then the [catchClauses] will represent them, otherwise it will be `null`.
+  /// Similarly, if a finally block was included, then the [finallyKeyword] and
+  /// [finallyBlock] will be non-`null`, otherwise both will be `null`. If there
+  /// was an error in some part of the try statement, then an [errorReplacement]
+  /// might be provided, in which case it could be returned instead of the
+  /// representation of the try statement.
+  Statement tryStatement(Location tryKeyword, Statement body,
+      covariant catchClauses, Location finallyKeyword, Statement finallyBlock);
+
+  Statement variablesDeclaration(covariant List declarations, Uri uri);
+
+  Object variablesDeclarationExtractDeclarations(
+      covariant Statement variablesDeclaration);
+
+  Statement wrapVariables(Statement statement);
+
+  /// Return a representation of a while statement introduced by the
+  /// [whileKeyword] and consisting of the given [condition] and [body].
+  Statement whileStatement(
+      Location whileKeyword, covariant Expression condition, Statement body);
+
+  /// Return a representation of a yield statement consisting of the
+  /// [yieldKeyword], [star], [expression], and [semicolon]. The [star] is null
+  /// when no star was included in the source code.
+  Statement yieldStatement(Location yieldKeyword, Location star,
+      Expression expression, Location semicolon);
+
+  bool isBlock(Object node);
+
+  bool isErroneousNode(Object node);
+
+  bool isThisExpression(Object node);
+
+  bool isVariablesDeclaration(Object node);
+
+  /// Record that the [user] (a break statement) is associated with the [target]
+  /// statement.
+  void resolveBreak(covariant Statement target, covariant Statement user);
+
+  /// Record that the [user] (a continue statement) is associated with the
+  /// [target] statement.
+  void resolveContinue(covariant Statement target, covariant Statement user);
+
+  /// Record that the [user] (a continue statement inside a switch case) is
+  /// associated with the [target] statement.
+  void resolveContinueInSwitch(
+      covariant Object target, covariant Statement user);
 
   // TODO(ahe): Remove this method when all users are moved here.
   kernel.Arguments castArguments(Arguments arguments) {
diff --git a/pkg/front_end/lib/src/fasta/kernel/frontend_accessors.dart b/pkg/front_end/lib/src/fasta/kernel/frontend_accessors.dart
deleted file mode 100644
index e44e72d..0000000
--- a/pkg/front_end/lib/src/fasta/kernel/frontend_accessors.dart
+++ /dev/null
@@ -1,816 +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.
-
-/// A library to help transform compounds and null-aware accessors into
-/// let expressions.
-
-import 'package:kernel/ast.dart' hide MethodInvocation, InvalidExpression;
-
-import '../../scanner/token.dart' show Token;
-
-import '../names.dart' show equalsName, indexGetName, indexSetName;
-
-import '../parser.dart' show offsetForToken;
-
-import '../problems.dart' show unhandled;
-
-import 'fasta_accessors.dart' show BuilderHelper;
-
-import 'kernel_builder.dart' show LoadLibraryBuilder, PrefixBuilder;
-
-import 'kernel_shadow_ast.dart'
-    show
-        ShadowArguments,
-        ShadowComplexAssignment,
-        ShadowConditionalExpression,
-        ShadowIllegalAssignment,
-        ShadowMethodInvocation,
-        ShadowNullAwarePropertyGet,
-        ShadowPropertyAssign,
-        ShadowPropertyGet,
-        ShadowSuperMethodInvocation,
-        ShadowSuperPropertyGet,
-        ShadowThisExpression,
-        ShadowVariableDeclaration,
-        ShadowVariableGet;
-
-/// An [Accessor] represents a subexpression for which we can't yet build a
-/// kernel [Expression] because we don't yet know the context in which it is
-/// used.
-///
-/// Once the context is known, an [Accessor] can be converted into an
-/// [Expression] by calling a "build" method.
-///
-/// For example, when building a kernel representation for `a[x] = b`, after
-/// parsing `a[x]` but before parsing `= b`, we don't yet know whether to
-/// generate an invocation of `operator[]` or `operator[]=`, so we generate an
-/// [Accessor] object.  Later, after `= b` is parsed, [buildAssignment] will be
-/// called.
-abstract class Accessor<Arguments> {
-  final BuilderHelper helper;
-  final Token token;
-
-  Accessor(this.helper, this.token);
-
-  /// Builds an [Expression] representing a read from the accessor.
-  Expression buildSimpleRead() {
-    return _finish(_makeSimpleRead(), null);
-  }
-
-  /// Builds an [Expression] representing an assignment with the accessor on
-  /// the LHS and [value] on the RHS.
-  ///
-  /// The returned expression evaluates to the assigned value, unless
-  /// [voidContext] is true, in which case it may evaluate to anything.
-  Expression buildAssignment(Expression value, {bool voidContext: false}) {
-    var complexAssignment = startComplexAssignment(value);
-    return _finish(_makeSimpleWrite(value, voidContext, complexAssignment),
-        complexAssignment);
-  }
-
-  /// Returns an [Expression] representing a null-aware assignment (`??=`) with
-  /// the accessor on the LHS and [value] on the RHS.
-  ///
-  /// The returned expression evaluates to the assigned value, unless
-  /// [voidContext] is true, in which case it may evaluate to anything.
-  ///
-  /// [type] is the static type of the RHS.
-  Expression buildNullAwareAssignment(
-      Expression value, DartType type, int offset,
-      {bool voidContext: false}) {
-    var complexAssignment = startComplexAssignment(value);
-    if (voidContext) {
-      var nullAwareCombiner = new ShadowConditionalExpression(
-          buildIsNull(_makeRead(complexAssignment), offset),
-          _makeWrite(value, false, complexAssignment),
-          new NullLiteral());
-      complexAssignment?.nullAwareCombiner = nullAwareCombiner;
-      return _finish(nullAwareCombiner, complexAssignment);
-    }
-    var tmp = new VariableDeclaration.forValue(_makeRead(complexAssignment));
-    var nullAwareCombiner = new ShadowConditionalExpression(
-        buildIsNull(new VariableGet(tmp), offset),
-        _makeWrite(value, false, complexAssignment),
-        new VariableGet(tmp));
-    complexAssignment?.nullAwareCombiner = nullAwareCombiner;
-    return _finish(makeLet(tmp, nullAwareCombiner), complexAssignment);
-  }
-
-  /// Returns an [Expression] representing a compound assignment (e.g. `+=`)
-  /// with the accessor on the LHS and [value] on the RHS.
-  Expression buildCompoundAssignment(Name binaryOperator, Expression value,
-      {int offset: TreeNode.noOffset,
-      bool voidContext: false,
-      Procedure interfaceTarget,
-      bool isPreIncDec: false}) {
-    var complexAssignment = startComplexAssignment(value);
-    complexAssignment?.isPreIncDec = isPreIncDec;
-    var combiner = makeBinary(
-        _makeRead(complexAssignment), binaryOperator, interfaceTarget, value,
-        offset: offset);
-    complexAssignment?.combiner = combiner;
-    return _finish(_makeWrite(combiner, voidContext, complexAssignment),
-        complexAssignment);
-  }
-
-  /// Returns an [Expression] representing a pre-increment or pre-decrement
-  /// of the accessor.
-  Expression buildPrefixIncrement(Name binaryOperator,
-      {int offset: TreeNode.noOffset,
-      bool voidContext: false,
-      Procedure interfaceTarget}) {
-    return buildCompoundAssignment(binaryOperator, new IntLiteral(1),
-        offset: offset,
-        voidContext: voidContext,
-        interfaceTarget: interfaceTarget,
-        isPreIncDec: true);
-  }
-
-  /// Returns an [Expression] representing a post-increment or post-decrement
-  /// of the accessor.
-  Expression buildPostfixIncrement(Name binaryOperator,
-      {int offset: TreeNode.noOffset,
-      bool voidContext: false,
-      Procedure interfaceTarget}) {
-    if (voidContext) {
-      return buildPrefixIncrement(binaryOperator,
-          offset: offset, voidContext: true, interfaceTarget: interfaceTarget);
-    }
-    var rhs = new IntLiteral(1);
-    var complexAssignment = startComplexAssignment(rhs);
-    var value = new VariableDeclaration.forValue(_makeRead(complexAssignment));
-    valueAccess() => new VariableGet(value);
-    var combiner = makeBinary(
-        valueAccess(), binaryOperator, interfaceTarget, rhs,
-        offset: offset);
-    complexAssignment?.combiner = combiner;
-    complexAssignment?.isPostIncDec = true;
-    var dummy = new ShadowVariableDeclaration.forValue(
-        _makeWrite(combiner, true, complexAssignment),
-        helper.functionNestingLevel);
-    return _finish(
-        makeLet(value, makeLet(dummy, valueAccess())), complexAssignment);
-  }
-
-  Expression _makeSimpleRead() => _makeRead(null);
-
-  Expression _makeSimpleWrite(Expression value, bool voidContext,
-      ShadowComplexAssignment complexAssignment) {
-    return _makeWrite(value, voidContext, complexAssignment);
-  }
-
-  Expression _makeRead(ShadowComplexAssignment complexAssignment);
-
-  Expression _makeWrite(Expression value, bool voidContext,
-      ShadowComplexAssignment complexAssignment);
-
-  Expression _finish(
-      Expression body, ShadowComplexAssignment complexAssignment) {
-    if (complexAssignment != null) {
-      complexAssignment.desugared = body;
-      return complexAssignment;
-    } else {
-      return body;
-    }
-  }
-
-  /// Returns an [Expression] representing a compile-time error.
-  ///
-  /// At runtime, an exception will be thrown.
-  makeInvalidRead() {
-    return unhandled("compile-time error", "$runtimeType",
-        offsetForToken(token), helper.uri);
-  }
-
-  /// Returns an [Expression] representing a compile-time error wrapping
-  /// [value].
-  ///
-  /// At runtime, [value] will be evaluated before throwing an exception.
-  makeInvalidWrite(Expression value) {
-    return unhandled("compile-time error", "$runtimeType",
-        offsetForToken(token), helper.uri);
-  }
-
-  /// Creates a data structure for tracking the desugaring of a complex
-  /// assignment expression whose right hand side is [rhs].
-  ShadowComplexAssignment startComplexAssignment(Expression rhs) =>
-      new ShadowIllegalAssignment(rhs);
-}
-
-abstract class VariableAccessor<Arguments> extends Accessor<Arguments> {
-  VariableDeclaration variable;
-  DartType promotedType;
-
-  VariableAccessor(
-      BuilderHelper helper, this.variable, this.promotedType, Token token)
-      : super(helper, token);
-
-  Expression _makeRead(ShadowComplexAssignment complexAssignment) {
-    var fact = helper.typePromoter
-        .getFactForAccess(variable, helper.functionNestingLevel);
-    var scope = helper.typePromoter.currentScope;
-    var read = new ShadowVariableGet(variable, fact, scope)
-      ..fileOffset = offsetForToken(token);
-    complexAssignment?.read = read;
-    return read;
-  }
-
-  Expression _makeWrite(Expression value, bool voidContext,
-      ShadowComplexAssignment 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;
-    return write;
-  }
-}
-
-class PropertyAccessor<Arguments> extends Accessor<Arguments> {
-  VariableDeclaration _receiverVariable;
-  Expression receiver;
-  Name name;
-  Member getter, setter;
-
-  static Accessor make(BuilderHelper helper, Expression receiver, Name name,
-      Member getter, Member setter,
-      {Token token}) {
-    if (receiver is ThisExpression) {
-      return new ThisPropertyAccessor(helper, name, getter, setter, token);
-    } else {
-      return new PropertyAccessor.internal(
-          helper, receiver, name, getter, setter, token);
-    }
-  }
-
-  PropertyAccessor.internal(BuilderHelper helper, this.receiver, this.name,
-      this.getter, this.setter, Token token)
-      : super(helper, token);
-
-  Expression _makeSimpleRead() => new ShadowPropertyGet(receiver, name, getter)
-    ..fileOffset = offsetForToken(token);
-
-  Expression _makeSimpleWrite(Expression value, bool voidContext,
-      ShadowComplexAssignment complexAssignment) {
-    var write = new PropertySet(receiver, name, value, setter)
-      ..fileOffset = offsetForToken(token);
-    complexAssignment?.write = write;
-    return write;
-  }
-
-  receiverAccess() {
-    _receiverVariable ??= new VariableDeclaration.forValue(receiver);
-    return new VariableGet(_receiverVariable)
-      ..fileOffset = offsetForToken(token);
-  }
-
-  Expression _makeRead(ShadowComplexAssignment complexAssignment) {
-    var read = new ShadowPropertyGet(receiverAccess(), name, getter)
-      ..fileOffset = offsetForToken(token);
-    complexAssignment?.read = read;
-    return read;
-  }
-
-  Expression _makeWrite(Expression value, bool voidContext,
-      ShadowComplexAssignment complexAssignment) {
-    var write = new PropertySet(receiverAccess(), name, value, setter)
-      ..fileOffset = offsetForToken(token);
-    complexAssignment?.write = write;
-    return write;
-  }
-
-  Expression _finish(
-      Expression body, ShadowComplexAssignment complexAssignment) {
-    return super._finish(makeLet(_receiverVariable, body), complexAssignment);
-  }
-}
-
-/// Special case of [PropertyAccessor] to avoid creating an indirect access to
-/// 'this'.
-class ThisPropertyAccessor<Arguments> extends Accessor<Arguments> {
-  Name name;
-  Member getter, setter;
-
-  ThisPropertyAccessor(
-      BuilderHelper helper, this.name, this.getter, this.setter, Token token)
-      : super(helper, token);
-
-  Expression _makeRead(ShadowComplexAssignment complexAssignment) {
-    if (getter == null) {
-      helper.warnUnresolvedGet(name, offsetForToken(token));
-    }
-    var read = new ShadowPropertyGet(new ShadowThisExpression(), name, getter)
-      ..fileOffset = offsetForToken(token);
-    complexAssignment?.read = read;
-    return read;
-  }
-
-  Expression _makeWrite(Expression value, bool voidContext,
-      ShadowComplexAssignment complexAssignment) {
-    if (setter == null) {
-      helper.warnUnresolvedSet(name, offsetForToken(token));
-    }
-    var write = new PropertySet(new ShadowThisExpression(), name, value, setter)
-      ..fileOffset = offsetForToken(token);
-    complexAssignment?.write = write;
-    return write;
-  }
-}
-
-class NullAwarePropertyAccessor<Arguments> extends Accessor<Arguments> {
-  VariableDeclaration receiver;
-  Expression receiverExpression;
-  Name name;
-  Member getter, setter;
-  DartType type;
-
-  NullAwarePropertyAccessor(BuilderHelper helper, this.receiverExpression,
-      this.name, this.getter, this.setter, this.type, Token token)
-      : this.receiver = makeOrReuseVariable(receiverExpression),
-        super(helper, token);
-
-  receiverAccess() => new VariableGet(receiver);
-
-  Expression _makeRead(ShadowComplexAssignment complexAssignment) {
-    var read = new ShadowPropertyGet(receiverAccess(), name, getter)
-      ..fileOffset = offsetForToken(token);
-    complexAssignment?.read = read;
-    return read;
-  }
-
-  Expression _makeWrite(Expression value, bool voidContext,
-      ShadowComplexAssignment complexAssignment) {
-    var write = new PropertySet(receiverAccess(), name, value, setter)
-      ..fileOffset = offsetForToken(token);
-    complexAssignment?.write = write;
-    return write;
-  }
-
-  Expression _finish(
-      Expression body, ShadowComplexAssignment complexAssignment) {
-    var offset = offsetForToken(token);
-    var nullAwareGuard = new ConditionalExpression(
-        buildIsNull(receiverAccess(), offset), new NullLiteral(), body, null)
-      ..fileOffset = offset;
-    if (complexAssignment != null) {
-      body = makeLet(receiver, nullAwareGuard);
-      ShadowPropertyAssign kernelPropertyAssign = complexAssignment;
-      kernelPropertyAssign.nullAwareGuard = nullAwareGuard;
-      kernelPropertyAssign.desugared = body;
-      return kernelPropertyAssign;
-    } else {
-      return new ShadowNullAwarePropertyGet(receiver, nullAwareGuard)
-        ..fileOffset = offset;
-    }
-  }
-}
-
-class SuperPropertyAccessor<Arguments> extends Accessor<Arguments> {
-  Name name;
-  Member getter, setter;
-
-  SuperPropertyAccessor(
-      BuilderHelper helper, this.name, this.getter, this.setter, Token token)
-      : super(helper, token);
-
-  Expression _makeRead(ShadowComplexAssignment complexAssignment) {
-    if (getter == null) {
-      helper.warnUnresolvedGet(name, offsetForToken(token), isSuper: true);
-    }
-    // TODO(ahe): Use [DirectPropertyGet] when possible.
-    var read = new ShadowSuperPropertyGet(name, getter)
-      ..fileOffset = offsetForToken(token);
-    complexAssignment?.read = read;
-    return read;
-  }
-
-  Expression _makeWrite(Expression value, bool voidContext,
-      ShadowComplexAssignment complexAssignment) {
-    if (setter == null) {
-      helper.warnUnresolvedSet(name, offsetForToken(token), isSuper: true);
-    }
-    // TODO(ahe): Use [DirectPropertySet] when possible.
-    var write = new SuperPropertySet(name, value, setter)
-      ..fileOffset = offsetForToken(token);
-    complexAssignment?.write = write;
-    return write;
-  }
-}
-
-class IndexAccessor<Arguments> extends Accessor<Arguments> {
-  Expression receiver;
-  Expression index;
-  VariableDeclaration receiverVariable;
-  VariableDeclaration indexVariable;
-  Procedure getter, setter;
-
-  static Accessor make(BuilderHelper helper, Expression receiver,
-      Expression index, Procedure getter, Procedure setter,
-      {Token token}) {
-    if (receiver is ThisExpression) {
-      return new ThisIndexAccessor(helper, index, getter, setter, token);
-    } else {
-      return new IndexAccessor.internal(
-          helper, receiver, index, getter, setter, token);
-    }
-  }
-
-  IndexAccessor.internal(BuilderHelper helper, this.receiver, this.index,
-      this.getter, this.setter, Token token)
-      : super(helper, token);
-
-  Expression _makeSimpleRead() {
-    var read = new ShadowMethodInvocation(
-        receiver, indexGetName, new ShadowArguments(<Expression>[index]),
-        interfaceTarget: getter)
-      ..fileOffset = offsetForToken(token);
-    return read;
-  }
-
-  Expression _makeSimpleWrite(Expression value, bool voidContext,
-      ShadowComplexAssignment complexAssignment) {
-    if (!voidContext) return _makeWriteAndReturn(value, complexAssignment);
-    var write = new ShadowMethodInvocation(
-        receiver, indexSetName, new ShadowArguments(<Expression>[index, value]),
-        interfaceTarget: setter)
-      ..fileOffset = offsetForToken(token);
-    complexAssignment?.write = write;
-    return write;
-  }
-
-  receiverAccess() {
-    // We cannot reuse the receiver if it is a variable since it might be
-    // reassigned in the index expression.
-    receiverVariable ??= new VariableDeclaration.forValue(receiver);
-    return new VariableGet(receiverVariable)
-      ..fileOffset = offsetForToken(token);
-  }
-
-  indexAccess() {
-    indexVariable ??= new VariableDeclaration.forValue(index);
-    return new VariableGet(indexVariable)..fileOffset = offsetForToken(token);
-  }
-
-  Expression _makeRead(ShadowComplexAssignment complexAssignment) {
-    var read = new ShadowMethodInvocation(receiverAccess(), indexGetName,
-        new ShadowArguments(<Expression>[indexAccess()]),
-        interfaceTarget: getter)
-      ..fileOffset = offsetForToken(token);
-    complexAssignment?.read = read;
-    return read;
-  }
-
-  Expression _makeWrite(Expression value, bool voidContext,
-      ShadowComplexAssignment complexAssignment) {
-    if (!voidContext) return _makeWriteAndReturn(value, complexAssignment);
-    var write = new ShadowMethodInvocation(receiverAccess(), indexSetName,
-        new ShadowArguments(<Expression>[indexAccess(), value]),
-        interfaceTarget: setter)
-      ..fileOffset = offsetForToken(token);
-    complexAssignment?.write = write;
-    return write;
-  }
-
-  // TODO(dmitryas): remove this method after the "[]=" operator of the Context
-  // class is made to return a value.
-  _makeWriteAndReturn(
-      Expression value, ShadowComplexAssignment complexAssignment) {
-    // The call to []= does not return the value like direct-style assignments
-    // do.  We need to bind the value in a let.
-    var valueVariable = new VariableDeclaration.forValue(value);
-    var write = new ShadowMethodInvocation(
-        receiverAccess(),
-        indexSetName,
-        new ShadowArguments(
-            <Expression>[indexAccess(), new VariableGet(valueVariable)]),
-        interfaceTarget: setter)
-      ..fileOffset = offsetForToken(token);
-    complexAssignment?.write = write;
-    var dummy = new ShadowVariableDeclaration.forValue(
-        write, helper.functionNestingLevel);
-    return makeLet(
-        valueVariable, makeLet(dummy, new VariableGet(valueVariable)));
-  }
-
-  Expression _finish(
-      Expression body, ShadowComplexAssignment complexAssignment) {
-    return super._finish(
-        makeLet(receiverVariable, makeLet(indexVariable, body)),
-        complexAssignment);
-  }
-}
-
-/// Special case of [IndexAccessor] to avoid creating an indirect access to
-/// 'this'.
-class ThisIndexAccessor<Arguments> extends Accessor<Arguments> {
-  Expression index;
-  VariableDeclaration indexVariable;
-  Procedure getter, setter;
-
-  ThisIndexAccessor(
-      BuilderHelper helper, this.index, this.getter, this.setter, Token token)
-      : super(helper, token);
-
-  Expression _makeSimpleRead() {
-    return new ShadowMethodInvocation(new ShadowThisExpression(), indexGetName,
-        new ShadowArguments(<Expression>[index]),
-        interfaceTarget: getter)
-      ..fileOffset = offsetForToken(token);
-  }
-
-  Expression _makeSimpleWrite(Expression value, bool voidContext,
-      ShadowComplexAssignment complexAssignment) {
-    if (!voidContext) return _makeWriteAndReturn(value, complexAssignment);
-    var write = new ShadowMethodInvocation(new ShadowThisExpression(),
-        indexSetName, new ShadowArguments(<Expression>[index, value]),
-        interfaceTarget: setter)
-      ..fileOffset = offsetForToken(token);
-    complexAssignment?.write = write;
-    return write;
-  }
-
-  indexAccess() {
-    indexVariable ??= new VariableDeclaration.forValue(index);
-    return new VariableGet(indexVariable);
-  }
-
-  Expression _makeRead(ShadowComplexAssignment complexAssignment) {
-    var read = new ShadowMethodInvocation(new ShadowThisExpression(),
-        indexGetName, new ShadowArguments(<Expression>[indexAccess()]),
-        interfaceTarget: getter)
-      ..fileOffset = offsetForToken(token);
-    complexAssignment?.read = read;
-    return read;
-  }
-
-  Expression _makeWrite(Expression value, bool voidContext,
-      ShadowComplexAssignment complexAssignment) {
-    if (!voidContext) return _makeWriteAndReturn(value, complexAssignment);
-    var write = new ShadowMethodInvocation(new ShadowThisExpression(),
-        indexSetName, new ShadowArguments(<Expression>[indexAccess(), value]),
-        interfaceTarget: setter)
-      ..fileOffset = offsetForToken(token);
-    complexAssignment?.write = write;
-    return write;
-  }
-
-  _makeWriteAndReturn(
-      Expression value, ShadowComplexAssignment complexAssignment) {
-    var valueVariable = new VariableDeclaration.forValue(value);
-    var write = new ShadowMethodInvocation(
-        new ShadowThisExpression(),
-        indexSetName,
-        new ShadowArguments(
-            <Expression>[indexAccess(), new VariableGet(valueVariable)]),
-        interfaceTarget: setter)
-      ..fileOffset = offsetForToken(token);
-    complexAssignment?.write = write;
-    var dummy = new VariableDeclaration.forValue(write);
-    return makeLet(
-        valueVariable, makeLet(dummy, new VariableGet(valueVariable)));
-  }
-
-  Expression _finish(
-      Expression body, ShadowComplexAssignment complexAssignment) {
-    return super._finish(makeLet(indexVariable, body), complexAssignment);
-  }
-}
-
-class SuperIndexAccessor<Arguments> extends Accessor<Arguments> {
-  Expression index;
-  VariableDeclaration indexVariable;
-  Member getter, setter;
-
-  SuperIndexAccessor(
-      BuilderHelper helper, this.index, this.getter, this.setter, Token token)
-      : super(helper, token);
-
-  indexAccess() {
-    indexVariable ??= new VariableDeclaration.forValue(index);
-    return new VariableGet(indexVariable);
-  }
-
-  Expression _makeSimpleRead() {
-    if (getter == null) {
-      helper.warnUnresolvedMethod(indexGetName, offsetForToken(token),
-          isSuper: true);
-    }
-    // TODO(ahe): Use [DirectMethodInvocation] when possible.
-    return new ShadowSuperMethodInvocation(
-        indexGetName, new ShadowArguments(<Expression>[index]), getter)
-      ..fileOffset = offsetForToken(token);
-  }
-
-  Expression _makeSimpleWrite(Expression value, bool voidContext,
-      ShadowComplexAssignment complexAssignment) {
-    if (!voidContext) return _makeWriteAndReturn(value, complexAssignment);
-    if (setter == null) {
-      helper.warnUnresolvedMethod(indexSetName, offsetForToken(token),
-          isSuper: true);
-    }
-    var write = new SuperMethodInvocation(
-        indexSetName, new ShadowArguments(<Expression>[index, value]), setter)
-      ..fileOffset = offsetForToken(token);
-    complexAssignment?.write = write;
-    return write;
-  }
-
-  Expression _makeRead(ShadowComplexAssignment complexAssignment) {
-    if (getter == null) {
-      helper.warnUnresolvedMethod(indexGetName, offsetForToken(token),
-          isSuper: true);
-    }
-    var read = new SuperMethodInvocation(
-        indexGetName, new ShadowArguments(<Expression>[indexAccess()]), getter)
-      ..fileOffset = offsetForToken(token);
-    complexAssignment?.read = read;
-    return read;
-  }
-
-  Expression _makeWrite(Expression value, bool voidContext,
-      ShadowComplexAssignment complexAssignment) {
-    if (!voidContext) return _makeWriteAndReturn(value, complexAssignment);
-    if (setter == null) {
-      helper.warnUnresolvedMethod(indexSetName, offsetForToken(token),
-          isSuper: true);
-    }
-    var write = new SuperMethodInvocation(indexSetName,
-        new ShadowArguments(<Expression>[indexAccess(), value]), setter)
-      ..fileOffset = offsetForToken(token);
-    complexAssignment?.write = write;
-    return write;
-  }
-
-  _makeWriteAndReturn(
-      Expression value, ShadowComplexAssignment complexAssignment) {
-    var valueVariable = new VariableDeclaration.forValue(value);
-    if (setter == null) {
-      helper.warnUnresolvedMethod(indexSetName, offsetForToken(token),
-          isSuper: true);
-    }
-    var write = new SuperMethodInvocation(
-        indexSetName,
-        new ShadowArguments(
-            <Expression>[indexAccess(), new VariableGet(valueVariable)]),
-        setter)
-      ..fileOffset = offsetForToken(token);
-    complexAssignment?.write = write;
-    var dummy = new VariableDeclaration.forValue(write);
-    return makeLet(
-        valueVariable, makeLet(dummy, new VariableGet(valueVariable)));
-  }
-
-  Expression _finish(
-      Expression body, ShadowComplexAssignment complexAssignment) {
-    return super._finish(makeLet(indexVariable, body), complexAssignment);
-  }
-}
-
-class StaticAccessor<Arguments> extends Accessor<Arguments> {
-  Member readTarget;
-  Member writeTarget;
-
-  StaticAccessor(
-      BuilderHelper helper, this.readTarget, this.writeTarget, Token token)
-      : super(helper, token);
-
-  Expression _makeRead(ShadowComplexAssignment complexAssignment) {
-    if (readTarget == null) {
-      return makeInvalidRead();
-    } else {
-      var read = helper.makeStaticGet(readTarget, token);
-      complexAssignment?.read = read;
-      return read;
-    }
-  }
-
-  Expression _makeWrite(Expression value, bool voidContext,
-      ShadowComplexAssignment complexAssignment) {
-    Expression write;
-    if (writeTarget == null) {
-      write = makeInvalidWrite(value);
-    } else {
-      write = new StaticSet(writeTarget, value);
-      complexAssignment?.write = write;
-    }
-    write.fileOffset = offsetForToken(token);
-    return write;
-  }
-}
-
-abstract class LoadLibraryAccessor<Arguments> extends Accessor<Arguments> {
-  final LoadLibraryBuilder builder;
-
-  LoadLibraryAccessor(BuilderHelper helper, Token token, this.builder)
-      : super(helper, token);
-
-  Expression _makeRead(ShadowComplexAssignment complexAssignment) {
-    var read =
-        helper.makeStaticGet(builder.createTearoffMethod(helper.forest), token);
-    complexAssignment?.read = read;
-    return read;
-  }
-
-  Expression _makeWrite(Expression value, bool voidContext,
-      ShadowComplexAssignment complexAssignment) {
-    Expression write = makeInvalidWrite(value);
-    write.fileOffset = offsetForToken(token);
-    return write;
-  }
-}
-
-abstract class DeferredAccessor<Arguments> extends Accessor<Arguments> {
-  final PrefixBuilder builder;
-  final Accessor accessor;
-
-  DeferredAccessor(
-      BuilderHelper helper, Token token, this.builder, this.accessor)
-      : super(helper, token);
-
-  Expression _makeSimpleRead() {
-    return helper.wrapInDeferredCheck(
-        accessor._makeSimpleRead(), builder, token.charOffset);
-  }
-
-  Expression _makeRead(ShadowComplexAssignment complexAssignment) {
-    return helper.wrapInDeferredCheck(
-        accessor._makeRead(complexAssignment), builder, token.charOffset);
-  }
-
-  Expression _makeWrite(Expression value, bool voidContext,
-      ShadowComplexAssignment complexAssignment) {
-    return helper.wrapInDeferredCheck(
-        accessor._makeWrite(value, voidContext, complexAssignment),
-        builder,
-        token.charOffset);
-  }
-}
-
-class ReadOnlyAccessor<Arguments> extends Accessor<Arguments> {
-  Expression expression;
-  VariableDeclaration value;
-
-  ReadOnlyAccessor(BuilderHelper helper, this.expression, Token token)
-      : super(helper, token);
-
-  Expression _makeSimpleRead() => expression;
-
-  Expression _makeRead(ShadowComplexAssignment complexAssignment) {
-    value ??= new VariableDeclaration.forValue(expression);
-    return new VariableGet(value);
-  }
-
-  Expression _makeWrite(Expression value, bool voidContext,
-      ShadowComplexAssignment complexAssignment) {
-    var write = makeInvalidWrite(value);
-    complexAssignment?.write = write;
-    return write;
-  }
-
-  Expression _finish(
-          Expression body, ShadowComplexAssignment complexAssignment) =>
-      super._finish(makeLet(value, body), complexAssignment);
-}
-
-abstract class DelayedErrorAccessor<Arguments> extends Accessor<Arguments> {
-  DelayedErrorAccessor(BuilderHelper helper, Token token)
-      : super(helper, token);
-
-  Expression buildError();
-
-  Expression _makeSimpleRead() => buildError();
-  Expression _makeSimpleWrite(Expression value, bool voidContext,
-          ShadowComplexAssignment complexAssignment) =>
-      buildError();
-  Expression _makeRead(ShadowComplexAssignment complexAssignment) =>
-      buildError();
-  Expression _makeWrite(Expression value, bool voidContext,
-          ShadowComplexAssignment complexAssignment) =>
-      buildError();
-}
-
-Expression makeLet(VariableDeclaration variable, Expression body) {
-  if (variable == null) return body;
-  return new Let(variable, body);
-}
-
-Expression makeBinary(
-    Expression left, Name operator, Procedure interfaceTarget, Expression right,
-    {int offset: TreeNode.noOffset}) {
-  return new ShadowMethodInvocation(
-      left, operator, new ShadowArguments(<Expression>[right]),
-      interfaceTarget: interfaceTarget)
-    ..fileOffset = offset;
-}
-
-Expression buildIsNull(Expression value, int offset) {
-  return makeBinary(value, equalsName, null, new NullLiteral(), offset: offset);
-}
-
-VariableDeclaration makeOrReuseVariable(Expression value) {
-  // TODO: Devise a way to remember if a variable declaration was reused
-  // or is fresh (hence needs a let binding).
-  return new VariableDeclaration.forValue(value);
-}
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_api.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_api.dart
index 7d5877f..e48156c 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_api.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_api.dart
@@ -14,3 +14,35 @@
 export 'package:kernel/core_types.dart' show CoreTypes;
 
 export 'package:kernel/transformations/flags.dart' show TransformerFlag;
+
+export 'package:kernel/text/ast_to_text.dart' show NameSystem;
+
+import 'package:kernel/text/ast_to_text.dart' show NameSystem, Printer;
+
+import 'package:kernel/ast.dart' show Class, Member, Node;
+
+void printNodeOn(Node node, StringSink sink, {NameSystem syntheticNames}) {
+  if (node == null) {
+    sink.write("null");
+  } else {
+    syntheticNames ??= new NameSystem();
+    new Printer(sink, syntheticNames: syntheticNames).writeNode(node);
+  }
+}
+
+void printQualifiedNameOn(Member member, StringSink sink,
+    {NameSystem syntheticNames}) {
+  if (member == null) {
+    sink.write("null");
+  } else {
+    syntheticNames ??= new NameSystem();
+    sink.write(member.enclosingLibrary.importUri);
+    sink.write("::");
+    Class cls = member.enclosingClass;
+    if (cls != null) {
+      sink.write(cls.name ?? syntheticNames.nameClass(cls));
+      sink.write("::");
+    }
+    sink.write(member.name?.name ?? syntheticNames.nameMember(member));
+  }
+}
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_ast_api.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_ast_api.dart
index b2cad0c..6817deb 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_ast_api.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_ast_api.dart
@@ -15,7 +15,6 @@
         Catch,
         CheckLibraryIsLoaded,
         Class,
-        ConditionalExpression,
         Constructor,
         ConstructorInvocation,
         ContinueSwitchStatement,
@@ -39,23 +38,27 @@
         Name,
         NamedExpression,
         NamedType,
+        Node,
         Procedure,
         ProcedureKind,
+        PropertySet,
         Rethrow,
         ReturnStatement,
         Statement,
         StaticGet,
-        StaticInvocation,
+        StaticSet,
         StringConcatenation,
         SuperInitializer,
+        SuperMethodInvocation,
+        SuperPropertySet,
         SwitchCase,
-        ThisExpression,
         Throw,
         TreeNode,
         TypeParameter,
         TypeParameterType,
         VariableDeclaration,
         VariableGet,
+        VariableSet,
         VoidType,
         setParents;
 
@@ -63,14 +66,12 @@
     show
         ShadowAssertInitializer,
         ShadowAssertStatement,
-        ShadowBlock,
         ShadowBreakStatement,
         ShadowCascadeExpression,
         ShadowComplexAssignment,
         ShadowConstructorInvocation,
         ShadowContinueSwitchStatement,
         ShadowDeferredCheck,
-        ShadowDoStatement,
         ShadowExpressionStatement,
         ShadowFactoryConstructorInvocation,
         ShadowFieldInitializer,
@@ -89,9 +90,10 @@
         ShadowMethodInvocation,
         ShadowNamedFunctionExpression,
         ShadowNullAwareMethodInvocation,
+        ShadowNullAwarePropertyGet,
         ShadowPropertyAssign,
+        ShadowPropertyGet,
         ShadowRedirectingInitializer,
-        ShadowRethrow,
         ShadowReturnStatement,
         ShadowStaticAssignment,
         ShadowStaticGet,
@@ -101,11 +103,7 @@
         ShadowSuperPropertyGet,
         ShadowSwitchStatement,
         ShadowSyntheticExpression,
-        ShadowThrow,
-        ShadowTryCatch,
-        ShadowTryFinally,
         ShadowVariableAssignment,
         ShadowVariableDeclaration,
         ShadowVariableGet,
-        ShadowWhileStatement,
         ShadowYieldStatement;
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_body_builder.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_body_builder.dart
index e825cf4..f2ff3b6 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_body_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_body_builder.dart
@@ -39,4 +39,9 @@
       TypeInferrer typeInferrer)
       : super(library, member, scope, formalParameterScope, hierarchy,
             coreTypes, classBuilder, isInstanceMember, uri, typeInferrer);
+
+  @override
+  void enterThenForTypePromotion(Expression condition) {
+    typePromoter.enterThen(condition);
+  }
 }
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 884971a..7272014 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
@@ -8,21 +8,27 @@
     show
         Class,
         Constructor,
+        ThisExpression,
         DartType,
         DynamicType,
         Expression,
         Field,
         FunctionNode,
         InterfaceType,
+        AsExpression,
         ListLiteral,
         Member,
         Name,
         Procedure,
+        ReturnStatement,
+        VoidType,
+        MethodInvocation,
         ProcedureKind,
         StaticGet,
         Supertype,
         TypeParameter,
         TypeParameterType,
+        Arguments,
         VariableDeclaration;
 
 import 'package:kernel/class_hierarchy.dart' show ClassHierarchy;
@@ -84,6 +90,8 @@
 
 import 'redirecting_factory_body.dart' show RedirectingFactoryBody;
 
+import 'kernel_target.dart' show KernelTarget;
+
 abstract class KernelClassBuilder
     extends ClassBuilder<KernelTypeBuilder, InterfaceType> {
   KernelClassBuilder actualOrigin;
@@ -382,20 +390,48 @@
         noSuchMethod.enclosingClass.superclass != null;
   }
 
-  void addNoSuchMethodForwarderForProcedure(
-      Procedure procedure, ClassHierarchy hierarchy) {
+  void transformProcedureToNoSuchMethodForwarder(
+      Member noSuchMethodInterface, KernelTarget target, Procedure procedure) {
+    String prefix =
+        procedure.isGetter ? 'get:' : procedure.isSetter ? 'set:' : '';
+    Expression invocation = target.backendTarget.instantiateInvocation(
+        target.loader.coreTypes,
+        new ThisExpression(),
+        prefix + procedure.name.name,
+        new Arguments.forwarded(procedure.function),
+        procedure.fileOffset,
+        /*isSuper=*/ false);
+    Expression result = new MethodInvocation(new ThisExpression(),
+        noSuchMethodName, new Arguments([invocation]), noSuchMethodInterface)
+      ..fileOffset = procedure.fileOffset;
+    if (procedure.function.returnType is! VoidType) {
+      result = new AsExpression(result, procedure.function.returnType)
+        ..isTypeError = true
+        ..fileOffset = procedure.fileOffset;
+    }
+    procedure.function.body = new ReturnStatement(result)
+      ..fileOffset = procedure.fileOffset;
+    procedure.function.body.parent = procedure.function;
+
+    procedure.isAbstract = false;
+    procedure.isNoSuchMethodForwarder = true;
+    procedure.isForwardingStub = false;
+    procedure.isForwardingSemiStub = false;
+  }
+
+  void addNoSuchMethodForwarderForProcedure(Member noSuchMethod,
+      KernelTarget target, Procedure procedure, ClassHierarchy hierarchy) {
     CloneWithoutBody cloner = new CloneWithoutBody(
         typeSubstitution: getSubstitutionMap(
             hierarchy.getClassAsInstanceOf(cls, procedure.enclosingClass)));
     Procedure cloned = cloner.clone(procedure);
-    cloned.isAbstract = true;
-    cloned.isNoSuchMethodForwarder = true;
-
+    transformProcedureToNoSuchMethodForwarder(noSuchMethod, target, cloned);
     cls.procedures.add(cloned);
     cloned.parent = cls;
   }
 
-  void addNoSuchMethodForwarders(ClassHierarchy hierarchy) {
+  void addNoSuchMethodForwarders(
+      KernelTarget target, ClassHierarchy hierarchy) {
     if (!hasUserDefinedNoSuchMethod(cls, hierarchy)) {
       return;
     }
@@ -443,14 +479,20 @@
 
     List<Member> concrete = hierarchy.getDispatchTargets(cls);
     List<Member> declared = hierarchy.getDeclaredMembers(cls);
+
+    Member noSuchMethod = ClassHierarchy.findMemberByName(
+        hierarchy.getInterfaceMembers(cls), noSuchMethodName);
+
     for (Member member in hierarchy.getInterfaceMembers(cls)) {
       if (member is Procedure &&
           ClassHierarchy.findMemberByName(concrete, member.name) == null &&
           !existingForwardersNames.contains(member.name)) {
         if (ClassHierarchy.findMemberByName(declared, member.name) != null) {
-          member.isNoSuchMethodForwarder = true;
+          transformProcedureToNoSuchMethodForwarder(
+              noSuchMethod, target, member);
         } else {
-          addNoSuchMethodForwarderForProcedure(member, hierarchy);
+          addNoSuchMethodForwarderForProcedure(
+              noSuchMethod, target, member, hierarchy);
         }
         existingForwardersNames.add(member.name);
       }
@@ -467,9 +509,11 @@
           !existingSetterForwardersNames.contains(member.name)) {
         if (ClassHierarchy.findMemberByName(declaredSetters, member.name) !=
             null) {
-          member.isNoSuchMethodForwarder = true;
+          transformProcedureToNoSuchMethodForwarder(
+              noSuchMethod, target, member);
         } else {
-          addNoSuchMethodForwarderForProcedure(member, hierarchy);
+          addNoSuchMethodForwarderForProcedure(
+              noSuchMethod, target, member, hierarchy);
         }
         existingSetterForwardersNames.add(member.name);
       }
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 463f5b4..b5f6854 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
@@ -990,47 +990,35 @@
     return count;
   }
 
-  int instantiateToBound(TypeBuilder dynamicType, TypeBuilder bottomType,
+  int computeDefaultTypes(TypeBuilder dynamicType, TypeBuilder bottomType,
       ClassBuilder objectClass) {
     int count = 0;
+    bool strongMode = loader.target.strongMode;
+
+    int computeDefaultTypesForVariables(List<TypeVariableBuilder> variables) {
+      if (variables == null) return 0;
+      List<KernelTypeBuilder> calculatedBounds = strongMode
+          ? calculateBounds(variables, dynamicType, bottomType, objectClass)
+          : null;
+      for (int i = 0; i < variables.length; ++i) {
+        variables[i].defaultType =
+            strongMode ? calculatedBounds[i] : dynamicType;
+      }
+      return variables.length;
+    }
 
     for (var declaration in libraryDeclaration.members.values) {
       if (declaration is KernelClassBuilder) {
-        if (declaration.typeVariables != null) {
-          List<KernelTypeBuilder> calculatedBounds;
-          if (loader.target.strongMode) {
-            calculatedBounds = calculateBounds(declaration.typeVariables,
-                dynamicType, bottomType, objectClass);
-          } else {
-            calculatedBounds =
-                new List<KernelTypeBuilder>(declaration.typeVariables.length);
-            for (int i = 0; i < calculatedBounds.length; ++i) {
-              calculatedBounds[i] = dynamicType;
-            }
+        count += computeDefaultTypesForVariables(declaration.typeVariables);
+        declaration.forEach((String name, Builder member) {
+          if (member is KernelProcedureBuilder) {
+            count += computeDefaultTypesForVariables(member.typeVariables);
           }
-          for (int i = 0; i < calculatedBounds.length; ++i) {
-            declaration.typeVariables[i].defaultType = calculatedBounds[i];
-          }
-          count += calculatedBounds.length;
-        }
+        });
       } else if (declaration is KernelFunctionTypeAliasBuilder) {
-        if (declaration.typeVariables != null) {
-          List<KernelTypeBuilder> calculatedBounds;
-          if (loader.target.strongMode) {
-            calculatedBounds = calculateBounds(declaration.typeVariables,
-                dynamicType, bottomType, objectClass);
-          } else {
-            calculatedBounds =
-                new List<KernelTypeBuilder>(declaration.typeVariables.length);
-            for (int i = 0; i < calculatedBounds.length; ++i) {
-              calculatedBounds[i] = dynamicType;
-            }
-          }
-          for (int i = 0; i < calculatedBounds.length; ++i) {
-            declaration.typeVariables[i].defaultType = calculatedBounds[i];
-          }
-          count += calculatedBounds.length;
-        }
+        count += computeDefaultTypesForVariables(declaration.typeVariables);
+      } else if (declaration is KernelFunctionBuilder) {
+        count += computeDefaultTypesForVariables(declaration.typeVariables);
       }
     }
 
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 71372b9..fac004f 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
@@ -20,26 +20,55 @@
 
 import 'dart:core' hide MapEntry;
 
-import 'package:front_end/src/base/instrumentation.dart';
-import 'package:front_end/src/fasta/fasta_codes.dart';
-import 'package:front_end/src/fasta/kernel/body_builder.dart';
-import 'package:front_end/src/fasta/kernel/fasta_accessors.dart';
-import 'package:front_end/src/fasta/source/source_class_builder.dart';
-import 'package:front_end/src/fasta/source/source_library_builder.dart';
-import 'package:front_end/src/fasta/type_inference/interface_resolver.dart';
-import 'package:front_end/src/fasta/type_inference/type_inference_engine.dart';
-import 'package:front_end/src/fasta/type_inference/type_inferrer.dart';
-import 'package:front_end/src/fasta/type_inference/type_promotion.dart';
-import 'package:front_end/src/fasta/type_inference/type_schema.dart';
-import 'package:front_end/src/fasta/type_inference/type_schema_elimination.dart';
-import 'package:front_end/src/fasta/type_inference/type_schema_environment.dart';
 import 'package:kernel/ast.dart' hide InvalidExpression, InvalidInitializer;
+
 import 'package:kernel/clone.dart' show CloneVisitor;
-import 'package:kernel/frontend/accessors.dart';
-import 'package:kernel/type_algebra.dart';
+
+import 'package:kernel/type_algebra.dart' show Substitution;
+
+import '../../base/instrumentation.dart'
+    show
+        Instrumentation,
+        InstrumentationValueForMember,
+        InstrumentationValueForType,
+        InstrumentationValueForTypeArgs;
+
+import '../fasta_codes.dart'
+    show templateCantUseSuperBoundedTypeForInstanceCreation;
 
 import '../problems.dart' show unhandled, unsupported;
 
+import '../source/source_class_builder.dart' show SourceClassBuilder;
+
+import '../source/source_library_builder.dart' show SourceLibraryBuilder;
+
+import '../type_inference/interface_resolver.dart' show InterfaceResolver;
+
+import '../type_inference/type_inference_engine.dart'
+    show
+        FieldInitializerInferenceNode,
+        IncludesTypeParametersCovariantly,
+        InferenceNode,
+        TypeInferenceEngine,
+        TypeInferenceEngineImpl;
+
+import '../type_inference/type_inferrer.dart'
+    show TypeInferrer, TypeInferrerDisabled, TypeInferrerImpl;
+
+import '../type_inference/type_promotion.dart'
+    show TypePromoter, TypePromoterImpl, TypePromotionFact, TypePromotionScope;
+
+import '../type_inference/type_schema.dart' show UnknownType;
+
+import '../type_inference/type_schema_elimination.dart' show greatestClosure;
+
+import '../type_inference/type_schema_environment.dart'
+    show TypeSchemaEnvironment, getPositionalParameterType;
+
+import 'body_builder.dart' show combineStatements;
+
+import 'expression_generator.dart' show BuilderHelper, makeLet;
+
 /// Indicates whether type inference involving conditional expressions should
 /// always use least upper bound.
 ///
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 96b6930..f76f827 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
@@ -242,7 +242,7 @@
       objectType.bind(loader.coreLibrary["Object"]);
       bottomType.bind(loader.coreLibrary["Null"]);
       loader.resolveTypes();
-      loader.instantiateToBound(dynamicType, bottomType, objectClassBuilder);
+      loader.computeDefaultTypes(dynamicType, bottomType, objectClassBuilder);
       List<SourceClassBuilder> myClasses = collectMyClasses();
       loader.checkSemantics(myClasses);
       loader.finishTypeVariables(objectClassBuilder, dynamicType);
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 fa6795b..1ba0f1e 100644
--- a/pkg/front_end/lib/src/fasta/kernel/type_algorithms.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/type_algorithms.dart
@@ -137,15 +137,7 @@
       new List<KernelTypeBuilder>(variables.length);
 
   for (int i = 0; i < variables.length; i++) {
-    KernelTypeBuilder type = variables[i].bound;
-    if (type == null ||
-        type is KernelNamedTypeBuilder &&
-            type.builder is KernelClassBuilder &&
-            (type.builder as KernelClassBuilder).cls == objectClass?.cls) {
-      type = dynamicType;
-    }
-
-    bounds[i] = type;
+    bounds[i] = variables[i].bound ?? dynamicType;
   }
 
   TypeVariablesGraph graph = new TypeVariablesGraph(variables, bounds);
diff --git a/pkg/front_end/lib/src/fasta/kernel/utils.dart b/pkg/front_end/lib/src/fasta/kernel/utils.dart
index 8bcda60..d95f852 100644
--- a/pkg/front_end/lib/src/fasta/kernel/utils.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/utils.dart
@@ -6,7 +6,10 @@
 
 import 'dart:io' show BytesBuilder, File, IOSink;
 
-import 'package:kernel/ast.dart' show Library, Component;
+import 'package:kernel/clone.dart' show CloneVisitor;
+
+import 'package:kernel/ast.dart'
+    show Library, Component, Procedure, Class, TypeParameter, Supertype;
 
 import 'package:kernel/binary/ast_to_binary.dart' show BinaryPrinter;
 
@@ -58,6 +61,39 @@
   return byteSink.builder.takeBytes();
 }
 
+List<int> serializeProcedure(Procedure procedure) {
+  Library fakeLibrary =
+      new Library(new Uri(scheme: 'evaluate', path: 'source'));
+
+  if (procedure.parent is Class) {
+    Class realClass = procedure.parent;
+
+    CloneVisitor cloner = new CloneVisitor();
+
+    Class fakeClass = new Class(name: realClass.name);
+    for (TypeParameter typeParam in realClass.typeParameters) {
+      fakeClass.typeParameters.add(typeParam.accept(cloner));
+    }
+
+    fakeClass.parent = fakeLibrary;
+    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);
+    procedure.parent = fakeClass;
+    fakeClass.procedures.add(procedure);
+    fakeLibrary.classes.add(fakeClass);
+  } else {
+    fakeLibrary.procedures.add(procedure);
+    procedure.parent = fakeLibrary;
+  }
+
+  Component program = new Component(libraries: [fakeLibrary]);
+  return serializeComponent(program);
+}
+
 /// A [Sink] that directly writes data into a byte builder.
 class ByteSink implements Sink<List<int>> {
   final BytesBuilder builder = new BytesBuilder();
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 4cb980b..65b8b20 100644
--- a/pkg/front_end/lib/src/fasta/parser/forwarding_listener.dart
+++ b/pkg/front_end/lib/src/fasta/parser/forwarding_listener.dart
@@ -1196,6 +1196,11 @@
   }
 
   @override
+  void handleParenthesizedCondition(Token token) {
+    listener?.handleParenthesizedCondition(token);
+  }
+
+  @override
   void handleParenthesizedExpression(Token token) {
     listener?.handleParenthesizedExpression(token);
   }
diff --git a/pkg/front_end/lib/src/fasta/parser/identifier_context.dart b/pkg/front_end/lib/src/fasta/parser/identifier_context.dart
index b9bbf76..962bded 100644
--- a/pkg/front_end/lib/src/fasta/parser/identifier_context.dart
+++ b/pkg/front_end/lib/src/fasta/parser/identifier_context.dart
@@ -102,10 +102,8 @@
 
   /// Identifier is the name of a type variable being declared (e.g. `Foo` in
   /// `class C<Foo extends num> {}`).
-  static const typeVariableDeclaration = const IdentifierContext(
-      'typeVariableDeclaration',
-      inDeclaration: true,
-      isBuiltInIdentifierAllowed: false);
+  static const typeVariableDeclaration =
+      const TypeVariableDeclarationIdentifierContext();
 
   /// Identifier is the start of a reference to a type that starts with prefix.
   static const prefixedTypeReference =
@@ -121,15 +119,16 @@
 
   /// Identifier is a name being declared by a top level variable declaration.
   static const topLevelVariableDeclaration =
-      const TopLevelVariableIdentifierContext();
+      const TopLevelDeclarationIdentifierContext(
+          'topLevelVariableDeclaration', const [';', '=', ',']);
 
   /// Identifier is a name being declared by a field declaration.
   static const fieldDeclaration = const FieldDeclarationIdentifierContext();
 
   /// Identifier is the name being declared by a top level function declaration.
-  static const topLevelFunctionDeclaration = const IdentifierContext(
-      'topLevelFunctionDeclaration',
-      inDeclaration: true);
+  static const topLevelFunctionDeclaration =
+      const TopLevelDeclarationIdentifierContext(
+          'topLevelFunctionDeclaration', const ['<', '(', '{', '=>']);
 
   /// Identifier is the start of the name being declared by a method
   /// declaration.
@@ -149,7 +148,8 @@
   /// TODO(paulberry,ahe): Does this ever occur in valid Dart, or does it only
   /// occur as part of error recovery?  If it's only as part of error recovery,
   /// perhaps we should just re-use methodDeclaration.
-  static const operatorName = const IdentifierContext('operatorName');
+  static const operatorName =
+      const MethodDeclarationIdentifierContext.continuation();
 
   /// Identifier is the name being declared by a local function declaration that
   /// uses a "get" or "set" keyword.
@@ -163,17 +163,15 @@
   /// Identifier is the start of the name being declared by a local function
   /// declaration.
   static const localFunctionDeclaration =
-      const IdentifierContext('localFunctionDeclaration', inDeclaration: true);
+      const LocalFunctionDeclarationIdentifierContext();
 
   /// Identifier is part of the name being declared by a local function
   /// declaration, but it's not the first identifier of the name.
   ///
   /// TODO(paulberry,ahe): Does this ever occur in valid Dart, or does it only
   /// occur as part of error recovery?
-  static const localFunctionDeclarationContinuation = const IdentifierContext(
-      'localFunctionDeclarationContinuation',
-      inDeclaration: true,
-      isContinuation: true);
+  static const localFunctionDeclarationContinuation =
+      const LocalFunctionDeclarationIdentifierContext.continuation();
 
   /// Identifier is the name appearing in a function expression.
   ///
diff --git a/pkg/front_end/lib/src/fasta/parser/identifier_context_impl.dart b/pkg/front_end/lib/src/fasta/parser/identifier_context_impl.dart
index f18b2ac..a5d808f 100644
--- a/pkg/front_end/lib/src/fasta/parser/identifier_context_impl.dart
+++ b/pkg/front_end/lib/src/fasta/parser/identifier_context_impl.dart
@@ -12,10 +12,9 @@
 
 import 'parser.dart' show Parser;
 
-import 'type_info.dart'
-    show insertSyntheticIdentifierAfter, isValidTypeReference;
+import 'type_info.dart' show isValidTypeReference;
 
-import 'util.dart' show optional;
+import 'util.dart' show isOneOfOrEof, optional;
 
 /// See [IdentifierContext.classOrNamedMixinDeclaration].
 class ClassOrNamedMixinIdentifierContext extends IdentifierContext {
@@ -46,7 +45,7 @@
       if (!identifier.isKeywordOrIdentifier) {
         // When in doubt, consume the token to ensure we make progress
         // but insert a synthetic identifier to satisfy listeners.
-        identifier = insertSyntheticIdentifierAfter(identifier, parser);
+        identifier = parser.rewriter.insertSyntheticIdentifier(identifier);
       }
     }
     return identifier;
@@ -88,7 +87,7 @@
       if (!identifier.isKeywordOrIdentifier) {
         // When in doubt, consume the token to ensure we make progress
         // but insert a synthetic identifier to satisfy listeners.
-        identifier = insertSyntheticIdentifierAfter(identifier, parser);
+        identifier = parser.rewriter.insertSyntheticIdentifier(identifier);
       }
     }
     return identifier;
@@ -123,7 +122,7 @@
       if (!identifier.isKeywordOrIdentifier) {
         // When in doubt, consume the token to ensure we make progress
         // but insert a synthetic identifier to satisfy listeners.
-        identifier = insertSyntheticIdentifierAfter(identifier, parser);
+        identifier = parser.rewriter.insertSyntheticIdentifier(identifier);
       }
     }
     return identifier;
@@ -148,11 +147,11 @@
         identifier, fasta.templateExpectedIdentifier);
     if (looksLikeStartOfNextTopLevelDeclaration(identifier) ||
         isOneOfOrEof(identifier, const [',', '}'])) {
-      return insertSyntheticIdentifierAfter(token, parser);
+      return parser.rewriter.insertSyntheticIdentifier(token);
     } else if (!identifier.isKeywordOrIdentifier) {
       // When in doubt, consume the token to ensure we make progress
       // but insert a synthetic identifier to satisfy listeners.
-      return insertSyntheticIdentifierAfter(identifier, parser);
+      return parser.rewriter.insertSyntheticIdentifier(identifier);
     }
     return identifier;
   }
@@ -204,7 +203,7 @@
       identifier = token.next;
     }
     // Insert a synthetic identifier to satisfy listeners.
-    return insertSyntheticIdentifierAfter(token, parser);
+    return parser.rewriter.insertSyntheticIdentifier(token);
   }
 }
 
@@ -257,11 +256,11 @@
     parser.reportRecoverableErrorWithToken(
         identifier, fasta.templateExpectedIdentifier);
     // Insert a synthetic identifier to satisfy listeners.
-    return insertSyntheticIdentifierAfter(token, parser);
+    return parser.rewriter.insertSyntheticIdentifier(token);
   }
 }
 
-/// See [IdentifierContext].importPrefixDeclaration
+/// See [IdentifierContext.importPrefixDeclaration].
 class ImportPrefixIdentifierContext extends IdentifierContext {
   const ImportPrefixIdentifierContext()
       : super('importPrefixDeclaration',
@@ -291,7 +290,44 @@
       if (!identifier.isKeywordOrIdentifier) {
         // When in doubt, consume the token to ensure we make progress
         // but insert a synthetic identifier to satisfy listeners.
-        identifier = insertSyntheticIdentifierAfter(identifier, parser);
+        identifier = parser.rewriter.insertSyntheticIdentifier(identifier);
+      }
+    }
+    return identifier;
+  }
+}
+
+/// See [IdentifierContext.localFunctionDeclaration]
+/// and [IdentifierContext.localFunctionDeclarationContinuation].
+class LocalFunctionDeclarationIdentifierContext extends IdentifierContext {
+  const LocalFunctionDeclarationIdentifierContext()
+      : super('localFunctionDeclaration', inDeclaration: true);
+
+  const LocalFunctionDeclarationIdentifierContext.continuation()
+      : super('localFunctionDeclarationContinuation',
+            inDeclaration: true, isContinuation: true);
+
+  @override
+  Token ensureIdentifier(Token token, Parser parser) {
+    Token identifier = token.next;
+    assert(identifier.kind != IDENTIFIER_TOKEN);
+    if (identifier.isIdentifier) {
+      checkAsyncAwaitYieldAsIdentifier(identifier, parser);
+      return identifier;
+    }
+
+    // Recovery
+    if (isOneOfOrEof(identifier, const ['.', '(', '{', '=>']) ||
+        looksLikeStartOfNextStatement(identifier)) {
+      identifier = parser.insertSyntheticIdentifier(token, this,
+          message: fasta.templateExpectedIdentifier.withArguments(identifier));
+    } else {
+      parser.reportRecoverableErrorWithToken(
+          identifier, fasta.templateExpectedIdentifier);
+      if (!identifier.isKeywordOrIdentifier) {
+        // When in doubt, consume the token to ensure we make progress
+        // but insert a synthetic identifier to satisfy listeners.
+        identifier = parser.rewriter.insertSyntheticIdentifier(identifier);
       }
     }
     return identifier;
@@ -335,7 +371,7 @@
       if (!identifier.isKeywordOrIdentifier) {
         // When in doubt, consume the token to ensure we make progress
         // but insert a synthetic identifier to satisfy listeners.
-        identifier = insertSyntheticIdentifierAfter(identifier, parser);
+        identifier = parser.rewriter.insertSyntheticIdentifier(identifier);
       }
     }
     return identifier;
@@ -367,14 +403,16 @@
       if (!identifier.isKeywordOrIdentifier) {
         // When in doubt, consume the token to ensure we make progress
         // but insert a synthetic identifier to satisfy listeners.
-        identifier = insertSyntheticIdentifierAfter(identifier, parser);
+        identifier = parser.rewriter.insertSyntheticIdentifier(identifier);
       }
     }
     return identifier;
   }
 }
 
-/// See [IdentifierContext.methodDeclaration].
+/// See [IdentifierContext.methodDeclaration],
+/// and [IdentifierContext.methodDeclarationContinuation],
+/// and [IdentifierContext.operatorName].
 class MethodDeclarationIdentifierContext extends IdentifierContext {
   const MethodDeclarationIdentifierContext()
       : super('methodDeclaration', inDeclaration: true);
@@ -383,6 +421,9 @@
       : super('methodDeclarationContinuation',
             inDeclaration: true, isContinuation: true);
 
+  const MethodDeclarationIdentifierContext.operatorName()
+      : super('operatorName', inDeclaration: true);
+
   @override
   Token ensureIdentifier(Token token, Parser parser) {
     Token identifier = token.next;
@@ -413,16 +454,18 @@
   }
 }
 
-/// See [IdentifierContext.topLevelVariableDeclaration].
-class TopLevelVariableIdentifierContext extends IdentifierContext {
-  const TopLevelVariableIdentifierContext()
-      : super('topLevelVariableDeclaration', inDeclaration: true);
+/// See [IdentifierContext.topLevelFunctionDeclaration]
+/// and [IdentifierContext.topLevelVariableDeclaration].
+class TopLevelDeclarationIdentifierContext extends IdentifierContext {
+  final List<String> followingValues;
+
+  const TopLevelDeclarationIdentifierContext(String name, this.followingValues)
+      : super(name, inDeclaration: true);
 
   @override
   Token ensureIdentifier(Token token, Parser parser) {
     Token identifier = token.next;
     assert(identifier.kind != IDENTIFIER_TOKEN);
-    const followingValues = const [';', '=', ','];
 
     if (identifier.isIdentifier) {
       Token next = identifier.next;
@@ -430,9 +473,9 @@
           isOneOfOrEof(next, followingValues)) {
         return identifier;
       }
-      // Although this is a valid top level var name, the var declaration
+      // Although this is a valid top level name, the declaration
       // is invalid and this looks like the start of the next declaration.
-      // In this situation, fall through to insert a synthetic var name.
+      // In this situation, fall through to insert a synthetic name.
     }
 
     // Recovery
@@ -449,14 +492,14 @@
       if (!identifier.isKeywordOrIdentifier) {
         // When in doubt, consume the token to ensure we make progress
         // but insert a synthetic identifier to satisfy listeners.
-        identifier = insertSyntheticIdentifierAfter(identifier, parser);
+        identifier = parser.rewriter.insertSyntheticIdentifier(identifier);
       }
     }
     return identifier;
   }
 }
 
-/// See [IdentifierContext].typedefDeclaration
+/// See [IdentifierContext.typedefDeclaration].
 class TypedefDeclarationIdentifierContext extends IdentifierContext {
   const TypedefDeclarationIdentifierContext()
       : super('typedefDeclaration',
@@ -467,11 +510,15 @@
     Token identifier = token.next;
     assert(identifier.kind != IDENTIFIER_TOKEN);
     if (identifier.type.isPseudo) {
+      if (optional('Function', identifier)) {
+        parser.reportRecoverableErrorWithToken(
+            identifier, fasta.templateExpectedIdentifier);
+      }
       return identifier;
     }
 
     // Recovery
-    const followingValues = const ['(', '<', '=', ';', 'var'];
+    const followingValues = const ['(', '<', '=', ';'];
     if (identifier.type.isBuiltIn &&
         isOneOfOrEof(identifier.next, followingValues)) {
       parser.reportRecoverableErrorWithToken(
@@ -486,7 +533,7 @@
       if (!identifier.isKeywordOrIdentifier) {
         // When in doubt, consume the token to ensure we make progress
         // but insert a synthetic identifier to satisfy listeners.
-        identifier = insertSyntheticIdentifierAfter(identifier, parser);
+        identifier = parser.rewriter.insertSyntheticIdentifier(identifier);
       }
     }
     return identifier;
@@ -538,7 +585,39 @@
       next = token.next;
     }
     // Insert a synthetic identifier to satisfy listeners.
-    return insertSyntheticIdentifierAfter(token, parser);
+    return parser.rewriter.insertSyntheticIdentifier(token);
+  }
+}
+
+// See [IdentifierContext.typeVariableDeclaration].
+class TypeVariableDeclarationIdentifierContext extends IdentifierContext {
+  const TypeVariableDeclarationIdentifierContext()
+      : super('typeVariableDeclaration',
+            inDeclaration: true, isBuiltInIdentifierAllowed: false);
+
+  @override
+  Token ensureIdentifier(Token token, Parser parser) {
+    Token identifier = token.next;
+    assert(identifier.kind != IDENTIFIER_TOKEN);
+    if (identifier.type.isPseudo) {
+      return identifier;
+    }
+
+    // Recovery
+    parser.reportRecoverableErrorWithToken(
+        identifier, fasta.templateExpectedIdentifier);
+    const followingValues = const ['<', '>', ';', '}', 'extends', 'super'];
+    if (looksLikeStartOfNextTopLevelDeclaration(identifier) ||
+        looksLikeStartOfNextClassMember(identifier) ||
+        looksLikeStartOfNextStatement(identifier) ||
+        isOneOfOrEof(identifier, followingValues)) {
+      identifier = parser.rewriter.insertSyntheticIdentifier(token);
+    } else {
+      // When in doubt, consume the token to ensure we make progress
+      // but insert a synthetic identifier to satisfy listeners.
+      identifier = parser.rewriter.insertSyntheticIdentifier(identifier);
+    }
+    return identifier;
   }
 }
 
@@ -554,15 +633,6 @@
   }
 }
 
-bool isOneOfOrEof(Token token, Iterable<String> followingValues) {
-  for (String tokenValue in followingValues) {
-    if (optional(tokenValue, token)) {
-      return true;
-    }
-  }
-  return token.isEof;
-}
-
 bool looksLikeStartOfNextClassMember(Token token) =>
     token.isModifier || isOneOfOrEof(token, const ['get', 'set', 'void']);
 
@@ -585,4 +655,5 @@
 
 bool looksLikeStartOfNextTopLevelDeclaration(Token token) =>
     token.isTopLevelKeyword ||
-    isOneOfOrEof(token, const ['const', 'get', 'final', 'set', 'var', 'void']);
+    isOneOfOrEof(
+        token, const ['class', 'const', 'get', 'final', 'set', 'var', 'void']);
diff --git a/pkg/front_end/lib/src/fasta/parser/listener.dart b/pkg/front_end/lib/src/fasta/parser/listener.dart
index 5c3e99c..e7bcb52 100644
--- a/pkg/front_end/lib/src/fasta/parser/listener.dart
+++ b/pkg/front_end/lib/src/fasta/parser/listener.dart
@@ -1113,6 +1113,18 @@
     logEvent("InvalidOperatorName");
   }
 
+  /// Handle the condition in a control structure:
+  /// - if statement
+  /// - do while loop
+  /// - switch statement
+  /// - while loop
+  void handleParenthesizedCondition(Token token) {
+    logEvent("ParenthesizedCondition");
+  }
+
+  /// Handle a parenthesized expression.
+  /// These may be within the condition expression of a control structure
+  /// but will not be the condition of a control structure.
   void handleParenthesizedExpression(Token token) {
     logEvent("ParenthesizedExpression");
   }
diff --git a/pkg/front_end/lib/src/fasta/parser/parser.dart b/pkg/front_end/lib/src/fasta/parser/parser.dart
index 53154e7..d0777a2 100644
--- a/pkg/front_end/lib/src/fasta/parser/parser.dart
+++ b/pkg/front_end/lib/src/fasta/parser/parser.dart
@@ -89,6 +89,7 @@
         TypeParamOrArgInfo,
         computeMethodTypeArguments,
         computeType,
+        computeTypeParam,
         computeTypeParamOrArg,
         isGeneralizedFunctionType,
         isValidTypeReference,
@@ -501,8 +502,11 @@
       // and continue parsing as a top level function.
       rewriter.insertTokenAfter(
           next,
-          new SyntheticStringToken(TokenType.IDENTIFIER,
-              '#synthetic_function_${next.charOffset}', token.charOffset, 0));
+          new SyntheticStringToken(
+              TokenType.IDENTIFIER,
+              '#synthetic_function_${next.charOffset}',
+              next.next.charOffset,
+              0));
       return parseTopLevelMemberImpl(next);
     }
     // Ignore any preceding modifiers and just report the unexpected token
@@ -546,18 +550,14 @@
       directiveState?.checkDeclaration();
       return parseEnum(previous);
     } else if (identical(value, 'typedef')) {
-      Token next = token.next;
+      String nextValue = token.next.stringValue;
       directiveState?.checkDeclaration();
-      if (next.isIdentifier || optional("void", next)) {
-        return parseTypedef(previous);
-      } else if (next.isTopLevelKeyword ||
-          optional('var', next) ||
-          optional('=', next) ||
-          next.isEof) {
-        // Recovery
-        return parseTypedef(previous);
-      } else {
+      if (identical('(', nextValue) ||
+          identical('<', nextValue) ||
+          identical('.', nextValue)) {
         return parseTopLevelMemberImpl(previous);
+      } else {
+        return parseTypedef(previous);
       }
     } else {
       // The remaining top level keywords are built-in keywords
@@ -1045,9 +1045,13 @@
 
   /// ```
   /// typeAlias:
-  ///   metadata 'typedef' typeAliasBody
+  ///   metadata 'typedef' typeAliasBody |
+  ///   metadata 'typedef' identifier typeParameters? '=' functionType ';'
   /// ;
   ///
+  /// functionType:
+  ///   returnType? 'Function' typeParameters? parameterTypeList
+  ///
   /// typeAliasBody:
   ///   functionTypeAlias
   /// ;
@@ -1064,18 +1068,21 @@
     Token typedefKeyword = token.next;
     assert(optional('typedef', typedefKeyword));
     listener.beginFunctionTypeAlias(typedefKeyword);
+    TypeInfo typeInfo = computeType(typedefKeyword, false);
+    token = typeInfo.skipType(typedefKeyword).next;
     Token equals;
-    Token afterType = parseType(typedefKeyword, TypeContinuation.Typedef);
-    if (afterType == null) {
-      token = ensureIdentifier(
-          typedefKeyword, IdentifierContext.typedefDeclaration);
-      token = parseTypeVariablesOpt(token).next;
-      equals = token;
-      expect('=', token);
-      token = parseType(token);
+    TypeParamOrArgInfo typeParam = computeTypeParamOrArg(token);
+    if (typeInfo == noType &&
+        (token.kind == IDENTIFIER_TOKEN || token.type.isPseudo) &&
+        optional('=', typeParam.skip(token).next)) {
+      listener.handleIdentifier(token, IdentifierContext.typedefDeclaration);
+      equals = typeParam.parseVariables(token, this).next;
+      assert(optional('=', equals));
+      token = computeType(equals, true).ensureTypeOrVoid(equals, this);
     } else {
-      token = ensureIdentifier(afterType, IdentifierContext.typedefDeclaration);
-      token = parseTypeVariablesOpt(token);
+      token = typeInfo.parseType(typedefKeyword, this);
+      token = ensureIdentifier(token, IdentifierContext.typedefDeclaration);
+      token = typeParam.parseVariables(token, this);
       token =
           parseFormalParametersRequiredOpt(token, MemberKind.FunctionTypeAlias);
     }
@@ -1351,7 +1358,8 @@
 
     Token endInlineFunctionType;
     if (beforeInlineFunctionType != null) {
-      endInlineFunctionType = parseTypeVariablesOpt(beforeInlineFunctionType);
+      endInlineFunctionType = computeTypeParamOrArg(beforeInlineFunctionType)
+          .parseVariables(beforeInlineFunctionType, this);
       listener.beginFunctionTypedFormalParameter(beforeInlineFunctionType.next);
       token = typeInfo.parseType(beforeType, this);
       endInlineFunctionType = parseFormalParametersRequiredOpt(
@@ -1648,10 +1656,10 @@
     Token abstractToken = beforeAbstractToken?.next;
     Token begin = abstractToken ?? token;
     Token classKeyword = token;
-    expect("class", token);
+    assert(optional('class', token));
     Token name =
         ensureIdentifier(token, IdentifierContext.classOrNamedMixinDeclaration);
-    token = parseTypeVariablesOpt(name);
+    token = computeTypeParam(name).parseVariables(name, this);
     if (optional('=', token.next)) {
       listener.beginNamedMixinApplication(begin, abstractToken, name);
       return parseNamedMixinApplication(token, begin, classKeyword);
@@ -1665,7 +1673,7 @@
       Token token, Token begin, Token classKeyword) {
     Token equals = token = token.next;
     assert(optional('=', equals));
-    token = parseType(token);
+    token = computeType(token, true).ensureTypeNotVoid(token, this);
     token = parseMixinApplicationRest(token);
     Token implementsKeyword = null;
     if (optional('implements', token.next)) {
@@ -1753,7 +1761,8 @@
             TokenType.IDENTIFIER, 'Object', next.offset, 0);
         rewriter.insertTokenAfter(token, extendsKeyword);
         rewriter.insertTokenAfter(extendsKeyword, superclassToken);
-        token = parseType(extendsKeyword);
+        token = computeType(extendsKeyword, true)
+            .ensureTypeNotVoid(extendsKeyword, this);
         token = parseMixinApplicationRest(token);
         listener.handleClassExtends(extendsKeyword);
       } else {
@@ -1817,7 +1826,7 @@
     Token next = token.next;
     if (optional('extends', next)) {
       Token extendsKeyword = next;
-      token = parseType(next);
+      token = computeType(next, true).ensureTypeNotVoid(next, this);
       if (optional('with', token.next)) {
         token = parseMixinApplicationRest(token);
       } else {
@@ -1842,7 +1851,8 @@
     if (optional('implements', token.next)) {
       implementsKeyword = token.next;
       do {
-        token = parseType(token.next);
+        token =
+            computeType(token.next, true).ensureTypeNotVoid(token.next, this);
         ++interfacesCount;
       } while (optional(',', token.next));
     }
@@ -2012,13 +2022,6 @@
       followingValues = ['.', ';'];
     } else if (context == IdentifierContext.localAccessorDeclaration) {
       followingValues = ['(', '{', '=>'];
-    } else if (context == IdentifierContext.localFunctionDeclaration ||
-        context == IdentifierContext.localFunctionDeclarationContinuation) {
-      followingValues = ['.', '(', '{', '=>'];
-    } else if (context == IdentifierContext.topLevelFunctionDeclaration) {
-      followingValues = ['(', '{', '=>'];
-    } else if (context == IdentifierContext.typeVariableDeclaration) {
-      followingValues = ['<', '>', ';', '}'];
     } else {
       return false;
     }
@@ -2080,17 +2083,9 @@
       initialKeywords = statementKeywords();
     } else if (context == IdentifierContext.localAccessorDeclaration) {
       initialKeywords = statementKeywords();
-    } else if (context == IdentifierContext.localFunctionDeclaration) {
-      initialKeywords = statementKeywords();
     } else if (context ==
         IdentifierContext.localFunctionDeclarationContinuation) {
       initialKeywords = statementKeywords();
-    } else if (context == IdentifierContext.topLevelFunctionDeclaration) {
-      initialKeywords = topLevelKeywords();
-    } else if (context == IdentifierContext.typeVariableDeclaration) {
-      initialKeywords = topLevelKeywords()
-        ..addAll(classMemberKeywords())
-        ..addAll(statementKeywords());
     } else {
       return false;
     }
@@ -2370,12 +2365,6 @@
         hasVar = true;
         continue optional;
 
-      case TypeContinuation.Typedef:
-        if (optional('=', token)) {
-          return null; // This isn't a type, it's a new-style typedef.
-        }
-        continue optional;
-
       case TypeContinuation.SendOrFunctionLiteral:
         Token beforeName;
         Token name;
@@ -2693,7 +2682,7 @@
     Token token;
     bool isGetter = false;
     if (getOrSet == null) {
-      token = parseTypeVariablesOpt(name);
+      token = computeTypeParam(name).parseVariables(name, this);
     } else {
       isGetter = optional("get", getOrSet);
       token = name;
@@ -4444,20 +4433,36 @@
     return token;
   }
 
-  Token parseParenthesizedExpression(Token token) {
-    Token previousToken = token;
-    token = token.next;
-    if (!optional('(', token)) {
+  Token parseParenthesizedCondition(Token token) {
+    if (!optional('(', token.next)) {
       // Recover
+      Token next = token.next;
       reportRecoverableError(
-          token, fasta.templateExpectedToken.withArguments('('));
+          next, fasta.templateExpectedToken.withArguments('('));
+      // TODO(danrubel): Consider removing the 2nd error message.
       reportRecoverableError(
-          token, fasta.templateExpectedToken.withArguments(')'));
+          next, fasta.templateExpectedToken.withArguments(')'));
       BeginToken replacement = link(
-          new SyntheticBeginToken(TokenType.OPEN_PAREN, token.charOffset),
-          new SyntheticToken(TokenType.CLOSE_PAREN, token.charOffset));
-      token = rewriter.insertTokenAfter(previousToken, replacement).next;
+          new SyntheticBeginToken(TokenType.OPEN_PAREN, next.charOffset),
+          new SyntheticToken(TokenType.CLOSE_PAREN, next.charOffset));
+      rewriter.insertTokenAfter(token, replacement).next;
     }
+    Token begin = token.next;
+    token = parseExpressionInParenthesis(token);
+    listener.handleParenthesizedCondition(begin);
+    return token;
+  }
+
+  Token parseParenthesizedExpression(Token token) {
+    Token begin = token.next;
+    token = parseExpressionInParenthesis(token);
+    listener.handleParenthesizedExpression(begin);
+    return token;
+  }
+
+  Token parseExpressionInParenthesis(Token token) {
+    token = token.next;
+    assert(optional('(', token));
     BeginToken begin = token;
     token = parseExpression(token).next;
     if (!identical(begin.endGroup, token)) {
@@ -4465,8 +4470,7 @@
           token, fasta.templateExpectedButGot.withArguments(')'));
       token = begin.endGroup;
     }
-    listener.handleParenthesizedExpression(begin);
-    expect(')', token);
+    assert(optional(')', token));
     return token;
   }
 
@@ -5274,7 +5278,7 @@
     Token ifToken = token.next;
     assert(optional('if', ifToken));
     listener.beginIfStatement(ifToken);
-    token = parseParenthesizedExpression(ifToken);
+    token = parseParenthesizedCondition(ifToken);
     listener.beginThenStatement(token.next);
     token = parseStatement(token);
     listener.endThenStatement(token);
@@ -5494,7 +5498,7 @@
     Token whileToken = token.next;
     assert(optional('while', whileToken));
     listener.beginWhileStatement(whileToken);
-    token = parseParenthesizedExpression(whileToken);
+    token = parseParenthesizedCondition(whileToken);
     listener.beginWhileStatementBody(token.next);
     LoopState savedLoopState = loopState;
     loopState = LoopState.InsideLoop;
@@ -5529,7 +5533,7 @@
               new SyntheticKeywordToken(Keyword.WHILE, whileToken.charOffset))
           .next;
     }
-    token = parseParenthesizedExpression(whileToken);
+    token = parseParenthesizedCondition(whileToken);
     token = ensureSemicolon(token);
     listener.endDoWhileStatement(doToken, whileToken, token);
     return token;
@@ -5757,7 +5761,7 @@
     Token switchKeyword = token.next;
     assert(optional('switch', switchKeyword));
     listener.beginSwitchStatement(switchKeyword);
-    token = parseParenthesizedExpression(switchKeyword);
+    token = parseParenthesizedCondition(switchKeyword);
     LoopState savedLoopState = loopState;
     if (loopState == LoopState.OutsideLoop) {
       loopState = LoopState.InsideSwitch;
diff --git a/pkg/front_end/lib/src/fasta/parser/token_stream_rewriter.dart b/pkg/front_end/lib/src/fasta/parser/token_stream_rewriter.dart
index d5b8eae..b8ab28e 100644
--- a/pkg/front_end/lib/src/fasta/parser/token_stream_rewriter.dart
+++ b/pkg/front_end/lib/src/fasta/parser/token_stream_rewriter.dart
@@ -2,8 +2,16 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+import 'package:front_end/src/fasta/util/link.dart';
+
 import '../../scanner/token.dart'
-    show BeginToken, SimpleToken, Token, TokenType;
+    show
+        BeginToken,
+        SimpleToken,
+        SyntheticStringToken,
+        SyntheticToken,
+        Token,
+        TokenType;
 
 import 'util.dart' show optional;
 
@@ -33,6 +41,61 @@
   /// Initialize a newly created re-writer.
   TokenStreamRewriter();
 
+  /// For every `<` in [unbalancedLt] append a synthetic `>`.
+  /// Return the first `<`.
+  ///
+  /// [unbalancedLt] is a collection of `<` without closing `>` in the reverse
+  /// order from which they were encountered in the token stream.
+  Token balanceLt(final Token beforeLt, Token end, Link<Token> unbalancedLt) {
+    assert(optional('<', beforeLt.next));
+    assert(unbalancedLt.isNotEmpty);
+
+    BeginToken lt;
+    while (unbalancedLt.isNotEmpty) {
+      lt = unbalancedLt.head;
+      unbalancedLt = unbalancedLt.tail;
+      Token next = end.next;
+      Token gt;
+
+      if (optional('>', next)) {
+        gt = next;
+      } else if (optional('>>', next)) {
+        gt = new SimpleToken(TokenType.GT, next.charOffset)
+          ..setNext(new SimpleToken(TokenType.GT, next.charOffset + 1)
+            ..setNext(next.next));
+      } else if (optional('>=', next)) {
+        gt = new SimpleToken(TokenType.GT, next.charOffset)
+          ..setNext(new SimpleToken(TokenType.EQ, next.charOffset + 1)
+            ..setNext(next.next));
+      } else if (optional('>>=', next)) {
+        gt = new SimpleToken(TokenType.GT, next.charOffset)
+          ..setNext(new SimpleToken(TokenType.GT, next.charOffset + 1)
+            ..setNext(new SimpleToken(TokenType.EQ, next.charOffset + 2)
+              ..setNext(next.next)));
+      } else {
+        gt = new SyntheticToken(TokenType.GT, next.charOffset)..setNext(next);
+      }
+
+      lt.endGroup = gt;
+      end.setNext(gt);
+      end = gt;
+    }
+    assert(beforeLt.next == lt);
+    return lt;
+  }
+
+  /// Insert a synthetic identifier after [token] and return the new identifier.
+  Token insertSyntheticIdentifier(Token token) {
+    Token identifier = new SyntheticStringToken(
+        TokenType.IDENTIFIER, '', token.next.charOffset, 0)
+      ..setNext(token.next);
+
+    // A no-op rewriter could simply return the synthetic identifier here.
+
+    token.setNext(identifier);
+    return identifier;
+  }
+
   /// Insert the chain of tokens starting at the [insertedToken] immediately
   /// after the [previousToken]. Return the [previousToken].
   Token insertTokenAfter(Token previousToken, Token insertedToken) {
diff --git a/pkg/front_end/lib/src/fasta/parser/type_continuation.dart b/pkg/front_end/lib/src/fasta/parser/type_continuation.dart
index a8aafd2..1f317ab 100644
--- a/pkg/front_end/lib/src/fasta/parser/type_continuation.dart
+++ b/pkg/front_end/lib/src/fasta/parser/type_continuation.dart
@@ -25,10 +25,6 @@
   /// Same as [Optional], but we have seen `var`.
   OptionalAfterVar,
 
-  /// Indicates that the keyword `typedef` has just been seen, and the parser
-  /// should parse the following as a type unless it is followed by `=`.
-  Typedef,
-
   /// Indicates that the parser is parsing an expression and has just seen an
   /// identifier.
   SendOrFunctionLiteral,
diff --git a/pkg/front_end/lib/src/fasta/parser/type_info.dart b/pkg/front_end/lib/src/fasta/parser/type_info.dart
index b70a1e2..47f587f 100644
--- a/pkg/front_end/lib/src/fasta/parser/type_info.dart
+++ b/pkg/front_end/lib/src/fasta/parser/type_info.dart
@@ -4,7 +4,7 @@
 
 library fasta.parser.type_info;
 
-import '../../scanner/token.dart' show SyntheticStringToken, Token, TokenType;
+import '../../scanner/token.dart' show Token, TokenType;
 
 import '../scanner/token_constants.dart' show IDENTIFIER_TOKEN, KEYWORD_TOKEN;
 
@@ -65,6 +65,13 @@
   /// when parsing `>>` in valid code or during recovery.
   Token parseArguments(Token token, Parser parser);
 
+  /// Call this function to parse optional type parameters
+  /// (also known as type variables) after [token].
+  /// This function will call the appropriate event methods on the [Parser]'s
+  /// listener to handle the parameters. This may modify the token stream
+  /// when parsing `>>` in valid code or during recovery.
+  Token parseVariables(Token token, Parser parser);
+
   /// Call this function with the [token] before the type var to obtain
   /// the last token in the type var. If there is no type var, then this method
   /// will return [token]. This does not modify the token stream.
@@ -101,13 +108,6 @@
 /// `<` identifier `>`.
 const TypeParamOrArgInfo simpleTypeArgument1 = const SimpleTypeArgument1();
 
-Token insertSyntheticIdentifierAfter(Token token, Parser parser) {
-  Token identifier = new SyntheticStringToken(
-      TokenType.IDENTIFIER, '', token.next.charOffset, 0);
-  parser.rewriter.insertTokenAfter(token, identifier);
-  return identifier;
-}
-
 bool isGeneralizedFunctionType(Token token) {
   return optional('Function', token) &&
       (optional('<', token.next) || optional('(', token.next));
@@ -255,6 +255,29 @@
 }
 
 /// Called by the parser to obtain information about a possible group of type
+/// parameters that follow [token] in a top level or class member declaration.
+/// It assumes that a leading `<` cannot be part of an expression, and thus
+/// tries to more aggressively recover given an unmatched '<'
+TypeParamOrArgInfo computeTypeParam(Token token) {
+  if (!optional('<', token.next)) {
+    return noTypeParamOrArg;
+  }
+  TypeParamOrArgInfo typeParam = computeTypeParamOrArgImpl(token);
+  if (typeParam != noTypeParamOrArg) {
+    return typeParam;
+  }
+
+  // Recovery
+  if (token.next.endGroup == null) {
+    // Attempt to find where the missing `>` should be inserted.
+    return new ComplexTypeParamOrArgInfo(token).computeRecovery();
+  } else {
+    // The `<` `>` are balanced but there's still a problem.
+    return noTypeParamOrArg;
+  }
+}
+
+/// Called by the parser to obtain information about a possible group of type
 /// parameters or type arguments that follow [token].
 /// This does not modify the token stream.
 ///
@@ -262,18 +285,23 @@
 /// with `>>`, then then [innerEndGroup] is set to either `>>` if the token
 /// has not been split or the first `>` if the `>>` token has been split.
 TypeParamOrArgInfo computeTypeParamOrArg(Token token, [Token innerEndGroup]) {
+  return optional('<', token.next)
+      ? computeTypeParamOrArgImpl(token, innerEndGroup)
+      : noTypeParamOrArg;
+}
+
+TypeParamOrArgInfo computeTypeParamOrArgImpl(Token token,
+    [Token innerEndGroup]) {
   Token next = token.next;
-  if (!optional('<', next)) {
-    return noTypeParamOrArg;
-  }
+  assert(optional('<', next));
   Token endGroup = next.endGroup ?? innerEndGroup;
   if (endGroup == null) {
     return noTypeParamOrArg;
   }
   Token identifier = next.next;
-  // identifier `<` `void` `>` is handled by ComplexTypeInfo.
-  if (isValidTypeReference(identifier) &&
-      !optional('void', identifier) &&
+  // identifier `<` `void` `>` and `<` `dynamic` `>`
+  // are handled by ComplexTypeInfo.
+  if ((identifier.kind == IDENTIFIER_TOKEN || identifier.type.isPseudo) &&
       identifier.next == endGroup) {
     return simpleTypeArgument1;
   }
diff --git a/pkg/front_end/lib/src/fasta/parser/type_info_impl.dart b/pkg/front_end/lib/src/fasta/parser/type_info_impl.dart
index 376d485..a18b898 100644
--- a/pkg/front_end/lib/src/fasta/parser/type_info_impl.dart
+++ b/pkg/front_end/lib/src/fasta/parser/type_info_impl.dart
@@ -22,7 +22,7 @@
 
 import 'type_info.dart';
 
-import 'util.dart' show optional, skipMetadata;
+import 'util.dart' show isOneOf, optional, skipMetadata;
 
 /// See documentation on the [noType] const.
 class NoType implements TypeInfo {
@@ -35,7 +35,7 @@
   Token ensureTypeNotVoid(Token token, Parser parser) {
     parser.reportRecoverableErrorWithToken(
         token.next, fasta.templateExpectedType);
-    insertSyntheticIdentifierAfter(token, parser);
+    parser.rewriter.insertSyntheticIdentifier(token);
     return simpleType.parseType(token, parser);
   }
 
@@ -502,6 +502,12 @@
   }
 
   @override
+  Token parseVariables(Token token, Parser parser) {
+    parser.listener.handleNoTypeVariables(token.next);
+    return token;
+  }
+
+  @override
   Token skip(Token token) => token;
 }
 
@@ -515,23 +521,27 @@
     Listener listener = parser.listener;
     listener.beginTypeArguments(token);
     token = simpleType.parseType(token, parser);
-    Token next = token.next;
+    token = processEndGroup(token, start, parser);
+    parser.listener.endTypeArguments(1, start, token);
+    return token;
+  }
 
-    if (next == start.endGroup) {
-      parser.listener.endTypeArguments(1, start, next);
-      return next;
-    } else if (optional('>', next)) {
-      // When `>>` is split, the inner group's endGroup updated here.
-      start.endGroup = next;
-      parser.listener.endTypeArguments(1, start, next);
-      return next;
-    } else if (optional('>>', next)) {
-      parser.listener.endTypeArguments(1, start, next);
-      // In this case, the last consumed token is the token before `>>`.
-      return token;
-    } else {
-      throw "Internal error: Expected '>' or '>>' but found '$next'.";
-    }
+  @override
+  Token parseVariables(Token token, Parser parser) {
+    BeginToken start = token = token.next;
+    assert(optional('<', token));
+    Listener listener = parser.listener;
+    listener.beginTypeVariables(token);
+    token = token.next;
+    listener.beginTypeVariable(token);
+    listener.beginMetadataStar(token);
+    listener.endMetadataStar(0);
+    listener.handleIdentifier(token, IdentifierContext.typeVariableDeclaration);
+    listener.handleNoType(token);
+    token = processEndGroup(token, start, parser);
+    listener.endTypeVariable(token, null);
+    listener.endTypeVariables(1, start, token);
+    return token;
   }
 
   @override
@@ -553,6 +563,10 @@
   /// `>>` for the outer group and the token before `>>` for the inner group.
   Token end;
 
+  /// A collection of `<` without closing `>` in the reverse order from which
+  /// they were encountered in the token stream.
+  Link<Token> unbalancedLt = const Link<Token>();
+
   ComplexTypeParamOrArgInfo(Token token)
       : assert(optional('<', token.next)),
         start = token.next;
@@ -575,7 +589,6 @@
     do {
       TypeInfo typeInfo = computeType(next, true, innerEndGroup);
       if (typeInfo == noType) {
-        // Recovery
         while (typeInfo == noType && optional('@', next.next)) {
           next = skipMetadata(next);
           typeInfo = computeType(next, true, innerEndGroup);
@@ -590,6 +603,10 @@
       }
       token = typeInfo.skipType(next);
       next = token.next;
+      if (optional('extends', next) || optional('super', next)) {
+        token = computeType(next, true, innerEndGroup).skipType(next);
+        next = token.next;
+      }
     } while (optional(',', next));
 
     if (next == start.endGroup) {
@@ -605,17 +622,60 @@
     return this;
   }
 
-  @override
-  Token parseArguments(Token token, Parser parser) {
-    assert(identical(start, token.next));
-
-    Token innerEndGroup;
-    if (start.endGroup != null && optional('>>', start.endGroup)) {
-      innerEndGroup = parser.rewriter.splitGtGt(start);
+  /// Parse the tokens and return the receiver or [noTypeParamOrArg] if there
+  /// are no type parameters or arguments. This does not modify the token
+  /// stream.
+  ///
+  /// This is called when parsing type parameters in a top level
+  /// or class member declaration. It assumes that a leading `<` cannot be part
+  /// of an expression, and thus tries to more aggressively recover
+  /// given an unmatched '<'.
+  ///
+  TypeParamOrArgInfo computeRecovery() {
+    assert(start.endGroup == null);
+    unbalancedLt = unbalancedLt.prepend(start);
+    Token token = start;
+    Token next = token.next;
+    while (!next.isEof) {
+      if (optional('Function', next)) {
+        next = next.next;
+        if (optional('<', next)) {
+          next = skipTypeVariables(next);
+          if (next == null) {
+            break;
+          }
+          next = next.next;
+        }
+        if (optional('(', next)) {
+          next = next.endGroup;
+        } else {
+          break;
+        }
+      } else if (optional('<', next)) {
+        Token endGroup = skipTypeVariables(next);
+        if (endGroup != null) {
+          next = endGroup;
+        } else {
+          unbalancedLt = unbalancedLt.prepend(next);
+        }
+      } else if (!isValidTypeReference(next) &&
+          !isOneOf(next, const ['.', ',', 'extends', 'super'])) {
+        break;
+      }
+      token = next;
+      next = token.next;
     }
 
-    Token next = start;
-    parser.listener.beginTypeArguments(start);
+    end = token;
+    return this;
+  }
+
+  @override
+  Token parseArguments(Token token, Parser parser) {
+    Token begin = balanceLt(token, parser);
+    Token next = begin;
+    Token innerEndGroup = processBeginGroup(begin, parser);
+    parser.listener.beginTypeArguments(begin);
     int count = 0;
     do {
       TypeInfo typeInfo = computeType(next, true, innerEndGroup);
@@ -633,28 +693,101 @@
       next = token.next;
       ++count;
     } while (optional(',', next));
+    end = processEndGroup(token, begin, parser);
+    parser.listener.endTypeArguments(count, begin, end);
+    return end;
+  }
 
-    if (next == start.endGroup) {
-      end = next;
-      parser.listener.endTypeArguments(count, start, end);
-      return end;
-    } else if (optional('>', next)) {
-      // When `>>` is split, this method is recursively called
-      // and the inner group's endGroup updated here.
-      assert(start.endGroup == null);
-      end = start.endGroup = next;
-      parser.listener.endTypeArguments(count, start, end);
-      return end;
-    } else if (optional('>>', next)) {
-      // In this case, the end or last consumed token is the token before `>>`.
-      end = token;
-      parser.listener.endTypeArguments(count, start, next);
-      return end;
-    } else {
-      throw "Internal error: Expected '>' or '>>' but found '$next'.";
-    }
+  @override
+  Token parseVariables(Token token, Parser parser) {
+    Token begin = balanceLt(token, parser);
+    Token next = begin;
+    Token innerEndGroup = processBeginGroup(begin, parser);
+    parser.listener.beginTypeVariables(begin);
+    int count = 0;
+    do {
+      parser.listener.beginTypeVariable(next.next);
+      token = parser.parseMetadataStar(next);
+      token = parser.ensureIdentifier(
+          token, IdentifierContext.typeVariableDeclaration);
+      Token extendsOrSuper = null;
+      next = token.next;
+      if (optional('extends', next) || optional('super', next)) {
+        extendsOrSuper = next;
+        token = computeType(next, true, innerEndGroup)
+            .ensureTypeOrVoid(next, parser);
+        next = token.next;
+      } else {
+        parser.listener.handleNoType(token);
+      }
+      parser.listener.endTypeVariable(next, extendsOrSuper);
+      ++count;
+    } while (optional(',', next));
+    end = processEndGroup(token, begin, parser);
+    parser.listener.endTypeVariables(count, begin, end);
+    return end;
   }
 
   @override
   Token skip(Token token) => end;
+
+  /// For every unbalanced `<` append a synthetic `>`. Return the first `<`
+  Token balanceLt(Token token, Parser parser) {
+    assert(identical(start, token.next));
+    if (unbalancedLt.isEmpty) {
+      return start;
+    }
+    Token begin = parser.rewriter.balanceLt(token, end, unbalancedLt);
+    assert(begin.endGroup != null);
+    if (begin.endGroup.isSynthetic) {
+      parser.reportRecoverableError(
+          begin.endGroup.next, fasta.templateExpectedButGot.withArguments('>'));
+    }
+    return begin;
+  }
+}
+
+Token processBeginGroup(BeginToken start, Parser parser) {
+  Token innerEndGroup;
+  if (start.endGroup != null && optional('>>', start.endGroup)) {
+    innerEndGroup = parser.rewriter.splitGtGt(start);
+  }
+  return innerEndGroup;
+}
+
+Token processEndGroup(Token token, BeginToken start, Parser parser) {
+  Token next = token.next;
+  if (next == start.endGroup) {
+    return next;
+  } else if (optional('>', next)) {
+    // When `>>` is split, the inner group's endGroup updated here.
+    assert(start.endGroup == null);
+    start.endGroup = next;
+    return next;
+  } else if (optional('>>', next)) {
+    // In this case, the last consumed token is the token before `>>`.
+    return token;
+  } else {
+    // Recovery
+    parser.reportRecoverableErrorWithToken(next, fasta.templateUnexpectedToken);
+    if (start.endGroup != null) {
+      return start.endGroup;
+    }
+    while (true) {
+      if (optional('>', next)) {
+        start.endGroup = next;
+        return next;
+      }
+      if (optional('>>', next)) {
+        // In this case, the last consumed token is the token before `>>`.
+        return token;
+      }
+      if (next.isEof) {
+        // Sanity check.
+        return next;
+      }
+      token = next;
+      next = token.next;
+    }
+  }
 }
diff --git a/pkg/front_end/lib/src/fasta/parser/util.dart b/pkg/front_end/lib/src/fasta/parser/util.dart
index 7eb1f46..bbbd361 100644
--- a/pkg/front_end/lib/src/fasta/parser/util.dart
+++ b/pkg/front_end/lib/src/fasta/parser/util.dart
@@ -39,6 +39,26 @@
   return token == null ? TreeNode.noOffset : token.offset;
 }
 
+/// Return true if the given token matches one of the given values.
+bool isOneOf(Token token, Iterable<String> values) {
+  for (String tokenValue in values) {
+    if (optional(tokenValue, token)) {
+      return true;
+    }
+  }
+  return false;
+}
+
+/// Return true if the given token matches one of the given values or is EOF.
+bool isOneOfOrEof(Token token, Iterable<String> values) {
+  for (String tokenValue in values) {
+    if (optional(tokenValue, token)) {
+      return true;
+    }
+  }
+  return token.isEof;
+}
+
 /// A null-aware alternative to `token.length`.  If [token] is `null`, returns
 /// [noLength].
 int lengthForToken(Token token) {
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 5419f26..5b02dc9 100644
--- a/pkg/front_end/lib/src/fasta/source/source_loader.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_loader.dart
@@ -20,7 +20,8 @@
         ProcedureKind,
         Supertype;
 
-import 'package:kernel/class_hierarchy.dart' show ClassHierarchy;
+import 'package:kernel/class_hierarchy.dart'
+    show ClassHierarchy, HandleAmbiguousSupertypes;
 
 import 'package:kernel/core_types.dart' show CoreTypes;
 
@@ -395,16 +396,16 @@
     ticker.logMs("Resolved $count type-variable bounds");
   }
 
-  void instantiateToBound(TypeBuilder dynamicType, TypeBuilder bottomType,
+  void computeDefaultTypes(TypeBuilder dynamicType, TypeBuilder bottomType,
       ClassBuilder objectClass) {
     int count = 0;
     builders.forEach((Uri uri, LibraryBuilder library) {
       if (library.loader == this) {
         count +=
-            library.instantiateToBound(dynamicType, bottomType, objectClass);
+            library.computeDefaultTypes(dynamicType, bottomType, objectClass);
       }
     });
-    ticker.logMs("Instantiated $count type variables to their bounds");
+    ticker.logMs("Computed default types for $count type variables");
   }
 
   void finishNativeMethods() {
@@ -619,17 +620,38 @@
     return new Component()..libraries.addAll(libraries);
   }
 
+  List<Class> computeListOfLoaderClasses() {
+    List<Class> result = <Class>[];
+    builders.forEach((Uri uri, LibraryBuilder libraryBuilder) {
+      if (!libraryBuilder.isPart &&
+          !libraryBuilder.isPatch &&
+          (libraryBuilder.loader == this)) {
+        Library library = libraryBuilder.target;
+        result.addAll(library.classes);
+      }
+    });
+    return result;
+  }
+
   void computeHierarchy() {
     List<List> ambiguousTypesRecords = [];
-    hierarchy = new ClassHierarchy(computeFullComponent(),
-        onAmbiguousSupertypes: (Class cls, Supertype a, Supertype b) {
+    HandleAmbiguousSupertypes onAmbiguousSupertypes =
+        (Class cls, Supertype a, Supertype b) {
       if (ambiguousTypesRecords != null) {
         ambiguousTypesRecords.add([cls, a, b]);
       }
-    },
-        mixinInferrer: target.strongMode
-            ? new StrongModeMixinInferrer(this)
-            : new LegacyModeMixinInferrer());
+    };
+    if (hierarchy == null) {
+      hierarchy = new ClassHierarchy(computeFullComponent(),
+          onAmbiguousSupertypes: onAmbiguousSupertypes,
+          mixinInferrer: target.strongMode
+              ? new StrongModeMixinInferrer(this)
+              : new LegacyModeMixinInferrer());
+    } else {
+      hierarchy.onAmbiguousSupertypes = onAmbiguousSupertypes;
+      hierarchy.applyTreeChanges(const [], computeListOfLoaderClasses(),
+          reissueAmbiguousSupertypesFor: computeFullComponent());
+    }
     for (List record in ambiguousTypesRecords) {
       handleAmbiguousSupertypes(record[0], record[1], record[2]);
     }
@@ -687,7 +709,7 @@
 
     for (SourceClassBuilder builder in sourceClasses) {
       if (builder.library.loader == this) {
-        builder.addNoSuchMethodForwarders(hierarchy);
+        builder.addNoSuchMethodForwarders(target, hierarchy);
       }
     }
     ticker.logMs("Added noSuchMethod forwarders");
@@ -736,11 +758,27 @@
   /// assign their types.
   void performTopLevelInference(List<SourceClassBuilder> sourceClasses) {
     typeInferenceEngine.finishTopLevelFields();
+    List<Class> changedClasses = new List<Class>();
     for (var builder in orderedClasses) {
       ShadowClass class_ = builder.target;
+      int memberCount = class_.fields.length +
+          class_.constructors.length +
+          class_.procedures.length +
+          class_.redirectingFactoryConstructors.length;
       class_.finalizeCovariance(interfaceResolver);
       ShadowClass.clearClassInferenceInfo(class_);
+      int newMemberCount = class_.fields.length +
+          class_.constructors.length +
+          class_.procedures.length +
+          class_.redirectingFactoryConstructors.length;
+      if (newMemberCount != memberCount) {
+        // The inference potentially adds new members (but doesn't otherwise
+        // change the classes), so if the member count has changed we need to
+        // update the class in the class hierarchy.
+        changedClasses.add(class_);
+      }
     }
+
     orderedClasses = null;
     typeInferenceEngine.finishTopLevelInitializingFormals();
     if (instrumentation != null) {
@@ -754,11 +792,8 @@
     // Since finalization of covariance may have added forwarding stubs, we need
     // to recompute the class hierarchy so that method compilation will properly
     // target those forwarding stubs.
-    // TODO(paulberry): could we make this unnecessary by not clearing class
-    // inference info?
-    typeInferenceEngine.classHierarchy = hierarchy = new ClassHierarchy(
-        computeFullComponent(),
-        onAmbiguousSupertypes: ignoreAmbiguousSupertypes);
+    hierarchy.onAmbiguousSupertypes = ignoreAmbiguousSupertypes;
+    hierarchy.applyMemberChanges(changedClasses, findDescendants: true);
     ticker.logMs("Performed top level inference");
   }
 
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 938ad81..f312680 100644
--- a/pkg/front_end/lib/src/fasta/source/stack_listener.dart
+++ b/pkg/front_end/lib/src/fasta/source/stack_listener.dart
@@ -277,6 +277,11 @@
   }
 
   @override
+  void handleParenthesizedCondition(Token token) {
+    debugEvent("handleParenthesizedCondition");
+  }
+
+  @override
   void handleParenthesizedExpression(Token token) {
     debugEvent("ParenthesizedExpression");
   }
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 06f8279..0333163 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
@@ -13,22 +13,10 @@
 import 'package:front_end/src/fasta/type_inference/type_schema_environment.dart';
 import 'package:kernel/ast.dart';
 import 'package:kernel/class_hierarchy.dart';
-import 'package:kernel/text/ast_to_text.dart';
 import 'package:kernel/transformations/flags.dart' show TransformerFlag;
 import 'package:kernel/type_algebra.dart';
 import 'package:kernel/type_environment.dart';
 
-/// Set this flag to `true` to cause debugging information about covariance
-/// checks to be printed to standard output.
-const bool debugCovariance = false;
-
-/// Type of a closure which applies a covariance annotation to a class member.
-///
-/// This is necessary since we need to determine which covariance annotations
-/// need to be added before creating a forwarding stub, but the covariance
-/// annotations themselves need to be applied to the forwarding stub.
-typedef void _CovarianceFix(FunctionNode function);
-
 /// Concrete class derived from [InferenceNode] to represent type inference of
 /// getters, setters, and fields based on inheritance.
 class AccessorInferenceNode extends InferenceNode {
@@ -192,41 +180,59 @@
   /// Does not create forwarding stubs.
   Procedure resolve() => _resolution ??= _resolve();
 
-  /// Determines which covariance fixes need to be applied to the given
-  /// [interfaceMember].
+  /// Tag the parameters of [interfaceMember] that need type checks
   ///
-  /// [substitution] indicates the necessary substitutions to convert types
-  /// named in [interfaceMember] to types in the target class.
+  /// Parameters can need type checks for calls coming from statically typed
+  /// call sites, due to covariant generics and overrides with explicit
+  /// `covariant` parameters.
   ///
-  /// The fixes are not applied immediately (since [interfaceMember] might be
-  /// a member of another class, and a forwarding stub may need to be
-  /// generated).
-  void _computeCovarianceFixes(Substitution substitution,
-      Procedure interfaceMember, List<_CovarianceFix> fixes) {
-    if (debugCovariance) {
-      print('Considering covariance fixes for '
-          '${_printProcedure(interfaceMember, enclosingClass)}');
-      for (int i = _start; i < _end; i++) {
-        print('  Candidate: ${_printProcedure(_candidates[i])}');
-      }
-    }
-    var class_ = enclosingClass;
+  /// Tag parameters of [interfaceMember] that need such checks when the member
+  /// occurs in [enclosingClass]'s interface.  If parameters need checks but
+  /// they would not be checked in an inherited implementation, a forwarding
+  /// stub is introduced as a place to put the checks.
+  Procedure _computeCovarianceFixes(Procedure interfaceMember) {
+    assert(_interfaceResolver.strongMode);
+    var substitution =
+        _interfaceResolver._substitutionFor(interfaceMember, enclosingClass);
+    // We always create a forwarding stub when we've inherited a member from an
+    // interface other than the first override candidate.  This is to work
+    // around a bug in the Kernel type checker where it chooses the first
+    // override candidate.
+    //
+    // TODO(kmillikin): Fix the Kernel type checker and stop creating these
+    // extra stubs.
+    var stub = interfaceMember.enclosingClass == enclosingClass ||
+            interfaceMember == _resolvedCandidate(_start)
+        ? interfaceMember
+        : _createForwardingStub(substitution, interfaceMember);
+
     var interfaceFunction = interfaceMember.function;
     var interfacePositionalParameters = interfaceFunction.positionalParameters;
     var interfaceNamedParameters = interfaceFunction.namedParameters;
     var interfaceTypeParameters = interfaceFunction.typeParameters;
+
+    void createStubIfNeeded() {
+      if (stub != interfaceMember) return;
+      if (interfaceMember.enclosingClass == enclosingClass) return;
+      stub = _createForwardingStub(substitution, interfaceMember);
+    }
+
     bool isImplCreated = false;
     void createImplIfNeeded() {
       if (isImplCreated) return;
-      fixes.add(_createForwardingImplIfNeeded);
+      createStubIfNeeded();
+      _createForwardingImplIfNeeded(stub.function);
       isImplCreated = true;
     }
 
     IncludesTypeParametersCovariantly needsCheckVisitor =
-        class_.typeParameters.isEmpty
+        enclosingClass.typeParameters.isEmpty
             ? null
-            : ShadowClass.getClassInferenceInfo(class_).needsCheckVisitor ??=
-                new IncludesTypeParametersCovariantly(class_.typeParameters);
+            : ShadowClass
+                    .getClassInferenceInfo(enclosingClass)
+                    .needsCheckVisitor ??=
+                new IncludesTypeParametersCovariantly(
+                    enclosingClass.typeParameters);
     bool needsCheck(DartType type) => needsCheckVisitor == null
         ? false
         : substitution.substituteType(type).accept(needsCheckVisitor);
@@ -252,19 +258,23 @@
           isCovariant = true;
         }
       }
-      if (isGenericCovariantImpl != superParameter.isGenericCovariantImpl) {
-        createImplIfNeeded();
+      if (isGenericCovariantImpl) {
+        if (!superParameter.isGenericCovariantImpl) {
+          createImplIfNeeded();
+        }
+        if (!parameter.isGenericCovariantImpl) {
+          createStubIfNeeded();
+          stub.function.positionalParameters[i].isGenericCovariantImpl = true;
+        }
       }
-      if (isGenericCovariantImpl != parameter.isGenericCovariantImpl) {
-        fixes.add((FunctionNode function) => function.positionalParameters[i]
-            .isGenericCovariantImpl = isGenericCovariantImpl);
-      }
-      if (isCovariant != superParameter.isCovariant) {
-        createImplIfNeeded();
-      }
-      if (isCovariant != parameter.isCovariant) {
-        fixes.add((FunctionNode function) =>
-            function.positionalParameters[i].isCovariant = isCovariant);
+      if (isCovariant) {
+        if (!superParameter.isCovariant) {
+          createImplIfNeeded();
+        }
+        if (!parameter.isCovariant) {
+          createStubIfNeeded();
+          stub.function.positionalParameters[i].isCovariant = true;
+        }
       }
     }
     for (int i = 0; i < interfaceNamedParameters.length; i++) {
@@ -288,19 +298,23 @@
           isCovariant = true;
         }
       }
-      if (isGenericCovariantImpl != superParameter.isGenericCovariantImpl) {
-        createImplIfNeeded();
+      if (isGenericCovariantImpl) {
+        if (!superParameter.isGenericCovariantImpl) {
+          createImplIfNeeded();
+        }
+        if (!parameter.isGenericCovariantImpl) {
+          createStubIfNeeded();
+          stub.function.namedParameters[i].isGenericCovariantImpl = true;
+        }
       }
-      if (isGenericCovariantImpl != parameter.isGenericCovariantImpl) {
-        fixes.add((FunctionNode function) => function.namedParameters[i]
-            .isGenericCovariantImpl = isGenericCovariantImpl);
-      }
-      if (isCovariant != superParameter.isCovariant) {
-        createImplIfNeeded();
-      }
-      if (isCovariant != parameter.isCovariant) {
-        fixes.add((FunctionNode function) =>
-            function.namedParameters[i].isCovariant = isCovariant);
+      if (isCovariant) {
+        if (!superParameter.isCovariant) {
+          createImplIfNeeded();
+        }
+        if (!parameter.isCovariant) {
+          createStubIfNeeded();
+          stub.function.namedParameters[i].isCovariant = true;
+        }
       }
     }
     for (int i = 0; i < interfaceTypeParameters.length; i++) {
@@ -320,18 +334,17 @@
           isGenericCovariantImpl = true;
         }
       }
-      if (isGenericCovariantImpl != superTypeParameter.isGenericCovariantImpl) {
-        createImplIfNeeded();
-      }
-      if (isGenericCovariantImpl != typeParameter.isGenericCovariantImpl) {
-        fixes.add((FunctionNode function) => function
-            .typeParameters[i].isGenericCovariantImpl = isGenericCovariantImpl);
+      if (isGenericCovariantImpl) {
+        if (!superTypeParameter.isGenericCovariantImpl) {
+          createImplIfNeeded();
+        }
+        if (!typeParameter.isGenericCovariantImpl) {
+          createStubIfNeeded();
+          stub.function.typeParameters[i].isGenericCovariantImpl = true;
+        }
       }
     }
-
-    if (debugCovariance && fixes.isNotEmpty) {
-      print('  ${fixes.length} fix(es)');
-    }
+    return stub;
   }
 
   void _createForwardingImplIfNeeded(FunctionNode function) {
@@ -467,28 +480,9 @@
   /// Creates a forwarding stub for this node if necessary, and propagates
   /// covariance information.
   Procedure _finalize() {
-    var member = resolve();
-    var substitution =
-        _interfaceResolver._substitutionFor(member, enclosingClass);
-    bool isDeclaredInThisClass =
-        identical(member.enclosingClass, enclosingClass);
-
-    // Now decide whether we need a forwarding stub or not, and propagate
-    // covariance.
-    var covarianceFixes = <_CovarianceFix>[];
-    if (_interfaceResolver.strongMode) {
-      _computeCovarianceFixes(substitution, member, covarianceFixes);
-    }
-    if (!isDeclaredInThisClass &&
-        (!identical(member, _resolvedCandidate(_start)) ||
-            covarianceFixes.isNotEmpty)) {
-      member = _createForwardingStub(substitution, member);
-    }
-    var function = member.function;
-    for (var fix in covarianceFixes) {
-      fix(function);
-    }
-    return member;
+    return _interfaceResolver.strongMode
+        ? _computeCovarianceFixes(resolve())
+        : resolve();
   }
 
   /// Returns the [i]th element of [_candidates], finalizing it if necessary.
@@ -500,29 +494,6 @@
         : candidate;
   }
 
-  /// Returns a string describing the signature of [procedure], along with the
-  /// class it's in.
-  ///
-  /// Only used if [debugCovariance] is `true`.
-  ///
-  /// If [class_] is provided, it is used instead of [procedure]'s enclosing
-  /// class.
-  String _printProcedure(Procedure procedure, [Class class_]) {
-    class_ ??= procedure.enclosingClass;
-    var buffer = new StringBuffer();
-    if (procedure.function == null) {
-      buffer.write(procedure.toString());
-    } else {
-      procedure.accept(new Printer(buffer));
-    }
-    var text = buffer.toString();
-    var newlineIndex = text.indexOf('\n');
-    if (newlineIndex != -1) {
-      text = text.substring(0, newlineIndex);
-    }
-    return '$class_: $text';
-  }
-
   /// Determines which inherited member this node resolves to, and also performs
   /// type inference.
   Procedure _resolve() {
@@ -797,7 +768,6 @@
     int getterIndex = 0;
     int setterIndex = 0;
     forEachApiMember(candidates, (int start, int end, Name name) {
-      // TODO(paulberry): check for illegal getter/method mixing
       Procedure member = candidates[start];
       ProcedureKind kind = _kindOf(member);
       if (kind != ProcedureKind.Getter && kind != ProcedureKind.Setter) {
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 719ca60..eaa54e0 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
@@ -62,10 +62,8 @@
 
 import '../fasta_codes.dart';
 
-import '../kernel/fasta_accessors.dart'
-    show BuilderHelper, CalleeDesignation, FunctionTypeAccessor;
-
-import '../kernel/frontend_accessors.dart' show buildIsNull;
+import '../kernel/expression_generator.dart'
+    show BuilderHelper, CalleeDesignation, FunctionTypeAccessor, buildIsNull;
 
 import '../kernel/kernel_shadow_ast.dart'
     show
@@ -496,7 +494,7 @@
           var parent = expression.parent;
           var t = new VariableDeclaration.forValue(expression, type: actualType)
             ..fileOffset = fileOffset;
-          var nullCheck = buildIsNull(new VariableGet(t), fileOffset);
+          var nullCheck = buildIsNull(new VariableGet(t), fileOffset, helper);
           var tearOff =
               new PropertyGet(new VariableGet(t), callName, callMember)
                 ..fileOffset = fileOffset;
diff --git a/pkg/front_end/lib/src/scanner/token.dart b/pkg/front_end/lib/src/scanner/token.dart
index 530b6f0..7842a42 100644
--- a/pkg/front_end/lib/src/scanner/token.dart
+++ b/pkg/front_end/lib/src/scanner/token.dart
@@ -216,12 +216,17 @@
 
   static const Keyword IN = const Keyword("in", "IN");
 
+  static const Keyword INTERFACE =
+      const Keyword("interface", "INTERFACE", isBuiltIn: true);
+
   static const Keyword IS =
       const Keyword("is", "IS", precedence: RELATIONAL_PRECEDENCE);
 
   static const Keyword LIBRARY = const Keyword("library", "LIBRARY",
       isBuiltIn: true, isTopLevelKeyword: true);
 
+  static const Keyword MIXIN = const Keyword("mixin", "MIXIN", isBuiltIn: true);
+
   static const Keyword NATIVE =
       const Keyword("native", "NATIVE", isPseudo: true);
 
@@ -316,8 +321,10 @@
     IMPLEMENTS,
     IMPORT,
     IN,
+    INTERFACE,
     IS,
     LIBRARY,
+    MIXIN,
     NATIVE,
     NEW,
     NULL,
diff --git a/pkg/front_end/messages.status b/pkg/front_end/messages.status
index 692b8d5..d6a7570 100644
--- a/pkg/front_end/messages.status
+++ b/pkg/front_end/messages.status
@@ -1,6 +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.md file.
+
 AbstractClassInstantiation/analyzerCode: Fail
 AbstractClassInstantiation/example: Fail
 AbstractClassMember/script5: Fail
@@ -61,6 +62,26 @@
 ConstAndVar/script1: Fail
 ConstConstructorNonFinalField/analyzerCode: Fail
 ConstConstructorNonFinalField/example: Fail
+ConstEvalContext/analyzerCode: Fail # This is just used for displaying the context.
+ConstEvalContext/example: Fail # This is just used for displaying the context.
+ConstEvalDuplicateKey/dart2jsCode: Fail
+ConstEvalDuplicateKey/example: Fail
+ConstEvalFailedAssertion/dart2jsCode: Fail
+ConstEvalFailedAssertion/example: Fail
+ConstEvalFailedAssertionWithMessage/dart2jsCode: Fail
+ConstEvalFailedAssertionWithMessage/example: Fail
+ConstEvalInvalidBinaryOperandType/analyzerCode: Fail # CONST_EVAL_TYPE_NUM / CONST_EVAL_TYPE_BOOL
+ConstEvalInvalidBinaryOperandType/example: Fail
+ConstEvalInvalidMethodInvocation/dart2jsCode: Fail
+ConstEvalInvalidMethodInvocation/example: Fail
+ConstEvalInvalidStaticInvocation/dart2jsCode: Fail
+ConstEvalInvalidStaticInvocation/example: Fail
+ConstEvalInvalidStringInterpolationOperand/dart2jsCode: Fail
+ConstEvalInvalidStringInterpolationOperand/example: Fail
+ConstEvalInvalidType/analyzerCode: Fail # CONST_CONSTRUCTOR_FIELD_TYPE_MISMATCH / CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH / CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH / ...
+ConstEvalInvalidType/example: Fail
+ConstEvalNonConstantLiteral/dart2jsCode: Fail
+ConstEvalNonConstantLiteral/example: Fail
 ConstFieldWithoutInitializer/example: Fail
 ConstructorHasNoSuchNamedParameter/analyzerCode: Fail
 ConstructorHasNoSuchNamedParameter/example: Fail
@@ -170,6 +191,10 @@
 FinalFieldWithoutInitializer/example: Fail
 FinalInstanceVariableAlreadyInitialized/analyzerCode: Fail
 FinalInstanceVariableAlreadyInitialized/example: Fail
+ForInLoopExactlyOneVariable/analyzerCode: Fail # The analyzer doesn't recover well.
+ForInLoopExactlyOneVariable/statement: Fail # Fasta reports too many errors.
+ForInLoopNotAssignable/analyzerCode: Fail # The analyzer reports a different error.
+ForInLoopNotAssignable/statement: Fail
 FunctionHasNoSuchNamedParameter/analyzerCode: Fail
 FunctionHasNoSuchNamedParameter/example: Fail
 FunctionTypeDefaultValue/example: Fail
@@ -390,7 +415,6 @@
 TypeVariableInStaticContext/example: Fail
 TypeVariableSameNameAsEnclosing/analyzerCode: Fail
 TypeVariableSameNameAsEnclosing/example: Fail
-TypedefNotFunction/analyzerCode: Fail
 TypedefNotFunction/example: Fail
 UnexpectedDollarInString/analyzerCode: Fail
 UnexpectedDollarInString/script1: Fail
diff --git a/pkg/front_end/messages.yaml b/pkg/front_end/messages.yaml
index f18ea4d..acbe910 100644
--- a/pkg/front_end/messages.yaml
+++ b/pkg/front_end/messages.yaml
@@ -77,6 +77,43 @@
   analyzerCode: ILLEGAL_CHARACTER
   expression: "\x1b 1"
 
+ConstEvalContext:
+  template: "While analyzing:"
+
+ConstEvalDuplicateKey:
+  template: "The key '#constant' conflicts with another existing key in the map."
+  analyzerCode: EQUAL_KEYS_IN_MAP
+
+ConstEvalNonConstantLiteral:
+  template: "Can't have a non-constant #string literal within a const context."
+  analyzerCode: NON_CONSTANT_DEFAULT_VALUE
+
+ConstEvalInvalidType:
+  template: "Expected constant '#constant' to be of type '#type', but was of type '#type2'."
+
+ConstEvalInvalidBinaryOperandType:
+  template: "Binary operator '#string' on '#constant' requires operand of type '#type', but was of type '#type2'."
+
+ConstEvalInvalidMethodInvocation:
+  template: "The method '#string' can't be invoked on '#constant' within a const context."
+  analyzerCode: UNDEFINED_OPERATOR
+
+ConstEvalInvalidStringInterpolationOperand:
+  template: "The '#constant' can't be used as part of a string interpolation within a const context, only values of type 'null', 'bool', 'int', 'double', or 'String' can be used."
+  analyzerCode: CONST_EVAL_TYPE_BOOL_NUM_STRING
+
+ConstEvalInvalidStaticInvocation:
+  template: "The invocation of '#name' is not allowed within a const context."
+  analyzerCode: CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
+
+ConstEvalFailedAssertion:
+  template: "This assertion failed."
+  analyzerCode: CONST_EVAL_THROWS_EXCEPTION
+
+ConstEvalFailedAssertionWithMessage:
+  template: "This assertion failed with message: #string"
+  analyzerCode: CONST_EVAL_THROWS_EXCEPTION
+
 NonAsciiIdentifier:
   template: "The non-ASCII character '#character' (#unicode) can't be used in identifiers, only in strings and comments."
   tip: "Try using an US-ASCII letter, a digit, '_' (an underscore), or '$' (a dollar sign)."
@@ -1165,7 +1202,7 @@
         Read the SDK platform from <file>, which should be in Dill/Kernel IR format
         and contain the Dart SDK.
 
-      --target=none|vm|vmcc|vmreify|flutter
+      --target=dart2js|dart2js_server|dart_runner|flutter|flutter_runner|none|vm
         Specify the target configuration.
 
       --verify
@@ -1611,6 +1648,8 @@
 
 TypedefNotFunction:
   template: "Can't create typedef from non-function type."
+  analyzerCode: INVALID_GENERIC_FUNCTION_TYPE
+  dart2jsCode: "*fatal*"
 
 LibraryDirectiveNotFirst:
   template: "The library directive must appear before all other directives."
@@ -2182,3 +2221,19 @@
 ExpectedOneExpression:
   template: "Expected one expression, but found additional input."
   severity: ERROR
+
+ForInLoopNotAssignable:
+  template: "Can't assign to this, so it can't be used in a for-in loop."
+  severity: ERROR
+  statement: "for (1 in []) {}"
+  script: |
+    import "dart:core" as prefix;
+
+    main() {
+      for (prefix in []) {}
+    }
+
+ForInLoopExactlyOneVariable:
+  template: "A for-in loop can't have more than one loop variable."
+  severity: ERROR
+  statement: "for (var x, y in []) {}"
diff --git a/pkg/front_end/pubspec.yaml b/pkg/front_end/pubspec.yaml
index 1f9aa73..90c0247 100644
--- a/pkg/front_end/pubspec.yaml
+++ b/pkg/front_end/pubspec.yaml
@@ -1,22 +1,24 @@
 name: front_end
-version: 0.1.0-alpha.12
+# Currently, front_end API is not stable and users should not
+# depend on semver semantics when depending on this package.
+version: 0.1.0
 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
 environment:
-  sdk: '>=1.12.0 <2.0.0'
+  sdk: '>=2.0.0-dev.48.0 <2.0.0'
 dependencies:
   charcode: '^1.1.1'
   convert: '^2.0.1'
   crypto: '^2.0.2'
-  kernel: 0.3.0-alpha.12
+  kernel: 0.3.0
   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.30.0 <0.32.0'
+  analyzer: '>=0.31.0 <0.33.0'
   args: '>=0.13.0 <2.0.0'
   dart_style: '^1.0.7'
   json_rpc_2: ^2.0.4
diff --git a/pkg/front_end/test/fasta/expression_test.dart b/pkg/front_end/test/fasta/expression_test.dart
index 4a21e78..ee97b9d 100644
--- a/pkg/front_end/test/fasta/expression_test.dart
+++ b/pkg/front_end/test/fasta/expression_test.dart
@@ -325,6 +325,7 @@
             test.expression,
             definitions,
             typeParams,
+            "debugExpr",
             test.library,
             test.className,
             test.isStaticMethod);
diff --git a/pkg/front_end/test/fasta/generator_to_string_test.dart b/pkg/front_end/test/fasta/generator_to_string_test.dart
new file mode 100644
index 0000000..de65fd9
--- /dev/null
+++ b/pkg/front_end/test/fasta/generator_to_string_test.dart
@@ -0,0 +1,232 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/// Test of toString on generators.
+
+import 'package:expect/expect.dart' show Expect;
+
+import 'package:kernel/ast.dart'
+    show
+        Arguments,
+        Class,
+        DartType,
+        Expression,
+        FunctionNode,
+        Library,
+        Member,
+        Name,
+        Procedure,
+        ProcedureKind,
+        StringLiteral,
+        TypeParameter,
+        VariableDeclaration,
+        VariableGet,
+        VoidType;
+
+import 'package:kernel/target/targets.dart' show NoneTarget, TargetFlags;
+
+import 'package:front_end/src/fasta/compiler_context.dart' show CompilerContext;
+
+import 'package:front_end/src/fasta/dill/dill_target.dart' show DillTarget;
+
+import 'package:front_end/src/fasta/kernel/kernel_builder.dart'
+    show
+        KernelLibraryBuilder,
+        KernelTypeVariableBuilder,
+        LoadLibraryBuilder,
+        PrefixBuilder,
+        TypeDeclarationBuilder;
+
+import 'package:front_end/src/fasta/kernel/kernel_target.dart'
+    show KernelTarget;
+
+import 'package:front_end/src/fasta/fasta_codes.dart'
+    show Message, templateUnspecified;
+
+import 'package:front_end/src/fasta/kernel/expression_generator.dart'
+    show
+        DeferredAccessGenerator,
+        FastaAccessor,
+        IncompleteError,
+        IncompletePropertyAccessor,
+        IndexedAccessGenerator,
+        LargeIntAccessGenerator,
+        LoadLibraryGenerator,
+        NullAwarePropertyAccessGenerator,
+        ParenthesizedExpression,
+        PropertyAccessGenerator,
+        ReadOnlyAccessGenerator,
+        SendAccessor,
+        StaticAccessGenerator,
+        SuperIndexedAccessGenerator,
+        SuperPropertyAccessGenerator,
+        ThisAccessGenerator,
+        ThisIndexedAccessGenerator,
+        ThisPropertyAccessGenerator,
+        TypeDeclarationAccessor,
+        UnresolvedAccessor,
+        VariableUseGenerator;
+
+import 'package:front_end/src/fasta/kernel/body_builder.dart'
+    show DelayedAssignment, DelayedPostfixIncrement;
+
+import 'package:front_end/src/fasta/kernel/kernel_body_builder.dart'
+    show KernelBodyBuilder;
+
+import 'package:front_end/src/fasta/scanner.dart' show Token, scanString;
+
+void check(String expected, FastaAccessor<Arguments> generator) {
+  Expect.stringEquals(expected, "$generator");
+}
+
+main() {
+  CompilerContext.runWithDefaultOptions((CompilerContext c) {
+    Token token = scanString("    myToken").tokens;
+    Uri uri = Uri.parse("org-dartlang-test:my_library.dart");
+
+    Arguments arguments = new Arguments(<Expression>[new StringLiteral("arg")]);
+    DartType type = const VoidType();
+    Expression expression =
+        new VariableGet(new VariableDeclaration("expression"));
+    Expression index = new VariableGet(new VariableDeclaration("index"));
+    KernelLibraryBuilder libraryBuilder = new KernelLibraryBuilder(
+        uri,
+        uri,
+        new KernelTarget(
+                null,
+                false,
+                new DillTarget(null, null, new NoneTarget(new TargetFlags())),
+                null)
+            .loader,
+        null,
+        null);
+    LoadLibraryBuilder loadLibraryBuilder =
+        new LoadLibraryBuilder(libraryBuilder, null, -1);
+    Member getter = new Procedure(
+        new Name("myGetter"), ProcedureKind.Getter, new FunctionNode(null));
+    Member interfaceTarget = new Procedure(new Name("myInterfaceTarget"),
+        ProcedureKind.Method, new FunctionNode(null));
+    Member setter = new Procedure(
+        new Name("mySetter"), ProcedureKind.Setter, new FunctionNode(null));
+    Message message = templateUnspecified.withArguments("My Message.");
+    Name binaryOperator = new Name("+");
+    Name name = new Name("bar");
+    PrefixBuilder prefixBuilder =
+        new PrefixBuilder("myPrefix", false, libraryBuilder, -1);
+    String assignmentOperator = "+=";
+    TypeDeclarationBuilder declaration =
+        new KernelTypeVariableBuilder.fromKernel(
+            new TypeParameter("T"), libraryBuilder);
+    VariableDeclaration variable = new VariableDeclaration(null);
+
+    KernelBodyBuilder helper = new KernelBodyBuilder(
+        libraryBuilder, null, null, null, null, null, null, false, uri, null);
+
+    FastaAccessor accessor =
+        new ThisAccessGenerator<Arguments>(helper, token, false);
+
+    Library library = new Library(uri);
+    Class cls = new Class();
+    library.addClass(cls);
+    library.addProcedure(getter);
+    library.addProcedure(setter);
+    cls.addMember(interfaceTarget);
+
+    check(
+        "DelayedAssignment(offset: 4, value: expression,"
+        " assignmentOperator: +=)",
+        new DelayedAssignment<Arguments>(
+            helper, token, accessor, expression, assignmentOperator));
+    check(
+        "DelayedPostfixIncrement(offset: 4, binaryOperator: +,"
+        " interfaceTarget: $uri::#class1::myInterfaceTarget)",
+        new DelayedPostfixIncrement<Arguments>(
+            helper, token, accessor, binaryOperator, interfaceTarget));
+    check(
+        "VariableUseGenerator(offset: 4, variable: dynamic #t1;\n,"
+        " promotedType: void)",
+        new VariableUseGenerator<Arguments>(helper, token, variable, type));
+    check(
+        "PropertyAccessGenerator(offset: 4, _receiverVariable: null,"
+        " receiver: expression, name: bar, getter: $uri::myGetter,"
+        " setter: $uri::mySetter)",
+        new PropertyAccessGenerator<Arguments>.internal(
+            helper, token, expression, name, getter, setter));
+    check(
+        "ThisPropertyAccessGenerator(offset: 4, name: bar,"
+        " getter: $uri::myGetter, setter: $uri::mySetter)",
+        new ThisPropertyAccessGenerator<Arguments>(
+            helper, token, name, getter, setter));
+    check(
+        "NullAwarePropertyAccessGenerator(offset: 4,"
+        " receiver: final dynamic #t1 = expression;\n,"
+        " receiverExpression: expression, name: bar, getter: $uri::myGetter,"
+        " setter: $uri::mySetter, type: void)",
+        new NullAwarePropertyAccessGenerator<Arguments>(
+            helper, token, expression, name, getter, setter, type));
+    check(
+        "SuperPropertyAccessGenerator(offset: 4, name: bar,"
+        " getter: $uri::myGetter, setter: $uri::mySetter)",
+        new SuperPropertyAccessGenerator<Arguments>(
+            helper, token, name, getter, setter));
+    check(
+        "IndexedAccessGenerator(offset: 4, receiver: expression, index: index,"
+        " getter: $uri::myGetter, setter: $uri::mySetter,"
+        " receiverVariable: null, indexVariable: null)",
+        new IndexedAccessGenerator<Arguments>.internal(
+            helper, token, expression, index, getter, setter));
+    check(
+        "ThisIndexedAccessGenerator(offset: 4, index: index,"
+        " getter: $uri::myGetter, setter: $uri::mySetter, indexVariable: null)",
+        new ThisIndexedAccessGenerator<Arguments>(
+            helper, token, index, getter, setter));
+    check(
+        "SuperIndexedAccessGenerator(offset: 4, index: index,"
+        " getter: $uri::myGetter, setter: $uri::mySetter, indexVariable: null)",
+        new SuperIndexedAccessGenerator<Arguments>(
+            helper, token, index, getter, setter));
+    check(
+        "StaticAccessGenerator(offset: 4, readTarget: $uri::myGetter,"
+        " writeTarget: $uri::mySetter)",
+        new StaticAccessGenerator<Arguments>(helper, token, getter, setter));
+    check(
+        "LoadLibraryGenerator(offset: 4,"
+        " builder: Instance of 'LoadLibraryBuilder')",
+        new LoadLibraryGenerator<Arguments>(helper, token, loadLibraryBuilder));
+    check(
+        "ThisAccessGenerator(offset: 4, isInitializer: false, isSuper: false)",
+        new ThisAccessGenerator<Arguments>(helper, token, false));
+    check("IncompleteError(offset: 4, message: Unspecified)",
+        new IncompleteError<Arguments>(helper, token, message));
+    check("SendAccessor(offset: 4, name: bar, arguments: (\"arg\"))",
+        new SendAccessor<Arguments>(helper, token, name, arguments));
+    check("IncompletePropertyAccessor(offset: 4, name: bar)",
+        new IncompletePropertyAccessor<Arguments>(helper, token, name));
+    check(
+        "DeferredAccessGenerator(offset: 4, "
+        "builder: Instance of 'PrefixBuilder',"
+        " accessor: ThisAccessGenerator(offset: 4, isInitializer: false,"
+        " isSuper: false))",
+        new DeferredAccessGenerator<Arguments>(
+            helper, token, prefixBuilder, accessor));
+    check(
+        "ReadOnlyAccessGenerator(offset: 4, expression: expression,"
+        " plainNameForRead: foo, value: null)",
+        new ReadOnlyAccessGenerator<Arguments>(
+            helper, token, expression, "foo"));
+    check("LargeIntAccessGenerator(offset: 4, lexeme: myToken)",
+        new LargeIntAccessGenerator<Arguments>(helper, token));
+    check(
+        "ParenthesizedExpression(offset: 4, expression: expression,"
+        " plainNameForRead: null, value: null)",
+        new ParenthesizedExpression<Arguments>(helper, token, expression));
+    check(
+        "TypeDeclarationAccessor(offset: 4, expression: T,"
+        " plainNameForRead: foo, value: null)",
+        new TypeDeclarationAccessor<Arguments>(
+            helper, token, prefixBuilder, -1, declaration, "foo"));
+    check("UnresolvedAccessor(offset: 4, name: bar)",
+        new UnresolvedAccessor<Arguments>(helper, token, name));
+  });
+}
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 c0b27e8..4790175 100644
--- a/pkg/front_end/test/fasta/parser/type_info_test.dart
+++ b/pkg/front_end/test/fasta/parser/type_info_test.dart
@@ -247,7 +247,7 @@
         'handleIdentifier T typeReference',
         'handleNoTypeArguments >>',
         'handleType T >>',
-        'endTypeArguments 1 < >>',
+        'endTypeArguments 1 < T',
         'handleType C >>',
       ]);
       expect(listener.errors, isNull);
@@ -304,16 +304,16 @@
         expectedErrors: [error(codeBuiltInIdentifierAsType, 0, 6)]);
     expectComplexInfo('abstract Function()',
         required: false,
-        tokenAfter: 'Function',
+        expectedAfter: 'Function',
         expectedErrors: [error(codeBuiltInIdentifierAsType, 0, 8)]);
     expectComplexInfo('export Function()',
         required: false,
-        tokenAfter: 'Function',
+        expectedAfter: 'Function',
         expectedErrors: [error(codeBuiltInIdentifierAsType, 0, 6)]);
   }
 
   void test_computeType_gft() {
-    expectComplexInfo('Function() m', tokenAfter: 'm', expectedCalls: [
+    expectComplexInfo('Function() m', expectedAfter: 'm', expectedCalls: [
       'handleNoTypeVariables (',
       'beginFunctionType Function',
       'handleNoType ',
@@ -321,7 +321,7 @@
       'endFormalParameters 0 ( ) MemberKind.GeneralizedFunctionType',
       'endFunctionType Function m',
     ]);
-    expectComplexInfo('Function<T>() m', tokenAfter: 'm', expectedCalls: [
+    expectComplexInfo('Function<T>() m', expectedAfter: 'm', expectedCalls: [
       'beginTypeVariables <',
       'beginTypeVariable T',
       'beginMetadataStar T',
@@ -336,7 +336,7 @@
       'endFormalParameters 0 ( ) MemberKind.GeneralizedFunctionType',
       'endFunctionType Function m',
     ]);
-    expectComplexInfo('Function(int) m', tokenAfter: 'm', expectedCalls: [
+    expectComplexInfo('Function(int) m', expectedAfter: 'm', expectedCalls: [
       'handleNoTypeVariables (',
       'beginFunctionType Function',
       'handleNoType ',
@@ -354,7 +354,7 @@
       'endFormalParameters 1 ( ) MemberKind.GeneralizedFunctionType',
       'endFunctionType Function m',
     ]);
-    expectComplexInfo('Function<T>(int) m', tokenAfter: 'm', expectedCalls: [
+    expectComplexInfo('Function<T>(int) m', expectedAfter: 'm', expectedCalls: [
       'beginTypeVariables <',
       'beginTypeVariable T',
       'beginMetadataStar T',
@@ -385,13 +385,13 @@
     expectComplexInfo('Function(int x)', required: true);
     expectComplexInfo('Function<T>(int x)', required: true);
 
-    expectComplexInfo('Function(int x) m', tokenAfter: 'm');
-    expectComplexInfo('Function<T>(int x) m', tokenAfter: 'm');
+    expectComplexInfo('Function(int x) m', expectedAfter: 'm');
+    expectComplexInfo('Function<T>(int x) m', expectedAfter: 'm');
     expectComplexInfo('Function<T>(int x) Function<T>(int x)',
-        required: false, tokenAfter: 'Function');
+        required: false, expectedAfter: 'Function');
     expectComplexInfo('Function<T>(int x) Function<T>(int x)', required: true);
     expectComplexInfo('Function<T>(int x) Function<T>(int x) m',
-        tokenAfter: 'm');
+        expectedAfter: 'm');
   }
 
   void test_computeType_identifier() {
@@ -437,7 +437,7 @@
     expectComplexInfo('C Function(int x)', required: true);
     expectComplexInfo('C Function<T>(int x)', required: true);
     expectComplexInfo('C Function<T>(int x) Function<T>(int x)',
-        required: false, tokenAfter: 'Function');
+        required: false, expectedAfter: 'Function');
     expectComplexInfo('C Function<T>(int x) Function<T>(int x)',
         required: true);
     expectComplexInfo('C Function(', // Scanner inserts synthetic ')'.
@@ -510,7 +510,7 @@
       'endTypeArguments 1 < >',
       'handleType C ',
     ]);
-    expectComplexInfo('C<S,T> f', tokenAfter: 'f', expectedCalls: [
+    expectComplexInfo('C<S,T> f', expectedAfter: 'f', expectedCalls: [
       'handleIdentifier C typeReference',
       'beginTypeArguments <',
       'handleIdentifier S typeReference',
@@ -522,7 +522,7 @@
       'endTypeArguments 2 < >',
       'handleType C f',
     ]);
-    expectComplexInfo('C<S<T>> f', tokenAfter: 'f', expectedCalls: [
+    expectComplexInfo('C<S<T>> f', expectedAfter: 'f', expectedCalls: [
       'handleIdentifier C typeReference',
       'beginTypeArguments <',
       'handleIdentifier S typeReference',
@@ -555,7 +555,7 @@
           'endFunctionType Function ',
         ]);
     expectComplexInfo('C<T> Function<T>(int x) Function<T>(int x)',
-        required: false, tokenAfter: 'Function');
+        required: false, expectedAfter: 'Function');
     expectComplexInfo('C<T> Function<T>(int x) Function<T>(int x)',
         required: true);
   }
@@ -594,17 +594,21 @@
     ], expectedErrors: [
       error(codeExpectedType, 2, 1)
     ]);
-    expectComplexInfo('C<> f', required: true, tokenAfter: 'f', expectedCalls: [
-      'handleIdentifier C typeReference',
-      'beginTypeArguments <',
-      'handleIdentifier  typeReference',
-      'handleNoTypeArguments >',
-      'handleType  >',
-      'endTypeArguments 1 < >',
-      'handleType C f',
-    ], expectedErrors: [
-      error(codeExpectedType, 2, 1)
-    ]);
+    expectComplexInfo('C<> f',
+        required: true,
+        expectedAfter: 'f',
+        expectedCalls: [
+          'handleIdentifier C typeReference',
+          'beginTypeArguments <',
+          'handleIdentifier  typeReference',
+          'handleNoTypeArguments >',
+          'handleType  >',
+          'endTypeArguments 1 < >',
+          'handleType C f',
+        ],
+        expectedErrors: [
+          error(codeExpectedType, 2, 1)
+        ]);
 
     // Statements that should not have a type
     expectInfo(noType, 'C<T ; T>U;', required: false);
@@ -653,11 +657,11 @@
   }
 
   void test_computeType_prefixedComplex() {
-    expectComplexInfo('a < b, c > d', tokenAfter: 'd');
-    expectComplexInfo('a < b, c > d', tokenAfter: 'd');
+    expectComplexInfo('a < b, c > d', expectedAfter: 'd');
+    expectComplexInfo('a < b, c > d', expectedAfter: 'd');
 
-    expectComplexInfo('a < p.b, c > d', tokenAfter: 'd');
-    expectComplexInfo('a < b, p.c > d', tokenAfter: 'd');
+    expectComplexInfo('a < p.b, c > d', expectedAfter: 'd');
+    expectComplexInfo('a < b, p.c > d', expectedAfter: 'd');
 
     expectInfo(noType, 'a < p.q.b, c > d', required: false);
     expectInfo(noType, 'a < b, p.q.c > d', required: false);
@@ -682,7 +686,7 @@
           'endFunctionType Function ',
         ]);
     expectComplexInfo('C.a Function<T>(int x) Function<T>(int x)',
-        required: false, tokenAfter: 'Function');
+        required: false, expectedAfter: 'Function');
     expectComplexInfo('C.a Function<T>(int x) Function<T>(int x)',
         required: true);
   }
@@ -700,7 +704,7 @@
       'handleType C ',
     ]);
 
-    expectComplexInfo('C.a<T> f', tokenAfter: 'f', expectedCalls: [
+    expectComplexInfo('C.a<T> f', expectedAfter: 'f', expectedCalls: [
       'handleIdentifier C prefixedTypeReference',
       'handleIdentifier a typeReferenceContinuation',
       'handleQualified .',
@@ -823,7 +827,7 @@
     expectComplexInfo('void Function<T>(int x)', required: true);
 
     expectComplexInfo('void Function<T>(int x) Function<T>(int x)',
-        required: false, tokenAfter: 'Function');
+        required: false, expectedAfter: 'Function');
     expectComplexInfo('void Function<T>(int x) Function<T>(int x)',
         required: true);
   }
@@ -846,6 +850,15 @@
     expect(listener.errors, isNull);
   }
 
+  void test_noTypeParamOrArg_parseVariables() {
+    final Token start = scanString('before after').tokens;
+    final TypeInfoListener listener = new TypeInfoListener();
+
+    expect(noTypeParamOrArg.parseVariables(start, new Parser(listener)), start);
+    expect(listener.calls, ['handleNoTypeVariables after']);
+    expect(listener.errors, isNull);
+  }
+
   void test_simple_skip() {
     final Token start = scanString('before <T> after').tokens;
     final Token gt = start.next.next.next;
@@ -879,6 +892,26 @@
     expect(listener.errors, isNull);
   }
 
+  void test_simple_parseVariables() {
+    final Token start = scanString('before <T> after').tokens;
+    final Token gt = start.next.next.next;
+    expect(gt.lexeme, '>');
+    final TypeInfoListener listener = new TypeInfoListener();
+
+    expect(simpleTypeArgument1.parseVariables(start, new Parser(listener)), gt);
+    expect(listener.calls, [
+      'beginTypeVariables <',
+      'beginTypeVariable T',
+      'beginMetadataStar T',
+      'endMetadataStar 0',
+      'handleIdentifier T typeVariableDeclaration',
+      'handleNoType T',
+      'endTypeVariable > null',
+      'endTypeVariables 1 < >',
+    ]);
+    expect(listener.errors, isNull);
+  }
+
   void test_simple_parseArguments2() {
     final Token start = scanString('before <S<T>> after').tokens.next.next;
     Token t = start.next.next;
@@ -891,7 +924,27 @@
       'handleIdentifier T typeReference',
       'handleNoTypeArguments >>',
       'handleType T >>',
-      'endTypeArguments 1 < >>'
+      'endTypeArguments 1 < T'
+    ]);
+    expect(listener.errors, isNull);
+  }
+
+  void test_simple_parseVariables2() {
+    final Token start = scanString('before <S<T>> after').tokens.next.next;
+    Token t = start.next.next;
+    expect(t.next.lexeme, '>>');
+    final TypeInfoListener listener = new TypeInfoListener();
+
+    expect(simpleTypeArgument1.parseVariables(start, new Parser(listener)), t);
+    expect(listener.calls, [
+      'beginTypeVariables <',
+      'beginTypeVariable T',
+      'beginMetadataStar T',
+      'endMetadataStar 0',
+      'handleIdentifier T typeVariableDeclaration',
+      'handleNoType T',
+      'endTypeVariable T null',
+      'endTypeVariables 1 < T',
     ]);
     expect(listener.errors, isNull);
   }
@@ -920,8 +973,8 @@
     expect(typeVarInfo, simpleTypeArgument1, reason: source);
   }
 
-  void test_computeTypeVar_complex() {
-    expectComplexTypeParamOrArg('<S,T>', expectedCalls: [
+  void test_computeTypeArg_complex() {
+    expectComplexTypeArg('<S,T>', expectedCalls: [
       'beginTypeArguments <',
       'handleIdentifier S typeReference',
       'handleNoTypeArguments ,',
@@ -931,7 +984,7 @@
       'handleType T >',
       'endTypeArguments 2 < >'
     ]);
-    expectComplexTypeParamOrArg('<S Function()>', expectedCalls: [
+    expectComplexTypeArg('<S Function()>', expectedCalls: [
       'beginTypeArguments <',
       'handleNoTypeVariables (',
       'beginFunctionType S',
@@ -943,7 +996,7 @@
       'endFunctionType Function >',
       'endTypeArguments 1 < >'
     ]);
-    expectComplexTypeParamOrArg('<void Function()>', expectedCalls: [
+    expectComplexTypeArg('<void Function()>', expectedCalls: [
       'beginTypeArguments <',
       'handleNoTypeVariables (',
       'beginFunctionType void',
@@ -953,7 +1006,7 @@
       'endFunctionType Function >',
       'endTypeArguments 1 < >'
     ]);
-    expectComplexTypeParamOrArg('<S<T>>', expectedCalls: [
+    expectComplexTypeArg('<S<T>>', expectedCalls: [
       'beginTypeArguments <',
       'handleIdentifier S typeReference',
       'beginTypeArguments <',
@@ -964,18 +1017,18 @@
       'handleType S >',
       'endTypeArguments 1 < >'
     ]);
-    expectComplexTypeParamOrArg('<S<T>>', splitGtGt: false, expectedCalls: [
+    expectComplexTypeArg('<S<T>>', splitGtGt: false, expectedCalls: [
       'beginTypeArguments <',
       'handleIdentifier S typeReference',
       'beginTypeArguments <',
       'handleIdentifier T typeReference',
       'handleNoTypeArguments >>',
       'handleType T >>',
-      'endTypeArguments 1 < >>',
+      'endTypeArguments 1 < T',
       'handleType S >>',
       'endTypeArguments 1 < >>'
     ]);
-    expectComplexTypeParamOrArg('<S<Function()>>', expectedCalls: [
+    expectComplexTypeArg('<S<Function()>>', expectedCalls: [
       'beginTypeArguments <',
       'handleIdentifier S typeReference',
       'beginTypeArguments <',
@@ -989,23 +1042,21 @@
       'handleType S >',
       'endTypeArguments 1 < >'
     ]);
-    expectComplexTypeParamOrArg('<S<Function()>>',
-        splitGtGt: false,
-        expectedCalls: [
-          'beginTypeArguments <',
-          'handleIdentifier S typeReference',
-          'beginTypeArguments <',
-          'handleNoTypeVariables (',
-          'beginFunctionType Function',
-          'handleNoType <',
-          'beginFormalParameters ( MemberKind.GeneralizedFunctionType',
-          'endFormalParameters 0 ( ) MemberKind.GeneralizedFunctionType',
-          'endFunctionType Function >>',
-          'endTypeArguments 1 < >>',
-          'handleType S >>',
-          'endTypeArguments 1 < >>'
-        ]);
-    expectComplexTypeParamOrArg('<S<void Function()>>', expectedCalls: [
+    expectComplexTypeArg('<S<Function()>>', splitGtGt: false, expectedCalls: [
+      'beginTypeArguments <',
+      'handleIdentifier S typeReference',
+      'beginTypeArguments <',
+      'handleNoTypeVariables (',
+      'beginFunctionType Function',
+      'handleNoType <',
+      'beginFormalParameters ( MemberKind.GeneralizedFunctionType',
+      'endFormalParameters 0 ( ) MemberKind.GeneralizedFunctionType',
+      'endFunctionType Function >>',
+      'endTypeArguments 1 < )',
+      'handleType S >>',
+      'endTypeArguments 1 < >>'
+    ]);
+    expectComplexTypeArg('<S<void Function()>>', expectedCalls: [
       'beginTypeArguments <',
       'handleIdentifier S typeReference',
       'beginTypeArguments <',
@@ -1019,7 +1070,7 @@
       'handleType S >',
       'endTypeArguments 1 < >'
     ]);
-    expectComplexTypeParamOrArg('<S<void Function()>>',
+    expectComplexTypeArg('<S<void Function()>>',
         splitGtGt: false,
         expectedCalls: [
           'beginTypeArguments <',
@@ -1031,14 +1082,44 @@
           'beginFormalParameters ( MemberKind.GeneralizedFunctionType',
           'endFormalParameters 0 ( ) MemberKind.GeneralizedFunctionType',
           'endFunctionType Function >>',
-          'endTypeArguments 1 < >>',
+          'endTypeArguments 1 < )',
           'handleType S >>',
           'endTypeArguments 1 < >>'
         ]);
   }
 
-  void test_computeTypeVar_complex_recovery() {
-    expectComplexTypeParamOrArg('<@A S,T>', expectedErrors: [
+  void test_computeTypeArg_complex_recovery() {
+    expectComplexTypeArg('<S extends T>', expectedErrors: [
+      error(codeUnexpectedToken, 3, 7)
+    ], expectedCalls: [
+      'beginTypeArguments <',
+      'handleIdentifier S typeReference',
+      'handleNoTypeArguments extends',
+      'handleType S extends',
+      'endTypeArguments 1 < >',
+    ]);
+    expectComplexTypeArg('<S extends List<T>>', expectedErrors: [
+      error(codeUnexpectedToken, 3, 7)
+    ], expectedCalls: [
+      'beginTypeArguments <',
+      'handleIdentifier S typeReference',
+      'handleNoTypeArguments extends',
+      'handleType S extends',
+      'endTypeArguments 1 < >',
+    ]);
+    expectComplexTypeArg('<S extends List<T>>',
+        splitGtGt: false,
+        expectedErrors: [
+          error(codeUnexpectedToken, 3, 7)
+        ],
+        expectedCalls: [
+          'beginTypeArguments <',
+          'handleIdentifier S typeReference',
+          'handleNoTypeArguments extends',
+          'handleType S extends',
+          'endTypeArguments 1 < >>',
+        ]);
+    expectComplexTypeArg('<@A S,T>', expectedErrors: [
       error(codeUnexpectedToken, 1, 1)
     ], expectedCalls: [
       'beginTypeArguments <',
@@ -1050,7 +1131,7 @@
       'handleType T >',
       'endTypeArguments 2 < >'
     ]);
-    expectComplexTypeParamOrArg('<@A() S,T>', expectedErrors: [
+    expectComplexTypeArg('<@A() S,T>', expectedErrors: [
       error(codeUnexpectedToken, 1, 1)
     ], expectedCalls: [
       'beginTypeArguments <',
@@ -1062,7 +1143,7 @@
       'handleType T >',
       'endTypeArguments 2 < >'
     ]);
-    expectComplexTypeParamOrArg('<@A() @B S,T>', expectedErrors: [
+    expectComplexTypeArg('<@A() @B S,T>', expectedErrors: [
       error(codeUnexpectedToken, 1, 1),
       error(codeUnexpectedToken, 6, 1),
     ], expectedCalls: [
@@ -1076,40 +1157,257 @@
       'endTypeArguments 2 < >'
     ]);
   }
+
+  void test_computeTypeParam_complex() {
+    expectComplexTypeParam('<S,T>', expectedCalls: [
+      'beginTypeVariables <',
+      'beginTypeVariable S',
+      'beginMetadataStar S',
+      'endMetadataStar 0',
+      'handleIdentifier S typeVariableDeclaration',
+      'handleNoType S',
+      'endTypeVariable , null',
+      'beginTypeVariable T',
+      'beginMetadataStar T',
+      'endMetadataStar 0',
+      'handleIdentifier T typeVariableDeclaration',
+      'handleNoType T',
+      'endTypeVariable > null',
+      'endTypeVariables 2 < >',
+    ]);
+    expectComplexTypeParam('<S extends T>', expectedCalls: [
+      'beginTypeVariables <',
+      'beginTypeVariable S',
+      'beginMetadataStar S',
+      'endMetadataStar 0',
+      'handleIdentifier S typeVariableDeclaration',
+      'handleIdentifier T typeReference',
+      'handleNoTypeArguments >',
+      'handleType T >',
+      'endTypeVariable > extends',
+      'endTypeVariables 1 < >',
+    ]);
+    expectComplexTypeParam('<S super T>', expectedCalls: [
+      'beginTypeVariables <',
+      'beginTypeVariable S',
+      'beginMetadataStar S',
+      'endMetadataStar 0',
+      'handleIdentifier S typeVariableDeclaration',
+      'handleIdentifier T typeReference',
+      'handleNoTypeArguments >',
+      'handleType T >',
+      'endTypeVariable > super',
+      'endTypeVariables 1 < >',
+    ]);
+    expectComplexTypeParam('<S extends List<T>>', expectedCalls: [
+      'beginTypeVariables <',
+      'beginTypeVariable S',
+      'beginMetadataStar S',
+      'endMetadataStar 0',
+      'handleIdentifier S typeVariableDeclaration',
+      'handleIdentifier List typeReference',
+      'beginTypeArguments <',
+      'handleIdentifier T typeReference',
+      'handleNoTypeArguments >',
+      'handleType T >',
+      'endTypeArguments 1 < >',
+      'handleType List >',
+      'endTypeVariable > extends',
+      'endTypeVariables 1 < >',
+    ]);
+    expectComplexTypeParam('<S extends List<T>>',
+        splitGtGt: false,
+        expectedCalls: [
+          'beginTypeVariables <',
+          'beginTypeVariable S',
+          'beginMetadataStar S',
+          'endMetadataStar 0',
+          'handleIdentifier S typeVariableDeclaration',
+          'handleIdentifier List typeReference',
+          'beginTypeArguments <',
+          'handleIdentifier T typeReference',
+          'handleNoTypeArguments >>',
+          'handleType T >>',
+          'endTypeArguments 1 < T',
+          'handleType List >>',
+          'endTypeVariable >> extends',
+          'endTypeVariables 1 < >>',
+        ]);
+    expectComplexTypeParam('<R, S extends void Function()>', expectedCalls: [
+      'beginTypeVariables <',
+      'beginTypeVariable R',
+      'beginMetadataStar R',
+      'endMetadataStar 0',
+      'handleIdentifier R typeVariableDeclaration',
+      'handleNoType R',
+      'endTypeVariable , null',
+      'beginTypeVariable S',
+      'beginMetadataStar S',
+      'endMetadataStar 0',
+      'handleIdentifier S typeVariableDeclaration',
+      'handleNoTypeVariables (',
+      'beginFunctionType void',
+      'handleVoidKeyword void',
+      'beginFormalParameters ( MemberKind.GeneralizedFunctionType',
+      'endFormalParameters 0 ( ) MemberKind.GeneralizedFunctionType',
+      'endFunctionType Function >',
+      'endTypeVariable > extends',
+      'endTypeVariables 2 < >',
+    ]);
+    expectComplexTypeParam('<@A S,T>', expectedCalls: [
+      'beginTypeVariables <',
+      'beginTypeVariable @',
+      'beginMetadataStar @',
+      'beginMetadata @',
+      'handleIdentifier A metadataReference',
+      'handleNoTypeArguments S',
+      'handleNoArguments S',
+      'endMetadata @ null S',
+      'endMetadataStar 1',
+      'handleIdentifier S typeVariableDeclaration',
+      'handleNoType S',
+      'endTypeVariable , null',
+      'beginTypeVariable T',
+      'beginMetadataStar T',
+      'endMetadataStar 0',
+      'handleIdentifier T typeVariableDeclaration',
+      'handleNoType T',
+      'endTypeVariable > null',
+      'endTypeVariables 2 < >',
+    ]);
+    expectComplexTypeParam('<@A() S,T>', expectedCalls: [
+      'beginTypeVariables <',
+      'beginTypeVariable @',
+      'beginMetadataStar @',
+      'beginMetadata @',
+      'handleIdentifier A metadataReference',
+      'handleNoTypeArguments (',
+      'beginArguments (',
+      'endArguments 0 ( )',
+      'endMetadata @ null S',
+      'endMetadataStar 1',
+      'handleIdentifier S typeVariableDeclaration',
+      'handleNoType S',
+      'endTypeVariable , null',
+      'beginTypeVariable T',
+      'beginMetadataStar T',
+      'endMetadataStar 0',
+      'handleIdentifier T typeVariableDeclaration',
+      'handleNoType T',
+      'endTypeVariable > null',
+      'endTypeVariables 2 < >',
+    ]);
+    expectComplexTypeParam('<@A() @B S,T>', expectedCalls: [
+      'beginTypeVariables <',
+      'beginTypeVariable @',
+      'beginMetadataStar @',
+      'beginMetadata @',
+      'handleIdentifier A metadataReference',
+      'handleNoTypeArguments (',
+      'beginArguments (',
+      'endArguments 0 ( )',
+      'endMetadata @ null @',
+      'beginMetadata @',
+      'handleIdentifier B metadataReference',
+      'handleNoTypeArguments S',
+      'handleNoArguments S',
+      'endMetadata @ null S',
+      'endMetadataStar 2',
+      'handleIdentifier S typeVariableDeclaration',
+      'handleNoType S',
+      'endTypeVariable , null',
+      'beginTypeVariable T',
+      'beginMetadataStar T',
+      'endMetadataStar 0',
+      'handleIdentifier T typeVariableDeclaration',
+      'handleNoType T',
+      'endTypeVariable > null',
+      'endTypeVariables 2 < >',
+    ]);
+  }
+
+  void test_computeTypeParam_complex_recovery() {
+    expectComplexTypeParam('<S Function()>', expectedErrors: [
+      error(codeUnexpectedToken, 3, 8),
+    ], expectedCalls: [
+      'beginTypeVariables <',
+      'beginTypeVariable S',
+      'beginMetadataStar S',
+      'endMetadataStar 0',
+      'handleIdentifier S typeVariableDeclaration',
+      'handleNoType S',
+      'endTypeVariable Function null',
+      'endTypeVariables 1 < >',
+    ]);
+    expectComplexTypeParam('<void Function()>', expectedErrors: [
+      error(codeExpectedIdentifier, 1, 4),
+      error(codeUnexpectedToken, 1, 4),
+    ], expectedCalls: [
+      'beginTypeVariables <',
+      'beginTypeVariable void',
+      'beginMetadataStar void',
+      'endMetadataStar 0',
+      'handleIdentifier  typeVariableDeclaration',
+      'handleNoType ',
+      'endTypeVariable void null',
+      'endTypeVariables 1 < >',
+    ]);
+    expectComplexTypeParam('<S<T>>', expectedErrors: [
+      error(codeUnexpectedToken, 2, 1),
+    ], expectedCalls: [
+      'beginTypeVariables <',
+      'beginTypeVariable S',
+      'beginMetadataStar S',
+      'endMetadataStar 0',
+      'handleIdentifier S typeVariableDeclaration',
+      'handleNoType S',
+      'endTypeVariable < null',
+      'endTypeVariables 1 < >',
+    ]);
+    expectComplexTypeParam('<S<T>>',
+        expectedErrors: [
+          error(codeUnexpectedToken, 2, 1),
+        ],
+        splitGtGt: false,
+        expectedCalls: [
+          'beginTypeVariables <',
+          'beginTypeVariable S',
+          'beginMetadataStar S',
+          'endMetadataStar 0',
+          'handleIdentifier S typeVariableDeclaration',
+          'handleNoType S',
+          'endTypeVariable < null',
+          'endTypeVariables 1 < >>',
+        ]);
+  }
 }
 
-void expectInfo(expectedInfo, String source,
-    {bool required,
-    String expectedAfter,
-    List<String> expectedCalls,
-    List<ExpectedError> expectedErrors}) {
-  Token start = scan(source);
+void expectInfo(expectedInfo, String source, {bool required}) {
   if (required == null) {
-    compute(expectedInfo, source, start, true, expectedAfter, expectedCalls,
-        expectedErrors);
-    start = scan(source);
-    compute(expectedInfo, source, start, false, expectedAfter, expectedCalls,
-        expectedErrors);
+    compute(expectedInfo, source, scan(source), true);
+    compute(expectedInfo, source, scan(source), false);
   } else {
-    compute(expectedInfo, source, start, required, expectedAfter, expectedCalls,
-        expectedErrors);
+    compute(expectedInfo, source, scan(source), required);
   }
 }
 
 void expectComplexInfo(String source,
     {bool required,
-    String tokenAfter,
+    String expectedAfter,
     List<String> expectedCalls,
     List<ExpectedError> expectedErrors}) {
-  expectInfo(const isInstanceOf<ComplexTypeInfo>(), source,
-      required: required,
-      expectedAfter: tokenAfter,
-      expectedCalls: expectedCalls,
-      expectedErrors: expectedErrors);
+  if (required == null) {
+    computeComplex(source, scan(source), true, expectedAfter, expectedCalls,
+        expectedErrors);
+    computeComplex(source, scan(source), false, expectedAfter, expectedCalls,
+        expectedErrors);
+  } else {
+    computeComplex(source, scan(source), required, expectedAfter, expectedCalls,
+        expectedErrors);
+  }
 }
 
-void expectNestedInfo(expectedInfo, String source,
-    {List<String> expectedCalls, List<ExpectedError> expectedErrors}) {
+void expectNestedInfo(expectedInfo, String source) {
   expect(source.startsWith('<'), isTrue);
   Token start = scan(source).next;
   Token innerEndGroup = start;
@@ -1119,73 +1417,148 @@
   if (!optional('>>', innerEndGroup)) {
     innerEndGroup = null;
   }
-  compute(expectedInfo, source, start, true, innerEndGroup != null ? '>>' : '>',
-      expectedCalls, expectedErrors,
-      innerEndGroup: innerEndGroup);
+  compute(expectedInfo, source, start, true, innerEndGroup: innerEndGroup);
 }
 
-void expectNestedComplexInfo(String source,
-    {List<String> expectedCalls, List<ExpectedError> expectedErrors}) {
-  expectNestedInfo(const isInstanceOf<ComplexTypeInfo>(), source,
-      expectedCalls: expectedCalls, expectedErrors: expectedErrors);
+void expectNestedComplexInfo(String source) {
+  expectNestedInfo(const isInstanceOf<ComplexTypeInfo>(), source);
 }
 
-void compute(
-    expectedInfo,
-    String source,
-    Token start,
-    bool required,
-    String expectedAfter,
-    List<String> expectedCalls,
-    List<ExpectedError> expectedErrors,
+TypeInfo compute(expectedInfo, String source, Token start, bool required,
     {Token innerEndGroup}) {
   int expectedGtGtAndNullEndCount = countGtGtAndNullEnd(start);
   TypeInfo typeInfo = computeType(start, required, innerEndGroup);
   expect(typeInfo, expectedInfo, reason: source);
   expect(countGtGtAndNullEnd(start), expectedGtGtAndNullEndCount,
       reason: 'computeType should not modify the token stream');
-
-  if (typeInfo is ComplexTypeInfo) {
-    expect(typeInfo.start, start.next, reason: source);
-    expect(typeInfo.couldBeExpression, isFalse);
-    expectEnd(expectedAfter, typeInfo.skipType(start));
-    expect(countGtGtAndNullEnd(start), expectedGtGtAndNullEndCount,
-        reason: 'TypeInfo.skipType should not modify the token stream');
-
-    TypeInfoListener listener;
-    assertResult(Token actualEnd) {
-      expectEnd(expectedAfter, actualEnd);
-      if (expectedCalls != null) {
-        // TypeInfoListener listener2 = new TypeInfoListener();
-        // new Parser(listener2).parseType(start, TypeContinuation.Required);
-        // print('[');
-        // for (String call in listener2.calls) {
-        //   print("'$call',");
-        // }
-        // print(']');
-
-        expect(listener.calls, expectedCalls, reason: source);
-      }
-      expect(listener.errors, expectedErrors, reason: source);
-    }
-
-    listener = new TypeInfoListener();
-    assertResult(typeInfo.parseType(start, new Parser(listener)));
-  } else {
-    expect(expectedErrors, isNull);
-  }
+  return typeInfo;
 }
 
-void expectComplexTypeParamOrArg(String source,
+ComplexTypeInfo computeComplex(
+    String source,
+    Token start,
+    bool required,
+    String expectedAfter,
+    List<String> expectedCalls,
+    List<ExpectedError> expectedErrors) {
+  int expectedGtGtAndNullEndCount = countGtGtAndNullEnd(start);
+  ComplexTypeInfo typeInfo =
+      compute(const isInstanceOf<ComplexTypeInfo>(), source, start, required);
+  expect(typeInfo.start, start.next, reason: source);
+  expect(typeInfo.couldBeExpression, isFalse);
+  expectEnd(expectedAfter, typeInfo.skipType(start));
+  expect(countGtGtAndNullEnd(start), expectedGtGtAndNullEndCount,
+      reason: 'TypeInfo.skipType should not modify the token stream');
+
+  TypeInfoListener listener = new TypeInfoListener();
+  Token actualEnd = typeInfo.parseType(start, new Parser(listener));
+
+  expectEnd(expectedAfter, actualEnd);
+  if (expectedCalls != null) {
+    // TypeInfoListener listener2 = new TypeInfoListener();
+    // new Parser(listener2).parseType(start, TypeContinuation.Required);
+    // print('[');
+    // for (String call in listener2.calls) {
+    //   print("'$call',");
+    // }
+    // print(']');
+
+    expect(listener.calls, expectedCalls, reason: source);
+  }
+  expect(listener.errors, expectedErrors, reason: source);
+  return typeInfo;
+}
+
+void expectComplexTypeArg(String source,
     {bool splitGtGt: true,
-    String tokenAfter,
+    String expectedAfter,
     List<String> expectedCalls,
     List<ExpectedError> expectedErrors}) {
-  expectTypeParamOrArg(const isInstanceOf<ComplexTypeParamOrArgInfo>(), source,
-      splitGtGt: splitGtGt,
-      expectedAfter: tokenAfter,
-      expectedCalls: expectedCalls,
-      expectedErrors: expectedErrors);
+  Token start = scan(source);
+  int expectedGtGtAndNullEndCount = countGtGtAndNullEnd(start);
+  ComplexTypeParamOrArgInfo typeVarInfo = computeVar(
+      const isInstanceOf<ComplexTypeParamOrArgInfo>(), source, start);
+
+  expect(typeVarInfo.start, start.next, reason: source);
+  expectEnd(expectedAfter, typeVarInfo.skip(start));
+  expect(countGtGtAndNullEnd(start), expectedGtGtAndNullEndCount,
+      reason: 'TypeParamOrArgInfo.skipType'
+          ' should not modify the token stream');
+
+  TypeInfoListener listener = new TypeInfoListener();
+  Parser parser = new Parser(listener);
+  if (!splitGtGt) {
+    parser.cachedRewriter = new TokenStreamNonRewriter();
+  }
+  Token actualEnd = typeVarInfo.parseArguments(start, parser);
+  expectEnd(expectedAfter, actualEnd);
+  if (!splitGtGt) {
+    expect(countGtGtAndNullEnd(start), expectedGtGtAndNullEndCount,
+        reason: 'TypeParamOrArgInfo.parseArguments'
+            ' should not modify the token stream');
+  }
+
+  if (expectedCalls != null) {
+    try {
+      expect(listener.calls, expectedCalls, reason: source);
+    } catch (e) {
+      TypeInfoListener listener2 = new TypeInfoListener();
+      new Parser(listener2).parseTypeArgumentsOpt(start);
+      print('Events from parseTypeArgumentsOpt: [');
+      for (String call in listener2.calls) {
+        print("  '$call',");
+      }
+      print(']');
+      rethrow;
+    }
+  }
+  expect(listener.errors, expectedErrors, reason: source);
+}
+
+void expectComplexTypeParam(String source,
+    {bool splitGtGt: true,
+    String expectedAfter,
+    List<String> expectedCalls,
+    List<ExpectedError> expectedErrors}) {
+  Token start = scan(source);
+  int expectedGtGtAndNullEndCount = countGtGtAndNullEnd(start);
+  ComplexTypeParamOrArgInfo typeVarInfo = computeVar(
+      const isInstanceOf<ComplexTypeParamOrArgInfo>(), source, start);
+
+  expect(typeVarInfo.start, start.next, reason: source);
+  expectEnd(expectedAfter, typeVarInfo.skip(start));
+  expect(countGtGtAndNullEnd(start), expectedGtGtAndNullEndCount,
+      reason: 'TypeParamOrArgInfo.skipType'
+          ' should not modify the token stream');
+
+  TypeInfoListener listener = new TypeInfoListener(metadataAllowed: true);
+  Parser parser = new Parser(listener);
+  if (!splitGtGt) {
+    parser.cachedRewriter = new TokenStreamNonRewriter();
+  }
+  Token actualEnd = typeVarInfo.parseVariables(start, parser);
+  expectEnd(expectedAfter, actualEnd);
+  if (!splitGtGt) {
+    expect(countGtGtAndNullEnd(start), expectedGtGtAndNullEndCount,
+        reason: 'TypeParamOrArgInfo.parseVariables'
+            ' should not modify the token stream');
+  }
+
+  if (expectedCalls != null) {
+    try {
+      expect(listener.calls, expectedCalls, reason: source);
+    } catch (e) {
+      TypeInfoListener listener2 = new TypeInfoListener(metadataAllowed: true);
+      new Parser(listener2).parseTypeVariablesOpt(start);
+      print('Events from parseTypeVariablesOpt: [');
+      for (String call in listener2.calls) {
+        print("  '$call',");
+      }
+      print(']');
+      rethrow;
+    }
+  }
+  expect(listener.errors, expectedErrors, reason: source);
 }
 
 void expectTypeParamOrArg(expectedInfo, String source,
@@ -1194,59 +1567,16 @@
     List<String> expectedCalls,
     List<ExpectedError> expectedErrors}) {
   Token start = scan(source);
-  computeVar(expectedInfo, source, start, splitGtGt, expectedAfter,
-      expectedCalls, expectedErrors);
+  computeVar(expectedInfo, source, start);
 }
 
-void computeVar(
-    expectedInfo,
-    String source,
-    Token start,
-    bool splitGtGt,
-    String expectedAfter,
-    List<String> expectedCalls,
-    List<ExpectedError> expectedErrors) {
+TypeParamOrArgInfo computeVar(expectedInfo, String source, Token start) {
   int expectedGtGtAndNullEndCount = countGtGtAndNullEnd(start);
   TypeParamOrArgInfo typeVarInfo = computeTypeParamOrArg(start);
   expect(typeVarInfo, expectedInfo, reason: source);
   expect(countGtGtAndNullEnd(start), expectedGtGtAndNullEndCount,
       reason: 'computeTypeParamOrArg should not modify the token stream');
-
-  if (typeVarInfo is ComplexTypeParamOrArgInfo) {
-    expect(typeVarInfo.start, start.next, reason: source);
-    expectEnd(expectedAfter, typeVarInfo.skip(start));
-    expect(countGtGtAndNullEnd(start), expectedGtGtAndNullEndCount,
-        reason: 'TypeParamOrArgInfo.skipType'
-            ' should not modify the token stream');
-
-    TypeInfoListener listener = new TypeInfoListener();
-    Parser parser = new Parser(listener);
-    if (!splitGtGt) {
-      parser.cachedRewriter = new TokenStreamNonRewriter();
-    }
-    Token actualEnd = typeVarInfo.parseArguments(start, parser);
-    expectEnd(expectedAfter, actualEnd);
-    if (!splitGtGt) {
-      expect(countGtGtAndNullEnd(start), expectedGtGtAndNullEndCount,
-          reason: 'TypeParamOrArgInfo.parseArguments'
-              ' should not modify the token stream');
-    }
-
-    if (expectedCalls != null) {
-      // TypeInfoListener listener2 = new TypeInfoListener();
-      // new Parser(listener2).parseTypeArgumentsOpt(start);
-      // print('[');
-      // for (String call in listener2.calls) {
-      //   print("'$call',");
-      // }
-      // print(']');
-
-      expect(listener.calls, expectedCalls, reason: source);
-    }
-    expect(listener.errors, expectedErrors, reason: source);
-  } else {
-    expect(expectedErrors, isNull);
-  }
+  return typeVarInfo;
 }
 
 void expectEnd(String tokenAfter, Token end) {
@@ -1279,9 +1609,21 @@
 }
 
 class TypeInfoListener implements Listener {
+  final bool metadataAllowed;
   List<String> calls = <String>[];
   List<ExpectedError> errors;
 
+  TypeInfoListener({this.metadataAllowed: false});
+
+  @override
+  void beginArguments(Token token) {
+    if (metadataAllowed) {
+      calls.add('beginArguments $token');
+    } else {
+      throw 'beginArguments should not be called.';
+    }
+  }
+
   @override
   void beginFormalParameter(Token token, MemberKind kind, Token covariantToken,
       Token varFinalOrConst) {
@@ -1299,6 +1641,15 @@
   }
 
   @override
+  void beginMetadata(Token token) {
+    if (metadataAllowed) {
+      calls.add('beginMetadata $token');
+    } else {
+      throw 'beginMetadata should not be called.';
+    }
+  }
+
+  @override
   void beginMetadataStar(Token token) {
     calls.add('beginMetadataStar $token');
   }
@@ -1325,6 +1676,15 @@
   }
 
   @override
+  void endArguments(int count, Token beginToken, Token endToken) {
+    if (metadataAllowed) {
+      calls.add('endArguments $count $beginToken $endToken');
+    } else {
+      throw 'endArguments should not be called.';
+    }
+  }
+
+  @override
   void endFormalParameter(Token thisKeyword, Token periodAfterThis,
       Token nameToken, FormalParameterKind kind, MemberKind memberKind) {
     calls.add('beginTypeVariables $thisKeyword $periodAfterThis '
@@ -1337,6 +1697,15 @@
   }
 
   @override
+  void endMetadata(Token beginToken, Token periodBeforeName, Token endToken) {
+    if (metadataAllowed) {
+      calls.add('endMetadata $beginToken $periodBeforeName $endToken');
+    } else {
+      throw 'endMetadata should not be called.';
+    }
+  }
+
+  @override
   void endMetadataStar(int count) {
     calls.add('endMetadataStar $count');
   }
@@ -1367,6 +1736,15 @@
   }
 
   @override
+  void handleNoArguments(Token token) {
+    if (metadataAllowed) {
+      calls.add('handleNoArguments $token');
+    } else {
+      throw 'handleNoArguments should not be called.';
+    }
+  }
+
+  @override
   void handleNoName(Token token) {
     calls.add('handleNoName $token');
   }
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 0bb2e82..5089798 100644
--- a/pkg/front_end/test/incremental_load_from_dill_test.dart
+++ b/pkg/front_end/test/incremental_load_from_dill_test.dart
@@ -235,9 +235,9 @@
       }
     }
     bool gotError = false;
-    List<String> formattedErrors = <String>[];
+    final List<String> formattedErrors = <String>[];
     bool gotWarning = false;
-    List<String> formattedWarnings = <String>[];
+    final List<String> formattedWarnings = <String>[];
 
     options.onProblem = (FormattedMessage problem, Severity severity,
         List<FormattedMessage> context) {
@@ -264,16 +264,8 @@
     Stopwatch stopwatch = new Stopwatch()..start();
     Component component = await compiler.computeDelta(
         fullComponent: brandNewWorld ? false : true);
-    if (world["errors"] == true && !gotError) {
-      throw "Expected error, but didn't get any.";
-    } else if (world["errors"] != true && gotError) {
-      throw "Got unexpected error(s): $formattedErrors.";
-    }
-    if (world["warnings"] == true && !gotWarning) {
-      throw "Expected warning, but didn't get any.";
-    } else if (world["warnings"] != true && gotWarning) {
-      throw "Got unexpected warnings(s): $formattedWarnings.";
-    }
+    performErrorAndWarningCheck(
+        world, gotError, formattedErrors, gotWarning, formattedWarnings);
     util.throwOnEmptyMixinBodies(component);
     print("Compile took ${stopwatch.elapsedMilliseconds} ms");
     newestWholeComponent = serializeComponent(component);
@@ -307,13 +299,37 @@
     }
 
     {
+      gotError = false;
+      formattedErrors.clear();
+      gotWarning = false;
+      formattedWarnings.clear();
       Component component2 = await compiler.computeDelta(fullComponent: true);
+      performErrorAndWarningCheck(
+          world, gotError, formattedErrors, gotWarning, formattedWarnings);
       List<int> thisWholeComponent = serializeComponent(component2);
       checkIsEqual(newestWholeComponent, thisWholeComponent);
     }
   }
 }
 
+void performErrorAndWarningCheck(
+    Map<String, dynamic> world,
+    bool gotError,
+    List<String> formattedErrors,
+    bool gotWarning,
+    List<String> formattedWarnings) {
+  if (world["errors"] == true && !gotError) {
+    throw "Expected error, but didn't get any.";
+  } else if (world["errors"] != true && gotError) {
+    throw "Got unexpected error(s): $formattedErrors.";
+  }
+  if (world["warnings"] == true && !gotWarning) {
+    throw "Expected warning, but didn't get any.";
+  } else if (world["warnings"] != true && gotWarning) {
+    throw "Got unexpected warnings(s): $formattedWarnings.";
+  }
+}
+
 void checkIsEqual(List<int> a, List<int> b) {
   int length = a.length;
   if (b.length < length) {
diff --git a/pkg/front_end/test/scanner_test.dart b/pkg/front_end/test/scanner_test.dart
index 861b2fd..d03ee59 100644
--- a/pkg/front_end/test/scanner_test.dart
+++ b/pkg/front_end/test/scanner_test.dart
@@ -592,6 +592,10 @@
     _assertKeywordToken("implements");
   }
 
+  void test_keyword_interface() {
+    _assertKeywordToken("interface");
+  }
+
   void test_keyword_import() {
     _assertKeywordToken("import");
   }
@@ -608,6 +612,10 @@
     _assertKeywordToken("library");
   }
 
+  void test_keyword_mixin() {
+    _assertKeywordToken("mixin");
+  }
+
   void test_keyword_native() {
     _assertKeywordToken("native");
   }
diff --git a/pkg/front_end/test/summary_generator_test.dart b/pkg/front_end/test/summary_generator_test.dart
index 05d582c..435e5ec 100644
--- a/pkg/front_end/test/summary_generator_test.dart
+++ b/pkg/front_end/test/summary_generator_test.dart
@@ -14,9 +14,9 @@
     var summary = await summarize(['a.dart'], allSources);
     var component = loadComponentFromBytes(summary);
 
-    // Note: the kernel representation always has an empty '' key in the map,
+    // Note: the kernel representation always has a null key in the map,
     // but otherwise no other data is included here.
-    expect(component.uriToSource.keys.single, Uri.parse(""));
+    expect(component.uriToSource.keys.single, null);
   });
 
   test('summary includes declarations, but no method bodies', () async {
diff --git a/pkg/front_end/test/token_test.dart b/pkg/front_end/test/token_test.dart
index 78ec8ba..aa1e79e 100644
--- a/pkg/front_end/test/token_test.dart
+++ b/pkg/front_end/test/token_test.dart
@@ -158,7 +158,9 @@
       Keyword.GET,
       Keyword.IMPLEMENTS,
       Keyword.IMPORT,
+      Keyword.INTERFACE,
       Keyword.LIBRARY,
+      Keyword.MIXIN,
       Keyword.OPERATOR,
       Keyword.PART,
       Keyword.SET,
diff --git a/pkg/front_end/testcases/argument_mismatch.dart.direct.expect b/pkg/front_end/testcases/argument_mismatch.dart.direct.expect
index 5d084af..5f3f9aa 100644
--- a/pkg/front_end/testcases/argument_mismatch.dart.direct.expect
+++ b/pkg/front_end/testcases/argument_mismatch.dart.direct.expect
@@ -4,6 +4,6 @@
 
 static method foo() → dynamic {}
 static method test() → dynamic {
-  throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#foo, 32, const <core::Type>[], <dynamic>[null].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
+  throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#foo, 32, const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[null]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/argument_mismatch.dart.direct.transformed.expect b/pkg/front_end/testcases/argument_mismatch.dart.direct.transformed.expect
index 5d084af..5f3f9aa 100644
--- a/pkg/front_end/testcases/argument_mismatch.dart.direct.transformed.expect
+++ b/pkg/front_end/testcases/argument_mismatch.dart.direct.transformed.expect
@@ -4,6 +4,6 @@
 
 static method foo() → dynamic {}
 static method test() → dynamic {
-  throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#foo, 32, const <core::Type>[], <dynamic>[null].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
+  throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#foo, 32, const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[null]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/expression/class_invalid_static.expression.yaml.expect b/pkg/front_end/testcases/expression/class_invalid_static.expression.yaml.expect
index 1c3d9f3..d60b2fc 100644
--- a/pkg/front_end/testcases/expression/class_invalid_static.expression.yaml.expect
+++ b/pkg/front_end/testcases/expression/class_invalid_static.expression.yaml.expect
@@ -2,4 +2,4 @@
   Method not found: 'doit_with_this'. (@0)
 }
 static method /* from org-dartlang-debug:synthetic_debug_expression */ debugExpr() → dynamic
-  return throw new dart.core::NoSuchMethodError::withInvocation(null, new dart.core::_InvocationMirror::_withType(#doit_with_this, 32, const <dart.core::Type>[], <dynamic>[3].toList(growable: false), dart.core::Map::unmodifiable<dart.core::Symbol, dynamic>(const <dart.core::Symbol, dynamic>{})));
+  return throw new dart.core::NoSuchMethodError::withInvocation(null, new dart.core::_InvocationMirror::_withType(#doit_with_this, 32, const <dart.core::Type>[], dart.core::List::unmodifiable<dynamic>(<dynamic>[3]), dart.core::Map::unmodifiable<dart.core::Symbol, dynamic>(const <dart.core::Symbol, dynamic>{})));
diff --git a/pkg/front_end/testcases/expression/class_invalid_static_setter.expression.yaml.expect b/pkg/front_end/testcases/expression/class_invalid_static_setter.expression.yaml.expect
index ff2d316..8480ea2 100644
--- a/pkg/front_end/testcases/expression/class_invalid_static_setter.expression.yaml.expect
+++ b/pkg/front_end/testcases/expression/class_invalid_static_setter.expression.yaml.expect
@@ -2,4 +2,4 @@
   Setter not found: 'z'. (@0)
 }
 static method /* from org-dartlang-debug:synthetic_debug_expression */ debugExpr() → dynamic
-  return throw new dart.core::NoSuchMethodError::withInvocation(null, new dart.core::_InvocationMirror::_withType(#z, 34, const <dart.core::Type>[], <dynamic>[2].toList(growable: false), dart.core::Map::unmodifiable<dart.core::Symbol, dynamic>(const <dart.core::Symbol, dynamic>{})));
+  return throw new dart.core::NoSuchMethodError::withInvocation(null, new dart.core::_InvocationMirror::_withType(#z, 34, const <dart.core::Type>[], dart.core::List::unmodifiable<dynamic>(<dynamic>[2]), dart.core::Map::unmodifiable<dart.core::Symbol, dynamic>(const <dart.core::Symbol, dynamic>{})));
diff --git a/pkg/front_end/testcases/expression/class_static2.expression.yaml.expect b/pkg/front_end/testcases/expression/class_static2.expression.yaml.expect
index 2a1fd01..af61daf 100644
--- a/pkg/front_end/testcases/expression/class_static2.expression.yaml.expect
+++ b/pkg/front_end/testcases/expression/class_static2.expression.yaml.expect
@@ -2,4 +2,4 @@
   Method not found: 'doit_with_this'. (@0)
 }
 static method /* from org-dartlang-debug:synthetic_debug_expression */ debugExpr() → dynamic
-  return throw new dart.core::NoSuchMethodError::withInvocation(null, new dart.core::_InvocationMirror::_withType(#doit_with_this, 32, const <dart.core::Type>[], <dynamic>[2].toList(growable: false), dart.core::Map::unmodifiable<dart.core::Symbol, dynamic>(const <dart.core::Symbol, dynamic>{})));
+  return throw new dart.core::NoSuchMethodError::withInvocation(null, new dart.core::_InvocationMirror::_withType(#doit_with_this, 32, const <dart.core::Type>[], dart.core::List::unmodifiable<dynamic>(<dynamic>[2]), dart.core::Map::unmodifiable<dart.core::Symbol, dynamic>(const <dart.core::Symbol, dynamic>{})));
diff --git a/pkg/front_end/testcases/expression/invalid.expression.yaml.expect b/pkg/front_end/testcases/expression/invalid.expression.yaml.expect
index 1e3cd80..cc26db7 100644
--- a/pkg/front_end/testcases/expression/invalid.expression.yaml.expect
+++ b/pkg/front_end/testcases/expression/invalid.expression.yaml.expect
@@ -5,4 +5,4 @@
   Getter not found: ''. (@0)
 }
 method /* from org-dartlang-debug:synthetic_debug_expression */ debugExpr() → dynamic
-  return (throw new dart.core::NoSuchMethodError::withInvocation(null, new dart.core::_InvocationMirror::_withType(#, 33, const <dart.core::Type>[], const <dynamic>[], dart.core::Map::unmodifiable<dart.core::Symbol, dynamic>(const <dart.core::Symbol, dynamic>{})))).*(throw new dart.core::NoSuchMethodError::withInvocation(null, new dart.core::_InvocationMirror::_withType(#foo, 32, const <dart.core::Type>[], <dynamic>[3].toList(growable: false), dart.core::Map::unmodifiable<dart.core::Symbol, dynamic>(const <dart.core::Symbol, dynamic>{}))));
+  return (throw new dart.core::NoSuchMethodError::withInvocation(null, new dart.core::_InvocationMirror::_withType(#, 33, const <dart.core::Type>[], const <dynamic>[], dart.core::Map::unmodifiable<dart.core::Symbol, dynamic>(const <dart.core::Symbol, dynamic>{})))).*(throw new dart.core::NoSuchMethodError::withInvocation(null, new dart.core::_InvocationMirror::_withType(#foo, 32, const <dart.core::Type>[], dart.core::List::unmodifiable<dynamic>(<dynamic>[3]), dart.core::Map::unmodifiable<dart.core::Symbol, dynamic>(const <dart.core::Symbol, dynamic>{}))));
diff --git a/pkg/front_end/testcases/expression/lib_nonreference.expression.yaml.expect b/pkg/front_end/testcases/expression/lib_nonreference.expression.yaml.expect
index d7a9a32..4c7dfed 100644
--- a/pkg/front_end/testcases/expression/lib_nonreference.expression.yaml.expect
+++ b/pkg/front_end/testcases/expression/lib_nonreference.expression.yaml.expect
@@ -2,4 +2,4 @@
   Method not found: 'acos'. (@0)
 }
 method /* from org-dartlang-debug:synthetic_debug_expression */ debugExpr() → dynamic
-  return throw new dart.core::NoSuchMethodError::withInvocation(null, new dart.core::_InvocationMirror::_withType(#acos, 32, const <dart.core::Type>[], <dynamic>[1.0].toList(growable: false), dart.core::Map::unmodifiable<dart.core::Symbol, dynamic>(const <dart.core::Symbol, dynamic>{})));
+  return throw new dart.core::NoSuchMethodError::withInvocation(null, new dart.core::_InvocationMirror::_withType(#acos, 32, const <dart.core::Type>[], dart.core::List::unmodifiable<dynamic>(<dynamic>[1.0]), dart.core::Map::unmodifiable<dart.core::Symbol, dynamic>(const <dart.core::Symbol, dynamic>{})));
diff --git a/pkg/front_end/testcases/expression/lib_nonshown_ctor.expression.yaml.expect b/pkg/front_end/testcases/expression/lib_nonshown_ctor.expression.yaml.expect
index 699e4fa..f6b2dd6 100644
--- a/pkg/front_end/testcases/expression/lib_nonshown_ctor.expression.yaml.expect
+++ b/pkg/front_end/testcases/expression/lib_nonshown_ctor.expression.yaml.expect
@@ -2,4 +2,4 @@
   Method not found: 'Directory'. (@4)
 }
 method /* from org-dartlang-debug:synthetic_debug_expression */ debugExpr() → dynamic
-  return throw new dart.core::NoSuchMethodError::withInvocation(null, new dart.core::_InvocationMirror::_withType(#Directory, 32, const <dart.core::Type>[], <dynamic>["test"].toList(growable: false), dart.core::Map::unmodifiable<dart.core::Symbol, dynamic>(const <dart.core::Symbol, dynamic>{})));
+  return throw new dart.core::NoSuchMethodError::withInvocation(null, new dart.core::_InvocationMirror::_withType(#Directory, 32, const <dart.core::Type>[], dart.core::List::unmodifiable<dynamic>(<dynamic>["test"]), dart.core::Map::unmodifiable<dart.core::Symbol, dynamic>(const <dart.core::Symbol, dynamic>{})));
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 9ac1d76..53674fd 100644
--- a/pkg/front_end/testcases/implicit_scope_test.dart.strong.expect
+++ b/pkg/front_end/testcases/implicit_scope_test.dart.strong.expect
@@ -14,28 +14,28 @@
     core::String a = "foo";
     dynamic b;
     if(self::ImplicitScopeTest::alwaysTrue()) {
-      dynamic a = "bar";
+      core::String a = "bar";
     }
     else {
-      dynamic b = a;
+      core::String b = a;
     }
     exp::Expect::equals("foo", a);
     exp::Expect::equals(null, b);
     while (!self::ImplicitScopeTest::alwaysTrue()) {
-      dynamic a = "bar";
-      dynamic b = "baz";
+      core::String a = "bar";
+      core::String b = "baz";
     }
     exp::Expect::equals("foo", a);
     exp::Expect::equals(null, b);
     for (core::int i = 0; i.{core::num::<}(10); i = i.{core::num::+}(1)) {
-      dynamic a = "bar";
-      dynamic b = "baz";
+      core::String a = "bar";
+      core::String b = "baz";
     }
     exp::Expect::equals("foo", a);
     exp::Expect::equals(null, b);
     do {
-      dynamic a = "bar";
-      dynamic b = "baz";
+      core::String a = "bar";
+      core::String b = "baz";
     }
     while ("black".{core::String::==}("white"))
     exp::Expect::equals("foo", a);
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 9ac1d76..53674fd 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
@@ -14,28 +14,28 @@
     core::String a = "foo";
     dynamic b;
     if(self::ImplicitScopeTest::alwaysTrue()) {
-      dynamic a = "bar";
+      core::String a = "bar";
     }
     else {
-      dynamic b = a;
+      core::String b = a;
     }
     exp::Expect::equals("foo", a);
     exp::Expect::equals(null, b);
     while (!self::ImplicitScopeTest::alwaysTrue()) {
-      dynamic a = "bar";
-      dynamic b = "baz";
+      core::String a = "bar";
+      core::String b = "baz";
     }
     exp::Expect::equals("foo", a);
     exp::Expect::equals(null, b);
     for (core::int i = 0; i.{core::num::<}(10); i = i.{core::num::+}(1)) {
-      dynamic a = "bar";
-      dynamic b = "baz";
+      core::String a = "bar";
+      core::String b = "baz";
     }
     exp::Expect::equals("foo", a);
     exp::Expect::equals(null, b);
     do {
-      dynamic a = "bar";
-      dynamic b = "baz";
+      core::String a = "bar";
+      core::String b = "baz";
     }
     while ("black".{core::String::==}("white"))
     exp::Expect::equals("foo", a);
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/invaldation_across_compile_time_error.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/invaldation_across_compile_time_error.yaml
new file mode 100644
index 0000000..f1213e3
--- /dev/null
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/invaldation_across_compile_time_error.yaml
@@ -0,0 +1,69 @@
+# Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+# for details. All rights reserved. Use of this source code is governed by a
+# BSD-style license that can be found in the LICENSE.md file.
+
+# Compile an application that's fine.
+# Invalidate a file that's been updated and fine (and would pull in another
+# library). Also invalidate another file that's been updated to produce a
+# compile time error.
+# Update again, fixing the error.
+# The invalidation of the good file should still apply, i.e. the new library
+# that it pulled in should be included.
+
+type: newworld
+strong: false
+worlds:
+  - entry: main.dart
+    sources:
+      main.dart: |
+        import "b.dart";
+        main() {
+          print("hello");
+          b();
+        }
+      b.dart: |
+        b() {
+          print("hello from b");
+        }
+      c.dart: |
+        c() {
+          print("hello from c");
+        }
+    expectedLibraryCount: 2
+  - entry: main.dart
+    worldType: updated
+    expectInitializeFromDill: false
+    checkInvalidatedFiles: false
+    invalidate:
+      - b.dart
+      - main.dart
+    sources:
+      main.dart: |
+        import "b.dart";
+        import "nonexistin.dart";
+        main() {
+          print("hello");
+          b();
+        }
+      b.dart: |
+        import "c.dart";
+        b() {
+          print("hello from b");
+          c();
+        }
+    errors: true
+    expectedLibraryCount: 1
+  - entry: main.dart
+    worldType: updated
+    expectInitializeFromDill: false
+    checkInvalidatedFiles: false
+    invalidate:
+      - main.dart
+    sources:
+      main.dart: |
+        import "b.dart";
+        main() {
+          print("hello");
+          b();
+        }
+    expectedLibraryCount: 3
\ No newline at end of file
diff --git a/pkg/front_end/testcases/inference/future_then.dart.direct.expect b/pkg/front_end/testcases/inference/future_then.dart.direct.expect
index 238fc77..98124f7 100644
--- a/pkg/front_end/testcases/inference/future_then.dart.direct.expect
+++ b/pkg/front_end/testcases/inference/future_then.dart.direct.expect
@@ -12,10 +12,14 @@
     return null;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
     return null;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
 }
 static method test() → void {
   self::MyFuture<dynamic> f;
diff --git a/pkg/front_end/testcases/inference/future_then.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/future_then.dart.direct.transformed.expect
index d3553bd..440a04c 100644
--- a/pkg/front_end/testcases/inference/future_then.dart.direct.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then.dart.direct.transformed.expect
@@ -12,10 +12,14 @@
     return null;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
     return null;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
 }
 static method test() → void {
   self::MyFuture<dynamic> f;
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 0e4e4b9..638eb19 100644
--- a/pkg/front_end/testcases/inference/future_then.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/future_then.dart.outline.expect
@@ -12,10 +12,14 @@
     ;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError}) → self::MyFuture<self::MyFuture::then::S>
     ;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
 }
 static method test() → void
   ;
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 e39f077..b0f41cc 100644
--- a/pkg/front_end/testcases/inference/future_then.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/future_then.dart.strong.expect
@@ -12,10 +12,14 @@
     return null;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
     return null;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
 }
 static method test() → void {
   self::MyFuture<dynamic> f;
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 7c6f301..ab76573 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
@@ -12,10 +12,14 @@
     return null;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
     return null;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
 }
 static method test() → void {
   self::MyFuture<dynamic> f;
diff --git a/pkg/front_end/testcases/inference/future_then_2.dart.direct.expect b/pkg/front_end/testcases/inference/future_then_2.dart.direct.expect
index d6b1ae2..5f0821f 100644
--- a/pkg/front_end/testcases/inference/future_then_2.dart.direct.expect
+++ b/pkg/front_end/testcases/inference/future_then_2.dart.direct.expect
@@ -12,10 +12,14 @@
     return null;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
     return null;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
 }
 static method test() → void {
   self::MyFuture<dynamic> f;
diff --git a/pkg/front_end/testcases/inference/future_then_2.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/future_then_2.dart.direct.transformed.expect
index 433be3a..8dd522c 100644
--- a/pkg/front_end/testcases/inference/future_then_2.dart.direct.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_2.dart.direct.transformed.expect
@@ -12,10 +12,14 @@
     return null;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
     return null;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
 }
 static method test() → void {
   self::MyFuture<dynamic> f;
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 0e4e4b9..638eb19 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
@@ -12,10 +12,14 @@
     ;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError}) → self::MyFuture<self::MyFuture::then::S>
     ;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
 }
 static method test() → void
   ;
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 4a812f5..2c71d0b 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
@@ -12,10 +12,14 @@
     return null;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
     return null;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
 }
 static method test() → void {
   self::MyFuture<dynamic> f;
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 73bad2f..a5f1b36 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
@@ -12,10 +12,14 @@
     return null;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
     return null;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
 }
 static method test() → void {
   self::MyFuture<dynamic> f;
diff --git a/pkg/front_end/testcases/inference/future_then_3.dart.direct.expect b/pkg/front_end/testcases/inference/future_then_3.dart.direct.expect
index 28f970f..aea52b3 100644
--- a/pkg/front_end/testcases/inference/future_then_3.dart.direct.expect
+++ b/pkg/front_end/testcases/inference/future_then_3.dart.direct.expect
@@ -12,10 +12,14 @@
     return null;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
     return null;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
 }
 static method test() → void {
   self::MyFuture<dynamic> f;
diff --git a/pkg/front_end/testcases/inference/future_then_3.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/future_then_3.dart.direct.transformed.expect
index 05ea1f5..11ee82f 100644
--- a/pkg/front_end/testcases/inference/future_then_3.dart.direct.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_3.dart.direct.transformed.expect
@@ -12,10 +12,14 @@
     return null;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
     return null;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
 }
 static method test() → void {
   self::MyFuture<dynamic> f;
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 0e4e4b9..638eb19 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
@@ -12,10 +12,14 @@
     ;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError}) → self::MyFuture<self::MyFuture::then::S>
     ;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
 }
 static method test() → void
   ;
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 c317b12..14bbd85 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
@@ -12,10 +12,14 @@
     return null;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
     return null;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
 }
 static method test() → void {
   self::MyFuture<dynamic> f;
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 87a94a2..79dea19 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
@@ -12,10 +12,14 @@
     return null;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
     return null;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
 }
 static method test() → void {
   self::MyFuture<dynamic> f;
diff --git a/pkg/front_end/testcases/inference/future_then_4.dart.direct.expect b/pkg/front_end/testcases/inference/future_then_4.dart.direct.expect
index 9d89e58..7260212 100644
--- a/pkg/front_end/testcases/inference/future_then_4.dart.direct.expect
+++ b/pkg/front_end/testcases/inference/future_then_4.dart.direct.expect
@@ -12,10 +12,14 @@
     return null;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
     return null;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
 }
 static method test() → void {
   self::MyFuture<dynamic> f;
diff --git a/pkg/front_end/testcases/inference/future_then_4.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/future_then_4.dart.direct.transformed.expect
index ed1cac1..2c1403c 100644
--- a/pkg/front_end/testcases/inference/future_then_4.dart.direct.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_4.dart.direct.transformed.expect
@@ -12,10 +12,14 @@
     return null;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
     return null;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
 }
 static method test() → void {
   self::MyFuture<dynamic> f;
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 0e4e4b9..638eb19 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
@@ -12,10 +12,14 @@
     ;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError}) → self::MyFuture<self::MyFuture::then::S>
     ;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
 }
 static method test() → void
   ;
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 a2ad76f..79ba4a3 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
@@ -12,10 +12,14 @@
     return null;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
     return null;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
 }
 static method test() → void {
   self::MyFuture<dynamic> f;
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 8457b85..d0224a3 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
@@ -12,10 +12,14 @@
     return null;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
     return null;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
 }
 static method test() → void {
   self::MyFuture<dynamic> f;
diff --git a/pkg/front_end/testcases/inference/future_then_5.dart.direct.expect b/pkg/front_end/testcases/inference/future_then_5.dart.direct.expect
index d8ab165..c2e1984 100644
--- a/pkg/front_end/testcases/inference/future_then_5.dart.direct.expect
+++ b/pkg/front_end/testcases/inference/future_then_5.dart.direct.expect
@@ -12,10 +12,14 @@
     return null;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
     return null;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
 }
 static method test() → void {
   asy::Future<dynamic> f;
diff --git a/pkg/front_end/testcases/inference/future_then_5.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/future_then_5.dart.direct.transformed.expect
index 62658a3..c373616 100644
--- a/pkg/front_end/testcases/inference/future_then_5.dart.direct.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_5.dart.direct.transformed.expect
@@ -12,10 +12,14 @@
     return null;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
     return null;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
 }
 static method test() → void {
   asy::Future<dynamic> f;
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 0e4e4b9..638eb19 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
@@ -12,10 +12,14 @@
     ;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError}) → self::MyFuture<self::MyFuture::then::S>
     ;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
 }
 static method test() → void
   ;
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 44f49a0..4a8eee5 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
@@ -12,10 +12,14 @@
     return null;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
     return null;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
 }
 static method test() → void {
   asy::Future<dynamic> f;
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 a90f007..4181e8a 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
@@ -12,10 +12,14 @@
     return null;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
     return null;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
 }
 static method test() → void {
   asy::Future<dynamic> f;
diff --git a/pkg/front_end/testcases/inference/future_then_6.dart.direct.expect b/pkg/front_end/testcases/inference/future_then_6.dart.direct.expect
index be6b273..c74cdc3 100644
--- a/pkg/front_end/testcases/inference/future_then_6.dart.direct.expect
+++ b/pkg/front_end/testcases/inference/future_then_6.dart.direct.expect
@@ -12,10 +12,14 @@
     return null;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
     return null;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
 }
 static method test() → void {
   asy::Future<dynamic> f;
diff --git a/pkg/front_end/testcases/inference/future_then_6.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/future_then_6.dart.direct.transformed.expect
index 434b5d6..7ea34b6 100644
--- a/pkg/front_end/testcases/inference/future_then_6.dart.direct.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_6.dart.direct.transformed.expect
@@ -12,10 +12,14 @@
     return null;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
     return null;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
 }
 static method test() → void {
   asy::Future<dynamic> f;
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 0e4e4b9..638eb19 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
@@ -12,10 +12,14 @@
     ;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError}) → self::MyFuture<self::MyFuture::then::S>
     ;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
 }
 static method test() → void
   ;
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 9beae3a..98b7e61 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
@@ -12,10 +12,14 @@
     return null;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
     return null;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
 }
 static method test() → void {
   asy::Future<dynamic> f;
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 b6243b1..5013ebe 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
@@ -12,10 +12,14 @@
     return null;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
     return null;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
 }
 static method test() → void {
   asy::Future<dynamic> f;
diff --git a/pkg/front_end/testcases/inference/future_then_conditional.dart.direct.expect b/pkg/front_end/testcases/inference/future_then_conditional.dart.direct.expect
index 60890bc..c81cc0b 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional.dart.direct.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional.dart.direct.expect
@@ -12,10 +12,14 @@
     return null;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
     return null;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
 }
 static method test() → void {
   self::MyFuture<core::bool> f;
diff --git a/pkg/front_end/testcases/inference/future_then_conditional.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/future_then_conditional.dart.direct.transformed.expect
index f2f15cd..ef09e80 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional.dart.direct.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional.dart.direct.transformed.expect
@@ -12,10 +12,14 @@
     return null;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
     return null;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
 }
 static method test() → void {
   self::MyFuture<core::bool> f;
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 0e4e4b9..638eb19 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
@@ -12,10 +12,14 @@
     ;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError}) → self::MyFuture<self::MyFuture::then::S>
     ;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
 }
 static method test() → void
   ;
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 fbba4bf..cd172d7 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
@@ -12,10 +12,14 @@
     return null;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
     return null;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
 }
 static method test() → void {
   self::MyFuture<core::bool> f;
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 40bc63d..d37757e 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
@@ -12,10 +12,14 @@
     return null;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
     return null;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
 }
 static method test() → void {
   self::MyFuture<core::bool> f;
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_2.dart.direct.expect b/pkg/front_end/testcases/inference/future_then_conditional_2.dart.direct.expect
index ffc7080..63e39eb 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional_2.dart.direct.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional_2.dart.direct.expect
@@ -12,10 +12,14 @@
     return null;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
     return null;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
 }
 static method test() → void {
   self::MyFuture<core::bool> f;
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_2.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/future_then_conditional_2.dart.direct.transformed.expect
index 2fa2c058..633179c 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional_2.dart.direct.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional_2.dart.direct.transformed.expect
@@ -12,10 +12,14 @@
     return null;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
     return null;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
 }
 static method test() → void {
   self::MyFuture<core::bool> f;
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 0e4e4b9..638eb19 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
@@ -12,10 +12,14 @@
     ;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError}) → self::MyFuture<self::MyFuture::then::S>
     ;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
 }
 static method test() → void
   ;
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 d571a7d..58fc7dc 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
@@ -12,10 +12,14 @@
     return null;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
     return null;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
 }
 static method test() → void {
   self::MyFuture<core::bool> f;
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 6ce1dea..ce0b933 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
@@ -12,10 +12,14 @@
     return null;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
     return null;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
 }
 static method test() → void {
   self::MyFuture<core::bool> f;
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_3.dart.direct.expect b/pkg/front_end/testcases/inference/future_then_conditional_3.dart.direct.expect
index 215e634..4d5d177 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional_3.dart.direct.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional_3.dart.direct.expect
@@ -12,10 +12,14 @@
     return null;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
     return null;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
 }
 static method test() → void {
   self::MyFuture<core::bool> f;
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_3.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/future_then_conditional_3.dart.direct.transformed.expect
index ef2e0fb..ef96253 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional_3.dart.direct.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional_3.dart.direct.transformed.expect
@@ -12,10 +12,14 @@
     return null;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
     return null;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
 }
 static method test() → void {
   self::MyFuture<core::bool> f;
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 0e4e4b9..638eb19 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
@@ -12,10 +12,14 @@
     ;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError}) → self::MyFuture<self::MyFuture::then::S>
     ;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
 }
 static method test() → void
   ;
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 3497766..60b455d 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
@@ -12,10 +12,14 @@
     return null;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
     return null;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
 }
 static method test() → void {
   self::MyFuture<core::bool> f;
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 a4ca1ff..cf77812 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
@@ -12,10 +12,14 @@
     return null;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
     return null;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
 }
 static method test() → void {
   self::MyFuture<core::bool> f;
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_4.dart.direct.expect b/pkg/front_end/testcases/inference/future_then_conditional_4.dart.direct.expect
index 801d3e8..0e1c731 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional_4.dart.direct.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional_4.dart.direct.expect
@@ -12,10 +12,14 @@
     return null;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
     return null;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
 }
 static method test() → void {
   self::MyFuture<core::bool> f;
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_4.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/future_then_conditional_4.dart.direct.transformed.expect
index 5ceaae0..8299fbb 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional_4.dart.direct.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional_4.dart.direct.transformed.expect
@@ -12,10 +12,14 @@
     return null;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
     return null;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
 }
 static method test() → void {
   self::MyFuture<core::bool> f;
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 0e4e4b9..638eb19 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
@@ -12,10 +12,14 @@
     ;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError}) → self::MyFuture<self::MyFuture::then::S>
     ;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
 }
 static method test() → void
   ;
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 af913b3..9207e2c 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
@@ -12,10 +12,14 @@
     return null;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
     return null;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
 }
 static method test() → void {
   self::MyFuture<core::bool> f;
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 cae896d..e57873c 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
@@ -12,10 +12,14 @@
     return null;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
     return null;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
 }
 static method test() → void {
   self::MyFuture<core::bool> f;
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_5.dart.direct.expect b/pkg/front_end/testcases/inference/future_then_conditional_5.dart.direct.expect
index 94ca72c..5efa1a5 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional_5.dart.direct.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional_5.dart.direct.expect
@@ -12,10 +12,14 @@
     return null;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
     return null;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
 }
 static method test() → void {
   asy::Future<core::bool> f;
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_5.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/future_then_conditional_5.dart.direct.transformed.expect
index a20328a..4d49b6e 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional_5.dart.direct.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional_5.dart.direct.transformed.expect
@@ -12,10 +12,14 @@
     return null;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
     return null;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
 }
 static method test() → void {
   asy::Future<core::bool> f;
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 0e4e4b9..638eb19 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
@@ -12,10 +12,14 @@
     ;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError}) → self::MyFuture<self::MyFuture::then::S>
     ;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
 }
 static method test() → void
   ;
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 06319b5..4375997 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
@@ -12,10 +12,14 @@
     return null;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
     return null;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
 }
 static method test() → void {
   asy::Future<core::bool> f;
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 6d3f557..468ec31 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
@@ -12,10 +12,14 @@
     return null;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
     return null;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
 }
 static method test() → void {
   asy::Future<core::bool> f;
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_6.dart.direct.expect b/pkg/front_end/testcases/inference/future_then_conditional_6.dart.direct.expect
index 57291da..66fd5b3 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional_6.dart.direct.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional_6.dart.direct.expect
@@ -12,10 +12,14 @@
     return null;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
     return null;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
 }
 static method test() → void {
   asy::Future<core::bool> f;
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_6.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/future_then_conditional_6.dart.direct.transformed.expect
index 77de0e0..ba9e600 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional_6.dart.direct.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional_6.dart.direct.transformed.expect
@@ -12,10 +12,14 @@
     return null;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
     return null;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
 }
 static method test() → void {
   asy::Future<core::bool> f;
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 0e4e4b9..638eb19 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
@@ -12,10 +12,14 @@
     ;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError}) → self::MyFuture<self::MyFuture::then::S>
     ;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
 }
 static method test() → void
   ;
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 4b0e44c..af3fa30 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
@@ -12,10 +12,14 @@
     return null;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
     return null;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
 }
 static method test() → void {
   asy::Future<core::bool> f;
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 5d100b9..792ef91 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
@@ -12,10 +12,14 @@
     return null;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
     return null;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
 }
 static method test() → void {
   asy::Future<core::bool> f;
diff --git a/pkg/front_end/testcases/inference/future_then_ifNull.dart.direct.expect b/pkg/front_end/testcases/inference/future_then_ifNull.dart.direct.expect
index 2665c52..5d21b4b 100644
--- a/pkg/front_end/testcases/inference/future_then_ifNull.dart.direct.expect
+++ b/pkg/front_end/testcases/inference/future_then_ifNull.dart.direct.expect
@@ -12,10 +12,14 @@
     return null;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
     return null;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
 }
 static method test() → void {
   self::MyFuture<core::int> f;
diff --git a/pkg/front_end/testcases/inference/future_then_ifNull.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/future_then_ifNull.dart.direct.transformed.expect
index cb0d0d1..e57d937 100644
--- a/pkg/front_end/testcases/inference/future_then_ifNull.dart.direct.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_ifNull.dart.direct.transformed.expect
@@ -12,10 +12,14 @@
     return null;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
     return null;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
 }
 static method test() → void {
   self::MyFuture<core::int> f;
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 0e4e4b9..638eb19 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
@@ -12,10 +12,14 @@
     ;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError}) → self::MyFuture<self::MyFuture::then::S>
     ;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
 }
 static method test() → void
   ;
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 9e96f13..1eddb4a 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
@@ -12,10 +12,14 @@
     return null;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
     return null;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
 }
 static method test() → void {
   self::MyFuture<core::int> f;
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 aeb0d5a..311f23d 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
@@ -12,10 +12,14 @@
     return null;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
     return null;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
 }
 static method test() → void {
   self::MyFuture<core::int> f;
diff --git a/pkg/front_end/testcases/inference/future_then_upwards.dart.direct.expect b/pkg/front_end/testcases/inference/future_then_upwards.dart.direct.expect
index 4f7b85b..4d6cabd7 100644
--- a/pkg/front_end/testcases/inference/future_then_upwards.dart.direct.expect
+++ b/pkg/front_end/testcases/inference/future_then_upwards.dart.direct.expect
@@ -12,10 +12,14 @@
     return null;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
     return null;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
 }
 static method main() → void {
   dynamic f = self::foo().then((dynamic _) → dynamic => 2.3);
diff --git a/pkg/front_end/testcases/inference/future_then_upwards.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/future_then_upwards.dart.direct.transformed.expect
index 4f7b85b..4d6cabd7 100644
--- a/pkg/front_end/testcases/inference/future_then_upwards.dart.direct.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_upwards.dart.direct.transformed.expect
@@ -12,10 +12,14 @@
     return null;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
     return null;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
 }
 static method main() → void {
   dynamic f = self::foo().then((dynamic _) → dynamic => 2.3);
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 b0ad581..c63fbb8 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
@@ -12,10 +12,14 @@
     ;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError}) → self::MyFuture<self::MyFuture::then::S>
     ;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
 }
 static method main() → void
   ;
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 544b68b..f73a813 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
@@ -12,10 +12,14 @@
     return null;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
     return null;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
 }
 static method main() → void {
   self::MyFuture<core::double> f = self::foo().{self::MyFuture::then}<core::double>((dynamic _) → core::double => 2.3);
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 671d8b5..62c39b7 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
@@ -12,10 +12,14 @@
     return null;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
     return null;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
 }
 static method main() → void {
   self::MyFuture<core::double> f = self::foo().{self::MyFuture::then}<core::double>((dynamic _) → core::double => 2.3);
diff --git a/pkg/front_end/testcases/inference/future_then_upwards_2.dart.direct.expect b/pkg/front_end/testcases/inference/future_then_upwards_2.dart.direct.expect
index 8e506d2..dcb5ae3 100644
--- a/pkg/front_end/testcases/inference/future_then_upwards_2.dart.direct.expect
+++ b/pkg/front_end/testcases/inference/future_then_upwards_2.dart.direct.expect
@@ -12,10 +12,14 @@
     return null;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
     return null;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
 }
 static method main() → void {
   dynamic f = self::foo().then((dynamic _) → dynamic => 2.3);
diff --git a/pkg/front_end/testcases/inference/future_then_upwards_2.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/future_then_upwards_2.dart.direct.transformed.expect
index 8e506d2..dcb5ae3 100644
--- a/pkg/front_end/testcases/inference/future_then_upwards_2.dart.direct.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_upwards_2.dart.direct.transformed.expect
@@ -12,10 +12,14 @@
     return null;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
     return null;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
 }
 static method main() → void {
   dynamic f = self::foo().then((dynamic _) → dynamic => 2.3);
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 b0ad581..c63fbb8 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
@@ -12,10 +12,14 @@
     ;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError}) → self::MyFuture<self::MyFuture::then::S>
     ;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
 }
 static method main() → void
   ;
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 dec6374..1e8d4cc 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
@@ -12,10 +12,14 @@
     return null;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
     return null;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
 }
 static method main() → void {
   self::MyFuture<core::double> f = self::foo().{self::MyFuture::then}<core::double>((dynamic _) → core::double => 2.3);
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 70bf88a..2f256a9 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
@@ -12,10 +12,14 @@
     return null;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
     return null;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
 }
 static method main() → void {
   self::MyFuture<core::double> f = self::foo().{self::MyFuture::then}<core::double>((dynamic _) → core::double => 2.3);
diff --git a/pkg/front_end/testcases/inference/future_then_upwards_3.dart.direct.expect b/pkg/front_end/testcases/inference/future_then_upwards_3.dart.direct.expect
index 78825bf..994012f 100644
--- a/pkg/front_end/testcases/inference/future_then_upwards_3.dart.direct.expect
+++ b/pkg/front_end/testcases/inference/future_then_upwards_3.dart.direct.expect
@@ -12,10 +12,14 @@
     return null;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
     return null;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
 }
 static method test() → void {
   dynamic f = self::foo().then((dynamic _) → dynamic => 2.3);
diff --git a/pkg/front_end/testcases/inference/future_then_upwards_3.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/future_then_upwards_3.dart.direct.transformed.expect
index 78825bf..994012f 100644
--- a/pkg/front_end/testcases/inference/future_then_upwards_3.dart.direct.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_upwards_3.dart.direct.transformed.expect
@@ -12,10 +12,14 @@
     return null;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
     return null;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
 }
 static method test() → void {
   dynamic f = self::foo().then((dynamic _) → dynamic => 2.3);
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 f7f3336..cfcba8d 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
@@ -12,10 +12,14 @@
     ;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError}) → self::MyFuture<self::MyFuture::then::S>
     ;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
 }
 static method test() → void
   ;
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 e5af8f4..73b2edf 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
@@ -12,10 +12,14 @@
     return null;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
     return null;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
 }
 static method test() → void {
   asy::Future<core::double> f = self::foo().{asy::Future::then}<core::double>((dynamic _) → core::double => 2.3);
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 2a2356f..7380ae9 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
@@ -12,10 +12,14 @@
     return null;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
     return null;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
 }
 static method test() → void {
   asy::Future<core::double> f = self::foo().{asy::Future::then}<core::double>((dynamic _) → core::double => 2.3);
diff --git a/pkg/front_end/testcases/inference/future_union_async_conditional.dart.direct.expect b/pkg/front_end/testcases/inference/future_union_async_conditional.dart.direct.expect
index cf63b53..81cd117 100644
--- a/pkg/front_end/testcases/inference/future_union_async_conditional.dart.direct.expect
+++ b/pkg/front_end/testcases/inference/future_union_async_conditional.dart.direct.expect
@@ -12,10 +12,14 @@
     return null;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
     return null;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
 }
 static method g1(core::bool x) → asy::Future<core::int> async {
   return x ? 42 : asy::Future::value<dynamic>(42);
diff --git a/pkg/front_end/testcases/inference/future_union_async_conditional.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/future_union_async_conditional.dart.direct.transformed.expect
index b058d42..9397ba5 100644
--- a/pkg/front_end/testcases/inference/future_union_async_conditional.dart.direct.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_union_async_conditional.dart.direct.transformed.expect
@@ -12,10 +12,14 @@
     return null;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
     return null;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
 }
 static method g1(core::bool x) → asy::Future<core::int> /* originally async */ {
   final asy::Completer<core::int> :completer = asy::Completer::sync<core::int>();
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 cb95b45..d6eb3cf 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
@@ -12,10 +12,14 @@
     ;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError}) → self::MyFuture<self::MyFuture::then::S>
     ;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
 }
 static method g1(core::bool x) → asy::Future<core::int>
   ;
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 011546b..360051f 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
@@ -12,10 +12,14 @@
     return null;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
     return null;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
 }
 static method g1(core::bool x) → asy::Future<core::int> async {
   return (x ?{core::Object} 42 : asy::Future::value<core::int>(42)) as{TypeError} asy::FutureOr<core::int>;
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 ed67f60..61d62cb 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
@@ -12,10 +12,14 @@
     return null;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
     return null;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
 }
 static method g1(core::bool x) → asy::Future<core::int> /* originally async */ {
   final asy::Completer<core::int> :completer = asy::Completer::sync<core::int>();
diff --git a/pkg/front_end/testcases/inference/future_union_async_conditional_2.dart.direct.expect b/pkg/front_end/testcases/inference/future_union_async_conditional_2.dart.direct.expect
index d08eb4f..696d941 100644
--- a/pkg/front_end/testcases/inference/future_union_async_conditional_2.dart.direct.expect
+++ b/pkg/front_end/testcases/inference/future_union_async_conditional_2.dart.direct.expect
@@ -12,10 +12,14 @@
     return null;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
     return null;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
 }
 static method g1(core::bool x) → asy::Future<core::int> async {
   return x ? 42 : new self::MyFuture::value<dynamic>(42);
diff --git a/pkg/front_end/testcases/inference/future_union_async_conditional_2.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/future_union_async_conditional_2.dart.direct.transformed.expect
index fa93ea9..f31e5ca 100644
--- a/pkg/front_end/testcases/inference/future_union_async_conditional_2.dart.direct.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_union_async_conditional_2.dart.direct.transformed.expect
@@ -12,10 +12,14 @@
     return null;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
     return null;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
 }
 static method g1(core::bool x) → asy::Future<core::int> /* originally async */ {
   final asy::Completer<core::int> :completer = asy::Completer::sync<core::int>();
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 cb95b45..d6eb3cf 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
@@ -12,10 +12,14 @@
     ;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError}) → self::MyFuture<self::MyFuture::then::S>
     ;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
 }
 static method g1(core::bool x) → asy::Future<core::int>
   ;
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 a5c2511..27f64bd 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
@@ -12,10 +12,14 @@
     return null;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
     return null;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
 }
 static method g1(core::bool x) → asy::Future<core::int> async {
   return (x ?{core::Object} 42 : new self::MyFuture::value<core::int>(42)) as{TypeError} asy::FutureOr<core::int>;
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 611b1c4..ab69947 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
@@ -12,10 +12,14 @@
     return null;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
     return null;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
 }
 static method g1(core::bool x) → asy::Future<core::int> /* originally async */ {
   final asy::Completer<core::int> :completer = asy::Completer::sync<core::int>();
diff --git a/pkg/front_end/testcases/inference/future_union_downwards.dart.direct.expect b/pkg/front_end/testcases/inference/future_union_downwards.dart.direct.expect
index 31c6b7a..eb9e275 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards.dart.direct.expect
+++ b/pkg/front_end/testcases/inference/future_union_downwards.dart.direct.expect
@@ -12,10 +12,14 @@
     return null;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
     return null;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
 }
 static field self::MyFuture<dynamic> f;
 static field asy::Future<core::int> t1 = self::f.then((dynamic _) → dynamic => asy::Future::value<dynamic>("hi"));
diff --git a/pkg/front_end/testcases/inference/future_union_downwards.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/future_union_downwards.dart.direct.transformed.expect
index 167fe79..fab89fe 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards.dart.direct.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_union_downwards.dart.direct.transformed.expect
@@ -12,10 +12,14 @@
     return null;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
     return null;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
 }
 static field self::MyFuture<dynamic> f;
 static field asy::Future<core::int> t1 = self::f.then((dynamic _) → dynamic => asy::Future::value<dynamic>("hi"));
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 2bad4e8..8fbf742 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
@@ -12,10 +12,14 @@
     ;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError}) → self::MyFuture<self::MyFuture::then::S>
     ;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
 }
 static field self::MyFuture<dynamic> f;
 static field asy::Future<core::int> t1;
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 ab7fd1f..a2ccb18 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
@@ -12,10 +12,14 @@
     return null;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
     return null;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
 }
 static field self::MyFuture<dynamic> f;
 static field asy::Future<core::int> t1 = self::f.{self::MyFuture::then}<core::int>((dynamic _) → asy::Future<core::int> => asy::Future::value<core::int>(let final dynamic #t1 = let dynamic _ = null in invalid-expression "pkg/front_end/testcases/inference/future_union_downwards.dart:21:44: Error: A value of type 'dart.core::String' can't be assigned to a variable of type 'dart.async::FutureOr<dart.core::int>'.
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 97f2740..c8a55a9 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
@@ -12,10 +12,14 @@
     return null;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
     return null;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
 }
 static field self::MyFuture<dynamic> f;
 static field asy::Future<core::int> t1 = self::f.{self::MyFuture::then}<core::int>((dynamic _) → asy::Future<core::int> => asy::Future::value<core::int>(let final dynamic #t1 = let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/future_union_downwards.dart:21:44: Error: A value of type 'dart.core::String' can't be assigned to a variable of type 'dart.async::FutureOr<dart.core::int>'.
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_2.dart.direct.expect b/pkg/front_end/testcases/inference/future_union_downwards_2.dart.direct.expect
index e8e6411..88065da 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards_2.dart.direct.expect
+++ b/pkg/front_end/testcases/inference/future_union_downwards_2.dart.direct.expect
@@ -12,10 +12,14 @@
     return null;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
     return null;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
 }
 static field self::MyFuture<dynamic> f;
 static field asy::Future<core::int> t1 = self::f.then((dynamic _) → dynamic => new self::MyFuture::value<dynamic>("hi"));
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_2.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/future_union_downwards_2.dart.direct.transformed.expect
index 24fedaa..b669441 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards_2.dart.direct.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_union_downwards_2.dart.direct.transformed.expect
@@ -12,10 +12,14 @@
     return null;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
     return null;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
 }
 static field self::MyFuture<dynamic> f;
 static field asy::Future<core::int> t1 = self::f.then((dynamic _) → dynamic => new self::MyFuture::value<dynamic>("hi"));
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 2bad4e8..8fbf742 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
@@ -12,10 +12,14 @@
     ;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError}) → self::MyFuture<self::MyFuture::then::S>
     ;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
 }
 static field self::MyFuture<dynamic> f;
 static field asy::Future<core::int> t1;
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 ff63cfd..bf7763d 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
@@ -12,10 +12,14 @@
     return null;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
     return null;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
 }
 static field self::MyFuture<dynamic> f;
 static field asy::Future<core::int> t1 = self::f.{self::MyFuture::then}<core::int>((dynamic _) → self::MyFuture<core::int> => new self::MyFuture::value<core::int>("hi"));
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 9a1784c..9dfa187 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
@@ -12,10 +12,14 @@
     return null;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
     return null;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
 }
 static field self::MyFuture<dynamic> f;
 static field asy::Future<core::int> t1 = self::f.{self::MyFuture::then}<core::int>((dynamic _) → self::MyFuture<core::int> => new self::MyFuture::value<core::int>("hi"));
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_3.dart.direct.expect b/pkg/front_end/testcases/inference/future_union_downwards_3.dart.direct.expect
index 9027e83..55b480f 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards_3.dart.direct.expect
+++ b/pkg/front_end/testcases/inference/future_union_downwards_3.dart.direct.expect
@@ -12,10 +12,14 @@
     return null;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
     return null;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
 }
 static field asy::Future<dynamic> f;
 static field asy::Future<core::int> t1 = self::f.then((dynamic _) → dynamic => asy::Future::value<dynamic>("hi"));
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_3.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/future_union_downwards_3.dart.direct.transformed.expect
index aacc250..7e22485 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards_3.dart.direct.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_union_downwards_3.dart.direct.transformed.expect
@@ -12,10 +12,14 @@
     return null;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
     return null;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
 }
 static field asy::Future<dynamic> f;
 static field asy::Future<core::int> t1 = self::f.then((dynamic _) → dynamic => asy::Future::value<dynamic>("hi"));
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 4e0c84c..08527e8 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
@@ -12,10 +12,14 @@
     ;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError}) → self::MyFuture<self::MyFuture::then::S>
     ;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
 }
 static field asy::Future<dynamic> f;
 static field asy::Future<core::int> t1;
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 74ed3dc..3ad2061 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
@@ -12,10 +12,14 @@
     return null;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
     return null;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
 }
 static field asy::Future<dynamic> f;
 static field asy::Future<core::int> t1 = self::f.{asy::Future::then}<core::int>((dynamic _) → asy::Future<core::int> => asy::Future::value<core::int>(let final dynamic #t1 = let dynamic _ = null in invalid-expression "pkg/front_end/testcases/inference/future_union_downwards_3.dart:21:44: Error: A value of type 'dart.core::String' can't be assigned to a variable of type 'dart.async::FutureOr<dart.core::int>'.
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 e53a2b4..55eb919 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
@@ -12,10 +12,14 @@
     return null;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
     return null;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
 }
 static field asy::Future<dynamic> f;
 static field asy::Future<core::int> t1 = self::f.{asy::Future::then}<core::int>((dynamic _) → asy::Future<core::int> => asy::Future::value<core::int>(let final dynamic #t1 = let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/future_union_downwards_3.dart:21:44: Error: A value of type 'dart.core::String' can't be assigned to a variable of type 'dart.async::FutureOr<dart.core::int>'.
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_4.dart.direct.expect b/pkg/front_end/testcases/inference/future_union_downwards_4.dart.direct.expect
index 4873748..5ec4bdd 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards_4.dart.direct.expect
+++ b/pkg/front_end/testcases/inference/future_union_downwards_4.dart.direct.expect
@@ -12,10 +12,14 @@
     return null;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
     return null;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
 }
 static field asy::Future<dynamic> f;
 static field asy::Future<core::int> t1 = self::f.then((dynamic _) → dynamic => new self::MyFuture::value<dynamic>("hi"));
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_4.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/future_union_downwards_4.dart.direct.transformed.expect
index 87239a3..7d02922 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards_4.dart.direct.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_union_downwards_4.dart.direct.transformed.expect
@@ -12,10 +12,14 @@
     return null;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
     return null;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
 }
 static field asy::Future<dynamic> f;
 static field asy::Future<core::int> t1 = self::f.then((dynamic _) → dynamic => new self::MyFuture::value<dynamic>("hi"));
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 4e0c84c..08527e8 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
@@ -12,10 +12,14 @@
     ;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError}) → self::MyFuture<self::MyFuture::then::S>
     ;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
 }
 static field asy::Future<dynamic> f;
 static field asy::Future<core::int> t1;
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 afa05ba..d06ad27 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
@@ -12,10 +12,14 @@
     return null;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
     return null;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
 }
 static field asy::Future<dynamic> f;
 static field asy::Future<core::int> t1 = self::f.{asy::Future::then}<core::int>((dynamic _) → self::MyFuture<core::int> => new self::MyFuture::value<core::int>("hi"));
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 1234c31..f9e32bb 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
@@ -12,10 +12,14 @@
     return null;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
     return null;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("catchError", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#test: test}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("whenComplete", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("timeout", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#onTimeout: onTimeout}), false)) as{TypeError} asy::Future<self::MyFuture::T>;
+  no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>
+    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withoutType("asStream", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} asy::Stream<self::MyFuture::T>;
 }
 static field asy::Future<dynamic> f;
 static field asy::Future<core::int> t1 = self::f.{asy::Future::then}<core::int>((dynamic _) → self::MyFuture<core::int> => new self::MyFuture::value<core::int>("hi"));
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 9daa0ae..74cc102 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
@@ -6,7 +6,7 @@
   synthetic constructor •() → void
     : super core::Object::•()
     ;
-  method method<generic-covariant-impl U extends self::Foo::T = dynamic>(self::Foo::method::U u) → self::Foo::method::U
+  method method<generic-covariant-impl U extends self::Foo::T = self::Foo::T>(self::Foo::method::U u) → self::Foo::method::U
     return u;
 }
 static method main() → dynamic {
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 7572fdd..39a38a2 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
@@ -7,7 +7,7 @@
   synthetic constructor •() → void
     : super core::Object::•()
     ;
-  method m<T extends core::num = dynamic>(self::C::m::T x, self::C::m::T y) → self::C::m::T
+  method m<T extends core::num = core::num>(self::C::m::T x, self::C::m::T y) → self::C::m::T
     return null;
 }
 static method test() → dynamic {
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 a687df6..4a4c032 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
@@ -7,7 +7,7 @@
   synthetic constructor •() → void
     : super core::Object::•()
     ;
-  method m<T extends core::num = dynamic>(self::C::m::T x, self::C::m::T y) → self::C::m::T
+  method m<T extends core::num = core::num>(self::C::m::T x, self::C::m::T y) → self::C::m::T
     return null;
 }
 static method test() → dynamic {
diff --git a/pkg/front_end/testcases/inference/infer_local_function_referenced_before_declaration.dart.direct.expect b/pkg/front_end/testcases/inference/infer_local_function_referenced_before_declaration.dart.direct.expect
index 544bc96..9071805 100644
--- a/pkg/front_end/testcases/inference/infer_local_function_referenced_before_declaration.dart.direct.expect
+++ b/pkg/front_end/testcases/inference/infer_local_function_referenced_before_declaration.dart.direct.expect
@@ -6,7 +6,7 @@
   function f() → dynamic
     return throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#g, 32, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
   {
-    let dynamic _ = null in invalid-expression "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.
+    invalid-expression "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;
   ^";
     function g() → dynamic
diff --git a/pkg/front_end/testcases/inference/infer_local_function_referenced_before_declaration.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/infer_local_function_referenced_before_declaration.dart.direct.transformed.expect
index 544bc96..9071805 100644
--- a/pkg/front_end/testcases/inference/infer_local_function_referenced_before_declaration.dart.direct.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_local_function_referenced_before_declaration.dart.direct.transformed.expect
@@ -6,7 +6,7 @@
   function f() → dynamic
     return throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#g, 32, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
   {
-    let dynamic _ = null in invalid-expression "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.
+    invalid-expression "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;
   ^";
     function g() → dynamic
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 1b564d8..ab874a0 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
@@ -9,10 +9,10 @@
   function f() → dynamic
     return throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#g, 32, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
   {
-    let dynamic _ = null in invalid-expression "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.
+    invalid-expression "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;
   ^";
-    function g() → dynamic
+    function g() → core::int
       return 0;
   }
   () → dynamic v = f;
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 fa37ad4..ab874a0 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
@@ -9,10 +9,10 @@
   function f() → dynamic
     return throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#g, 32, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
   {
-    let<BottomType> _ = null in invalid-expression "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.
+    invalid-expression "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;
   ^";
-    function g() → dynamic
+    function g() → core::int
       return 0;
   }
   () → dynamic v = f;
diff --git a/pkg/front_end/testcases/inference/promote_bounds.dart.strong.expect b/pkg/front_end/testcases/inference/promote_bounds.dart.strong.expect
index a25cdbd..0c5b98a 100644
--- a/pkg/front_end/testcases/inference/promote_bounds.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/promote_bounds.dart.strong.expect
@@ -14,7 +14,7 @@
     ;
   abstract method bar() → void;
 }
-static method f<T extends self::B = dynamic>(self::f::T a) → void {
+static method f<T extends self::B = self::B>(self::f::T a) → void {
   if(a is core::String) {
     a.{self::B::foo}();
   }
diff --git a/pkg/front_end/testcases/inference/promote_bounds.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/promote_bounds.dart.strong.transformed.expect
index a25cdbd..0c5b98a 100644
--- a/pkg/front_end/testcases/inference/promote_bounds.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/promote_bounds.dart.strong.transformed.expect
@@ -14,7 +14,7 @@
     ;
   abstract method bar() → void;
 }
-static method f<T extends self::B = dynamic>(self::f::T a) → void {
+static method f<T extends self::B = self::B>(self::f::T a) → void {
   if(a is core::String) {
     a.{self::B::foo}();
   }
diff --git a/pkg/front_end/testcases/named_function_scope.dart.direct.expect b/pkg/front_end/testcases/named_function_scope.dart.direct.expect
index 637e4c1..b5ce346 100644
--- a/pkg/front_end/testcases/named_function_scope.dart.direct.expect
+++ b/pkg/front_end/testcases/named_function_scope.dart.direct.expect
@@ -64,7 +64,7 @@
   {
     self::T t;
     {
-      let dynamic _ = null in invalid-expression "pkg/front_end/testcases/named_function_scope.dart:68:47: Error: Can't declare 'T' because it was already used in this scope.
+      invalid-expression "pkg/front_end/testcases/named_function_scope.dart:68:47: Error: Can't declare 'T' because it was already used in this scope.
     T /*@error=DuplicatedNamePreviouslyUsed*/ T() {}
                                               ^";
       function T() → self::T {}
@@ -72,7 +72,7 @@
   }
   {
     {
-      let dynamic _ = null in invalid-expression "pkg/front_end/testcases/named_function_scope.dart:72:47: Error: Can't declare 'T' because it was already used in this scope.
+      invalid-expression "pkg/front_end/testcases/named_function_scope.dart:72:47: Error: Can't declare 'T' because it was already used in this scope.
     T /*@error=DuplicatedNamePreviouslyUsed*/ T() {}
                                               ^";
       function T() → self::T {}
@@ -81,7 +81,7 @@
   {
     self::T t;
     {
-      let dynamic _ = null in invalid-expression "pkg/front_end/testcases/named_function_scope.dart:77:47: Error: Can't declare 'T' because it was already used in this scope.
+      invalid-expression "pkg/front_end/testcases/named_function_scope.dart:77:47: Error: Can't declare 'T' because it was already used in this scope.
     T /*@error=DuplicatedNamePreviouslyUsed*/ T(T t) {}
                                               ^";
       function T(self::T t) → self::T {}
@@ -89,7 +89,7 @@
   }
   {
     {
-      let dynamic _ = null in invalid-expression "pkg/front_end/testcases/named_function_scope.dart:81:47: Error: Can't declare 'T' because it was already used in this scope.
+      invalid-expression "pkg/front_end/testcases/named_function_scope.dart:81:47: Error: Can't declare 'T' because it was already used in this scope.
     T /*@error=DuplicatedNamePreviouslyUsed*/ T(T t) {}
                                               ^";
       function T(self::T t) → self::T {}
diff --git a/pkg/front_end/testcases/named_function_scope.dart.direct.transformed.expect b/pkg/front_end/testcases/named_function_scope.dart.direct.transformed.expect
index 637e4c1..b5ce346 100644
--- a/pkg/front_end/testcases/named_function_scope.dart.direct.transformed.expect
+++ b/pkg/front_end/testcases/named_function_scope.dart.direct.transformed.expect
@@ -64,7 +64,7 @@
   {
     self::T t;
     {
-      let dynamic _ = null in invalid-expression "pkg/front_end/testcases/named_function_scope.dart:68:47: Error: Can't declare 'T' because it was already used in this scope.
+      invalid-expression "pkg/front_end/testcases/named_function_scope.dart:68:47: Error: Can't declare 'T' because it was already used in this scope.
     T /*@error=DuplicatedNamePreviouslyUsed*/ T() {}
                                               ^";
       function T() → self::T {}
@@ -72,7 +72,7 @@
   }
   {
     {
-      let dynamic _ = null in invalid-expression "pkg/front_end/testcases/named_function_scope.dart:72:47: Error: Can't declare 'T' because it was already used in this scope.
+      invalid-expression "pkg/front_end/testcases/named_function_scope.dart:72:47: Error: Can't declare 'T' because it was already used in this scope.
     T /*@error=DuplicatedNamePreviouslyUsed*/ T() {}
                                               ^";
       function T() → self::T {}
@@ -81,7 +81,7 @@
   {
     self::T t;
     {
-      let dynamic _ = null in invalid-expression "pkg/front_end/testcases/named_function_scope.dart:77:47: Error: Can't declare 'T' because it was already used in this scope.
+      invalid-expression "pkg/front_end/testcases/named_function_scope.dart:77:47: Error: Can't declare 'T' because it was already used in this scope.
     T /*@error=DuplicatedNamePreviouslyUsed*/ T(T t) {}
                                               ^";
       function T(self::T t) → self::T {}
@@ -89,7 +89,7 @@
   }
   {
     {
-      let dynamic _ = null in invalid-expression "pkg/front_end/testcases/named_function_scope.dart:81:47: Error: Can't declare 'T' because it was already used in this scope.
+      invalid-expression "pkg/front_end/testcases/named_function_scope.dart:81:47: Error: Can't declare 'T' because it was already used in this scope.
     T /*@error=DuplicatedNamePreviouslyUsed*/ T(T t) {}
                                               ^";
       function T(self::T t) → self::T {}
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 3c4db65..3790ec0 100644
--- a/pkg/front_end/testcases/named_function_scope.dart.strong.expect
+++ b/pkg/front_end/testcases/named_function_scope.dart.strong.expect
@@ -66,7 +66,7 @@
   {
     self::T t;
     {
-      let dynamic _ = null in invalid-expression "pkg/front_end/testcases/named_function_scope.dart:68:47: Error: Can't declare 'T' because it was already used in this scope.
+      invalid-expression "pkg/front_end/testcases/named_function_scope.dart:68:47: Error: Can't declare 'T' because it was already used in this scope.
     T /*@error=DuplicatedNamePreviouslyUsed*/ T() {}
                                               ^";
       function T() → self::T {}
@@ -74,7 +74,7 @@
   }
   {
     {
-      let dynamic _ = null in invalid-expression "pkg/front_end/testcases/named_function_scope.dart:72:47: Error: Can't declare 'T' because it was already used in this scope.
+      invalid-expression "pkg/front_end/testcases/named_function_scope.dart:72:47: Error: Can't declare 'T' because it was already used in this scope.
     T /*@error=DuplicatedNamePreviouslyUsed*/ T() {}
                                               ^";
       function T() → self::T {}
@@ -83,7 +83,7 @@
   {
     self::T t;
     {
-      let dynamic _ = null in invalid-expression "pkg/front_end/testcases/named_function_scope.dart:77:47: Error: Can't declare 'T' because it was already used in this scope.
+      invalid-expression "pkg/front_end/testcases/named_function_scope.dart:77:47: Error: Can't declare 'T' because it was already used in this scope.
     T /*@error=DuplicatedNamePreviouslyUsed*/ T(T t) {}
                                               ^";
       function T(self::T t) → self::T {}
@@ -91,7 +91,7 @@
   }
   {
     {
-      let dynamic _ = null in invalid-expression "pkg/front_end/testcases/named_function_scope.dart:81:47: Error: Can't declare 'T' because it was already used in this scope.
+      invalid-expression "pkg/front_end/testcases/named_function_scope.dart:81:47: Error: Can't declare 'T' because it was already used in this scope.
     T /*@error=DuplicatedNamePreviouslyUsed*/ T(T t) {}
                                               ^";
       function T(self::T t) → self::T {}
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 155e18a..94ed7c1 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
@@ -66,7 +66,7 @@
   {
     self::T t;
     {
-      let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/named_function_scope.dart:68:47: Error: Can't declare 'T' because it was already used in this scope.
+      invalid-expression "pkg/front_end/testcases/named_function_scope.dart:68:47: Error: Can't declare 'T' because it was already used in this scope.
     T /*@error=DuplicatedNamePreviouslyUsed*/ T() {}
                                               ^";
       function T() → self::T {}
@@ -74,7 +74,7 @@
   }
   {
     {
-      let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/named_function_scope.dart:72:47: Error: Can't declare 'T' because it was already used in this scope.
+      invalid-expression "pkg/front_end/testcases/named_function_scope.dart:72:47: Error: Can't declare 'T' because it was already used in this scope.
     T /*@error=DuplicatedNamePreviouslyUsed*/ T() {}
                                               ^";
       function T() → self::T {}
@@ -83,7 +83,7 @@
   {
     self::T t;
     {
-      let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/named_function_scope.dart:77:47: Error: Can't declare 'T' because it was already used in this scope.
+      invalid-expression "pkg/front_end/testcases/named_function_scope.dart:77:47: Error: Can't declare 'T' because it was already used in this scope.
     T /*@error=DuplicatedNamePreviouslyUsed*/ T(T t) {}
                                               ^";
       function T(self::T t) → self::T {}
@@ -91,7 +91,7 @@
   }
   {
     {
-      let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/named_function_scope.dart:81:47: Error: Can't declare 'T' because it was already used in this scope.
+      invalid-expression "pkg/front_end/testcases/named_function_scope.dart:81:47: Error: Can't declare 'T' because it was already used in this scope.
     T /*@error=DuplicatedNamePreviouslyUsed*/ T(T t) {}
                                               ^";
       function T(self::T t) → self::T {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/abstract_interface_nsm_inherited.dart.direct.expect b/pkg/front_end/testcases/no_such_method_forwarders/abstract_interface_nsm_inherited.dart.direct.expect
index 77108c2..2a97b62 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/abstract_interface_nsm_inherited.dart.direct.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/abstract_interface_nsm_inherited.dart.direct.expect
@@ -20,6 +20,7 @@
   synthetic constructor •() → void
     : super self::A::•()
     ;
-  abstract no-such-method-forwarder method foo() → void;
+  no-such-method-forwarder method foo() → void
+    return this.{self::A::noSuchMethod}(new core::_InvocationMirror::_withoutType("foo", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false));
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/abstract_interface_nsm_inherited.dart.direct.transformed.expect b/pkg/front_end/testcases/no_such_method_forwarders/abstract_interface_nsm_inherited.dart.direct.transformed.expect
index 77108c2..2a97b62 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/abstract_interface_nsm_inherited.dart.direct.transformed.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/abstract_interface_nsm_inherited.dart.direct.transformed.expect
@@ -20,6 +20,7 @@
   synthetic constructor •() → void
     : super self::A::•()
     ;
-  abstract no-such-method-forwarder method foo() → void;
+  no-such-method-forwarder method foo() → void
+    return this.{self::A::noSuchMethod}(new core::_InvocationMirror::_withoutType("foo", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false));
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/abstract_interface_nsm_inherited.dart.outline.expect b/pkg/front_end/testcases/no_such_method_forwarders/abstract_interface_nsm_inherited.dart.outline.expect
index f5898c4..e05ba5e 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/abstract_interface_nsm_inherited.dart.outline.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/abstract_interface_nsm_inherited.dart.outline.expect
@@ -16,7 +16,8 @@
 class B extends self::A implements self::I {
   synthetic constructor •() → void
     ;
-  abstract no-such-method-forwarder method foo() → void;
+  no-such-method-forwarder method foo() → void
+    return this.{self::A::noSuchMethod}(new core::_InvocationMirror::_withoutType("foo", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false));
 }
 static method main() → dynamic
   ;
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/abstract_interface_nsm_inherited.dart.strong.expect b/pkg/front_end/testcases/no_such_method_forwarders/abstract_interface_nsm_inherited.dart.strong.expect
index 77108c2..2a97b62 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/abstract_interface_nsm_inherited.dart.strong.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/abstract_interface_nsm_inherited.dart.strong.expect
@@ -20,6 +20,7 @@
   synthetic constructor •() → void
     : super self::A::•()
     ;
-  abstract no-such-method-forwarder method foo() → void;
+  no-such-method-forwarder method foo() → void
+    return this.{self::A::noSuchMethod}(new core::_InvocationMirror::_withoutType("foo", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false));
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/abstract_interface_nsm_inherited.dart.strong.transformed.expect b/pkg/front_end/testcases/no_such_method_forwarders/abstract_interface_nsm_inherited.dart.strong.transformed.expect
index 77108c2..2a97b62 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/abstract_interface_nsm_inherited.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/abstract_interface_nsm_inherited.dart.strong.transformed.expect
@@ -20,6 +20,7 @@
   synthetic constructor •() → void
     : super self::A::•()
     ;
-  abstract no-such-method-forwarder method foo() → void;
+  no-such-method-forwarder method foo() → void
+    return this.{self::A::noSuchMethod}(new core::_InvocationMirror::_withoutType("foo", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false));
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/interface_with_concrete.dart.direct.expect b/pkg/front_end/testcases/no_such_method_forwarders/interface_with_concrete.dart.direct.expect
index 6de0ac2..6928073 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/interface_with_concrete.dart.direct.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/interface_with_concrete.dart.direct.expect
@@ -20,6 +20,7 @@
   synthetic constructor •() → void
     : super self::A::•()
     ;
-  abstract no-such-method-forwarder method foo() → void;
+  no-such-method-forwarder method foo() → void
+    return this.{self::A::noSuchMethod}(new core::_InvocationMirror::_withoutType("foo", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false));
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/interface_with_concrete.dart.direct.transformed.expect b/pkg/front_end/testcases/no_such_method_forwarders/interface_with_concrete.dart.direct.transformed.expect
index 6de0ac2..6928073 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/interface_with_concrete.dart.direct.transformed.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/interface_with_concrete.dart.direct.transformed.expect
@@ -20,6 +20,7 @@
   synthetic constructor •() → void
     : super self::A::•()
     ;
-  abstract no-such-method-forwarder method foo() → void;
+  no-such-method-forwarder method foo() → void
+    return this.{self::A::noSuchMethod}(new core::_InvocationMirror::_withoutType("foo", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false));
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/interface_with_concrete.dart.outline.expect b/pkg/front_end/testcases/no_such_method_forwarders/interface_with_concrete.dart.outline.expect
index a299436..f1b794a 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/interface_with_concrete.dart.outline.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/interface_with_concrete.dart.outline.expect
@@ -17,7 +17,8 @@
 class B extends self::A implements self::I {
   synthetic constructor •() → void
     ;
-  abstract no-such-method-forwarder method foo() → void;
+  no-such-method-forwarder method foo() → void
+    return this.{self::A::noSuchMethod}(new core::_InvocationMirror::_withoutType("foo", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false));
 }
 static method main() → dynamic
   ;
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/interface_with_concrete.dart.strong.expect b/pkg/front_end/testcases/no_such_method_forwarders/interface_with_concrete.dart.strong.expect
index 6de0ac2..6928073 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/interface_with_concrete.dart.strong.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/interface_with_concrete.dart.strong.expect
@@ -20,6 +20,7 @@
   synthetic constructor •() → void
     : super self::A::•()
     ;
-  abstract no-such-method-forwarder method foo() → void;
+  no-such-method-forwarder method foo() → void
+    return this.{self::A::noSuchMethod}(new core::_InvocationMirror::_withoutType("foo", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false));
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/interface_with_concrete.dart.strong.transformed.expect b/pkg/front_end/testcases/no_such_method_forwarders/interface_with_concrete.dart.strong.transformed.expect
index 6de0ac2..6928073 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/interface_with_concrete.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/interface_with_concrete.dart.strong.transformed.expect
@@ -20,6 +20,7 @@
   synthetic constructor •() → void
     : super self::A::•()
     ;
-  abstract no-such-method-forwarder method foo() → void;
+  no-such-method-forwarder method foo() → void
+    return this.{self::A::noSuchMethod}(new core::_InvocationMirror::_withoutType("foo", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false));
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/interface_with_nsm.dart.direct.expect b/pkg/front_end/testcases/no_such_method_forwarders/interface_with_nsm.dart.direct.expect
index 7463788..5d8ddf7 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/interface_with_nsm.dart.direct.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/interface_with_nsm.dart.direct.expect
@@ -8,7 +8,8 @@
     ;
   method noSuchMethod(core::Invocation i) → dynamic
     return null;
-  abstract no-such-method-forwarder method foo() → void;
+  no-such-method-forwarder method foo() → void
+    return this.{self::I::noSuchMethod}(new core::_InvocationMirror::_withoutType("foo", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false));
 }
 class M extends core::Object {
   synthetic constructor •() → void
@@ -23,7 +24,8 @@
   synthetic constructor •() → void
     : super core::Object::•()
     ;
-  abstract no-such-method-forwarder method foo() → void;
+  no-such-method-forwarder method foo() → void
+    return this.{self::M::noSuchMethod}(new core::_InvocationMirror::_withoutType("foo", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false));
 }
 abstract class _B&Object&M = core::Object with self::M {
 }
@@ -31,6 +33,7 @@
   synthetic constructor •() → void
     : super core::Object::•()
     ;
-  abstract no-such-method-forwarder method foo() → void;
+  no-such-method-forwarder method foo() → void
+    return this.{self::M::noSuchMethod}(new core::_InvocationMirror::_withoutType("foo", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false));
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/interface_with_nsm.dart.direct.transformed.expect b/pkg/front_end/testcases/no_such_method_forwarders/interface_with_nsm.dart.direct.transformed.expect
index 49caf94..eb2d0a0 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/interface_with_nsm.dart.direct.transformed.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/interface_with_nsm.dart.direct.transformed.expect
@@ -8,7 +8,8 @@
     ;
   method noSuchMethod(core::Invocation i) → dynamic
     return null;
-  abstract no-such-method-forwarder method foo() → void;
+  no-such-method-forwarder method foo() → void
+    return this.{self::I::noSuchMethod}(new core::_InvocationMirror::_withoutType("foo", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false));
 }
 class M extends core::Object {
   synthetic constructor •() → void
@@ -28,7 +29,8 @@
   synthetic constructor •() → void
     : super core::Object::•()
     ;
-  abstract no-such-method-forwarder method foo() → void;
+  no-such-method-forwarder method foo() → void
+    return this.{self::M::noSuchMethod}(new core::_InvocationMirror::_withoutType("foo", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false));
 }
 abstract class _B&Object&M extends core::Object implements self::M {
   synthetic constructor •() → void
@@ -41,6 +43,7 @@
   synthetic constructor •() → void
     : super core::Object::•()
     ;
-  abstract no-such-method-forwarder method foo() → void;
+  no-such-method-forwarder method foo() → void
+    return this.{self::M::noSuchMethod}(new core::_InvocationMirror::_withoutType("foo", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false));
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/interface_with_nsm.dart.outline.expect b/pkg/front_end/testcases/no_such_method_forwarders/interface_with_nsm.dart.outline.expect
index f61d498..0901c24 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/interface_with_nsm.dart.outline.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/interface_with_nsm.dart.outline.expect
@@ -7,7 +7,8 @@
     ;
   method noSuchMethod(core::Invocation i) → dynamic
     ;
-  abstract no-such-method-forwarder method foo() → void;
+  no-such-method-forwarder method foo() → void
+    return this.{self::I::noSuchMethod}(new core::_InvocationMirror::_withoutType("foo", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false));
 }
 class M extends core::Object {
   synthetic constructor •() → void
@@ -20,14 +21,16 @@
 class A extends self::_A&Object&M implements self::I {
   synthetic constructor •() → void
     ;
-  abstract no-such-method-forwarder method foo() → void;
+  no-such-method-forwarder method foo() → void
+    return this.{self::M::noSuchMethod}(new core::_InvocationMirror::_withoutType("foo", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false));
 }
 abstract class _B&Object&M = core::Object with self::M {
 }
 class B extends self::_B&Object&M implements self::I {
   synthetic constructor •() → void
     ;
-  abstract no-such-method-forwarder method foo() → void;
+  no-such-method-forwarder method foo() → void
+    return this.{self::M::noSuchMethod}(new core::_InvocationMirror::_withoutType("foo", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false));
 }
 static method main() → dynamic
   ;
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/interface_with_nsm.dart.strong.expect b/pkg/front_end/testcases/no_such_method_forwarders/interface_with_nsm.dart.strong.expect
index 7463788..5d8ddf7 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/interface_with_nsm.dart.strong.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/interface_with_nsm.dart.strong.expect
@@ -8,7 +8,8 @@
     ;
   method noSuchMethod(core::Invocation i) → dynamic
     return null;
-  abstract no-such-method-forwarder method foo() → void;
+  no-such-method-forwarder method foo() → void
+    return this.{self::I::noSuchMethod}(new core::_InvocationMirror::_withoutType("foo", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false));
 }
 class M extends core::Object {
   synthetic constructor •() → void
@@ -23,7 +24,8 @@
   synthetic constructor •() → void
     : super core::Object::•()
     ;
-  abstract no-such-method-forwarder method foo() → void;
+  no-such-method-forwarder method foo() → void
+    return this.{self::M::noSuchMethod}(new core::_InvocationMirror::_withoutType("foo", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false));
 }
 abstract class _B&Object&M = core::Object with self::M {
 }
@@ -31,6 +33,7 @@
   synthetic constructor •() → void
     : super core::Object::•()
     ;
-  abstract no-such-method-forwarder method foo() → void;
+  no-such-method-forwarder method foo() → void
+    return this.{self::M::noSuchMethod}(new core::_InvocationMirror::_withoutType("foo", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false));
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/interface_with_nsm.dart.strong.transformed.expect b/pkg/front_end/testcases/no_such_method_forwarders/interface_with_nsm.dart.strong.transformed.expect
index 49caf94..eb2d0a0 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/interface_with_nsm.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/interface_with_nsm.dart.strong.transformed.expect
@@ -8,7 +8,8 @@
     ;
   method noSuchMethod(core::Invocation i) → dynamic
     return null;
-  abstract no-such-method-forwarder method foo() → void;
+  no-such-method-forwarder method foo() → void
+    return this.{self::I::noSuchMethod}(new core::_InvocationMirror::_withoutType("foo", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false));
 }
 class M extends core::Object {
   synthetic constructor •() → void
@@ -28,7 +29,8 @@
   synthetic constructor •() → void
     : super core::Object::•()
     ;
-  abstract no-such-method-forwarder method foo() → void;
+  no-such-method-forwarder method foo() → void
+    return this.{self::M::noSuchMethod}(new core::_InvocationMirror::_withoutType("foo", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false));
 }
 abstract class _B&Object&M extends core::Object implements self::M {
   synthetic constructor •() → void
@@ -41,6 +43,7 @@
   synthetic constructor •() → void
     : super core::Object::•()
     ;
-  abstract no-such-method-forwarder method foo() → void;
+  no-such-method-forwarder method foo() → void
+    return this.{self::M::noSuchMethod}(new core::_InvocationMirror::_withoutType("foo", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false));
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/no_dup_from_mixin.dart.direct.expect b/pkg/front_end/testcases/no_such_method_forwarders/no_dup_from_mixin.dart.direct.expect
index aeadca5..0283bae 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/no_dup_from_mixin.dart.direct.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/no_dup_from_mixin.dart.direct.expect
@@ -14,7 +14,8 @@
     ;
   method noSuchMethod(core::Invocation i) → dynamic
     return null;
-  abstract no-such-method-forwarder method foo() → void;
+  no-such-method-forwarder method foo() → void
+    return this.{self::A::noSuchMethod}(new core::_InvocationMirror::_withoutType("foo", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false));
 }
 abstract class _B&Object&A = core::Object with self::A {
 }
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/no_dup_from_mixin.dart.direct.transformed.expect b/pkg/front_end/testcases/no_such_method_forwarders/no_dup_from_mixin.dart.direct.transformed.expect
index f43923a..bf046d8 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/no_dup_from_mixin.dart.direct.transformed.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/no_dup_from_mixin.dart.direct.transformed.expect
@@ -14,7 +14,8 @@
     ;
   method noSuchMethod(core::Invocation i) → dynamic
     return null;
-  abstract no-such-method-forwarder method foo() → void;
+  no-such-method-forwarder method foo() → void
+    return this.{self::A::noSuchMethod}(new core::_InvocationMirror::_withoutType("foo", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false));
 }
 abstract class _B&Object&A extends core::Object implements self::A {
   synthetic constructor •() → void
@@ -22,7 +23,8 @@
     ;
   method noSuchMethod(core::Invocation i) → dynamic
     return null;
-  abstract no-such-method-forwarder method foo() → void;
+  no-such-method-forwarder method foo() → void
+    return this.{self::A::noSuchMethod}(new core::_InvocationMirror::_withoutType("foo", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false));
 }
 class B extends self::_B&Object&A {
   synthetic constructor •() → void
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/no_dup_from_mixin.dart.outline.expect b/pkg/front_end/testcases/no_such_method_forwarders/no_dup_from_mixin.dart.outline.expect
index 71c513d..63d5358 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/no_dup_from_mixin.dart.outline.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/no_dup_from_mixin.dart.outline.expect
@@ -12,7 +12,8 @@
     ;
   method noSuchMethod(core::Invocation i) → dynamic
     ;
-  abstract no-such-method-forwarder method foo() → void;
+  no-such-method-forwarder method foo() → void
+    return this.{self::A::noSuchMethod}(new core::_InvocationMirror::_withoutType("foo", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false));
 }
 abstract class _B&Object&A = core::Object with self::A {
 }
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/no_dup_from_mixin.dart.strong.expect b/pkg/front_end/testcases/no_such_method_forwarders/no_dup_from_mixin.dart.strong.expect
index aeadca5..0283bae 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/no_dup_from_mixin.dart.strong.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/no_dup_from_mixin.dart.strong.expect
@@ -14,7 +14,8 @@
     ;
   method noSuchMethod(core::Invocation i) → dynamic
     return null;
-  abstract no-such-method-forwarder method foo() → void;
+  no-such-method-forwarder method foo() → void
+    return this.{self::A::noSuchMethod}(new core::_InvocationMirror::_withoutType("foo", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false));
 }
 abstract class _B&Object&A = core::Object with self::A {
 }
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/no_dup_from_mixin.dart.strong.transformed.expect b/pkg/front_end/testcases/no_such_method_forwarders/no_dup_from_mixin.dart.strong.transformed.expect
index f43923a..bf046d8 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/no_dup_from_mixin.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/no_dup_from_mixin.dart.strong.transformed.expect
@@ -14,7 +14,8 @@
     ;
   method noSuchMethod(core::Invocation i) → dynamic
     return null;
-  abstract no-such-method-forwarder method foo() → void;
+  no-such-method-forwarder method foo() → void
+    return this.{self::A::noSuchMethod}(new core::_InvocationMirror::_withoutType("foo", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false));
 }
 abstract class _B&Object&A extends core::Object implements self::A {
   synthetic constructor •() → void
@@ -22,7 +23,8 @@
     ;
   method noSuchMethod(core::Invocation i) → dynamic
     return null;
-  abstract no-such-method-forwarder method foo() → void;
+  no-such-method-forwarder method foo() → void
+    return this.{self::A::noSuchMethod}(new core::_InvocationMirror::_withoutType("foo", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false));
 }
 class B extends self::_B&Object&A {
   synthetic constructor •() → void
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/nsm_inherited.dart.direct.expect b/pkg/front_end/testcases/no_such_method_forwarders/nsm_inherited.dart.direct.expect
index 5b3dcdd..37a4788 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/nsm_inherited.dart.direct.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/nsm_inherited.dart.direct.expect
@@ -13,6 +13,7 @@
   synthetic constructor •() → void
     : super self::M::•()
     ;
-  abstract no-such-method-forwarder method call(core::String s) → void;
+  no-such-method-forwarder method call(core::String s) → void
+    return this.{self::M::noSuchMethod}(new core::_InvocationMirror::_withoutType("call", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[s]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false));
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/nsm_inherited.dart.direct.transformed.expect b/pkg/front_end/testcases/no_such_method_forwarders/nsm_inherited.dart.direct.transformed.expect
index 5b3dcdd..37a4788 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/nsm_inherited.dart.direct.transformed.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/nsm_inherited.dart.direct.transformed.expect
@@ -13,6 +13,7 @@
   synthetic constructor •() → void
     : super self::M::•()
     ;
-  abstract no-such-method-forwarder method call(core::String s) → void;
+  no-such-method-forwarder method call(core::String s) → void
+    return this.{self::M::noSuchMethod}(new core::_InvocationMirror::_withoutType("call", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[s]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false));
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/nsm_inherited.dart.outline.expect b/pkg/front_end/testcases/no_such_method_forwarders/nsm_inherited.dart.outline.expect
index 6fdc38e..b0427dc 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/nsm_inherited.dart.outline.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/nsm_inherited.dart.outline.expect
@@ -11,7 +11,8 @@
 class A extends self::M {
   synthetic constructor •() → void
     ;
-  abstract no-such-method-forwarder method call(core::String s) → void;
+  no-such-method-forwarder method call(core::String s) → void
+    return this.{self::M::noSuchMethod}(new core::_InvocationMirror::_withoutType("call", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[s]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false));
 }
 static method main() → dynamic
   ;
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/nsm_inherited.dart.strong.expect b/pkg/front_end/testcases/no_such_method_forwarders/nsm_inherited.dart.strong.expect
index 5b3dcdd..37a4788 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/nsm_inherited.dart.strong.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/nsm_inherited.dart.strong.expect
@@ -13,6 +13,7 @@
   synthetic constructor •() → void
     : super self::M::•()
     ;
-  abstract no-such-method-forwarder method call(core::String s) → void;
+  no-such-method-forwarder method call(core::String s) → void
+    return this.{self::M::noSuchMethod}(new core::_InvocationMirror::_withoutType("call", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[s]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false));
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/nsm_inherited.dart.strong.transformed.expect b/pkg/front_end/testcases/no_such_method_forwarders/nsm_inherited.dart.strong.transformed.expect
index 5b3dcdd..37a4788 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/nsm_inherited.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/nsm_inherited.dart.strong.transformed.expect
@@ -13,6 +13,7 @@
   synthetic constructor •() → void
     : super self::M::•()
     ;
-  abstract no-such-method-forwarder method call(core::String s) → void;
+  no-such-method-forwarder method call(core::String s) → void
+    return this.{self::M::noSuchMethod}(new core::_InvocationMirror::_withoutType("call", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[s]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false));
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/nsm_mixed_in.dart.direct.expect b/pkg/front_end/testcases/no_such_method_forwarders/nsm_mixed_in.dart.direct.expect
index 82b4b89..012c9be 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/nsm_mixed_in.dart.direct.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/nsm_mixed_in.dart.direct.expect
@@ -16,6 +16,7 @@
   synthetic constructor •() → void
     : super core::Object::•()
     ;
-  abstract no-such-method-forwarder method foo() → void;
+  no-such-method-forwarder method foo() → void
+    return this.{self::A::noSuchMethod}(new core::_InvocationMirror::_withoutType("foo", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false));
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/nsm_mixed_in.dart.direct.transformed.expect b/pkg/front_end/testcases/no_such_method_forwarders/nsm_mixed_in.dart.direct.transformed.expect
index 224585c..5b1b182 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/nsm_mixed_in.dart.direct.transformed.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/nsm_mixed_in.dart.direct.transformed.expect
@@ -22,6 +22,7 @@
   synthetic constructor •() → void
     : super core::Object::•()
     ;
-  abstract no-such-method-forwarder method foo() → void;
+  no-such-method-forwarder method foo() → void
+    return this.{self::A::noSuchMethod}(new core::_InvocationMirror::_withoutType("foo", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false));
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/nsm_mixed_in.dart.outline.expect b/pkg/front_end/testcases/no_such_method_forwarders/nsm_mixed_in.dart.outline.expect
index 6e0c11e..3a59956 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/nsm_mixed_in.dart.outline.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/nsm_mixed_in.dart.outline.expect
@@ -13,7 +13,8 @@
 class B extends self::_B&Object&A {
   synthetic constructor •() → void
     ;
-  abstract no-such-method-forwarder method foo() → void;
+  no-such-method-forwarder method foo() → void
+    return this.{self::A::noSuchMethod}(new core::_InvocationMirror::_withoutType("foo", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false));
 }
 static method main() → dynamic
   ;
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/nsm_mixed_in.dart.strong.expect b/pkg/front_end/testcases/no_such_method_forwarders/nsm_mixed_in.dart.strong.expect
index 82b4b89..012c9be 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/nsm_mixed_in.dart.strong.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/nsm_mixed_in.dart.strong.expect
@@ -16,6 +16,7 @@
   synthetic constructor •() → void
     : super core::Object::•()
     ;
-  abstract no-such-method-forwarder method foo() → void;
+  no-such-method-forwarder method foo() → void
+    return this.{self::A::noSuchMethod}(new core::_InvocationMirror::_withoutType("foo", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false));
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/nsm_mixed_in.dart.strong.transformed.expect b/pkg/front_end/testcases/no_such_method_forwarders/nsm_mixed_in.dart.strong.transformed.expect
index 224585c..5b1b182 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/nsm_mixed_in.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/nsm_mixed_in.dart.strong.transformed.expect
@@ -22,6 +22,7 @@
   synthetic constructor •() → void
     : super core::Object::•()
     ;
-  abstract no-such-method-forwarder method foo() → void;
+  no-such-method-forwarder method foo() → void
+    return this.{self::A::noSuchMethod}(new core::_InvocationMirror::_withoutType("foo", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false));
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/private.dart.direct.expect b/pkg/front_end/testcases/no_such_method_forwarders/private.dart.direct.expect
index 937b5a6..125b323 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/private.dart.direct.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/private.dart.direct.expect
@@ -14,7 +14,8 @@
   synthetic constructor •() → void
     : super self::Foo::•()
     ;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase:///private_module.dart */ _hest() → void;
+  no-such-method-forwarder method /* from org-dartlang-testcase:///private_module.dart */ _hest() → void
+    return this.{self::Foo::noSuchMethod}(new core::_InvocationMirror::_withoutType("_hest", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false));
 }
 class Baz extends self::Foo implements pri::Fisk {
   synthetic constructor •() → void
@@ -22,6 +23,7 @@
     ;
   method _hest() → dynamic
     return null;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase:///private_module.dart */ _hest() → void;
+  no-such-method-forwarder method /* from org-dartlang-testcase:///private_module.dart */ _hest() → void
+    return this.{self::Foo::noSuchMethod}(new core::_InvocationMirror::_withoutType("_hest", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false));
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/private.dart.direct.transformed.expect b/pkg/front_end/testcases/no_such_method_forwarders/private.dart.direct.transformed.expect
index 937b5a6..125b323 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/private.dart.direct.transformed.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/private.dart.direct.transformed.expect
@@ -14,7 +14,8 @@
   synthetic constructor •() → void
     : super self::Foo::•()
     ;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase:///private_module.dart */ _hest() → void;
+  no-such-method-forwarder method /* from org-dartlang-testcase:///private_module.dart */ _hest() → void
+    return this.{self::Foo::noSuchMethod}(new core::_InvocationMirror::_withoutType("_hest", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false));
 }
 class Baz extends self::Foo implements pri::Fisk {
   synthetic constructor •() → void
@@ -22,6 +23,7 @@
     ;
   method _hest() → dynamic
     return null;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase:///private_module.dart */ _hest() → void;
+  no-such-method-forwarder method /* from org-dartlang-testcase:///private_module.dart */ _hest() → void
+    return this.{self::Foo::noSuchMethod}(new core::_InvocationMirror::_withoutType("_hest", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false));
 }
 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 1817793..36ff954 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
@@ -12,14 +12,16 @@
 class Bar extends self::Foo implements pri::Fisk {
   synthetic constructor •() → void
     ;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase:///private_module.dart */ _hest() → void;
+  no-such-method-forwarder method /* from org-dartlang-testcase:///private_module.dart */ _hest() → void
+    return this.{self::Foo::noSuchMethod}(new core::_InvocationMirror::_withoutType("_hest", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false));
 }
 class Baz extends self::Foo implements pri::Fisk {
   synthetic constructor •() → void
     ;
   method _hest() → dynamic
     ;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase:///private_module.dart */ _hest() → void;
+  no-such-method-forwarder method /* from org-dartlang-testcase:///private_module.dart */ _hest() → void
+    return this.{self::Foo::noSuchMethod}(new core::_InvocationMirror::_withoutType("_hest", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false));
 }
 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 937b5a6..125b323 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
@@ -14,7 +14,8 @@
   synthetic constructor •() → void
     : super self::Foo::•()
     ;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase:///private_module.dart */ _hest() → void;
+  no-such-method-forwarder method /* from org-dartlang-testcase:///private_module.dart */ _hest() → void
+    return this.{self::Foo::noSuchMethod}(new core::_InvocationMirror::_withoutType("_hest", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false));
 }
 class Baz extends self::Foo implements pri::Fisk {
   synthetic constructor •() → void
@@ -22,6 +23,7 @@
     ;
   method _hest() → dynamic
     return null;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase:///private_module.dart */ _hest() → void;
+  no-such-method-forwarder method /* from org-dartlang-testcase:///private_module.dart */ _hest() → void
+    return this.{self::Foo::noSuchMethod}(new core::_InvocationMirror::_withoutType("_hest", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false));
 }
 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 937b5a6..125b323 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
@@ -14,7 +14,8 @@
   synthetic constructor •() → void
     : super self::Foo::•()
     ;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase:///private_module.dart */ _hest() → void;
+  no-such-method-forwarder method /* from org-dartlang-testcase:///private_module.dart */ _hest() → void
+    return this.{self::Foo::noSuchMethod}(new core::_InvocationMirror::_withoutType("_hest", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false));
 }
 class Baz extends self::Foo implements pri::Fisk {
   synthetic constructor •() → void
@@ -22,6 +23,7 @@
     ;
   method _hest() → dynamic
     return null;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase:///private_module.dart */ _hest() → void;
+  no-such-method-forwarder method /* from org-dartlang-testcase:///private_module.dart */ _hest() → void
+    return this.{self::Foo::noSuchMethod}(new core::_InvocationMirror::_withoutType("_hest", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false));
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/private_same.dart.direct.expect b/pkg/front_end/testcases/no_such_method_forwarders/private_same.dart.direct.expect
index dbc0d1d..2a23a7b 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/private_same.dart.direct.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/private_same.dart.direct.expect
@@ -14,6 +14,7 @@
     ;
   method noSuchMethod(core::Invocation invocation) → dynamic
     return null;
-  abstract no-such-method-forwarder method _foo() → void;
+  no-such-method-forwarder method _foo() → void
+    return this.{self::Bar::noSuchMethod}(new core::_InvocationMirror::_withoutType("_foo", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false));
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/private_same.dart.direct.transformed.expect b/pkg/front_end/testcases/no_such_method_forwarders/private_same.dart.direct.transformed.expect
index dbc0d1d..2a23a7b 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/private_same.dart.direct.transformed.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/private_same.dart.direct.transformed.expect
@@ -14,6 +14,7 @@
     ;
   method noSuchMethod(core::Invocation invocation) → dynamic
     return null;
-  abstract no-such-method-forwarder method _foo() → void;
+  no-such-method-forwarder method _foo() → void
+    return this.{self::Bar::noSuchMethod}(new core::_InvocationMirror::_withoutType("_foo", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false));
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/private_same.dart.outline.expect b/pkg/front_end/testcases/no_such_method_forwarders/private_same.dart.outline.expect
index 8dc462e..e8cddd1 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/private_same.dart.outline.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/private_same.dart.outline.expect
@@ -12,7 +12,8 @@
     ;
   method noSuchMethod(core::Invocation invocation) → dynamic
     ;
-  abstract no-such-method-forwarder method _foo() → void;
+  no-such-method-forwarder method _foo() → void
+    return this.{self::Bar::noSuchMethod}(new core::_InvocationMirror::_withoutType("_foo", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false));
 }
 static method main() → dynamic
   ;
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/private_same.dart.strong.expect b/pkg/front_end/testcases/no_such_method_forwarders/private_same.dart.strong.expect
index dbc0d1d..2a23a7b 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/private_same.dart.strong.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/private_same.dart.strong.expect
@@ -14,6 +14,7 @@
     ;
   method noSuchMethod(core::Invocation invocation) → dynamic
     return null;
-  abstract no-such-method-forwarder method _foo() → void;
+  no-such-method-forwarder method _foo() → void
+    return this.{self::Bar::noSuchMethod}(new core::_InvocationMirror::_withoutType("_foo", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false));
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/private_same.dart.strong.transformed.expect b/pkg/front_end/testcases/no_such_method_forwarders/private_same.dart.strong.transformed.expect
index dbc0d1d..2a23a7b 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/private_same.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/private_same.dart.strong.transformed.expect
@@ -14,6 +14,7 @@
     ;
   method noSuchMethod(core::Invocation invocation) → dynamic
     return null;
-  abstract no-such-method-forwarder method _foo() → void;
+  no-such-method-forwarder method _foo() → void
+    return this.{self::Bar::noSuchMethod}(new core::_InvocationMirror::_withoutType("_foo", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false));
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/same.dart.direct.expect b/pkg/front_end/testcases/no_such_method_forwarders/same.dart.direct.expect
index a8c2894..f043899 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/same.dart.direct.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/same.dart.direct.expect
@@ -9,6 +9,7 @@
   method noSuchMethod(core::Invocation i) → dynamic {
     return null;
   }
-  abstract no-such-method-forwarder method foo() → void;
+  no-such-method-forwarder method foo() → void
+    return this.{self::A::noSuchMethod}(new core::_InvocationMirror::_withoutType("foo", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false));
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/same.dart.direct.transformed.expect b/pkg/front_end/testcases/no_such_method_forwarders/same.dart.direct.transformed.expect
index a8c2894..f043899 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/same.dart.direct.transformed.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/same.dart.direct.transformed.expect
@@ -9,6 +9,7 @@
   method noSuchMethod(core::Invocation i) → dynamic {
     return null;
   }
-  abstract no-such-method-forwarder method foo() → void;
+  no-such-method-forwarder method foo() → void
+    return this.{self::A::noSuchMethod}(new core::_InvocationMirror::_withoutType("foo", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false));
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/same.dart.outline.expect b/pkg/front_end/testcases/no_such_method_forwarders/same.dart.outline.expect
index ef9c2e6..279022d 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/same.dart.outline.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/same.dart.outline.expect
@@ -7,7 +7,8 @@
     ;
   method noSuchMethod(core::Invocation i) → dynamic
     ;
-  abstract no-such-method-forwarder method foo() → void;
+  no-such-method-forwarder method foo() → void
+    return this.{self::A::noSuchMethod}(new core::_InvocationMirror::_withoutType("foo", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false));
 }
 static method main() → dynamic
   ;
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/same.dart.strong.expect b/pkg/front_end/testcases/no_such_method_forwarders/same.dart.strong.expect
index a8c2894..f043899 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/same.dart.strong.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/same.dart.strong.expect
@@ -9,6 +9,7 @@
   method noSuchMethod(core::Invocation i) → dynamic {
     return null;
   }
-  abstract no-such-method-forwarder method foo() → void;
+  no-such-method-forwarder method foo() → void
+    return this.{self::A::noSuchMethod}(new core::_InvocationMirror::_withoutType("foo", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false));
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/same.dart.strong.transformed.expect b/pkg/front_end/testcases/no_such_method_forwarders/same.dart.strong.transformed.expect
index a8c2894..f043899 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/same.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/same.dart.strong.transformed.expect
@@ -9,6 +9,7 @@
   method noSuchMethod(core::Invocation i) → dynamic {
     return null;
   }
-  abstract no-such-method-forwarder method foo() → void;
+  no-such-method-forwarder method foo() → void
+    return this.{self::A::noSuchMethod}(new core::_InvocationMirror::_withoutType("foo", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false));
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/subst_on_forwarder.dart.direct.expect b/pkg/front_end/testcases/no_such_method_forwarders/subst_on_forwarder.dart.direct.expect
index 4ff7688..4ae2d71 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/subst_on_forwarder.dart.direct.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/subst_on_forwarder.dart.direct.expect
@@ -22,6 +22,7 @@
   synthetic constructor •() → void
     : super core::Object::•()
     ;
-  abstract no-such-method-forwarder method foo() → core::int;
+  no-such-method-forwarder method foo() → core::int
+    return this.{self::M::noSuchMethod}(new core::_InvocationMirror::_withoutType("foo", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} core::int;
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/subst_on_forwarder.dart.direct.transformed.expect b/pkg/front_end/testcases/no_such_method_forwarders/subst_on_forwarder.dart.direct.transformed.expect
index 01d96cb..198f601 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/subst_on_forwarder.dart.direct.transformed.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/subst_on_forwarder.dart.direct.transformed.expect
@@ -28,6 +28,7 @@
   synthetic constructor •() → void
     : super core::Object::•()
     ;
-  abstract no-such-method-forwarder method foo() → core::int;
+  no-such-method-forwarder method foo() → core::int
+    return this.{self::M::noSuchMethod}(new core::_InvocationMirror::_withoutType("foo", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} core::int;
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/subst_on_forwarder.dart.outline.expect b/pkg/front_end/testcases/no_such_method_forwarders/subst_on_forwarder.dart.outline.expect
index 7e40698..5d00e53 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/subst_on_forwarder.dart.outline.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/subst_on_forwarder.dart.outline.expect
@@ -18,7 +18,8 @@
 class A extends self::_A&Object&M implements self::I<core::int> {
   synthetic constructor •() → void
     ;
-  abstract no-such-method-forwarder method foo() → core::int;
+  no-such-method-forwarder method foo() → core::int
+    return this.{self::M::noSuchMethod}(new core::_InvocationMirror::_withoutType("foo", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} core::int;
 }
 static method main() → dynamic
   ;
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/subst_on_forwarder.dart.strong.expect b/pkg/front_end/testcases/no_such_method_forwarders/subst_on_forwarder.dart.strong.expect
index 4ff7688..4ae2d71 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/subst_on_forwarder.dart.strong.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/subst_on_forwarder.dart.strong.expect
@@ -22,6 +22,7 @@
   synthetic constructor •() → void
     : super core::Object::•()
     ;
-  abstract no-such-method-forwarder method foo() → core::int;
+  no-such-method-forwarder method foo() → core::int
+    return this.{self::M::noSuchMethod}(new core::_InvocationMirror::_withoutType("foo", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} core::int;
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/subst_on_forwarder.dart.strong.transformed.expect b/pkg/front_end/testcases/no_such_method_forwarders/subst_on_forwarder.dart.strong.transformed.expect
index 01d96cb..198f601 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/subst_on_forwarder.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/subst_on_forwarder.dart.strong.transformed.expect
@@ -28,6 +28,7 @@
   synthetic constructor •() → void
     : super core::Object::•()
     ;
-  abstract no-such-method-forwarder method foo() → core::int;
+  no-such-method-forwarder method foo() → core::int
+    return this.{self::M::noSuchMethod}(new core::_InvocationMirror::_withoutType("foo", const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} core::int;
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/rasta/issue_000042.dart.direct.expect b/pkg/front_end/testcases/rasta/issue_000042.dart.direct.expect
index c4f7d99..ad208b6 100644
--- a/pkg/front_end/testcases/rasta/issue_000042.dart.direct.expect
+++ b/pkg/front_end/testcases/rasta/issue_000042.dart.direct.expect
@@ -3,7 +3,9 @@
 import "dart:core" as core;
 
 static method main() → dynamic {
-  for (final dynamic #t1 = let dynamic _ = null in invalid-expression "pkg/front_end/testcases/rasta/issue_000042.dart:6:8: Error: Expected lvalue, but got [x, y]\n  for (var x, y in []) {}\n       ^" in <dynamic>[]) {
+  for (final dynamic #t1 = let dynamic _ = null in invalid-expression "pkg/front_end/testcases/rasta/issue_000042.dart:6:8: Error: A for-loop can't have more than one loop variable.
+  for (var x, y in []) {}
+       ^^^" in <dynamic>[]) {
   }
   #L1:
   {
diff --git a/pkg/front_end/testcases/rasta/static.dart.direct.expect b/pkg/front_end/testcases/rasta/static.dart.direct.expect
index e047d82..2154f49 100644
--- a/pkg/front_end/testcases/rasta/static.dart.direct.expect
+++ b/pkg/front_end/testcases/rasta/static.dart.direct.expect
@@ -29,24 +29,24 @@
     self::use(self::Foo::staticGetter);
     throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticSetter, 33, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
     self::use(throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticSetter, 33, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))));
-    let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticConstant, 34, const <core::Type>[], <dynamic>[self::Foo::staticConstant.+(1)].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
-    self::use(let final dynamic #t1 = self::Foo::staticConstant in let final dynamic #t2 = let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticConstant, 34, const <core::Type>[], <dynamic>[#t1.+(1)].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))) in #t1);
+    let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticConstant, 34, const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[self::Foo::staticConstant.+(1)]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
+    self::use(let final dynamic #t1 = self::Foo::staticConstant in let final dynamic #t2 = let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticConstant, 34, const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[#t1.+(1)]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))) in #t1);
     self::Foo::staticField = self::Foo::staticField.+(1);
     self::use(let final dynamic #t3 = self::Foo::staticField in let final dynamic #t4 = self::Foo::staticField = #t3.+(1) in #t3);
-    let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticFunction, 34, const <core::Type>[], <dynamic>[self::Foo::staticFunction.+(1)].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
-    self::use(let final dynamic #t5 = self::Foo::staticFunction in let final dynamic #t6 = let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticFunction, 34, const <core::Type>[], <dynamic>[#t5.+(1)].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))) in #t5);
-    let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticGetter, 34, const <core::Type>[], <dynamic>[self::Foo::staticGetter.+(1)].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
-    self::use(let final dynamic #t7 = self::Foo::staticGetter in let final dynamic #t8 = let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticGetter, 34, const <core::Type>[], <dynamic>[#t7.+(1)].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))) in #t7);
+    let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticFunction, 34, const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[self::Foo::staticFunction.+(1)]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
+    self::use(let final dynamic #t5 = self::Foo::staticFunction in let final dynamic #t6 = let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticFunction, 34, const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[#t5.+(1)]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))) in #t5);
+    let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticGetter, 34, const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[self::Foo::staticGetter.+(1)]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
+    self::use(let final dynamic #t7 = self::Foo::staticGetter in let final dynamic #t8 = let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticGetter, 34, const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[#t7.+(1)]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))) in #t7);
     self::Foo::staticSetter = (let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticSetter, 33, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})))).+(1);
     self::use(let final dynamic #t9 = let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticSetter, 33, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))) in let final dynamic #t10 = self::Foo::staticSetter = #t9.+(1) in #t9);
-    let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticConstant, 34, const <core::Type>[], <dynamic>[self::Foo::staticConstant.+(1)].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
-    self::use(let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticConstant, 34, const <core::Type>[], <dynamic>[self::Foo::staticConstant.+(1)].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))));
+    let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticConstant, 34, const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[self::Foo::staticConstant.+(1)]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
+    self::use(let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticConstant, 34, const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[self::Foo::staticConstant.+(1)]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))));
     self::Foo::staticField = self::Foo::staticField.+(1);
     self::use(self::Foo::staticField = self::Foo::staticField.+(1));
-    let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticFunction, 34, const <core::Type>[], <dynamic>[self::Foo::staticFunction.+(1)].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
-    self::use(let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticFunction, 34, const <core::Type>[], <dynamic>[self::Foo::staticFunction.+(1)].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))));
-    let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticGetter, 34, const <core::Type>[], <dynamic>[self::Foo::staticGetter.+(1)].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
-    self::use(let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticGetter, 34, const <core::Type>[], <dynamic>[self::Foo::staticGetter.+(1)].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))));
+    let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticFunction, 34, const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[self::Foo::staticFunction.+(1)]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
+    self::use(let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticFunction, 34, const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[self::Foo::staticFunction.+(1)]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))));
+    let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticGetter, 34, const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[self::Foo::staticGetter.+(1)]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
+    self::use(let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticGetter, 34, const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[self::Foo::staticGetter.+(1)]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))));
     self::Foo::staticSetter = (let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticSetter, 33, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})))).+(1);
     self::use(self::Foo::staticSetter = (let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticSetter, 33, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})))).+(1));
     self::Foo::staticConstant.call();
@@ -59,24 +59,24 @@
     self::use(self::Foo::staticGetter.call());
     (throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticSetter, 33, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})))).call();
     self::use((throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticSetter, 33, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})))).call());
-    let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticConstant, 34, const <core::Type>[], <dynamic>[87].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
-    self::use(let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticConstant, 34, const <core::Type>[], <dynamic>[87].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))));
+    let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticConstant, 34, const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[87]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
+    self::use(let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticConstant, 34, const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[87]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))));
     self::Foo::staticField = 87;
     self::use(self::Foo::staticField = 87);
-    let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticFunction, 34, const <core::Type>[], <dynamic>[87].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
-    self::use(let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticFunction, 34, const <core::Type>[], <dynamic>[87].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))));
-    let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticGetter, 34, const <core::Type>[], <dynamic>[87].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
-    self::use(let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticGetter, 34, const <core::Type>[], <dynamic>[87].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))));
+    let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticFunction, 34, const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[87]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
+    self::use(let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticFunction, 34, const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[87]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))));
+    let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticGetter, 34, const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[87]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
+    self::use(let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticGetter, 34, const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[87]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))));
     self::Foo::staticSetter = 87;
     self::use(self::Foo::staticSetter = 87);
-    self::Foo::staticConstant.==(null) ? let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticConstant, 34, const <core::Type>[], <dynamic>[87].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))) : null;
-    self::use(let final dynamic #t11 = self::Foo::staticConstant in #t11.==(null) ? let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticConstant, 34, const <core::Type>[], <dynamic>[87].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))) : #t11);
+    self::Foo::staticConstant.==(null) ? let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticConstant, 34, const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[87]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))) : null;
+    self::use(let final dynamic #t11 = self::Foo::staticConstant in #t11.==(null) ? let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticConstant, 34, const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[87]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))) : #t11);
     self::Foo::staticField.==(null) ? self::Foo::staticField = 87 : null;
     self::use(let final dynamic #t12 = self::Foo::staticField in #t12.==(null) ? self::Foo::staticField = 87 : #t12);
-    self::Foo::staticFunction.==(null) ? let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticFunction, 34, const <core::Type>[], <dynamic>[87].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))) : null;
-    self::use(let final dynamic #t13 = self::Foo::staticFunction in #t13.==(null) ? let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticFunction, 34, const <core::Type>[], <dynamic>[87].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))) : #t13);
-    self::Foo::staticGetter.==(null) ? let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticGetter, 34, const <core::Type>[], <dynamic>[87].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))) : null;
-    self::use(let final dynamic #t14 = self::Foo::staticGetter in #t14.==(null) ? let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticGetter, 34, const <core::Type>[], <dynamic>[87].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))) : #t14);
+    self::Foo::staticFunction.==(null) ? let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticFunction, 34, const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[87]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))) : null;
+    self::use(let final dynamic #t13 = self::Foo::staticFunction in #t13.==(null) ? let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticFunction, 34, const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[87]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))) : #t13);
+    self::Foo::staticGetter.==(null) ? let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticGetter, 34, const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[87]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))) : null;
+    self::use(let final dynamic #t14 = self::Foo::staticGetter in #t14.==(null) ? let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticGetter, 34, const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[87]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))) : #t14);
     (let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticSetter, 33, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})))).==(null) ? self::Foo::staticSetter = 87 : null;
     self::use(let final dynamic #t15 = let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticSetter, 33, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))) in #t15.==(null) ? self::Foo::staticSetter = 87 : #t15);
   }
diff --git a/pkg/front_end/testcases/rasta/static.dart.direct.transformed.expect b/pkg/front_end/testcases/rasta/static.dart.direct.transformed.expect
index e047d82..2154f49 100644
--- a/pkg/front_end/testcases/rasta/static.dart.direct.transformed.expect
+++ b/pkg/front_end/testcases/rasta/static.dart.direct.transformed.expect
@@ -29,24 +29,24 @@
     self::use(self::Foo::staticGetter);
     throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticSetter, 33, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
     self::use(throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticSetter, 33, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))));
-    let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticConstant, 34, const <core::Type>[], <dynamic>[self::Foo::staticConstant.+(1)].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
-    self::use(let final dynamic #t1 = self::Foo::staticConstant in let final dynamic #t2 = let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticConstant, 34, const <core::Type>[], <dynamic>[#t1.+(1)].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))) in #t1);
+    let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticConstant, 34, const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[self::Foo::staticConstant.+(1)]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
+    self::use(let final dynamic #t1 = self::Foo::staticConstant in let final dynamic #t2 = let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticConstant, 34, const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[#t1.+(1)]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))) in #t1);
     self::Foo::staticField = self::Foo::staticField.+(1);
     self::use(let final dynamic #t3 = self::Foo::staticField in let final dynamic #t4 = self::Foo::staticField = #t3.+(1) in #t3);
-    let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticFunction, 34, const <core::Type>[], <dynamic>[self::Foo::staticFunction.+(1)].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
-    self::use(let final dynamic #t5 = self::Foo::staticFunction in let final dynamic #t6 = let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticFunction, 34, const <core::Type>[], <dynamic>[#t5.+(1)].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))) in #t5);
-    let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticGetter, 34, const <core::Type>[], <dynamic>[self::Foo::staticGetter.+(1)].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
-    self::use(let final dynamic #t7 = self::Foo::staticGetter in let final dynamic #t8 = let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticGetter, 34, const <core::Type>[], <dynamic>[#t7.+(1)].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))) in #t7);
+    let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticFunction, 34, const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[self::Foo::staticFunction.+(1)]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
+    self::use(let final dynamic #t5 = self::Foo::staticFunction in let final dynamic #t6 = let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticFunction, 34, const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[#t5.+(1)]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))) in #t5);
+    let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticGetter, 34, const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[self::Foo::staticGetter.+(1)]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
+    self::use(let final dynamic #t7 = self::Foo::staticGetter in let final dynamic #t8 = let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticGetter, 34, const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[#t7.+(1)]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))) in #t7);
     self::Foo::staticSetter = (let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticSetter, 33, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})))).+(1);
     self::use(let final dynamic #t9 = let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticSetter, 33, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))) in let final dynamic #t10 = self::Foo::staticSetter = #t9.+(1) in #t9);
-    let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticConstant, 34, const <core::Type>[], <dynamic>[self::Foo::staticConstant.+(1)].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
-    self::use(let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticConstant, 34, const <core::Type>[], <dynamic>[self::Foo::staticConstant.+(1)].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))));
+    let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticConstant, 34, const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[self::Foo::staticConstant.+(1)]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
+    self::use(let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticConstant, 34, const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[self::Foo::staticConstant.+(1)]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))));
     self::Foo::staticField = self::Foo::staticField.+(1);
     self::use(self::Foo::staticField = self::Foo::staticField.+(1));
-    let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticFunction, 34, const <core::Type>[], <dynamic>[self::Foo::staticFunction.+(1)].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
-    self::use(let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticFunction, 34, const <core::Type>[], <dynamic>[self::Foo::staticFunction.+(1)].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))));
-    let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticGetter, 34, const <core::Type>[], <dynamic>[self::Foo::staticGetter.+(1)].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
-    self::use(let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticGetter, 34, const <core::Type>[], <dynamic>[self::Foo::staticGetter.+(1)].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))));
+    let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticFunction, 34, const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[self::Foo::staticFunction.+(1)]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
+    self::use(let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticFunction, 34, const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[self::Foo::staticFunction.+(1)]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))));
+    let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticGetter, 34, const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[self::Foo::staticGetter.+(1)]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
+    self::use(let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticGetter, 34, const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[self::Foo::staticGetter.+(1)]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))));
     self::Foo::staticSetter = (let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticSetter, 33, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})))).+(1);
     self::use(self::Foo::staticSetter = (let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticSetter, 33, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})))).+(1));
     self::Foo::staticConstant.call();
@@ -59,24 +59,24 @@
     self::use(self::Foo::staticGetter.call());
     (throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticSetter, 33, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})))).call();
     self::use((throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticSetter, 33, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})))).call());
-    let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticConstant, 34, const <core::Type>[], <dynamic>[87].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
-    self::use(let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticConstant, 34, const <core::Type>[], <dynamic>[87].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))));
+    let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticConstant, 34, const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[87]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
+    self::use(let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticConstant, 34, const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[87]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))));
     self::Foo::staticField = 87;
     self::use(self::Foo::staticField = 87);
-    let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticFunction, 34, const <core::Type>[], <dynamic>[87].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
-    self::use(let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticFunction, 34, const <core::Type>[], <dynamic>[87].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))));
-    let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticGetter, 34, const <core::Type>[], <dynamic>[87].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
-    self::use(let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticGetter, 34, const <core::Type>[], <dynamic>[87].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))));
+    let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticFunction, 34, const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[87]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
+    self::use(let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticFunction, 34, const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[87]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))));
+    let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticGetter, 34, const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[87]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
+    self::use(let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticGetter, 34, const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[87]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))));
     self::Foo::staticSetter = 87;
     self::use(self::Foo::staticSetter = 87);
-    self::Foo::staticConstant.==(null) ? let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticConstant, 34, const <core::Type>[], <dynamic>[87].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))) : null;
-    self::use(let final dynamic #t11 = self::Foo::staticConstant in #t11.==(null) ? let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticConstant, 34, const <core::Type>[], <dynamic>[87].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))) : #t11);
+    self::Foo::staticConstant.==(null) ? let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticConstant, 34, const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[87]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))) : null;
+    self::use(let final dynamic #t11 = self::Foo::staticConstant in #t11.==(null) ? let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticConstant, 34, const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[87]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))) : #t11);
     self::Foo::staticField.==(null) ? self::Foo::staticField = 87 : null;
     self::use(let final dynamic #t12 = self::Foo::staticField in #t12.==(null) ? self::Foo::staticField = 87 : #t12);
-    self::Foo::staticFunction.==(null) ? let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticFunction, 34, const <core::Type>[], <dynamic>[87].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))) : null;
-    self::use(let final dynamic #t13 = self::Foo::staticFunction in #t13.==(null) ? let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticFunction, 34, const <core::Type>[], <dynamic>[87].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))) : #t13);
-    self::Foo::staticGetter.==(null) ? let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticGetter, 34, const <core::Type>[], <dynamic>[87].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))) : null;
-    self::use(let final dynamic #t14 = self::Foo::staticGetter in #t14.==(null) ? let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticGetter, 34, const <core::Type>[], <dynamic>[87].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))) : #t14);
+    self::Foo::staticFunction.==(null) ? let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticFunction, 34, const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[87]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))) : null;
+    self::use(let final dynamic #t13 = self::Foo::staticFunction in #t13.==(null) ? let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticFunction, 34, const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[87]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))) : #t13);
+    self::Foo::staticGetter.==(null) ? let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticGetter, 34, const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[87]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))) : null;
+    self::use(let final dynamic #t14 = self::Foo::staticGetter in #t14.==(null) ? let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticGetter, 34, const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[87]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))) : #t14);
     (let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticSetter, 33, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})))).==(null) ? self::Foo::staticSetter = 87 : null;
     self::use(let final dynamic #t15 = let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticSetter, 33, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))) in #t15.==(null) ? self::Foo::staticSetter = 87 : #t15);
   }
diff --git a/pkg/front_end/testcases/rasta/unresolved_for_in.dart.direct.expect b/pkg/front_end/testcases/rasta/unresolved_for_in.dart.direct.expect
index 9a7f7e0..09a7e0c 100644
--- a/pkg/front_end/testcases/rasta/unresolved_for_in.dart.direct.expect
+++ b/pkg/front_end/testcases/rasta/unresolved_for_in.dart.direct.expect
@@ -13,19 +13,19 @@
       core::print(this.key);
     }
     for (final dynamic #t2 in x) {
-      let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#Fisk, 34, const <core::Type>[], <dynamic>[#t2].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
+      let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#Fisk, 34, const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[#t2]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
       core::print(self::Fisk);
     }
-    for (final dynamic #t3 = let dynamic _ = null in invalid-expression "pkg/front_end/testcases/rasta/unresolved_for_in.dart:17:10: Error: Expected lvalue, but got Instance of 'KernelPrefixBuilder'
+    for (final dynamic #t3 = let dynamic _ = null in invalid-expression "pkg/front_end/testcases/rasta/unresolved_for_in.dart:17:10: Error: Can't assign to this, so it can't be used in a for-in loop.
     for (collection in x) {
-         ^" in x) {
+         ^^^^^^^^^^" in x) {
       core::print(invalid-expression "pkg/front_end/testcases/rasta/unresolved_for_in.dart: Error: A library can't be used as an expression.");
     }
     for (final dynamic #t4 in x) {
-      let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#VoidFunction, 34, const <core::Type>[], <dynamic>[#t4].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
+      let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#VoidFunction, 34, const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[#t4]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
       core::print(() → void);
     }
-    for (final dynamic #t5 = let dynamic _ = null in invalid-expression "pkg/front_end/testcases/rasta/unresolved_for_in.dart:23:10: Error: Expected lvalue, but got 1
+    for (final dynamic #t5 = let dynamic _ = null in 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) {
          ^" in x) {
       core::print(this.key);
@@ -40,23 +40,23 @@
 static method main(dynamic arguments) → dynamic {
   new self::Fisk::•();
   for (final dynamic #t6 in arguments) {
-    throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#key, 34, const <core::Type>[], <dynamic>[#t6].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
+    throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#key, 34, const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[#t6]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
     core::print(throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#key, 33, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))));
   }
   for (final dynamic #t7 in arguments) {
-    let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#Fisk, 34, const <core::Type>[], <dynamic>[#t7].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
+    let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#Fisk, 34, const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[#t7]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
     core::print(self::Fisk);
   }
-  for (final dynamic #t8 = let dynamic _ = null in invalid-expression "pkg/front_end/testcases/rasta/unresolved_for_in.dart:37:8: Error: Expected lvalue, but got Instance of 'KernelPrefixBuilder'
+  for (final dynamic #t8 = let dynamic _ = null in invalid-expression "pkg/front_end/testcases/rasta/unresolved_for_in.dart:37:8: Error: Can't assign to this, so it can't be used in a for-in loop.
   for (collection in arguments) {
-       ^" in arguments) {
+       ^^^^^^^^^^" in arguments) {
     core::print(invalid-expression "pkg/front_end/testcases/rasta/unresolved_for_in.dart: Error: A library can't be used as an expression.");
   }
   for (final dynamic #t9 in arguments) {
-    let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#VoidFunction, 34, const <core::Type>[], <dynamic>[#t9].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
+    let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#VoidFunction, 34, const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[#t9]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
     core::print(() → void);
   }
-  for (final dynamic #t10 = let dynamic _ = null in invalid-expression "pkg/front_end/testcases/rasta/unresolved_for_in.dart:43:8: Error: Expected lvalue, but got 1
+  for (final dynamic #t10 = let dynamic _ = null in 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) {
        ^" in arguments) {
     core::print(throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#key, 33, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))));
diff --git a/pkg/front_end/testcases/rasta/unresolved_for_in.dart.direct.transformed.expect b/pkg/front_end/testcases/rasta/unresolved_for_in.dart.direct.transformed.expect
index 9a7f7e0..09a7e0c 100644
--- a/pkg/front_end/testcases/rasta/unresolved_for_in.dart.direct.transformed.expect
+++ b/pkg/front_end/testcases/rasta/unresolved_for_in.dart.direct.transformed.expect
@@ -13,19 +13,19 @@
       core::print(this.key);
     }
     for (final dynamic #t2 in x) {
-      let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#Fisk, 34, const <core::Type>[], <dynamic>[#t2].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
+      let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#Fisk, 34, const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[#t2]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
       core::print(self::Fisk);
     }
-    for (final dynamic #t3 = let dynamic _ = null in invalid-expression "pkg/front_end/testcases/rasta/unresolved_for_in.dart:17:10: Error: Expected lvalue, but got Instance of 'KernelPrefixBuilder'
+    for (final dynamic #t3 = let dynamic _ = null in invalid-expression "pkg/front_end/testcases/rasta/unresolved_for_in.dart:17:10: Error: Can't assign to this, so it can't be used in a for-in loop.
     for (collection in x) {
-         ^" in x) {
+         ^^^^^^^^^^" in x) {
       core::print(invalid-expression "pkg/front_end/testcases/rasta/unresolved_for_in.dart: Error: A library can't be used as an expression.");
     }
     for (final dynamic #t4 in x) {
-      let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#VoidFunction, 34, const <core::Type>[], <dynamic>[#t4].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
+      let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#VoidFunction, 34, const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[#t4]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
       core::print(() → void);
     }
-    for (final dynamic #t5 = let dynamic _ = null in invalid-expression "pkg/front_end/testcases/rasta/unresolved_for_in.dart:23:10: Error: Expected lvalue, but got 1
+    for (final dynamic #t5 = let dynamic _ = null in 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) {
          ^" in x) {
       core::print(this.key);
@@ -40,23 +40,23 @@
 static method main(dynamic arguments) → dynamic {
   new self::Fisk::•();
   for (final dynamic #t6 in arguments) {
-    throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#key, 34, const <core::Type>[], <dynamic>[#t6].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
+    throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#key, 34, const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[#t6]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
     core::print(throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#key, 33, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))));
   }
   for (final dynamic #t7 in arguments) {
-    let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#Fisk, 34, const <core::Type>[], <dynamic>[#t7].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
+    let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#Fisk, 34, const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[#t7]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
     core::print(self::Fisk);
   }
-  for (final dynamic #t8 = let dynamic _ = null in invalid-expression "pkg/front_end/testcases/rasta/unresolved_for_in.dart:37:8: Error: Expected lvalue, but got Instance of 'KernelPrefixBuilder'
+  for (final dynamic #t8 = let dynamic _ = null in invalid-expression "pkg/front_end/testcases/rasta/unresolved_for_in.dart:37:8: Error: Can't assign to this, so it can't be used in a for-in loop.
   for (collection in arguments) {
-       ^" in arguments) {
+       ^^^^^^^^^^" in arguments) {
     core::print(invalid-expression "pkg/front_end/testcases/rasta/unresolved_for_in.dart: Error: A library can't be used as an expression.");
   }
   for (final dynamic #t9 in arguments) {
-    let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#VoidFunction, 34, const <core::Type>[], <dynamic>[#t9].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
+    let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#VoidFunction, 34, const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[#t9]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
     core::print(() → void);
   }
-  for (final dynamic #t10 = let dynamic _ = null in invalid-expression "pkg/front_end/testcases/rasta/unresolved_for_in.dart:43:8: Error: Expected lvalue, but got 1
+  for (final dynamic #t10 = let dynamic _ = null in 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) {
        ^" in arguments) {
     core::print(throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#key, 33, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))));
diff --git a/pkg/front_end/testcases/regress/issue_31299.dart.direct.expect b/pkg/front_end/testcases/regress/issue_31299.dart.direct.expect
index 0161677..be6f8dc 100644
--- a/pkg/front_end/testcases/regress/issue_31299.dart.direct.expect
+++ b/pkg/front_end/testcases/regress/issue_31299.dart.direct.expect
@@ -22,6 +22,6 @@
   new self::A::•().foo();
   new self::A::•().foo(1, 2);
   new self::A::foo();
-  throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#foo, 32, const <core::Type>[], <dynamic>[1, 2].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
+  throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#foo, 32, const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[1, 2]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/regress/issue_31299.dart.direct.transformed.expect b/pkg/front_end/testcases/regress/issue_31299.dart.direct.transformed.expect
index 0161677..be6f8dc 100644
--- a/pkg/front_end/testcases/regress/issue_31299.dart.direct.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_31299.dart.direct.transformed.expect
@@ -22,6 +22,6 @@
   new self::A::•().foo();
   new self::A::•().foo(1, 2);
   new self::A::foo();
-  throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#foo, 32, const <core::Type>[], <dynamic>[1, 2].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
+  throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#foo, 32, const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[1, 2]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
 }
 static method main() → dynamic {}
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 680a6d3..be7bde0 100644
--- a/pkg/front_end/testcases/regress/issue_31299.dart.strong.expect
+++ b/pkg/front_end/testcases/regress/issue_31299.dart.strong.expect
@@ -26,6 +26,6 @@
   new self::A::•().{self::A::foo}();
   new self::A::•().{self::A::foo}(1, 2);
   new self::A::foo();
-  throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#foo, 32, const <core::Type>[], <dynamic>[1, 2].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
+  throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#foo, 32, const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[1, 2]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/regress/issue_31766.dart.strong.expect b/pkg/front_end/testcases/regress/issue_31766.dart.strong.expect
index 33b060d..494d91f 100644
--- a/pkg/front_end/testcases/regress/issue_31766.dart.strong.expect
+++ b/pkg/front_end/testcases/regress/issue_31766.dart.strong.expect
@@ -10,11 +10,11 @@
     return null;
 }
 static method main() → dynamic {
-  function bar<T extends self::A = dynamic>(T t) → void {
+  function bar<T extends self::A = self::A>(T t) → void {
     core::print("t.foo()=${t.{self::A::foo}()}");
   }
   bar.call<self::A>(new self::A::•());
-  (<S extends self::A = dynamic>(S s) → core::Null {
+  (<S extends self::A = self::A>(S s) → core::Null {
     core::print("s.foo()=${s.{self::A::foo}()}");
   }).call<self::A>(new self::A::•());
 }
diff --git a/pkg/front_end/testcases/regress/issue_31766.dart.strong.transformed.expect b/pkg/front_end/testcases/regress/issue_31766.dart.strong.transformed.expect
index 33b060d..494d91f 100644
--- a/pkg/front_end/testcases/regress/issue_31766.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_31766.dart.strong.transformed.expect
@@ -10,11 +10,11 @@
     return null;
 }
 static method main() → dynamic {
-  function bar<T extends self::A = dynamic>(T t) → void {
+  function bar<T extends self::A = self::A>(T t) → void {
     core::print("t.foo()=${t.{self::A::foo}()}");
   }
   bar.call<self::A>(new self::A::•());
-  (<S extends self::A = dynamic>(S s) → core::Null {
+  (<S extends self::A = self::A>(S s) → core::Null {
     core::print("s.foo()=${s.{self::A::foo}()}");
   }).call<self::A>(new self::A::•());
 }
diff --git a/pkg/front_end/testcases/regress/issue_31846.dart.strong.expect b/pkg/front_end/testcases/regress/issue_31846.dart.strong.expect
index fc1a7b3..6f08277 100644
--- a/pkg/front_end/testcases/regress/issue_31846.dart.strong.expect
+++ b/pkg/front_end/testcases/regress/issue_31846.dart.strong.expect
@@ -5,6 +5,6 @@
 static method main() → dynamic {
   core::print(self::main is () → dynamic);
   core::print((<T extends core::Object = dynamic>(T x) → T => x).{core::Object::runtimeType});
-  core::print((<T extends core::num = dynamic>(T x) → T => x).{core::Object::runtimeType});
-  core::print((<T extends core::Comparable<T> = dynamic>(T x) → T => x).{core::Object::runtimeType});
+  core::print((<T extends core::num = core::num>(T x) → T => x).{core::Object::runtimeType});
+  core::print((<T extends core::Comparable<T> = core::Comparable<dynamic>>(T x) → T => x).{core::Object::runtimeType});
 }
diff --git a/pkg/front_end/testcases/regress/issue_31846.dart.strong.transformed.expect b/pkg/front_end/testcases/regress/issue_31846.dart.strong.transformed.expect
index fc1a7b3..6f08277 100644
--- a/pkg/front_end/testcases/regress/issue_31846.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_31846.dart.strong.transformed.expect
@@ -5,6 +5,6 @@
 static method main() → dynamic {
   core::print(self::main is () → dynamic);
   core::print((<T extends core::Object = dynamic>(T x) → T => x).{core::Object::runtimeType});
-  core::print((<T extends core::num = dynamic>(T x) → T => x).{core::Object::runtimeType});
-  core::print((<T extends core::Comparable<T> = dynamic>(T x) → T => x).{core::Object::runtimeType});
+  core::print((<T extends core::num = core::num>(T x) → T => x).{core::Object::runtimeType});
+  core::print((<T extends core::Comparable<T> = core::Comparable<dynamic>>(T x) → T => x).{core::Object::runtimeType});
 }
diff --git a/pkg/front_end/testcases/runtime_checks/contravariant_generic_method_type_parameter.dart.strong.expect b/pkg/front_end/testcases/runtime_checks/contravariant_generic_method_type_parameter.dart.strong.expect
index 9ca2a67..798b35d 100644
--- a/pkg/front_end/testcases/runtime_checks/contravariant_generic_method_type_parameter.dart.strong.expect
+++ b/pkg/front_end/testcases/runtime_checks/contravariant_generic_method_type_parameter.dart.strong.expect
@@ -7,7 +7,7 @@
   synthetic constructor •() → void
     : super core::Object::•()
     ;
-  method f<U extends (self::C::T) → void = dynamic>(self::C::f::U x) → void {}
+  method f<U extends (self::C::T) → void = (self::C::T) → void>(self::C::f::U x) → void {}
 }
 static method g(self::C<core::num> c) → void {
   c.{self::C::f}<(core::Object) → void>((core::Object o) → core::Null {});
diff --git a/pkg/front_end/testcases/runtime_checks/contravariant_generic_method_type_parameter.dart.strong.transformed.expect b/pkg/front_end/testcases/runtime_checks/contravariant_generic_method_type_parameter.dart.strong.transformed.expect
index 9ca2a67..798b35d 100644
--- a/pkg/front_end/testcases/runtime_checks/contravariant_generic_method_type_parameter.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/runtime_checks/contravariant_generic_method_type_parameter.dart.strong.transformed.expect
@@ -7,7 +7,7 @@
   synthetic constructor •() → void
     : super core::Object::•()
     ;
-  method f<U extends (self::C::T) → void = dynamic>(self::C::f::U x) → void {}
+  method f<U extends (self::C::T) → void = (self::C::T) → void>(self::C::f::U x) → void {}
 }
 static method g(self::C<core::num> c) → void {
   c.{self::C::f}<(core::Object) → void>((core::Object o) → core::Null {});
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 b8a0214..8427437 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
@@ -6,8 +6,8 @@
   synthetic constructor •() → void
     : super core::Object::•()
     ;
-  method f<generic-covariant-impl U extends self::C::T = dynamic>(self::C::f::U x) → void {}
-  method g1<generic-covariant-impl U extends self::C::T = dynamic>() → void {
+  method f<generic-covariant-impl U extends self::C::T = self::C::T>(self::C::f::U x) → void {}
+  method g1<generic-covariant-impl U extends self::C::T = self::C::T>() → void {
     this.{self::C::f}<self::C::g1::U>(let final dynamic #t1 = let dynamic _ = null in invalid-expression "pkg/front_end/testcases/runtime_checks/covariant_generic_method_type_parameter.dart:11:15: Error: A value of type 'dart.core::double' can't be assigned to a variable of type 'test::C::g1::U'.
 Try changing the type of the left hand side, or casting the right hand side to 'test::C::g1::U'.
     this.f<U>(1.5);
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 91a46da..b595fdf 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
@@ -6,8 +6,8 @@
   synthetic constructor •() → void
     : super core::Object::•()
     ;
-  method f<generic-covariant-impl U extends self::C::T = dynamic>(self::C::f::U x) → void {}
-  method g1<generic-covariant-impl U extends self::C::T = dynamic>() → void {
+  method f<generic-covariant-impl U extends self::C::T = self::C::T>(self::C::f::U x) → void {}
+  method g1<generic-covariant-impl U extends self::C::T = self::C::T>() → void {
     this.{self::C::f}<self::C::g1::U>(let final dynamic #t1 = let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/runtime_checks/covariant_generic_method_type_parameter.dart:11:15: Error: A value of type 'dart.core::double' can't be assigned to a variable of type 'test::C::g1::U'.
 Try changing the type of the left hand side, or casting the right hand side to 'test::C::g1::U'.
     this.f<U>(1.5);
diff --git a/pkg/front_end/testcases/runtime_checks/dynamic_invocation_generic.dart.strong.expect b/pkg/front_end/testcases/runtime_checks/dynamic_invocation_generic.dart.strong.expect
index bddd915..f5a72bc 100644
--- a/pkg/front_end/testcases/runtime_checks/dynamic_invocation_generic.dart.strong.expect
+++ b/pkg/front_end/testcases/runtime_checks/dynamic_invocation_generic.dart.strong.expect
@@ -6,7 +6,7 @@
   synthetic constructor •() → void
     : super core::Object::•()
     ;
-  method f<generic-covariant-impl U extends self::C::T = dynamic>(self::C::f::U x) → void {}
+  method f<generic-covariant-impl U extends self::C::T = self::C::T>(self::C::f::U x) → void {}
 }
 static method g1(dynamic d) → void {
   d.f<core::num>(1.5);
diff --git a/pkg/front_end/testcases/runtime_checks/dynamic_invocation_generic.dart.strong.transformed.expect b/pkg/front_end/testcases/runtime_checks/dynamic_invocation_generic.dart.strong.transformed.expect
index bddd915..f5a72bc 100644
--- a/pkg/front_end/testcases/runtime_checks/dynamic_invocation_generic.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/runtime_checks/dynamic_invocation_generic.dart.strong.transformed.expect
@@ -6,7 +6,7 @@
   synthetic constructor •() → void
     : super core::Object::•()
     ;
-  method f<generic-covariant-impl U extends self::C::T = dynamic>(self::C::f::U x) → void {}
+  method f<generic-covariant-impl U extends self::C::T = self::C::T>(self::C::f::U x) → void {}
 }
 static method g1(dynamic d) → void {
   d.f<core::num>(1.5);
diff --git a/pkg/front_end/testcases/runtime_checks_new/derived_class_typed.dart.strong.expect b/pkg/front_end/testcases/runtime_checks_new/derived_class_typed.dart.strong.expect
index 89abbed..452359a 100644
--- a/pkg/front_end/testcases/runtime_checks_new/derived_class_typed.dart.strong.expect
+++ b/pkg/front_end/testcases/runtime_checks_new/derived_class_typed.dart.strong.expect
@@ -8,7 +8,7 @@
     ;
   method f(generic-covariant-impl self::B::T x) → void {}
   method g({generic-covariant-impl self::B::T x = null}) → void {}
-  method h<generic-covariant-impl U extends self::B::T = dynamic>() → void {}
+  method h<generic-covariant-impl U extends self::B::T = self::B::T>() → void {}
 }
 class C extends self::B<core::int> {
   synthetic constructor •() → void
diff --git a/pkg/front_end/testcases/runtime_checks_new/derived_class_typed.dart.strong.transformed.expect b/pkg/front_end/testcases/runtime_checks_new/derived_class_typed.dart.strong.transformed.expect
index 89abbed..452359a 100644
--- a/pkg/front_end/testcases/runtime_checks_new/derived_class_typed.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/runtime_checks_new/derived_class_typed.dart.strong.transformed.expect
@@ -8,7 +8,7 @@
     ;
   method f(generic-covariant-impl self::B::T x) → void {}
   method g({generic-covariant-impl self::B::T x = null}) → void {}
-  method h<generic-covariant-impl U extends self::B::T = dynamic>() → void {}
+  method h<generic-covariant-impl U extends self::B::T = self::B::T>() → void {}
 }
 class C extends self::B<core::int> {
   synthetic constructor •() → void
diff --git a/pkg/front_end/tool/_fasta/additional_targets.dart b/pkg/front_end/tool/_fasta/additional_targets.dart
new file mode 100644
index 0000000..dd9a0a3
--- /dev/null
+++ b/pkg/front_end/tool/_fasta/additional_targets.dart
@@ -0,0 +1,25 @@
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library fasta.tool.additional_targets;
+
+import 'package:kernel/target/targets.dart' show TargetFlags, targets;
+
+import 'package:compiler/src/kernel/dart2js_target.dart' show Dart2jsTarget;
+
+import 'package:vm/target/dart_runner.dart' show DartRunnerTarget;
+
+import 'package:vm/target/flutter_runner.dart' show FlutterRunnerTarget;
+
+void installAdditionalTargets() {
+  // If you add new targets here, please also update FastaUsageLong in
+  // ../../messages.yaml.
+  targets["dart2js"] =
+      (TargetFlags flags) => new Dart2jsTarget("dart2js", flags);
+  targets["dart2js_server"] =
+      (TargetFlags flags) => new Dart2jsTarget("dart2js_server", flags);
+  targets["dart_runner"] = (TargetFlags flags) => new DartRunnerTarget(flags);
+  targets["flutter_runner"] =
+      (TargetFlags flags) => new FlutterRunnerTarget(flags);
+}
diff --git a/pkg/front_end/tool/_fasta/additional_targets_test.dart b/pkg/front_end/tool/_fasta/additional_targets_test.dart
new file mode 100644
index 0000000..041a363
--- /dev/null
+++ b/pkg/front_end/tool/_fasta/additional_targets_test.dart
@@ -0,0 +1,22 @@
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library fasta.tool.additional_targets_test;
+
+import 'package:kernel/target/targets.dart' show targets;
+
+import 'package:front_end/src/fasta/fasta_codes.dart'
+    show MessageCode, messageFastaUsageLong;
+
+import 'additional_targets.dart' show installAdditionalTargets;
+
+main() {
+  installAdditionalTargets();
+  String expected = "  --target=${(targets.keys.toList()..sort()).join('|')}";
+  MessageCode code = messageFastaUsageLong;
+  if (!code.message.contains(expected)) {
+    throw "Error: ${code.name} in pkg/front_end/messages.yaml doesn't contain"
+        " '$expected'.";
+  }
+}
diff --git a/pkg/front_end/tool/_fasta/compile_platform.dart b/pkg/front_end/tool/_fasta/compile_platform.dart
index 58cd0ce..52afecd 100644
--- a/pkg/front_end/tool/_fasta/compile_platform.dart
+++ b/pkg/front_end/tool/_fasta/compile_platform.dart
@@ -8,17 +8,9 @@
 
 import 'dart:io' show File, Platform, exitCode;
 
-import 'package:compiler/src/kernel/dart2js_target.dart' show Dart2jsTarget;
-
 import 'package:vm/bytecode/gen_bytecode.dart'
     show generateBytecode, isKernelBytecodeEnabledForPlatform;
 
-import 'package:vm/target/dart_runner.dart' show DartRunnerTarget;
-
-import 'package:vm/target/flutter_runner.dart' show FlutterRunnerTarget;
-
-import 'package:kernel/target/targets.dart' show TargetFlags, targets;
-
 import 'package:front_end/src/fasta/compiler_context.dart' show CompilerContext;
 
 import 'package:front_end/src/fasta/deprecated_problems.dart'
@@ -36,18 +28,14 @@
 
 import 'package:front_end/src/fasta/get_dependencies.dart' show getDependencies;
 
+import 'additional_targets.dart' show installAdditionalTargets;
+
 import 'command_line.dart' show withGlobalOptions;
 
 const int iterations = const int.fromEnvironment("iterations", defaultValue: 1);
 
 Future main(List<String> arguments) async {
-  targets["dart2js"] =
-      (TargetFlags flags) => new Dart2jsTarget("dart2js", flags);
-  targets["dart2js_server"] =
-      (TargetFlags flags) => new Dart2jsTarget("dart2js_server", flags);
-  targets["dart_runner"] = (TargetFlags flags) => new DartRunnerTarget(flags);
-  targets["flutter_runner"] =
-      (TargetFlags flags) => new FlutterRunnerTarget(flags);
+  installAdditionalTargets();
   for (int i = 0; i < iterations; i++) {
     if (i > 0) {
       print("\n");
diff --git a/pkg/front_end/tool/_fasta/entry_points.dart b/pkg/front_end/tool/_fasta/entry_points.dart
index 1586b35..a8b6a15 100644
--- a/pkg/front_end/tool/_fasta/entry_points.dart
+++ b/pkg/front_end/tool/_fasta/entry_points.dart
@@ -10,13 +10,9 @@
 
 import 'dart:io' show File, exitCode, stderr, stdin, stdout;
 
-import 'package:compiler/src/kernel/dart2js_target.dart' show Dart2jsTarget;
-
 import 'package:kernel/kernel.dart'
     show CanonicalName, Library, Component, Source, loadComponentFromBytes;
 
-import 'package:kernel/target/targets.dart' show TargetFlags, targets;
-
 import 'package:front_end/src/api_prototype/compiler_options.dart'
     show CompilerOptions;
 
@@ -42,6 +38,8 @@
 
 import 'package:front_end/src/fasta/uri_translator.dart' show UriTranslator;
 
+import 'additional_targets.dart' show installAdditionalTargets;
+
 import 'command_line.dart' show withGlobalOptions;
 
 const bool summary = const bool.fromEnvironment("summary", defaultValue: false);
@@ -49,10 +47,7 @@
 const int iterations = const int.fromEnvironment("iterations", defaultValue: 1);
 
 compileEntryPoint(List<String> arguments) async {
-  targets["dart2js"] =
-      (TargetFlags flags) => new Dart2jsTarget("dart2js", flags);
-  targets["dart2js_server"] =
-      (TargetFlags flags) => new Dart2jsTarget("dart2js_server", flags);
+  installAdditionalTargets();
 
   // Timing results for each iteration
   List<double> elapsedTimes = <double>[];
@@ -75,6 +70,8 @@
 }
 
 outlineEntryPoint(List<String> arguments) async {
+  installAdditionalTargets();
+
   for (int i = 0; i < iterations; i++) {
     if (i > 0) {
       print("\n");
@@ -84,6 +81,8 @@
 }
 
 batchEntryPoint(List<String> arguments) {
+  installAdditionalTargets();
+
   return new BatchCompiler(
           stdin.transform(utf8.decoder).transform(new LineSplitter()))
       .run();
diff --git a/pkg/front_end/tool/_fasta/generate_messages.dart b/pkg/front_end/tool/_fasta/generate_messages.dart
index 0ec9a18..397bded 100644
--- a/pkg/front_end/tool/_fasta/generate_messages.dart
+++ b/pkg/front_end/tool/_fasta/generate_messages.dart
@@ -2,6 +2,8 @@
 // for details. All 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 'dart:isolate';
@@ -14,6 +16,17 @@
 
 main(List<String> arguments) async {
   var port = new ReceivePort();
+  await new File.fromUri(await computeGeneratedFile())
+      .writeAsString(await generateMessagesFile(), flush: true);
+  port.close();
+}
+
+Future<Uri> computeGeneratedFile() {
+  return Isolate.resolvePackageUri(
+      Uri.parse('package:front_end/src/fasta/fasta_codes_generated.dart'));
+}
+
+Future<String> generateMessagesFile() async {
   Uri messagesFile = Platform.script.resolve("../../messages.yaml");
   Map yaml = loadYaml(await new File.fromUri(messagesFile).readAsStringSync());
   StringBuffer sb = new StringBuffer();
@@ -45,13 +58,7 @@
         map['analyzerCode'], map['dart2jsCode'], map['severity']));
   }
 
-  String dartfmtedText = new DartFormatter().format("$sb");
-
-  Uri problemsFile = await Isolate.resolvePackageUri(
-      Uri.parse('package:front_end/src/fasta/fasta_codes_generated.dart'));
-  await new File.fromUri(problemsFile)
-      .writeAsString(dartfmtedText, flush: true);
-  port.close();
+  return new DartFormatter().format("$sb");
 }
 
 final RegExp placeholderPattern = new RegExp("#[a-zA-Z0-9_]+");
@@ -172,6 +179,11 @@
         arguments.add("'count2': count2");
         break;
 
+      case "#constant":
+        parameters.add("Constant constant");
+        arguments.add("'constant': constant");
+        break;
+
       default:
         throw "Unhandled placeholder in template: ${match[0]}";
     }
diff --git a/pkg/front_end/tool/_fasta/generate_messages_test.dart b/pkg/front_end/tool/_fasta/generate_messages_test.dart
new file mode 100644
index 0000000..f242f01
--- /dev/null
+++ b/pkg/front_end/tool/_fasta/generate_messages_test.dart
@@ -0,0 +1,21 @@
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "dart:io" show File;
+
+import "package:async_helper/async_helper.dart" show asyncTest;
+
+import "package:expect/expect.dart" show Expect;
+
+import "generate_messages.dart" show computeGeneratedFile, generateMessagesFile;
+
+main() {
+  asyncTest(() async {
+    Uri generatedFile = await computeGeneratedFile();
+    String generated = await generateMessagesFile();
+    String actual = await new File.fromUri(generatedFile).readAsString();
+    Expect.stringEquals(
+        generated, actual, "${generatedFile.path} is out of date");
+  });
+}
diff --git a/pkg/kernel/README.md b/pkg/kernel/README.md
index fd48574..778bcc7 100644
--- a/pkg/kernel/README.md
+++ b/pkg/kernel/README.md
@@ -15,7 +15,9 @@
 - Serialization of kernel code
 
 _Note:_ The APIs in this package are in an early state; developers should be
-careful about depending on this package.
+careful about depending on this package.  In particular, there is no semver
+contract for release versions of this package.  Please depend directly
+on individual versions.
 
 Getting Kernel
 ------------
diff --git a/pkg/kernel/bin/transform.dart b/pkg/kernel/bin/transform.dart
index 1898ede..ae16bda 100755
--- a/pkg/kernel/bin/transform.dart
+++ b/pkg/kernel/bin/transform.dart
@@ -12,7 +12,6 @@
 import 'package:kernel/kernel.dart';
 import 'package:kernel/src/tool/batch_util.dart';
 import 'package:kernel/target/targets.dart';
-import 'package:kernel/transformations/closure_conversion.dart' as closures;
 import 'package:kernel/transformations/constants.dart' as constants;
 import 'package:kernel/transformations/continuation.dart' as cont;
 import 'package:kernel/transformations/empty.dart' as empty;
@@ -94,9 +93,6 @@
       mix.transformLibraries(
           new NoneTarget(null), coreTypes, hierarchy, component.libraries);
       break;
-    case 'closures':
-      component = closures.transformComponent(coreTypes, component);
-      break;
     case 'coq':
       component = coq.transformComponent(coreTypes, component);
       break;
diff --git a/pkg/kernel/binary.md b/pkg/kernel/binary.md
index 7bb45af..13b28bf 100644
--- a/pkg/kernel/binary.md
+++ b/pkg/kernel/binary.md
@@ -131,11 +131,11 @@
 
 type ComponentFile {
   UInt32 magic = 0x90ABCDEF;
-  UInt32 formatVersion;
-  MetadataPayload[] metadataPayloads;
+  UInt32 formatVersion = 6;
   Library[] libraries;
   UriSource sourceMap;
   List<CanonicalName> canonicalNames;
+  MetadataPayload[] metadataPayloads;
   RList<MetadataMapping> metadataMappings;
   StringTable strings;
   List<Constant> constants;
@@ -149,9 +149,8 @@
 
 type MetadataMapping {
   UInt32 tag;  // StringReference of a fixed size.
+  // Node offsets are absolute, while metadata offsets are relative to metadataPayloads.
   RList<Pair<UInt32, UInt32>> nodeOffsetToMetadataOffset;
-  RList<UInt32> nodeReferences;  // If metadata payload references nodes
-                              // they are encoded as indices in this array.
 }
 
 // Component index with all fixed-size-32-bit integers.
@@ -162,6 +161,8 @@
 type ComponentIndex {
   UInt32 binaryOffsetForSourceTable;
   UInt32 binaryOffsetForCanonicalNames;
+  UInt32 binaryOffsetForMetadataPayloads;
+  UInt32 binaryOffsetForMetadataMappings;
   UInt32 binaryOffsetForStringTable;
   UInt32 binaryOffsetForConstantTable;
   UInt32 mainMethodReference; // This is a ProcedureReference with a fixed-size integer.
diff --git a/pkg/kernel/lib/ast.dart b/pkg/kernel/lib/ast.dart
index a87b1b4..7ff892f 100644
--- a/pkg/kernel/lib/ast.dart
+++ b/pkg/kernel/lib/ast.dart
@@ -1575,7 +1575,6 @@
   }
 
   void set isNoSuchMethodForwarder(bool value) {
-    assert(isAbstract);
     flags = value
         ? (flags | FlagNoSuchMethodForwarder)
         : (flags & ~FlagNoSuchMethodForwarder);
@@ -2565,6 +2564,17 @@
         positional = <Expression>[],
         named = <NamedExpression>[];
 
+  factory Arguments.forwarded(FunctionNode function) {
+    return new Arguments(
+        function.positionalParameters.map((p) => new VariableGet(p)).toList(),
+        named: function.namedParameters
+            .map((p) => new NamedExpression(p.name, new VariableGet(p)))
+            .toList(),
+        types: function.typeParameters
+            .map((p) => new TypeParameterType(p))
+            .toList());
+  }
+
   accept(TreeVisitor v) => v.visitArguments(this);
 
   visitChildren(Visitor v) {
@@ -5527,14 +5537,28 @@
   /// Mutable mapping between nodes and their metadata.
   Map<TreeNode, T> get mapping;
 
-  /// Write the given metadata object into the given [BinarySink].
+  /// Write [metadata] object corresponding to the given [Node] into
+  /// the given [BinarySink].
   ///
-  /// Note: [metadata] must be an object owned by this repository.
-  void writeToBinary(T metadata, BinarySink sink);
+  /// Metadata is serialized immediately before serializing [node],
+  /// so implementation of this method can use serialization context of
+  /// [node]'s parents (such as declared type parameters and variables).
+  /// In order to use scope declared by the [node] itself, implementation of
+  /// this method can use [BinarySink.enterScope] and [BinarySink.leaveScope]
+  /// methods.
+  ///
+  /// [metadata] must be an object owned by this repository.
+  void writeToBinary(T metadata, Node node, BinarySink sink);
 
   /// Construct a metadata object from its binary payload read from the
   /// given [BinarySource].
-  T readFromBinary(BinarySource source);
+  ///
+  /// Metadata is deserialized immediately after deserializing [node],
+  /// so it can use deserialization context of [node]'s parents.
+  /// In order to use scope declared by the [node] itself, implementation of
+  /// this method can use [BinarySource.enterScope] and
+  /// [BinarySource.leaveScope] methods.
+  T readFromBinary(Node node, BinarySource source);
 
   /// Method to check whether a node can have metadata attached to it
   /// or referenced from the metadata payload.
@@ -5557,12 +5581,17 @@
 
   void writeCanonicalNameReference(CanonicalName name);
   void writeStringReference(String str);
+  void writeDartType(DartType type);
+  void writeNode(Node node);
 
-  /// Write a reference to a given node into the sink.
-  ///
-  /// Note: node must not be [MapEntry] because [MapEntry] and [MapEntry.key]
-  /// have the same offset in the binary and can't be distinguished.
-  void writeNodeReference(Node node);
+  void enterScope(
+      {List<TypeParameter> typeParameters,
+      bool memberScope: false,
+      bool variableScope: false});
+  void leaveScope(
+      {List<TypeParameter> typeParameters,
+      bool memberScope: false,
+      bool variableScope: false});
 }
 
 abstract class BinarySource {
@@ -5578,7 +5607,11 @@
 
   CanonicalName readCanonicalNameReference();
   String readStringReference();
-  Node readNodeReference();
+  DartType readDartType();
+  FunctionNode readFunctionNode();
+
+  void enterScope({List<TypeParameter> typeParameters});
+  void leaveScope({List<TypeParameter> typeParameters});
 }
 
 // ------------------------------------------------------------------------
diff --git a/pkg/kernel/lib/binary/ast_from_binary.dart b/pkg/kernel/lib/binary/ast_from_binary.dart
index 4ff4a37..0b8053d 100644
--- a/pkg/kernel/lib/binary/ast_from_binary.dart
+++ b/pkg/kernel/lib/binary/ast_from_binary.dart
@@ -23,9 +23,13 @@
 }
 
 class _ComponentIndex {
+  static const numberOfFixedFields = 9;
+
   int binaryOffsetForSourceTable;
-  int binaryOffsetForStringTable;
   int binaryOffsetForCanonicalNames;
+  int binaryOffsetForMetadataPayloads;
+  int binaryOffsetForMetadataMappings;
+  int binaryOffsetForStringTable;
   int binaryOffsetForConstantTable;
   int mainMethodReference;
   List<int> libraryOffsets;
@@ -141,19 +145,16 @@
     return string;
   }
 
-  /// Read metadataMappings section from the binary. Return [true] if
-  /// any metadata mapping contains metadata with node references.
-  /// In this case we need to disable lazy loading of the binary.
-  bool _readMetadataSection(Component component) {
+  /// Read metadataMappings section from the binary.
+  void _readMetadataMappings(
+      Component component, int binaryOffsetForMetadataPayloads) {
     // Default reader ignores metadata section entirely.
-    return false;
   }
 
-  /// Process any pending metadata associations. Called once the Component
-  /// is fully deserialized and metadata containing references to nodes can
-  /// be safely parsed.
-  void _processPendingMetadataAssociations(Component component) {
+  /// Reads metadata for the given [node].
+  Node _associateMetadata(Node node, int nodeOffset) {
     // Default reader ignores metadata section entirely.
+    return node;
   }
 
   void readStringTable(List<String> table) {
@@ -401,6 +402,22 @@
     }
   }
 
+  /// Deserializes the source and stores it in [component].
+  ///
+  /// The input bytes may contain multiple files concatenated.
+  void readComponentSource(Component component) {
+    List<int> componentFileSizes = _indexComponents();
+    if (componentFileSizes.length > 1) {
+      _disableLazyReading = true;
+    }
+    int componentFileIndex = 0;
+    while (_byteOffset < _bytes.length) {
+      _readOneComponentSource(
+          component, componentFileSizes[componentFileIndex]);
+      ++componentFileIndex;
+    }
+  }
+
   /// Reads a single component file from the input and loads it into [component],
   /// overwriting and reusing any existing data in the component.
   ///
@@ -445,14 +462,16 @@
     }
 
     // Skip to the start of the index.
-    // There are these fields: file size, library count, library count + 1
-    // offsets, main reference, string table offset, canonical name offset and
-    // source table offset. That's 6 fields + number of libraries.
-    _byteOffset -= (result.libraryCount + 8) * 4;
+    _byteOffset -=
+        ((result.libraryCount + 1) + _ComponentIndex.numberOfFixedFields) * 4;
 
     // Now read the component index.
     result.binaryOffsetForSourceTable = _componentStartOffset + readUint32();
     result.binaryOffsetForCanonicalNames = _componentStartOffset + readUint32();
+    result.binaryOffsetForMetadataPayloads =
+        _componentStartOffset + readUint32();
+    result.binaryOffsetForMetadataMappings =
+        _componentStartOffset + readUint32();
     result.binaryOffsetForStringTable = _componentStartOffset + readUint32();
     result.binaryOffsetForConstantTable = _componentStartOffset + readUint32();
     result.mainMethodReference = readUint32();
@@ -465,6 +484,31 @@
     return result;
   }
 
+  void _readOneComponentSource(Component component, int componentFileSize) {
+    _componentStartOffset = _byteOffset;
+
+    final int magic = readUint32();
+    if (magic != Tag.ComponentFile) {
+      throw fail('This is not a binary dart file. '
+          'Magic number was: ${magic.toRadixString(16)}');
+    }
+
+    final int formatVersion = readUint32();
+    if (formatVersion != Tag.BinaryFormatVersion) {
+      throw fail('Invalid kernel binary format version '
+          '(found ${formatVersion}, expected ${Tag.BinaryFormatVersion})');
+    }
+
+    // Read component index from the end of this ComponentFiles serialized data.
+    _ComponentIndex index = _readComponentIndex(componentFileSize);
+
+    _byteOffset = index.binaryOffsetForSourceTable;
+    Map<Uri, Source> uriToSource = readUriToSource();
+    component.uriToSource.addAll(uriToSource);
+
+    _byteOffset = _componentStartOffset + componentFileSize;
+  }
+
   void _readOneComponent(Component component, int componentFileSize) {
     _componentStartOffset = _byteOffset;
 
@@ -489,9 +533,9 @@
     _byteOffset = index.binaryOffsetForCanonicalNames;
     readLinkTable(component.root);
 
-    _byteOffset = index.binaryOffsetForStringTable;
-    _disableLazyReading =
-        _readMetadataSection(component) || _disableLazyReading;
+    // TODO(alexmarkov): reverse metadata mappings and read forwards
+    _byteOffset = index.binaryOffsetForStringTable; // Read backwards.
+    _readMetadataMappings(component, index.binaryOffsetForMetadataPayloads);
 
     _byteOffset = index.binaryOffsetForSourceTable;
     Map<Uri, Source> uriToSource = readUriToSource();
@@ -510,7 +554,7 @@
         getMemberReferenceFromInt(index.mainMethodReference, allowNull: true);
     component.mainMethodName ??= mainMethod;
 
-    _processPendingMetadataAssociations(component);
+    _associateMetadata(component, _componentStartOffset);
 
     _byteOffset = _componentStartOffset + componentFileSize;
   }
@@ -523,7 +567,9 @@
     Map<Uri, Source> uriToSource = <Uri, Source>{};
     for (int i = 0; i < length; ++i) {
       List<int> uriBytes = readByteList();
-      Uri uri = Uri.parse(const Utf8Decoder().convert(uriBytes));
+      Uri uri = uriBytes.isEmpty
+          ? null
+          : Uri.parse(const Utf8Decoder().convert(uriBytes));
       _sourceUriTable[i] = uri;
       List<int> sourceCode = readByteList();
       int lineCount = readUInt();
@@ -918,7 +964,7 @@
       debugPath.add(node.name?.name ?? 'constructor');
       return true;
     }());
-    var function = readFunctionNode(false, -1);
+    var function = readFunctionNode();
     pushVariableDeclarations(function.positionalParameters);
     pushVariableDeclarations(function.namedParameters);
     if (shouldWriteData) {
@@ -1075,11 +1121,13 @@
 
   FunctionNode readFunctionNodeOption(bool lazyLoadBody, int outerEndOffset) {
     return readAndCheckOptionTag()
-        ? readFunctionNode(lazyLoadBody, outerEndOffset)
+        ? readFunctionNode(
+            lazyLoadBody: lazyLoadBody, outerEndOffset: outerEndOffset)
         : null;
   }
 
-  FunctionNode readFunctionNode(bool lazyLoadBody, int outerEndOffset) {
+  FunctionNode readFunctionNode(
+      {bool lazyLoadBody: false, int outerEndOffset: -1}) {
     int tag = readByte();
     assert(tag == Tag.FunctionNode);
     int offset = readOffset();
@@ -1398,8 +1446,7 @@
         return new AwaitExpression(readExpression());
       case Tag.FunctionExpression:
         int offset = readOffset();
-        return new FunctionExpression(readFunctionNode(false, -1))
-          ..fileOffset = offset;
+        return new FunctionExpression(readFunctionNode())..fileOffset = offset;
       case Tag.Let:
         var variable = readVariableDeclaration();
         int stackHeight = variableStack.length;
@@ -1584,7 +1631,7 @@
         int offset = readOffset();
         var variable = readVariableDeclaration();
         variableStack.add(variable); // Will be popped by the enclosing scope.
-        var function = readFunctionNode(false, -1);
+        var function = readFunctionNode();
         return new FunctionDeclaration(variable, function)..fileOffset = offset;
       default:
         throw fail('Invalid statement tag: $tag');
@@ -1845,17 +1892,12 @@
   /// and are awaiting to be parsed and attached to nodes.
   List<_MetadataSubsection> _subsections;
 
-  /// Current mapping from node references to nodes used by readNodeReference.
-  /// Note: each metadata subsection has its own mapping.
-  List<Node> _referencedNodes;
-
   BinaryBuilderWithMetadata(bytes, [filename])
       : super(bytes, filename: filename);
 
   @override
-  bool _readMetadataSection(Component component) {
-    bool containsNodeReferences = false;
-
+  void _readMetadataMappings(
+      Component component, int binaryOffsetForMetadataPayloads) {
     // At the beginning of this function _byteOffset points right past
     // metadataMappings to string table.
 
@@ -1865,15 +1907,10 @@
 
     int endOffset = _byteOffset - 4; // End offset of the current subsection.
     for (var i = 0; i < subSectionCount; i++) {
-      // RList<UInt32> nodeReferences
-      _byteOffset = endOffset - 4;
-      final referencesLength = readUint32();
-      final referencesStart = (endOffset - 4) - 4 * referencesLength;
-
       // RList<Pair<UInt32, UInt32>> nodeOffsetToMetadataOffset
-      _byteOffset = referencesStart - 4;
+      _byteOffset = endOffset - 4;
       final mappingLength = readUint32();
-      final mappingStart = (referencesStart - 4) - 4 * 2 * mappingLength;
+      final mappingStart = (endOffset - 4) - 4 * 2 * mappingLength;
       _byteOffset = mappingStart - 4;
 
       // UInt32 tag (fixed size StringReference)
@@ -1881,73 +1918,49 @@
 
       final repository = component.metadata[tag];
       if (repository != null) {
-        // Read nodeReferences (if any).
-        Map<int, int> offsetToReferenceId;
-        List<Node> referencedNodes;
-        if (referencesLength > 0) {
-          offsetToReferenceId = <int, int>{};
-          _byteOffset = referencesStart;
-          for (var j = 0; j < referencesLength; j++) {
-            final nodeOffset = readUint32();
-            offsetToReferenceId[nodeOffset] = j;
-          }
-          referencedNodes =
-              new List<Node>.filled(referencesLength, null, growable: true);
-          containsNodeReferences = true;
-        }
-
         // Read nodeOffsetToMetadataOffset mapping.
         final mapping = <int, int>{};
         _byteOffset = mappingStart;
         for (var j = 0; j < mappingLength; j++) {
           final nodeOffset = readUint32();
-          final metadataOffset = readUint32();
+          final metadataOffset = binaryOffsetForMetadataPayloads + readUint32();
           mapping[nodeOffset] = metadataOffset;
         }
 
         _subsections ??= <_MetadataSubsection>[];
-        _subsections.add(new _MetadataSubsection(
-            repository, mapping, offsetToReferenceId, referencedNodes));
+        _subsections.add(new _MetadataSubsection(repository, mapping));
       }
 
       // Start of the subsection and the end of the previous one.
       endOffset = mappingStart - 4;
     }
-
-    return containsNodeReferences;
   }
 
-  @override
-  void _processPendingMetadataAssociations(Component component) {
-    if (_subsections == null) {
-      return;
-    }
-
-    _associateMetadata(component, _componentStartOffset);
-
-    for (var subsection in _subsections) {
-      if (subsection.pending == null) {
-        continue;
-      }
-
-      _referencedNodes = subsection.referencedNodes;
-      for (var i = 0; i < subsection.pending.length; i += 2) {
-        final Node node = subsection.pending[i];
-        final int metadataOffset = subsection.pending[i + 1];
-        subsection.repository.mapping[node] =
-            _readMetadata(subsection.repository, metadataOffset);
-      }
-    }
-  }
-
-  Object _readMetadata(MetadataRepository repository, int offset) {
+  Object _readMetadata(Node node, MetadataRepository repository, int offset) {
     final int savedOffset = _byteOffset;
     _byteOffset = offset;
-    final metadata = repository.readFromBinary(this);
+
+    final metadata = repository.readFromBinary(node, this);
+
     _byteOffset = savedOffset;
     return metadata;
   }
 
+  @override
+  void enterScope({List<TypeParameter> typeParameters}) {
+    if (typeParameters != null) {
+      typeParameterStack.addAll(typeParameters);
+    }
+  }
+
+  @override
+  void leaveScope({List<TypeParameter> typeParameters}) {
+    if (typeParameters != null) {
+      typeParameterStack.length -= typeParameters.length;
+    }
+  }
+
+  @override
   Node _associateMetadata(Node node, int nodeOffset) {
     if (_subsections == null) {
       return node;
@@ -1957,28 +1970,8 @@
       // First check if there is any metadata associated with this node.
       final metadataOffset = subsection.mapping[nodeOffset];
       if (metadataOffset != null) {
-        if (subsection.nodeOffsetToReferenceId == null) {
-          // This subsection does not contain any references to nodes from
-          // inside the payload. In this case we can deserialize metadata
-          // eagerly.
-          subsection.repository.mapping[node] =
-              _readMetadata(subsection.repository, metadataOffset);
-        } else {
-          // Metadata payload might contain references to nodes that
-          // are not yet deserialized. Postpone association of metadata
-          // with this node.
-          subsection.pending ??= <Object>[];
-          subsection.pending..add(node)..add(metadataOffset);
-        }
-      }
-
-      // Check if this node is referenced from this section and update
-      // referencedNodes array if that is the case.
-      if (subsection.nodeOffsetToReferenceId != null) {
-        final id = subsection.nodeOffsetToReferenceId[nodeOffset];
-        if (id != null) {
-          subsection.referencedNodes[id] = node;
-        }
+        subsection.repository.mapping[node] =
+            _readMetadata(node, subsection.repository, metadataOffset);
       }
     }
 
@@ -2049,9 +2042,11 @@
   }
 
   @override
-  FunctionNode readFunctionNode(bool lazyLoadBody, int outerEndOffset) {
+  FunctionNode readFunctionNode(
+      {bool lazyLoadBody: false, int outerEndOffset: -1}) {
     final nodeOffset = _byteOffset;
-    final result = super.readFunctionNode(lazyLoadBody, outerEndOffset);
+    final result = super.readFunctionNode(
+        lazyLoadBody: lazyLoadBody, outerEndOffset: outerEndOffset);
     return _associateMetadata(result, nodeOffset);
   }
 
@@ -2144,12 +2139,6 @@
 
   @override
   List<int> get bytes => _bytes;
-
-  @override
-  Node readNodeReference() {
-    final id = readUInt();
-    return id == 0 ? null : _referencedNodes[id - 1];
-  }
 }
 
 /// Deserialized MetadataMapping corresponding to the given metadata repository.
@@ -2160,18 +2149,5 @@
   /// Deserialized mapping from node offsets to metadata offsets.
   final Map<int, int> mapping;
 
-  /// Deserialized mapping from node offset to node reference ids.
-  final Map<int, int> nodeOffsetToReferenceId;
-
-  /// Array mapping node reference ids to corresponding nodes.
-  /// Will be gradually filled as nodes are deserialized.
-  final List<Node> referencedNodes;
-
-  /// A list of pairs (Node, int metadataOffset) that describes pending
-  /// metadata associations which will be processed once all nodes
-  /// are parsed.
-  List<Object> pending;
-
-  _MetadataSubsection(this.repository, this.mapping,
-      this.nodeOffsetToReferenceId, this.referencedNodes);
+  _MetadataSubsection(this.repository, this.mapping);
 }
diff --git a/pkg/kernel/lib/binary/ast_to_binary.dart b/pkg/kernel/lib/binary/ast_to_binary.dart
index a65dd03..0329a1f 100644
--- a/pkg/kernel/lib/binary/ast_to_binary.dart
+++ b/pkg/kernel/lib/binary/ast_to_binary.dart
@@ -8,8 +8,8 @@
 import '../ast.dart';
 import 'tag.dart';
 import 'dart:convert';
+import 'dart:io' show BytesBuilder;
 import 'dart:typed_data';
-import 'dart:collection';
 
 /// Writes to a binary file.
 ///
@@ -22,25 +22,25 @@
   final TypeParameterIndexer _typeParameterIndexer = new TypeParameterIndexer();
   final StringIndexer stringIndexer;
   ConstantIndexer _constantIndexer;
-  final StringIndexer _sourceUriIndexer = new StringIndexer();
+  final UriIndexer _sourceUriIndexer = new UriIndexer();
   final Set<Uri> _knownSourceUri = new Set<Uri>();
   Map<LibraryDependency, int> _libraryDependencyIndex =
       <LibraryDependency, int>{};
 
   List<_MetadataSubsection> _metadataSubsections;
 
-  /// Map used to assign reference ids to nodes contained within metadata
-  /// payloads.
-  Map<Node, int> _nodeReferences;
-
-  final BufferedSink _sink;
+  final BufferedSink _mainSink;
+  final BufferedSink _metadataSink;
+  BufferedSink _sink;
 
   List<int> libraryOffsets;
   List<int> classOffsets;
   List<int> procedureOffsets;
   int _binaryOffsetForSourceTable = -1;
-  int _binaryOffsetForStringTable = -1;
   int _binaryOffsetForLinkTable = -1;
+  int _binaryOffsetForMetadataPayloads = -1;
+  int _binaryOffsetForMetadataMappings = -1;
+  int _binaryOffsetForStringTable = -1;
   int _binaryOffsetForConstantTable = -1;
 
   List<CanonicalName> _canonicalNameList;
@@ -51,14 +51,12 @@
   ///
   /// The BinaryPrinter will use its own buffer, so the [sink] does not need
   /// one.
-  ///
-  /// If multiple binaries are to be written based on the same IR, a shared
-  /// [globalIndexer] may be passed in to avoid rebuilding the same indices
-  /// in every printer.
   BinaryPrinter(Sink<List<int>> sink, {StringIndexer stringIndexer})
-      : _sink = new BufferedSink(sink),
+      : _mainSink = new BufferedSink(sink),
+        _metadataSink = new BufferedSink(new BytesSink()),
         stringIndexer = stringIndexer ?? new StringIndexer() {
     _constantIndexer = new ConstantIndexer(this.stringIndexer);
+    _sink = _mainSink;
   }
 
   void _flush() {
@@ -103,15 +101,23 @@
     _binaryOffsetForStringTable = getBufferOffset();
 
     // Write the end offsets.
-    writeUInt30(indexer.numberOfStrings);
+    writeUInt30(indexer.index.length);
     int endOffset = 0;
-    for (var entry in indexer.entries) {
-      endOffset += entry.utf8Bytes.length;
+    List<List<int>> data =
+        new List<List<int>>.filled(indexer.index.length, null);
+    int i = 0;
+    Utf8Encoder utf8Encoder = const Utf8Encoder();
+    for (String key in indexer.index.keys) {
+      List<int> utf8Bytes = utf8Encoder.convert(key);
+      data[i] = utf8Bytes;
+      endOffset += utf8Bytes.length;
       writeUInt30(endOffset);
+      i++;
     }
+
     // Write the UTF-8 encoded strings.
-    for (var entry in indexer.entries) {
-      writeBytes(entry.utf8Bytes);
+    for (var entry in data) {
+      writeBytes(entry);
     }
   }
 
@@ -206,11 +212,12 @@
   // Returns the new active file uri.
   Uri writeUriReference(Uri uri) {
     if (_knownSourceUri.contains(uri)) {
-      final int index = _sourceUriIndexer.put(uri == null ? "" : "$uri");
+      final int index = _sourceUriIndexer.put(uri);
       writeUInt30(index);
       return uri;
     } else {
-      final int index = 0; // equivalent to index = _sourceUriIndexer[""];
+      // This is equivalent to `index = _sourceUriIndexer[null];`.
+      final int index = 0;
       writeUInt30(index);
       return null;
     }
@@ -232,7 +239,7 @@
 
   void writeNode(Node node) {
     if (_metadataSubsections != null) {
-      _recordNodeOffsetForMetadataMapping(node);
+      _writeNodeMetadata(node);
     }
     node.accept(this);
   }
@@ -303,11 +310,9 @@
     writeUInt32(Tag.BinaryFormatVersion);
     indexLinkTable(component);
     indexUris(component);
-    // Note: must write metadata payloads before any other node in the component
-    // to collect references to nodes contained within metadata payloads.
-    _writeMetadataPayloads(component);
+    _collectMetadata(component);
     if (_metadataSubsections != null) {
-      _recordNodeOffsetForMetadataMappingImpl(component, componentOffset);
+      _writeNodeMetadataImpl(component, componentOffset);
     }
     libraryOffsets = <int>[];
     CanonicalName main = getCanonicalNameOfMember(component.mainMethod);
@@ -317,7 +322,7 @@
     writeLibraries(component);
     writeUriToSource(component.uriToSource);
     writeLinkTable(component);
-    _writeMetadataMappingSection(component);
+    _writeMetadataSection(component);
     writeStringTable(stringIndexer);
     writeConstantTable(_constantIndexer);
     writeComponentIndex(component, component.libraries);
@@ -325,87 +330,95 @@
     _flush();
   }
 
-  @override
-  void writeNodeReference(Node node) {
-    if (!MetadataRepository.isSupported(node)) {
-      throw "Can't reference nodes of type ${node.runtimeType} from metadata.";
-    }
-
-    if (node == null) {
-      writeUInt30(0);
-    } else {
-      final id =
-          _nodeReferences.putIfAbsent(node, () => _nodeReferences.length);
-      writeUInt30(id + 1);
-    }
-  }
-
-  /// Collect and write out all metadata contained in metadata repositories
-  /// associated with the component.
-  ///
-  /// Non-empty metadata subsections will be collected in [_metadataSubsections]
-  /// and used to generate metadata mappings after all nodes in the component
-  /// are written and all node offsets are known.
-  ///
-  /// Note: must write metadata payloads before any other node in the component
-  /// to collect references to nodes contained within metadata payloads.
-  void _writeMetadataPayloads(Component component) {
+  /// Collect non-empty metadata repositories associated with the component.
+  void _collectMetadata(Component component) {
     component.metadata.forEach((tag, repository) {
       if (repository.mapping.isEmpty) {
         return;
       }
 
-      // Write all payloads collecting outgoing node references and remembering
-      // metadata offset for each node that had associated metadata.
-      _nodeReferences = <Node, int>{};
-      final metadataOffsets = <Node, int>{};
-      repository.mapping.forEach((node, value) {
-        if (!MetadataRepository.isSupported(node)) {
-          throw "Nodes of type ${node.runtimeType} can't have metadata.";
-        }
-
-        metadataOffsets[node] = getBufferOffset();
-        repository.writeToBinary(value, this);
-      });
-
       _metadataSubsections ??= <_MetadataSubsection>[];
-      _metadataSubsections.add(new _MetadataSubsection(
-          repository, metadataOffsets, _nodeReferences));
-
-      _nodeReferences = null;
+      _metadataSubsections.add(new _MetadataSubsection(repository));
     });
   }
 
-  /// If the given [Node] has any metadata associated with it or is referenced
-  /// from some metadata payload then we need to record its offset.
-  void _recordNodeOffsetForMetadataMapping(Node node) {
-    _recordNodeOffsetForMetadataMappingImpl(node, getBufferOffset());
+  /// Writes metadata associated with the given [Node].
+  void _writeNodeMetadata(Node node) {
+    _writeNodeMetadataImpl(node, getBufferOffset());
   }
 
-  void _recordNodeOffsetForMetadataMappingImpl(Node node, int nodeOffset) {
+  void _writeNodeMetadataImpl(Node node, int nodeOffset) {
     for (var subsection in _metadataSubsections) {
-      final metadataOffset = subsection.metadataOffsets[node];
-      if (metadataOffset != null) {
-        subsection.metadataMapping..add(nodeOffset)..add(metadataOffset);
+      final repository = subsection.repository;
+      final value = repository.mapping[node];
+      if (value == null) {
+        continue;
       }
-      if (subsection.nodeToReferenceId != null) {
-        final id = subsection.nodeToReferenceId[node];
-        if (id != null) {
-          subsection.offsetsOfReferencedNodes[id] = nodeOffset;
-        }
+
+      if (!MetadataRepository.isSupported(node)) {
+        throw "Nodes of type ${node.runtimeType} can't have metadata.";
       }
+
+      if (!identical(_sink, _mainSink)) {
+        throw "Node written into metadata can't have metadata "
+            "(metadata: ${repository.tag}, node: ${node.runtimeType} $node)";
+      }
+
+      _sink = _metadataSink;
+      subsection.metadataMapping.add(nodeOffset);
+      subsection.metadataMapping.add(getBufferOffset());
+      repository.writeToBinary(value, node, this);
+      _sink = _mainSink;
     }
   }
 
-  void _writeMetadataMappingSection(Component component) {
+  @override
+  void enterScope(
+      {List<TypeParameter> typeParameters,
+      bool memberScope: false,
+      bool variableScope: false}) {
+    if (typeParameters != null) {
+      _typeParameterIndexer.enter(typeParameters);
+    }
+    if (memberScope) {
+      _variableIndexer = new VariableIndexer();
+    }
+    if (variableScope) {
+      _variableIndexer.pushScope();
+    }
+  }
+
+  @override
+  void leaveScope(
+      {List<TypeParameter> typeParameters,
+      bool memberScope: false,
+      bool variableScope: false}) {
+    if (variableScope) {
+      _variableIndexer.popScope();
+    }
+    if (memberScope) {
+      _variableIndexer = null;
+    }
+    if (typeParameters != null) {
+      _typeParameterIndexer.exit(typeParameters);
+    }
+  }
+
+  void _writeMetadataSection(Component component) {
+    _binaryOffsetForMetadataPayloads = getBufferOffset();
+
     if (_metadataSubsections == null) {
+      _binaryOffsetForMetadataMappings = getBufferOffset();
       writeUInt32(0); // Empty section.
       return;
     }
 
-    _recordNodeOffsetForMetadataMappingImpl(component, 0);
+    assert(identical(_sink, _mainSink));
+    _metadataSink.flushAndDestroy();
+    writeBytes((_metadataSink._sink as BytesSink).builder.takeBytes());
 
     // RList<MetadataMapping> metadataMappings
+    _binaryOffsetForMetadataMappings = getBufferOffset();
     for (var subsection in _metadataSubsections) {
       // UInt32 tag
       writeUInt32(stringIndexer.put(subsection.repository.tag));
@@ -417,32 +430,6 @@
         writeUInt32(subsection.metadataMapping[i + 1]); // metadata offset
       }
       writeUInt32(mappingLength ~/ 2);
-
-      // RList<UInt32> nodeReferences
-      if (subsection.nodeToReferenceId != null) {
-        final offsets = subsection.offsetsOfReferencedNodes;
-        for (int i = 0; i < offsets.length; ++i) {
-          final nodeOffset = offsets[i];
-          if (nodeOffset < 0) {
-            // Dangling reference.
-            // Find a node which was referenced to report meaningful error.
-            Node referencedNode;
-            subsection.nodeToReferenceId.forEach((node, id) {
-              if (id == i) {
-                referencedNode = node;
-              }
-            });
-            throw 'Unable to write reference to node'
-                ' ${referencedNode.runtimeType} $referencedNode'
-                ' from metadata ${subsection.repository.tag}'
-                ' (node is not written into kernel binary)';
-          }
-          writeUInt32(nodeOffset);
-        }
-        writeUInt32(subsection.offsetsOfReferencedNodes.length);
-      } else {
-        writeUInt32(0);
-      }
     }
     writeUInt32(_metadataSubsections.length);
   }
@@ -458,6 +445,10 @@
     writeUInt32(_binaryOffsetForSourceTable);
     assert(_binaryOffsetForLinkTable >= 0);
     writeUInt32(_binaryOffsetForLinkTable);
+    assert(_binaryOffsetForMetadataPayloads >= 0);
+    writeUInt32(_binaryOffsetForMetadataPayloads);
+    assert(_binaryOffsetForMetadataMappings >= 0);
+    writeUInt32(_binaryOffsetForMetadataMappings);
     assert(_binaryOffsetForStringTable >= 0);
     writeUInt32(_binaryOffsetForStringTable);
     assert(_binaryOffsetForConstantTable >= 0);
@@ -487,19 +478,19 @@
   void writeUriToSource(Map<Uri, Source> uriToSource) {
     _binaryOffsetForSourceTable = getBufferOffset();
 
-    int length = _sourceUriIndexer.numberOfStrings;
+    int length = _sourceUriIndexer.index.length;
     writeUInt32(length);
-    List<int> index = new List<int>(_sourceUriIndexer.entries.length);
+    List<int> index = new List<int>(length);
 
     // Write data.
-    for (int i = 0; i < length; ++i) {
+    int i = 0;
+    Utf8Encoder utf8Encoder = const Utf8Encoder();
+    for (Uri uri in _sourceUriIndexer.index.keys) {
       index[i] = getBufferOffset();
 
-      StringTableEntry uri = _sourceUriIndexer.entries[i];
-      Source source = uriToSource[Uri.parse(uri.value)] ??
-          new Source(<int>[], const <int>[]);
+      Source source = uriToSource[uri] ?? new Source(<int>[], const <int>[]);
 
-      writeByteList(uri.utf8Bytes);
+      writeByteList(utf8Encoder.convert(uri == null ? "" : "$uri"));
       writeByteList(source.source);
       List<int> lineStarts = source.lineStarts;
       writeUInt30(lineStarts.length);
@@ -508,6 +499,7 @@
         writeUInt30(lineStart - previousLineStart);
         previousLineStart = lineStart;
       });
+      i++;
     }
 
     // Write index for random access.
@@ -588,7 +580,7 @@
 
   void writeName(Name node) {
     if (_metadataSubsections != null) {
-      _recordNodeOffsetForMetadataMapping(node);
+      _writeNodeMetadata(node);
     }
     writeStringReference(node.name);
     // TODO: Consider a more compressed format for private names within the
@@ -662,7 +654,7 @@
 
   void writeLibraryDependency(LibraryDependency node) {
     if (_metadataSubsections != null) {
-      _recordNodeOffsetForMetadataMapping(node);
+      _writeNodeMetadata(node);
     }
     writeOffset(node.fileOffset);
     writeByte(node.flags);
@@ -687,7 +679,7 @@
 
   void writeLibraryPart(LibraryPart node) {
     if (_metadataSubsections != null) {
-      _recordNodeOffsetForMetadataMapping(node);
+      _writeNodeMetadata(node);
     }
     writeAnnotationList(node.annotations);
     writeStringReference(node.partUri);
@@ -702,10 +694,10 @@
     writeOffset(node.fileOffset);
     writeStringReference(node.name);
     writeAnnotationList(node.annotations);
-    _typeParameterIndexer.enter(node.typeParameters);
+    enterScope(typeParameters: node.typeParameters);
     writeNodeList(node.typeParameters);
     writeNode(node.type);
-    _typeParameterIndexer.exit(node.typeParameters);
+    leaveScope(typeParameters: node.typeParameters);
 
     _activeFileUri = activeFileUriSaved;
   }
@@ -758,7 +750,7 @@
     writeStringReference(node.name ?? '');
 
     writeAnnotationList(node.annotations);
-    _typeParameterIndexer.enter(node.typeParameters);
+    enterScope(typeParameters: node.typeParameters);
     writeNodeList(node.typeParameters);
     writeOptionalNode(node.supertype);
     writeOptionalNode(node.mixedInType);
@@ -769,7 +761,7 @@
     writeNodeList(node.procedures);
     procedureOffsets.add(getBufferOffset());
     writeNodeList(node.redirectingFactoryConstructors);
-    _typeParameterIndexer.exit(node.typeParameters);
+    leaveScope(typeParameters: node.typeParameters);
 
     _activeFileUri = activeFileUriSaved;
 
@@ -787,7 +779,7 @@
     if (node.canonicalName == null) {
       throw 'Missing canonical name for $node';
     }
-    _variableIndexer = new VariableIndexer();
+    enterScope(memberScope: true);
     writeByte(Tag.Constructor);
     writeCanonicalNameReference(getCanonicalNameOfMember(node));
 
@@ -809,7 +801,7 @@
 
     _activeFileUri = activeFileUriSaved;
 
-    _variableIndexer = null;
+    leaveScope(memberScope: true);
   }
 
   @override
@@ -819,7 +811,7 @@
     if (node.canonicalName == null) {
       throw 'Missing canonical name for $node';
     }
-    _variableIndexer = new VariableIndexer();
+    enterScope(memberScope: true);
     writeByte(Tag.Procedure);
     writeCanonicalNameReference(getCanonicalNameOfMember(node));
 
@@ -838,7 +830,7 @@
 
     _activeFileUri = activeFileUriSaved;
 
-    _variableIndexer = null;
+    leaveScope(memberScope: true);
 
     assert((node.forwardingStubSuperTarget != null) ||
         !(node.isForwardingStub && node.function.body != null));
@@ -849,7 +841,7 @@
     if (node.canonicalName == null) {
       throw 'Missing canonical name for $node';
     }
-    _variableIndexer = new VariableIndexer();
+    enterScope(memberScope: true);
     writeByte(Tag.Field);
     writeCanonicalNameReference(getCanonicalNameOfMember(node));
 
@@ -866,7 +858,7 @@
 
     _activeFileUri = activeFileUriSaved;
 
-    _variableIndexer = null;
+    leaveScope(memberScope: true);
   }
 
   @override
@@ -875,9 +867,10 @@
       throw 'Missing canonical name for $node';
     }
     writeByte(Tag.RedirectingFactoryConstructor);
-    _variableIndexer = new VariableIndexer();
-    _variableIndexer.pushScope();
-    _typeParameterIndexer.enter(node.typeParameters);
+    enterScope(
+        typeParameters: node.typeParameters,
+        memberScope: true,
+        variableScope: true);
     writeCanonicalNameReference(getCanonicalNameOfMember(node));
 
     final Uri activeFileUriSaved = _activeFileUri;
@@ -896,12 +889,13 @@
     writeUInt30(node.requiredParameterCount);
     writeVariableDeclarationList(node.positionalParameters);
     writeVariableDeclarationList(node.namedParameters);
-    _typeParameterIndexer.exit(node.typeParameters);
 
     _activeFileUri = activeFileUriSaved;
 
-    _variableIndexer.popScope();
-    _variableIndexer = null;
+    leaveScope(
+        typeParameters: node.typeParameters,
+        memberScope: true,
+        variableScope: true);
   }
 
   @override
@@ -951,14 +945,12 @@
   @override
   void visitFunctionNode(FunctionNode node) {
     writeByte(Tag.FunctionNode);
-    assert(_variableIndexer != null);
-    _variableIndexer.pushScope();
+    enterScope(typeParameters: node.typeParameters, variableScope: true);
     var oldLabels = _labelIndexer;
     _labelIndexer = null;
     var oldCases = _switchCaseIndexer;
     _switchCaseIndexer = null;
     // Note: FunctionNode has no tag.
-    _typeParameterIndexer.enter(node.typeParameters);
     writeOffset(node.fileOffset);
     writeOffset(node.fileEndOffset);
     writeByte(node.asyncMarker.index);
@@ -972,8 +964,7 @@
     writeOptionalNode(node.body);
     _labelIndexer = oldLabels;
     _switchCaseIndexer = oldCases;
-    _typeParameterIndexer.exit(node.typeParameters);
-    _variableIndexer.popScope();
+    leaveScope(typeParameters: node.typeParameters, variableScope: true);
   }
 
   @override
@@ -1591,7 +1582,7 @@
 
   void writeVariableDeclaration(VariableDeclaration node) {
     if (_metadataSubsections != null) {
-      _recordNodeOffsetForMetadataMapping(node);
+      _writeNodeMetadata(node);
     }
     node.binaryOffsetNoTag = getBufferOffset();
     writeOffset(node.fileOffset);
@@ -1683,7 +1674,7 @@
       writeNode(node.returnType);
     } else {
       writeByte(Tag.FunctionType);
-      _typeParameterIndexer.enter(node.typeParameters);
+      enterScope(typeParameters: node.typeParameters);
       writeNodeList(node.typeParameters);
       writeUInt30(node.requiredParameterCount);
       writeUInt30(
@@ -1693,7 +1684,7 @@
       writeStringReferenceList(node.positionalParameterNames);
       writeReference(node.typedefReference);
       writeNode(node.returnType);
-      _typeParameterIndexer.exit(node.typeParameters);
+      leaveScope(typeParameters: node.typeParameters);
     }
   }
 
@@ -2024,59 +2015,32 @@
 
   ConstantIndexer(this.stringIndexer);
 
-  defaultConstantReference(Constant node) {
-    put(node);
-  }
-
   int put(Constant constant) {
-    final int value = index[constant];
-    if (value != null) return value;
+    final int oldIndex = index[constant];
+    if (oldIndex != null) return oldIndex;
 
     // Traverse DAG in post-order to ensure children have their id's assigned
     // before the parent.
-    return constant.accept(this);
-  }
+    constant.visitChildren(this);
 
-  defaultConstant(Constant node) {
-    final int oldIndex = index[node];
-    if (oldIndex != null) return oldIndex;
-
-    if (node is StringConstant) {
-      stringIndexer.put(node.value);
-    } else if (node is DoubleConstant) {
-      stringIndexer.put('${node.value}');
-    } else if (node is IntConstant) {
-      final int value = node.value;
+    if (constant is StringConstant) {
+      stringIndexer.put(constant.value);
+    } else if (constant is DoubleConstant) {
+      stringIndexer.put('${constant.value}');
+    } else if (constant is IntConstant) {
+      final int value = constant.value;
       if ((value.abs() >> 30) != 0) {
         stringIndexer.put('$value');
       }
     }
 
     final int newIndex = entries.length;
-    entries.add(node);
-    return index[node] = newIndex;
+    entries.add(constant);
+    return index[constant] = newIndex;
   }
 
-  visitMapConstant(MapConstant node) {
-    for (final ConstantMapEntry entry in node.entries) {
-      put(entry.key);
-      put(entry.value);
-    }
-    return defaultConstant(node);
-  }
-
-  visitListConstant(ListConstant node) {
-    for (final Constant entry in node.entries) {
-      put(entry);
-    }
-    return defaultConstant(node);
-  }
-
-  visitInstanceConstant(InstanceConstant node) {
-    for (final Constant entry in node.fieldValues.values) {
-      put(entry);
-    }
-    return defaultConstant(node);
+  defaultConstantReference(Constant node) {
+    put(node);
   }
 
   int operator [](Constant node) => index[node];
@@ -2095,34 +2059,24 @@
 
   void exit(List<TypeParameter> typeParameters) {
     stackHeight -= typeParameters.length;
+    typeParameters.forEach(index.remove);
   }
 
-  int operator [](TypeParameter parameter) => index[parameter];
-}
-
-class StringTableEntry {
-  final String value;
-  final List<int> utf8Bytes;
-
-  StringTableEntry(String value)
-      : value = value,
-        utf8Bytes = const Utf8Encoder().convert(value);
+  int operator [](TypeParameter parameter) =>
+      index[parameter] ?? (throw 'Type parameter $parameter is not indexed');
 }
 
 class StringIndexer {
-  final List<StringTableEntry> entries = <StringTableEntry>[];
-  final LinkedHashMap<String, int> index = new LinkedHashMap<String, int>();
+  // Note that the iteration order is important.
+  final Map<String, int> index = new Map<String, int>();
 
   StringIndexer() {
     put('');
   }
 
-  int get numberOfStrings => index.length;
-
   int put(String string) {
     var result = index[string];
     if (result == null) {
-      entries.add(new StringTableEntry(string));
       result = index.length;
       index[string] = result;
     }
@@ -2132,50 +2086,21 @@
   int operator [](String string) => index[string];
 }
 
-/// Computes and stores the index of a library, class, or member within its
-/// parent list.
-class GlobalIndexer extends TreeVisitor {
-  final Map<TreeNode, int> indices = <TreeNode, int>{};
+class UriIndexer {
+  // Note that the iteration order is important.
+  final Map<Uri, int> index = new Map<Uri, int>();
 
-  void buildIndexForContainer(TreeNode libraryOrClass) {
-    libraryOrClass.accept(this);
+  UriIndexer() {
+    put(null);
   }
 
-  void buildIndexForList(List<TreeNode> list) {
-    for (int i = 0; i < list.length; ++i) {
-      TreeNode child = list[i];
-      if (child != null) {
-        indices[child] = i;
-      }
+  int put(Uri uri) {
+    var result = index[uri];
+    if (result == null) {
+      result = index.length;
+      index[uri] = result;
     }
-  }
-
-  visitComponent(Component node) {
-    buildIndexForList(node.libraries);
-  }
-
-  visitLibrary(Library node) {
-    buildIndexForList(node.classes);
-    buildIndexForList(node.fields);
-    buildIndexForList(node.procedures);
-  }
-
-  visitClass(Class node) {
-    buildIndexForList(node.fields);
-    buildIndexForList(node.constructors);
-    buildIndexForList(node.procedures);
-  }
-
-  int operator [](TreeNode memberOrLibraryOrClass) {
-    var node = memberOrLibraryOrClass;
-    assert(node is Member || node is Library || node is Class);
-    int index = indices[node];
-    if (index == null) {
-      buildIndexForContainer(node.parent);
-      return indices[node];
-    } else {
-      return index;
-    }
+    return result;
   }
 }
 
@@ -2279,29 +2204,27 @@
 class _MetadataSubsection {
   final MetadataRepository<Object> repository;
 
-  /// Offsets of metadata payloads associated with the nodes.
-  final Map<Node, int> metadataOffsets;
-
   /// List of (nodeOffset, metadataOffset) pairs.
   /// Gradually filled by the writer as writing progresses, which by
   /// construction guarantees that pairs are sorted by first component
   /// (nodeOffset) in ascending order.
   final List<int> metadataMapping = <int>[];
 
-  /// Mapping between nodes that are referenced from inside metadata payloads
-  /// and their ids.
-  final Map<Node, int> nodeToReferenceId;
+  _MetadataSubsection(this.repository);
+}
 
-  /// Mapping between reference ids and offsets of referenced nodes.
-  /// Gradually filled by the writer as writing progresses but is not
-  /// guaranteed to be sorted.
-  final List<int> offsetsOfReferencedNodes;
+/// A [Sink] that directly writes data into a byte builder.
+// TODO(dartbug.com/28316): Remove this wrapper class.
+class BytesSink implements Sink<List<int>> {
+  final BytesBuilder builder = new BytesBuilder();
 
-  _MetadataSubsection(
-      this.repository, this.metadataOffsets, Map<Node, int> nodeToReferenceId)
-      : nodeToReferenceId =
-            nodeToReferenceId.isNotEmpty ? nodeToReferenceId : null,
-        offsetsOfReferencedNodes = nodeToReferenceId.isNotEmpty
-            ? new List<int>.filled(nodeToReferenceId.length, -1)
-            : null;
+  @override
+  void add(List<int> data) {
+    builder.add(data);
+  }
+
+  @override
+  void close() {
+    // Nothing to do.
+  }
 }
diff --git a/pkg/kernel/lib/binary/tag.dart b/pkg/kernel/lib/binary/tag.dart
index 877657f..1d016af 100644
--- a/pkg/kernel/lib/binary/tag.dart
+++ b/pkg/kernel/lib/binary/tag.dart
@@ -134,8 +134,8 @@
 
   /// Internal version of kernel binary format.
   /// Bump it when making incompatible changes in kernel binaries.
-  /// Keep in sync with runtime/vm/kernel_binary.h.
-  static const int BinaryFormatVersion = 5;
+  /// Keep in sync with runtime/vm/kernel_binary.h, pkg/kernel/binary.md.
+  static const int BinaryFormatVersion = 6;
 }
 
 abstract class ConstantTag {
diff --git a/pkg/kernel/lib/class_hierarchy.dart b/pkg/kernel/lib/class_hierarchy.dart
index be0c79a..3a9a036 100644
--- a/pkg/kernel/lib/class_hierarchy.dart
+++ b/pkg/kernel/lib/class_hierarchy.dart
@@ -3,10 +3,11 @@
 // BSD-style license that can be found in the LICENSE file.
 library kernel.class_hierarchy;
 
-import 'ast.dart';
-import 'dart:collection' show IterableBase;
+import 'dart:collection';
 import 'dart:math';
 import 'dart:typed_data';
+
+import 'ast.dart';
 import 'src/heap.dart';
 import 'type_algebra.dart';
 
@@ -17,16 +18,10 @@
 }
 
 /// Interface for answering various subclassing queries.
-/// TODO(scheglov) Several methods are not used, or used only in tests.
-/// Check if these methods are not useful and should be removed .
 abstract class ClassHierarchy {
   factory ClassHierarchy(Component component,
       {HandleAmbiguousSupertypes onAmbiguousSupertypes,
       MixinInferrer mixinInferrer}) {
-    int numberOfClasses = 0;
-    for (var library in component.libraries) {
-      numberOfClasses += library.classes.length;
-    }
     onAmbiguousSupertypes ??= (Class cls, Supertype a, Supertype b) {
       if (!cls.isSyntheticMixinImplementation) {
         // See https://github.com/dart-lang/sdk/issues/32091
@@ -34,33 +29,21 @@
       }
     };
     return new ClosedWorldClassHierarchy._internal(
-        component, numberOfClasses, onAmbiguousSupertypes)
-      .._initialize(mixinInferrer);
+        onAmbiguousSupertypes, mixinInferrer)
+      .._initialize(component.libraries);
   }
 
+  void set onAmbiguousSupertypes(
+      HandleAmbiguousSupertypes onAmbiguousSupertypes);
+
   /// 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.
   Iterable<Class> getOrderedClasses(Iterable<Class> unordered);
 
-  /// Returns the unique index of the [class_].
-  int getClassIndex(Class class_);
-
   /// True if the component contains another class that is a subtype of given one.
   bool hasProperSubtypes(Class class_);
 
-  /// Returns the number of steps in the longest inheritance path from [class_]
-  /// to [Object].
-  int getClassDepth(Class class_);
-
-  /// Returns a list of classes appropriate for use in calculating a least upper
-  /// bound.
-  ///
-  /// The returned list is a list of all classes that [class_] is a subtype of
-  /// (including itself), sorted first by depth (deepest first) and then by
-  /// class index.
-  List<Class> getRankedSuperclasses(Class class_);
-
   /// Returns the least upper bound of two interface types, as defined by Dart
   /// 1.0.
   ///
@@ -119,12 +102,6 @@
   /// The returned list should not be modified.
   List<Member> getDispatchTargets(Class class_, {bool setters: false});
 
-  /// Returns the single concrete target for invocation of the given interface
-  /// target, or `null` if it could not be resolved or there are multiple
-  /// possible targets.
-  Member getSingleTargetForInterfaceInvocation(Member interfaceTarget,
-      {bool setter: false});
-
   /// Returns the possibly abstract interface member of [class_] with the given
   /// [name].
   ///
@@ -153,20 +130,10 @@
   /// classes.
   List<Member> getDeclaredMembers(Class class_, {bool setters: false});
 
-  /// Returns the subclasses of [class_] as an interval list.
-  ClassSet getSubclassesOf(Class class_);
-
-  /// Returns the subtypes of [class_] as an interval list.
-  ClassSet getSubtypesOf(Class class_);
-
   /// True if [subclass] inherits from [superclass] though zero or more
   /// `extends` relationships.
   bool isSubclassOf(Class subclass, Class superclass);
 
-  /// True if [submixture] inherits from [superclass] though zero or more
-  /// `extends` and `with` relationships.
-  bool isSubmixtureOf(Class submixture, Class superclass);
-
   /// True if [subtype] inherits from [superclass] though zero or more
   /// `extends`, `with`, and `implements` relationships.
   bool isSubtypeOf(Class subtype, Class superclass);
@@ -175,12 +142,6 @@
   /// mixin application (i.e. [Class.mixedInType]).
   bool isUsedAsMixin(Class class_);
 
-  /// True if the given class is the direct super class of another class.
-  bool isUsedAsSuperClass(Class class_);
-
-  /// True if the given class is used in an `implements` clause.
-  bool isUsedAsSuperInterface(Class class_);
-
   /// Invokes [callback] for every member declared in or inherited by [class_]
   /// that overrides or implements a member in a supertype of [class_]
   /// (or in rare cases, overrides a member declared in [class_]).
@@ -211,11 +172,27 @@
   void forEachOverridePair(Class class_,
       callback(Member declaredMember, Member interfaceMember, bool isSetter));
 
-  /// This method is invoked by the client after it changed the [classes], and
-  /// some of the information that this hierarchy might have cached, is not
-  /// valid anymore. The hierarchy may perform required updates and return the
-  /// same instance, or return a new instance.
-  ClassHierarchy applyChanges(Iterable<Class> classes);
+  /// This method is invoked by the client after a change: removal, addition,
+  /// or modification of classes.
+  ///
+  /// For modified classes specify a class as both removed and added: Some of
+  /// the information that this hierarchy might have cached, is not valid
+  /// anymore.
+  ///
+  /// Note, that it is the clients responsibility to mark all subclasses as
+  /// changed too.
+  ClassHierarchy applyTreeChanges(
+      Iterable<Class> removedClasses, Iterable<Class> addedClasses,
+      {Component reissueAmbiguousSupertypesFor});
+
+  /// This method is invoked by the client after a member change on classes:
+  /// Some of the information that this hierarchy might have cached,
+  /// is not valid anymore.
+  /// Note, that it is the clients responsibility to mark all subclasses as
+  /// changed too, or - if [findDescendants] is true, the ClassHierarchy will
+  /// spend the time to find them for the caller.
+  ClassHierarchy applyMemberChanges(Iterable<Class> classes,
+      {bool findDescendants: false});
 
   /// Merges two sorted lists.
   ///
@@ -328,35 +305,160 @@
   }
 }
 
-/// Implementation of [ClassHierarchy] for closed world.
-class ClosedWorldClassHierarchy implements ClassHierarchy {
-  final HandleAmbiguousSupertypes _onAmbiguousSupertypes;
+abstract class ClassHierarchySubtypes {
+  /// Returns the subtypes of [class_] as an interval list.
+  ClassSet getSubtypesOf(Class class_);
 
-  /// The [Component] that this class hierarchy represents.
-  final Component _component;
+  /// Returns the single concrete target for invocation of the given interface
+  /// target, or `null` if it could not be resolved or there are multiple
+  /// possible targets.
+  Member getSingleTargetForInterfaceInvocation(Member interfaceTarget,
+      {bool setter: false});
+}
 
-  /// All classes in the component.
-  ///
-  /// The list is ordered so that classes occur after their super classes.
-  final List<Class> classes;
+class _ClassInfoSubtype {
+  final _ClassInfo classInfo;
+  int topDownIndex = -1;
 
-  final Map<Class, _ClassInfo> _infoFor = <Class, _ClassInfo>{};
+  /// Top-down indices of all subclasses of this class, represented as
+  /// interleaved begin/end interval end points.
+  Uint32List subtypeIntervalList;
 
-  /// All classes ordered by [_ClassInfo.topDownIndex].
+  _ClassInfoSubtype(this.classInfo);
+}
+
+class _ClosedWorldClassHierarchySubtypes implements ClassHierarchySubtypes {
+  final ClosedWorldClassHierarchy hierarchy;
   final List<Class> _classesByTopDownIndex;
+  final Map<Class, _ClassInfoSubtype> _infoFor = <Class, _ClassInfoSubtype>{};
+  bool invalidated = false;
 
-  ClosedWorldClassHierarchy._internal(
-      this._component, int numberOfClasses, this._onAmbiguousSupertypes)
-      : classes = new List<Class>(numberOfClasses),
-        _classesByTopDownIndex = new List<Class>(numberOfClasses);
+  _ClosedWorldClassHierarchySubtypes(this.hierarchy)
+      : _classesByTopDownIndex = new List<Class>(hierarchy._infoFor.length) {
+    if (hierarchy._infoFor.isNotEmpty) {
+      for (Class class_ in hierarchy._infoFor.keys) {
+        _infoFor[class_] = new _ClassInfoSubtype(hierarchy._infoFor[class_]);
+      }
+
+      _topDownSortVisit(_infoFor[hierarchy._infoFor.keys.first]);
+    }
+  }
+
+  /// Downwards traversal of the class hierarchy that orders classes so local
+  /// hierarchies have contiguous indices.
+  int _topDownSortIndex = 0;
+  void _topDownSortVisit(_ClassInfoSubtype subInfo) {
+    if (subInfo.topDownIndex != -1) return;
+    int index = _topDownSortIndex++;
+    subInfo.topDownIndex = index;
+    _classesByTopDownIndex[index] = subInfo.classInfo.classNode;
+    var subtypeSetBuilder = new _IntervalListBuilder()..addSingleton(index);
+    for (_ClassInfo subtype in subInfo.classInfo.directExtenders) {
+      _ClassInfoSubtype subtypeInfo = _infoFor[subtype.classNode];
+      _topDownSortVisit(subtypeInfo);
+      subtypeSetBuilder.addIntervalList(subtypeInfo.subtypeIntervalList);
+    }
+    for (_ClassInfo subtype in subInfo.classInfo.directMixers) {
+      _ClassInfoSubtype subtypeInfo = _infoFor[subtype.classNode];
+      _topDownSortVisit(subtypeInfo);
+      subtypeSetBuilder.addIntervalList(subtypeInfo.subtypeIntervalList);
+    }
+    for (_ClassInfo subtype in subInfo.classInfo.directImplementers) {
+      _ClassInfoSubtype subtypeInfo = _infoFor[subtype.classNode];
+      _topDownSortVisit(subtypeInfo);
+      subtypeSetBuilder.addIntervalList(subtypeInfo.subtypeIntervalList);
+    }
+    subInfo.subtypeIntervalList = subtypeSetBuilder.buildIntervalList();
+  }
 
   @override
-  int getClassIndex(Class class_) => _infoFor[class_].topologicalIndex;
+  Member getSingleTargetForInterfaceInvocation(Member interfaceTarget,
+      {bool setter: false}) {
+    if (invalidated) throw "This datastructure has been invalidated";
+    Name name = interfaceTarget.name;
+    Member target = null;
+    ClassSet subtypes = getSubtypesOf(interfaceTarget.enclosingClass);
+    for (Class c in subtypes) {
+      if (!c.isAbstract) {
+        Member candidate = hierarchy.getDispatchTarget(c, name, setter: setter);
+        if ((candidate != null) && !candidate.isAbstract) {
+          if (target == null) {
+            target = candidate;
+          } else if (target != candidate) {
+            return null;
+          }
+        }
+      }
+    }
+    return target;
+  }
+
+  @override
+  ClassSet getSubtypesOf(Class class_) {
+    if (invalidated) throw "This datastructure has been invalidated";
+    Set<Class> result = new Set<Class>();
+    Uint32List list = _infoFor[class_].subtypeIntervalList;
+    for (int i = 0; i < list.length; i += 2) {
+      int from = list[i];
+      int to = list[i + 1];
+      for (int j = from; j < to; j++) {
+        result.add(_classesByTopDownIndex[j]);
+      }
+    }
+    return new ClassSet(result);
+  }
+}
+
+/// Implementation of [ClassHierarchy] for closed world.
+class ClosedWorldClassHierarchy implements ClassHierarchy {
+  HandleAmbiguousSupertypes _onAmbiguousSupertypes;
+  HandleAmbiguousSupertypes _onAmbiguousSupertypesNotWrapped;
+  MixinInferrer mixinInferrer;
+
+  void set onAmbiguousSupertypes(
+      HandleAmbiguousSupertypes onAmbiguousSupertypes) {
+    _onAmbiguousSupertypesNotWrapped = onAmbiguousSupertypes;
+    _onAmbiguousSupertypes = (Class class_, Supertype a, Supertype b) {
+      onAmbiguousSupertypes(class_, a, b);
+      List<Supertype> recorded = _recordedAmbiguousSupertypes[class_];
+      if (recorded == null) {
+        recorded = new List<Supertype>();
+        _recordedAmbiguousSupertypes[class_] = recorded;
+      }
+      recorded.add(a);
+      recorded.add(b);
+    };
+  }
+
+  /// The insert order is important.
+  final Map<Class, _ClassInfo> _infoFor =
+      new LinkedHashMap<Class, _ClassInfo>();
+
+  /// Recorded errors for classes we have already calculated the class hierarchy
+  /// for, but will have to be reissued when re-using the calculation.
+  final Map<Class, List<Supertype>> _recordedAmbiguousSupertypes =
+      new LinkedHashMap<Class, List<Supertype>>();
+
+  Iterable<Class> get classes => _infoFor.keys;
+  int get numberOfClasses => _infoFor.length;
+
+  _ClosedWorldClassHierarchySubtypes _cachedClassHierarchySubtypes;
+
+  ClosedWorldClassHierarchy._internal(
+      HandleAmbiguousSupertypes onAmbiguousSupertypes, this.mixinInferrer) {
+    this.onAmbiguousSupertypes = onAmbiguousSupertypes;
+  }
+
+  ClassHierarchySubtypes computeSubtypesInformation() {
+    _cachedClassHierarchySubtypes ??=
+        new _ClosedWorldClassHierarchySubtypes(this);
+    return _cachedClassHierarchySubtypes;
+  }
 
   @override
   Iterable<Class> getOrderedClasses(Iterable<Class> unordered) {
     var unorderedSet = unordered.toSet();
-    return classes.where(unorderedSet.contains);
+    return _infoFor.keys.where(unorderedSet.contains);
   }
 
   @override
@@ -366,42 +468,16 @@
   }
 
   @override
-  bool isSubmixtureOf(Class submixture, Class superclass) {
-    if (identical(submixture, superclass)) return true;
-    return _infoFor[submixture].isSubmixtureOf(_infoFor[superclass]);
-  }
-
-  @override
   bool isSubtypeOf(Class subtype, Class superclass) {
     if (identical(subtype, superclass)) return true;
     return _infoFor[subtype].isSubtypeOf(_infoFor[superclass]);
   }
 
   @override
-  bool isUsedAsSuperClass(Class class_) {
-    return _infoFor[class_].directExtenders.isNotEmpty;
-  }
-
-  @override
   bool isUsedAsMixin(Class class_) {
     return _infoFor[class_].directMixers.isNotEmpty;
   }
 
-  @override
-  bool isUsedAsSuperInterface(Class class_) {
-    return _infoFor[class_].directImplementers.isNotEmpty;
-  }
-
-  @override
-  int getClassDepth(Class class_) => _infoFor[class_].depth;
-
-  @override
-  List<Class> getRankedSuperclasses(Class class_) {
-    return _getRankedSuperclassInfos(_infoFor[class_])
-        .map((info) => info.classNode)
-        .toList();
-  }
-
   List<_ClassInfo> _getRankedSuperclassInfos(_ClassInfo info) {
     if (info.leastUpperBoundInfos != null) return info.leastUpperBoundInfos;
     var heap = new _LubHeap()..add(info);
@@ -561,27 +637,6 @@
   }
 
   @override
-  Member getSingleTargetForInterfaceInvocation(Member interfaceTarget,
-      {bool setter: false}) {
-    Name name = interfaceTarget.name;
-    Member target = null;
-    ClassSet subtypes = getSubtypesOf(interfaceTarget.enclosingClass);
-    for (Class c in subtypes) {
-      if (!c.isAbstract) {
-        Member candidate = getDispatchTarget(c, name, setter: setter);
-        if ((candidate != null) && !candidate.isAbstract) {
-          if (target == null) {
-            target = candidate;
-          } else if (target != candidate) {
-            return null;
-          }
-        }
-      }
-    }
-    return target;
-  }
-
-  @override
   Member getInterfaceMember(Class class_, Name name, {bool setter: false}) {
     List<Member> list = getInterfaceMembers(class_, setters: setter);
     return ClassHierarchy.findMemberByName(list, name);
@@ -663,25 +718,111 @@
 
   @override
   bool hasProperSubtypes(Class class_) {
-    // If there are no subtypes then the subtype set contains the class itself.
-    return !getSubtypesOf(class_).isSingleton;
+    _ClassInfo info = _infoFor[class_];
+    return info.directExtenders.isNotEmpty ||
+        info.directImplementers.isNotEmpty ||
+        info.directMixers.isNotEmpty;
   }
 
   @override
-  ClassSet getSubtypesOf(Class class_) {
-    return new ClassSet(this, _infoFor[class_].subtypeIntervalList);
+  ClassHierarchy applyTreeChanges(
+      Iterable<Class> removedClasses, Iterable<Class> addedClasses,
+      {Component reissueAmbiguousSupertypesFor}) {
+    // Remove all references to the removed classes.
+    for (Class class_ in removedClasses) {
+      _ClassInfo info = _infoFor[class_];
+      if (class_.supertype != null) {
+        _infoFor[class_.supertype.classNode]?.directExtenders?.remove(info);
+      }
+      if (class_.mixedInType != null) {
+        _infoFor[class_.mixedInType.classNode]?.directMixers?.remove(info);
+      }
+      for (var supertype in class_.implementedTypes) {
+        _infoFor[supertype.classNode]?.directImplementers?.remove(info);
+      }
+
+      _infoFor.remove(class_);
+      _recordedAmbiguousSupertypes.remove(class_);
+    }
+
+    // If we have a cached computation of subtypes, invalidate it and stop
+    // caching it.
+    if (_cachedClassHierarchySubtypes != null) {
+      _cachedClassHierarchySubtypes.invalidated = true;
+    }
+
+    if (_recordedAmbiguousSupertypes.isNotEmpty &&
+        reissueAmbiguousSupertypesFor != null) {
+      Set<Library> libs =
+          new Set<Library>.from(reissueAmbiguousSupertypesFor.libraries);
+      for (Class class_ in _recordedAmbiguousSupertypes.keys) {
+        if (!libs.contains(class_.enclosingLibrary)) continue;
+        List<Supertype> recorded = _recordedAmbiguousSupertypes[class_];
+        for (int i = 0; i < recorded.length; i += 2) {
+          _onAmbiguousSupertypesNotWrapped(
+              class_, recorded[i], recorded[i + 1]);
+        }
+      }
+    }
+
+    // Add the new classes.
+    List<Class> addedClassesSorted = new List<Class>();
+    int expectedStartIndex = _topSortIndex;
+    for (Class class_ in addedClasses) {
+      _topologicalSortVisit(class_, new Set<Class>(),
+          orderedList: addedClassesSorted);
+    }
+    _initializeTopologicallySortedClasses(
+        addedClassesSorted, expectedStartIndex);
+
+    return this;
   }
 
   @override
-  ClassSet getSubclassesOf(Class class_) {
-    return new ClassSet(this, _infoFor[class_].subclassIntervalList);
-  }
-
-  @override
-  ClassHierarchy applyChanges(Iterable<Class> classes) {
+  ClassHierarchy applyMemberChanges(Iterable<Class> classes,
+      {bool findDescendants: false}) {
     if (classes.isEmpty) return this;
-    return new ClassHierarchy(_component,
-        onAmbiguousSupertypes: _onAmbiguousSupertypes);
+
+    List<_ClassInfo> infos = new List<_ClassInfo>();
+    if (findDescendants) {
+      Set<_ClassInfo> processedClasses = new Set<_ClassInfo>();
+      List<_ClassInfo> worklist = <_ClassInfo>[];
+      for (Class class_ in classes) {
+        _ClassInfo info = _infoFor[class_];
+        worklist.add(info);
+      }
+
+      while (worklist.isNotEmpty) {
+        _ClassInfo info = worklist.removeLast();
+        if (processedClasses.add(info)) {
+          worklist.addAll(info.directExtenders);
+          worklist.addAll(info.directImplementers);
+          worklist.addAll(info.directMixers);
+        }
+      }
+      infos.addAll(processedClasses);
+    } else {
+      for (Class class_ in classes) {
+        _ClassInfo info = _infoFor[class_];
+        infos.add(info);
+      }
+    }
+
+    infos.sort((_ClassInfo a, _ClassInfo b) {
+      return a.topologicalIndex - b.topologicalIndex;
+    });
+
+    for (_ClassInfo info in infos) {
+      Class class_ = info.classNode;
+      _buildDeclaredMembers(class_, info);
+      _buildImplementedMembers(class_, info);
+      info.interfaceSetters = null;
+      info.interfaceGettersAndCalls = null;
+      _buildInterfaceMembers(class_, info, setters: true);
+      _buildInterfaceMembers(class_, info, setters: false);
+    }
+
+    return this;
   }
 
   @override
@@ -698,19 +839,29 @@
     return map == null ? null : map[superclass]?.first;
   }
 
-  void _initialize(MixinInferrer mixinInferrer) {
+  void _initialize(List<Library> libraries) {
     // Build the class ordering based on a topological sort.
-    for (var library in _component.libraries) {
+    for (var library in libraries) {
       for (var classNode in library.classes) {
-        _topologicalSortVisit(classNode);
+        _topologicalSortVisit(classNode, new Set<Class>());
       }
     }
 
-    // Build index of direct children.  Do this after the topological sort so
-    // that super types always occur before subtypes.
-    for (int i = 0; i < classes.length; ++i) {
-      var class_ = classes[i];
-      var info = _infoFor[class_];
+    _initializeTopologicallySortedClasses(_infoFor.keys, 0);
+  }
+
+  /// - Build index of direct children.
+  /// - Build list of super classes and super types.
+  /// - Infer and record supertypes for the classes.
+  /// - Record interface members.
+  /// - Perform some sanity checking.
+  /// Do this after the topological sort so that super types always occur
+  /// before subtypes.
+  void _initializeTopologicallySortedClasses(
+      Iterable<Class> classes, int expectedStartingTopologicalIndex) {
+    int i = expectedStartingTopologicalIndex;
+    for (Class class_ in classes) {
+      _ClassInfo info = _infoFor[class_];
       if (class_.supertype != null) {
         _infoFor[class_.supertype.classNode].directExtenders.add(info);
       }
@@ -720,53 +871,30 @@
       for (var supertype in class_.implementedTypes) {
         _infoFor[supertype.classNode].directImplementers.add(info);
       }
-    }
+      _collectSupersForClass(class_);
 
-    // Run a downward traversal from the root, compute preorder numbers for
-    // each class, and build their subtype sets as interval lists.
-    if (classes.isNotEmpty) {
-      _topDownSortVisit(_infoFor[classes[0]]);
-    }
-
-    // Now that the intervals for subclass, mixer, and implementer queries are
-    // built, we may infer and record supertypes for the classes.
-    for (int i = 0; i < classes.length; ++i) {
-      Class classNode = classes[i];
-      _ClassInfo info = _infoFor[classNode];
-      if (classNode.supertype != null) {
-        _recordSuperTypes(info, classNode.supertype);
+      if (class_.supertype != null) {
+        _recordSuperTypes(info, class_.supertype);
       }
-      if (classNode.mixedInType != null) {
-        mixinInferrer?.infer(this, classNode);
-        _recordSuperTypes(info, classNode.mixedInType);
+      if (class_.mixedInType != null) {
+        mixinInferrer?.infer(this, class_);
+        _recordSuperTypes(info, class_.mixedInType);
       }
-      for (Supertype supertype in classNode.implementedTypes) {
+      for (Supertype supertype in class_.implementedTypes) {
         _recordSuperTypes(info, supertype);
       }
-    }
 
-    for (int i = 0; i < classes.length; ++i) {
-      var class_ = classes[i];
-      _buildInterfaceMembers(class_, _infoFor[class_], setters: true);
-      _buildInterfaceMembers(class_, _infoFor[class_], setters: false);
-    }
+      _buildInterfaceMembers(class_, info, setters: true);
+      _buildInterfaceMembers(class_, info, setters: false);
 
-    for (int i = 0; i < classes.length; ++i) {
-      Class cls = classes[i];
-      if (cls == null) {
-        throw "No class at index $i.";
-      }
-      _ClassInfo info = _infoFor[cls];
       if (info == null) {
-        throw "No info for ${cls.name} from ${cls.fileUri}.";
+        throw "No info for ${class_.name} from ${class_.fileUri}.";
       }
       if (info.topologicalIndex != i) {
         throw "Unexpected topologicalIndex (${info.topologicalIndex} != $i) "
-            "for ${cls.name} from ${cls.fileUri}.";
+            "for ${class_.name} from ${class_.fileUri}.";
       }
-      if (info.subtypeIntervalList == null) {
-        throw "No subtypeIntervalList for ${cls.name} from ${cls.fileUri}.";
-      }
+      i++;
     }
   }
 
@@ -776,34 +904,45 @@
   /// Returns the depth of the visited class (the number of steps in the longest
   /// inheritance path to the root class).
   int _topSortIndex = 0;
-  int _topologicalSortVisit(Class classNode) {
+  int _topologicalSortVisit(Class classNode, Set<Class> beingVisited,
+      {List<Class> orderedList}) {
     var info = _infoFor[classNode];
     if (info != null) {
-      if (info.isBeingVisited) {
-        throw 'Cyclic inheritance involving ${info.classNode.name}';
-      }
-      return info.depth; // Already built.
+      return info.depth;
     }
+
+    if (!beingVisited.add(classNode)) {
+      throw 'Cyclic inheritance involving ${classNode.name}';
+    }
+
+    info = new _ClassInfo(classNode);
+
     int superDepth = -1;
-    _infoFor[classNode] = info = new _ClassInfo(classNode);
-    info.isBeingVisited = true;
     if (classNode.supertype != null) {
-      superDepth =
-          max(superDepth, _topologicalSortVisit(classNode.supertype.classNode));
+      superDepth = max(
+          superDepth,
+          _topologicalSortVisit(classNode.supertype.classNode, beingVisited,
+              orderedList: orderedList));
     }
     if (classNode.mixedInType != null) {
       superDepth = max(
-          superDepth, _topologicalSortVisit(classNode.mixedInType.classNode));
+          superDepth,
+          _topologicalSortVisit(classNode.mixedInType.classNode, beingVisited,
+              orderedList: orderedList));
     }
     for (var supertype in classNode.implementedTypes) {
-      superDepth = max(superDepth, _topologicalSortVisit(supertype.classNode));
+      superDepth = max(
+          superDepth,
+          _topologicalSortVisit(supertype.classNode, beingVisited,
+              orderedList: orderedList));
     }
     _buildDeclaredMembers(classNode, info);
     _buildImplementedMembers(classNode, info);
-    int id = _topSortIndex++;
-    info.topologicalIndex = id;
-    classes[id] = info.classNode;
-    info.isBeingVisited = false;
+    info.topologicalIndex = _topSortIndex++;
+
+    _infoFor[classNode] = info;
+    orderedList?.add(classNode);
+    beingVisited.remove(classNode);
     return info.depth = superDepth + 1;
   }
 
@@ -1004,54 +1143,49 @@
     }
   }
 
-  /// Downwards traversal of the class hierarchy that orders classes so local
-  /// hierarchies have contiguous indices.
-  int _topDownSortIndex = 0;
-  void _topDownSortVisit(_ClassInfo info) {
-    if (info.topDownIndex != -1) return;
-    bool isMixedIn = info.directMixers.isNotEmpty;
-    int index = _topDownSortIndex++;
-    info.topDownIndex = index;
-    _classesByTopDownIndex[index] = info.classNode;
-    var subclassSetBuilder = new _IntervalListBuilder()..addSingleton(index);
-    var submixtureSetBuilder =
-        isMixedIn ? (new _IntervalListBuilder()..addSingleton(index)) : null;
-    var subtypeSetBuilder = new _IntervalListBuilder()..addSingleton(index);
-    for (var subtype in info.directExtenders) {
-      _topDownSortVisit(subtype);
-      subclassSetBuilder.addIntervalList(subtype.subclassIntervalList);
-      submixtureSetBuilder?.addIntervalList(subtype.submixtureIntervalList);
-      subtypeSetBuilder.addIntervalList(subtype.subtypeIntervalList);
+  /// Build lists of super types and super classes.
+  /// Note that the super class and super types of the class must already have
+  /// had their supers collected.
+  void _collectSupersForClass(Class class_) {
+    _ClassInfo info = _infoFor[class_];
+
+    var superclassSetBuilder = new _IntervalListBuilder()
+      ..addSingleton(info.topologicalIndex);
+    var supertypeSetBuilder = new _IntervalListBuilder()
+      ..addSingleton(info.topologicalIndex);
+
+    if (class_.supertype != null) {
+      _ClassInfo supertypeInfo = _infoFor[class_.supertype.classNode];
+      superclassSetBuilder
+          .addIntervalList(supertypeInfo.superclassIntervalList);
+      supertypeSetBuilder.addIntervalList(supertypeInfo.supertypeIntervalList);
     }
-    for (var subtype in info.directMixers) {
-      _topDownSortVisit(subtype);
-      submixtureSetBuilder.addIntervalList(subtype.submixtureIntervalList);
-      subtypeSetBuilder.addIntervalList(subtype.subtypeIntervalList);
+
+    if (class_.mixedInType != null) {
+      _ClassInfo mixedInTypeInfo = _infoFor[class_.mixedInType.classNode];
+      supertypeSetBuilder
+          .addIntervalList(mixedInTypeInfo.supertypeIntervalList);
     }
-    for (var subtype in info.directImplementers) {
-      _topDownSortVisit(subtype);
-      subtypeSetBuilder.addIntervalList(subtype.subtypeIntervalList);
+
+    for (Supertype supertype in class_.implementedTypes) {
+      _ClassInfo supertypeInfo = _infoFor[supertype.classNode];
+      supertypeSetBuilder.addIntervalList(supertypeInfo.supertypeIntervalList);
     }
-    info.subclassIntervalList = subclassSetBuilder.buildIntervalList();
-    info.submixtureIntervalList = isMixedIn
-        ? submixtureSetBuilder.buildIntervalList()
-        : info.subclassIntervalList;
-    info.subtypeIntervalList = subtypeSetBuilder.buildIntervalList();
+
+    info.superclassIntervalList = superclassSetBuilder.buildIntervalList();
+    info.supertypeIntervalList = supertypeSetBuilder.buildIntervalList();
   }
 
   /// Creates a histogram such that index `N` contains the number of classes
-  /// that have `N` intervals in its subclass or subtype set (whichever is
-  /// larger).
+  /// that have `N` intervals in its supertype set.
   ///
   /// The more numbers are condensed near the beginning, the more efficient the
   /// internal data structure is.
   List<int> getExpenseHistogram() {
     var result = <int>[];
-    for (Class class_ in classes) {
+    for (Class class_ in _infoFor.keys) {
       var info = _infoFor[class_];
-      int intervals = max(info.subclassIntervalList.length,
-              info.subtypeIntervalList.length) ~/
-          2;
+      int intervals = info.supertypeIntervalList.length ~/ 2;
       if (intervals >= result.length) {
         int oldLength = result.length;
         result.length = intervals + 1;
@@ -1062,29 +1196,30 @@
     return result;
   }
 
-  /// Returns the average number of intervals per subtype relation (less
+  /// Returns the average number of intervals per supertype relation (less
   /// is better, 1.0 is bad).
   ///
   /// This is an estimate of the memory use compared to a data structure that
-  /// enumerates all subclass/subtype pairs.
+  /// enumerates all superclass/supertype pairs.
   double getCompressionRatio() {
     int intervals = 0;
     int sizes = 0;
-    for (Class class_ in classes) {
+    for (Class class_ in _infoFor.keys) {
       var info = _infoFor[class_];
-      intervals += (info.subclassIntervalList.length +
-              info.subtypeIntervalList.length) ~/
+      intervals += (info.superclassIntervalList.length +
+              info.supertypeIntervalList.length) ~/
           2;
-      sizes += _intervalListSize(info.subclassIntervalList) +
-          _intervalListSize(info.subtypeIntervalList);
+      sizes += _intervalListSize(info.superclassIntervalList) +
+          _intervalListSize(info.supertypeIntervalList);
     }
+
     return sizes == 0 ? 1.0 : intervals / sizes;
   }
 
   /// Returns the number of entries in hash tables storing hierarchy data.
   int getSuperTypeHashTableSize() {
     int sum = 0;
-    for (Class class_ in classes) {
+    for (Class class_ in _infoFor.keys) {
       sum += _infoFor[class_].genericSuperTypes?.length ?? 0;
     }
     return sum;
@@ -1179,8 +1314,6 @@
 class _ClassInfo {
   final Class classNode;
   int topologicalIndex = 0;
-  int topDownIndex = -1;
-  bool isBeingVisited = false;
   int depth = 0;
 
   // Super types must always occur before subtypes in these lists.
@@ -1191,30 +1324,15 @@
   //
   // Here `A` must occur before `B` in the list of direct extenders of Object,
   // because `B` is a subtype of `A`.
-  final List<_ClassInfo> directExtenders = <_ClassInfo>[];
-  final List<_ClassInfo> directMixers = <_ClassInfo>[];
-  final List<_ClassInfo> directImplementers = <_ClassInfo>[];
+  final Set<_ClassInfo> directExtenders = new LinkedHashSet<_ClassInfo>();
+  final Set<_ClassInfo> directMixers = new LinkedHashSet<_ClassInfo>();
+  final Set<_ClassInfo> directImplementers = new LinkedHashSet<_ClassInfo>();
 
-  /// Top-down indices of all subclasses of this class, represented as
-  /// interleaved begin/end interval end points.
-  Uint32List subclassIntervalList;
-  Uint32List submixtureIntervalList;
-  Uint32List subtypeIntervalList;
+  Uint32List superclassIntervalList;
+  Uint32List supertypeIntervalList;
 
   List<_ClassInfo> leastUpperBoundInfos;
 
-  bool isSubclassOf(_ClassInfo other) {
-    return _intervalListContains(other.subclassIntervalList, topDownIndex);
-  }
-
-  bool isSubmixtureOf(_ClassInfo other) {
-    return _intervalListContains(other.submixtureIntervalList, topDownIndex);
-  }
-
-  bool isSubtypeOf(_ClassInfo other) {
-    return _intervalListContains(other.subtypeIntervalList, topDownIndex);
-  }
-
   /// Maps generic supertype classes to the instantiation implemented by this
   /// class.
   ///
@@ -1243,6 +1361,15 @@
 
   _ClassInfo(this.classNode);
 
+  bool isSubclassOf(_ClassInfo other) {
+    return _intervalListContains(
+        superclassIntervalList, other.topologicalIndex);
+  }
+
+  bool isSubtypeOf(_ClassInfo other) {
+    return _intervalListContains(supertypeIntervalList, other.topologicalIndex);
+  }
+
   void recordGenericSuperType(Class cls, Supertype type,
       HandleAmbiguousSupertypes onAmbiguousSupertypes) {
     List<Supertype> existing = genericSuperTypes[cls];
@@ -1255,79 +1382,23 @@
   }
 }
 
-/// An immutable set of classes, internally represented as an interval list.
+/// An immutable set of classes.
 class ClassSet extends IterableBase<Class> {
-  final ClosedWorldClassHierarchy _hierarchy;
-  final Uint32List _intervalList;
+  final Set<Class> _classes;
+  ClassSet(this._classes);
 
-  ClassSet(this._hierarchy, this._intervalList);
-
-  bool get isEmpty => _intervalList.isEmpty;
-
-  bool get isSingleton {
-    var list = _intervalList;
-    return list.length == 2 && list[0] + 1 == list[1];
-  }
-
-  @override
   bool contains(Object class_) {
-    return _intervalListContains(
-        _intervalList, _hierarchy._infoFor[class_ as Class].topDownIndex);
+    return _classes.contains(_classes);
   }
 
   ClassSet union(ClassSet other) {
-    assert(_hierarchy == other._hierarchy);
-    if (identical(_intervalList, other._intervalList)) return this;
-    _IntervalListBuilder builder = new _IntervalListBuilder();
-    builder.addIntervalList(_intervalList);
-    builder.addIntervalList(other._intervalList);
-    return new ClassSet(_hierarchy, builder.buildIntervalList());
+    Set<Class> result = new Set<Class>.from(_classes);
+    result.addAll(other._classes);
+    return new ClassSet(result);
   }
 
   @override
-  Iterator<Class> get iterator =>
-      new _ClassSetIterator(_hierarchy, _intervalList);
-}
-
-/// Iterator for [ClassSet].
-class _ClassSetIterator implements Iterator<Class> {
-  final ClosedWorldClassHierarchy _hierarchy;
-  final Uint32List _intervalList;
-  int _intervalIndex;
-  int _classIndex;
-  int _classIndexLimit;
-
-  // Interval list is a list of pairs (start, end).
-  static const int _intervalIndexStep = 2;
-
-  _ClassSetIterator(this._hierarchy, this._intervalList)
-      : _intervalIndex = -_intervalIndexStep,
-        _classIndex = -1,
-        _classIndexLimit = -1;
-
-  @override
-  bool moveNext() {
-    if (_classIndex + 1 < _classIndexLimit) {
-      _classIndex++;
-      return true;
-    }
-
-    if (_intervalIndex + _intervalIndexStep < _intervalList.length) {
-      _intervalIndex += _intervalIndexStep;
-      _classIndex = _intervalList[_intervalIndex];
-      _classIndexLimit = _intervalList[_intervalIndex + 1];
-      assert(_classIndex < _classIndexLimit);
-      return true;
-    }
-
-    _classIndex = _classIndexLimit = -1;
-    return false;
-  }
-
-  @override
-  Class get current => (_classIndex >= 0)
-      ? _hierarchy._classesByTopDownIndex[_classIndex]
-      : null;
+  Iterator<Class> get iterator => _classes.iterator;
 }
 
 /// Heap for use in computing least upper bounds.
diff --git a/pkg/kernel/lib/core_types.dart b/pkg/kernel/lib/core_types.dart
index c781398..e0fe377 100644
--- a/pkg/kernel/lib/core_types.dart
+++ b/pkg/kernel/lib/core_types.dart
@@ -62,6 +62,7 @@
   Class _noSuchMethodErrorClass;
   Constructor _noSuchMethodErrorDefaultConstructor;
   Procedure _listFromConstructor;
+  Procedure _listUnmodifiableConstructor;
   Procedure _printProcedure;
   Procedure _identicalProcedure;
   Constructor _constantExpressionErrorDefaultConstructor;
@@ -272,6 +273,11 @@
         index.getMember('dart:core', 'List', 'from');
   }
 
+  Procedure get listUnmodifiableConstructor {
+    return _listUnmodifiableConstructor ??=
+        index.getMember('dart:core', 'List', 'unmodifiable');
+  }
+
   Class get mapClass {
     return _mapClass ??= index.getClass('dart:core', 'Map');
   }
diff --git a/pkg/kernel/lib/frontend/accessors.dart b/pkg/kernel/lib/frontend/accessors.dart
deleted file mode 100644
index e132d55..0000000
--- a/pkg/kernel/lib/frontend/accessors.dart
+++ /dev/null
@@ -1,510 +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.
-
-/// A library to help transform compounds and null-aware accessors into
-/// let expressions.
-library kernel.frontend.accessors;
-
-import '../ast.dart';
-
-final Name indexGetName = new Name("[]");
-
-final Name indexSetName = new Name("[]=");
-
-/// An [Accessor] represents a subexpression for which we can't yet build a
-/// kernel [Expression] because we don't yet know the context in which it is
-/// used.
-///
-/// Once the context is known, an [Accessor] can be converted into an
-/// [Expression] by calling a "build" method.
-///
-/// For example, when building a kernel representation for `a[x] = b`, after
-/// parsing `a[x]` but before parsing `= b`, we don't yet know whether to
-/// generate an invocation of `operator[]` or `operator[]=`, so we generate an
-/// [Accessor] object.  Later, after `= b` is parsed, [buildAssignment] will be
-/// called.
-abstract class Accessor {
-  final int offset;
-
-  // [builtBinary] and [builtGetter] capture the inner nodes. Used by
-  // dart2js+rasta for determining how subexpressions map to legacy dart2js Ast
-  // nodes. This will be removed once dart2js type analysis (aka inference) is
-  // reimplemented on kernel.
-  Expression builtBinary;
-  Expression builtGetter;
-
-  Accessor(this.offset);
-
-  /// Builds an [Expression] representing a read from the accessor.
-  Expression buildSimpleRead() {
-    return _finish(_makeSimpleRead());
-  }
-
-  /// Builds an [Expression] representing an assignment with the accessor on
-  /// the LHS and [value] on the RHS.
-  ///
-  /// The returned expression evaluates to the assigned value, unless
-  /// [voidContext] is true, in which case it may evaluate to anything.
-  Expression buildAssignment(Expression value, {bool voidContext: false}) {
-    return _finish(_makeSimpleWrite(value, voidContext));
-  }
-
-  /// Returns an [Expression] representing a null-aware assignment (`??=`) with
-  /// the accessor on the LHS and [value] on the RHS.
-  ///
-  /// The returned expression evaluates to the assigned value, unless
-  /// [voidContext] is true, in which case it may evaluate to anything.
-  ///
-  /// [type] is the static type of the RHS.
-  Expression buildNullAwareAssignment(Expression value, DartType type,
-      {bool voidContext: false}) {
-    if (voidContext) {
-      return _finish(new ConditionalExpression(buildIsNull(_makeRead()),
-          _makeWrite(value, false), new NullLiteral(), type));
-    }
-    var tmp = new VariableDeclaration.forValue(_makeRead());
-    return _finish(makeLet(
-        tmp,
-        new ConditionalExpression(buildIsNull(new VariableGet(tmp)),
-            _makeWrite(value, false), new VariableGet(tmp), type)));
-  }
-
-  /// Returns an [Expression] representing a compound assignment (e.g. `+=`)
-  /// with the accessor on the LHS and [value] on the RHS.
-  Expression buildCompoundAssignment(Name binaryOperator, Expression value,
-      {int offset: TreeNode.noOffset,
-      bool voidContext: false,
-      Procedure interfaceTarget}) {
-    return _finish(_makeWrite(
-        builtBinary = makeBinary(
-            _makeRead(), binaryOperator, interfaceTarget, value,
-            offset: offset),
-        voidContext));
-  }
-
-  /// Returns an [Expression] representing a pre-increment or pre-decrement
-  /// of the accessor.
-  Expression buildPrefixIncrement(Name binaryOperator,
-      {int offset: TreeNode.noOffset,
-      bool voidContext: false,
-      Procedure interfaceTarget}) {
-    return buildCompoundAssignment(binaryOperator, new IntLiteral(1),
-        offset: offset,
-        voidContext: voidContext,
-        interfaceTarget: interfaceTarget);
-  }
-
-  /// Returns an [Expression] representing a post-increment or post-decrement
-  /// of the accessor.
-  Expression buildPostfixIncrement(Name binaryOperator,
-      {int offset: TreeNode.noOffset,
-      bool voidContext: false,
-      Procedure interfaceTarget}) {
-    if (voidContext) {
-      return buildPrefixIncrement(binaryOperator,
-          offset: offset, voidContext: true, interfaceTarget: interfaceTarget);
-    }
-    var value = new VariableDeclaration.forValue(_makeRead());
-    valueAccess() => new VariableGet(value);
-    var dummy = new VariableDeclaration.forValue(_makeWrite(
-        builtBinary = makeBinary(
-            valueAccess(), binaryOperator, interfaceTarget, new IntLiteral(1),
-            offset: offset),
-        true));
-    return _finish(makeLet(value, makeLet(dummy, valueAccess())));
-  }
-
-  Expression _makeSimpleRead() => _makeRead();
-
-  Expression _makeSimpleWrite(Expression value, bool voidContext) {
-    return _makeWrite(value, voidContext);
-  }
-
-  Expression _makeRead();
-
-  Expression _makeWrite(Expression value, bool voidContext);
-
-  Expression _finish(Expression body) => body;
-
-  /// Returns an [Expression] representing a compile-time error.
-  makeInvalidRead() => new InvalidExpression(null);
-
-  /// Returns an [Expression] representing a compile-time error wrapping
-  /// [value].
-  ///
-  /// The expression will be a compile-time error but will contain [value] as a
-  /// subexpression before the compile-time error.
-  makeInvalidWrite(Expression value) => wrapInvalid(value);
-}
-
-class VariableAccessor extends Accessor {
-  VariableDeclaration variable;
-  DartType promotedType;
-
-  VariableAccessor(this.variable, this.promotedType, int offset)
-      : super(offset);
-
-  _makeRead() => new VariableGet(variable, promotedType)..fileOffset = offset;
-
-  _makeWrite(Expression value, bool voidContext) {
-    return variable.isFinal || variable.isConst
-        ? makeInvalidWrite(value)
-        : new VariableSet(variable, value)
-      ..fileOffset = offset;
-  }
-}
-
-class PropertyAccessor extends Accessor {
-  VariableDeclaration _receiverVariable;
-  Expression receiver;
-  Name name;
-  Member getter, setter;
-
-  static Accessor make(
-      Expression receiver, Name name, Member getter, Member setter,
-      {int offset: TreeNode.noOffset}) {
-    if (receiver is ThisExpression) {
-      return new ThisPropertyAccessor(name, getter, setter, offset);
-    } else {
-      return new PropertyAccessor.internal(
-          receiver, name, getter, setter, offset);
-    }
-  }
-
-  PropertyAccessor.internal(
-      this.receiver, this.name, this.getter, this.setter, int offset)
-      : super(offset);
-
-  _makeSimpleRead() =>
-      new PropertyGet(receiver, name, getter)..fileOffset = offset;
-
-  _makeSimpleWrite(Expression value, bool voidContext) {
-    return new PropertySet(receiver, name, value, setter)..fileOffset = offset;
-  }
-
-  receiverAccess() {
-    _receiverVariable ??= new VariableDeclaration.forValue(receiver);
-    return new VariableGet(_receiverVariable)..fileOffset = offset;
-  }
-
-  _makeRead() => builtGetter = new PropertyGet(receiverAccess(), name, getter)
-    ..fileOffset = offset;
-
-  _makeWrite(Expression value, bool voidContext) {
-    return new PropertySet(receiverAccess(), name, value, setter)
-      ..fileOffset = offset;
-  }
-
-  _finish(Expression body) => makeLet(_receiverVariable, body);
-}
-
-/// Special case of [PropertyAccessor] to avoid creating an indirect access to
-/// 'this'.
-class ThisPropertyAccessor extends Accessor {
-  Name name;
-  Member getter, setter;
-
-  ThisPropertyAccessor(this.name, this.getter, this.setter, int offset)
-      : super(offset);
-
-  _makeRead() => builtGetter =
-      new PropertyGet(new ThisExpression(), name, getter)..fileOffset = offset;
-
-  _makeWrite(Expression value, bool voidContext) {
-    return new PropertySet(new ThisExpression(), name, value, setter)
-      ..fileOffset = offset;
-  }
-}
-
-class NullAwarePropertyAccessor extends Accessor {
-  VariableDeclaration receiver;
-  Name name;
-  Member getter, setter;
-  DartType type;
-
-  NullAwarePropertyAccessor(Expression receiver, this.name, this.getter,
-      this.setter, this.type, int offset)
-      : this.receiver = makeOrReuseVariable(receiver),
-        super(offset);
-
-  receiverAccess() => new VariableGet(receiver);
-
-  _makeRead() => builtGetter = new PropertyGet(receiverAccess(), name, getter);
-
-  _makeWrite(Expression value, bool voidContext) {
-    return new PropertySet(receiverAccess(), name, value, setter);
-  }
-
-  _finish(Expression body) => makeLet(
-      receiver,
-      new ConditionalExpression(
-          buildIsNull(receiverAccess()), new NullLiteral(), body, type));
-}
-
-class SuperPropertyAccessor extends Accessor {
-  Name name;
-  Member getter, setter;
-
-  SuperPropertyAccessor(this.name, this.getter, this.setter, int offset)
-      : super(offset);
-
-  _makeRead() {
-    if (getter == null) return makeInvalidRead();
-    // TODO(ahe): Use [DirectPropertyGet] when possible.
-    return builtGetter = new SuperPropertyGet(name, getter)
-      ..fileOffset = offset;
-  }
-
-  _makeWrite(Expression value, bool voidContext) {
-    if (setter == null) return makeInvalidWrite(value);
-    // TODO(ahe): Use [DirectPropertySet] when possible.
-    return new SuperPropertySet(name, value, setter)..fileOffset = offset;
-  }
-}
-
-class IndexAccessor extends Accessor {
-  Expression receiver;
-  Expression index;
-  VariableDeclaration receiverVariable;
-  VariableDeclaration indexVariable;
-  Procedure getter, setter;
-
-  static Accessor make(
-      Expression receiver, Expression index, Procedure getter, Procedure setter,
-      {int offset: TreeNode.noOffset}) {
-    if (receiver is ThisExpression) {
-      return new ThisIndexAccessor(index, getter, setter, offset);
-    } else {
-      return new IndexAccessor.internal(
-          receiver, index, getter, setter, offset);
-    }
-  }
-
-  IndexAccessor.internal(
-      this.receiver, this.index, this.getter, this.setter, int offset)
-      : super(offset);
-
-  _makeSimpleRead() => new MethodInvocation(
-      receiver, indexGetName, new Arguments(<Expression>[index]), getter)
-    ..fileOffset = offset;
-
-  _makeSimpleWrite(Expression value, bool voidContext) {
-    if (!voidContext) return _makeWriteAndReturn(value);
-    return new MethodInvocation(receiver, indexSetName,
-        new Arguments(<Expression>[index, value]), setter)
-      ..fileOffset = offset;
-  }
-
-  receiverAccess() {
-    // We cannot reuse the receiver if it is a variable since it might be
-    // reassigned in the index expression.
-    receiverVariable ??= new VariableDeclaration.forValue(receiver);
-    return new VariableGet(receiverVariable)..fileOffset = offset;
-  }
-
-  indexAccess() {
-    indexVariable ??= new VariableDeclaration.forValue(index);
-    return new VariableGet(indexVariable)..fileOffset = offset;
-  }
-
-  _makeRead() {
-    return builtGetter = new MethodInvocation(receiverAccess(), indexGetName,
-        new Arguments(<Expression>[indexAccess()]), getter)
-      ..fileOffset = offset;
-  }
-
-  _makeWrite(Expression value, bool voidContext) {
-    if (!voidContext) return _makeWriteAndReturn(value);
-    return new MethodInvocation(receiverAccess(), indexSetName,
-        new Arguments(<Expression>[indexAccess(), value]), setter)
-      ..fileOffset = offset;
-  }
-
-  // TODO(dmitryas): remove this method after the "[]=" operator of the Context
-  // class is made to return a value.
-  _makeWriteAndReturn(Expression value) {
-    // The call to []= does not return the value like direct-style assignments
-    // do.  We need to bind the value in a let.
-    var valueVariable = new VariableDeclaration.forValue(value);
-    var dummy = new VariableDeclaration.forValue(new MethodInvocation(
-        receiverAccess(),
-        indexSetName,
-        new Arguments(
-            <Expression>[indexAccess(), new VariableGet(valueVariable)]),
-        setter)
-      ..fileOffset = offset);
-    return makeLet(
-        valueVariable, makeLet(dummy, new VariableGet(valueVariable)));
-  }
-
-  Expression _finish(Expression body) {
-    return makeLet(receiverVariable, makeLet(indexVariable, body));
-  }
-}
-
-/// Special case of [IndexAccessor] to avoid creating an indirect access to
-/// 'this'.
-class ThisIndexAccessor extends Accessor {
-  Expression index;
-  VariableDeclaration indexVariable;
-  Procedure getter, setter;
-
-  ThisIndexAccessor(this.index, this.getter, this.setter, int offset)
-      : super(offset);
-
-  _makeSimpleRead() {
-    return new MethodInvocation(new ThisExpression(), indexGetName,
-        new Arguments(<Expression>[index]), getter);
-  }
-
-  _makeSimpleWrite(Expression value, bool voidContext) {
-    if (!voidContext) return _makeWriteAndReturn(value);
-    return new MethodInvocation(new ThisExpression(), indexSetName,
-        new Arguments(<Expression>[index, value]), setter);
-  }
-
-  indexAccess() {
-    indexVariable ??= new VariableDeclaration.forValue(index);
-    return new VariableGet(indexVariable);
-  }
-
-  _makeRead() => builtGetter = new MethodInvocation(new ThisExpression(),
-      indexGetName, new Arguments(<Expression>[indexAccess()]), getter);
-
-  _makeWrite(Expression value, bool voidContext) {
-    if (!voidContext) return _makeWriteAndReturn(value);
-    return new MethodInvocation(new ThisExpression(), indexSetName,
-        new Arguments(<Expression>[indexAccess(), value]), setter);
-  }
-
-  _makeWriteAndReturn(Expression value) {
-    var valueVariable = new VariableDeclaration.forValue(value);
-    var dummy = new VariableDeclaration.forValue(new MethodInvocation(
-        new ThisExpression(),
-        indexSetName,
-        new Arguments(
-            <Expression>[indexAccess(), new VariableGet(valueVariable)]),
-        setter));
-    return makeLet(
-        valueVariable, makeLet(dummy, new VariableGet(valueVariable)));
-  }
-
-  Expression _finish(Expression body) => makeLet(indexVariable, body);
-}
-
-class SuperIndexAccessor extends Accessor {
-  Expression index;
-  VariableDeclaration indexVariable;
-  Member getter, setter;
-
-  SuperIndexAccessor(this.index, this.getter, this.setter, int offset)
-      : super(offset);
-
-  indexAccess() {
-    indexVariable ??= new VariableDeclaration.forValue(index);
-    return new VariableGet(indexVariable);
-  }
-
-  _makeSimpleRead() => new SuperMethodInvocation(
-      indexGetName, new Arguments(<Expression>[index]), getter);
-
-  _makeSimpleWrite(Expression value, bool voidContext) {
-    if (!voidContext) return _makeWriteAndReturn(value);
-    return new SuperMethodInvocation(
-        indexSetName, new Arguments(<Expression>[index, value]), setter);
-  }
-
-  _makeRead() {
-    return builtGetter = new SuperMethodInvocation(
-        indexGetName, new Arguments(<Expression>[indexAccess()]), getter);
-  }
-
-  _makeWrite(Expression value, bool voidContext) {
-    if (!voidContext) return _makeWriteAndReturn(value);
-    return new SuperMethodInvocation(indexSetName,
-        new Arguments(<Expression>[indexAccess(), value]), setter);
-  }
-
-  _makeWriteAndReturn(Expression value) {
-    var valueVariable = new VariableDeclaration.forValue(value);
-    var dummy = new VariableDeclaration.forValue(new SuperMethodInvocation(
-        indexSetName,
-        new Arguments(
-            <Expression>[indexAccess(), new VariableGet(valueVariable)]),
-        setter));
-    return makeLet(
-        valueVariable, makeLet(dummy, new VariableGet(valueVariable)));
-  }
-
-  Expression _finish(Expression body) {
-    return makeLet(indexVariable, body);
-  }
-}
-
-class StaticAccessor extends Accessor {
-  Member readTarget;
-  Member writeTarget;
-
-  StaticAccessor(this.readTarget, this.writeTarget, int offset) : super(offset);
-
-  _makeRead() => builtGetter =
-      readTarget == null ? makeInvalidRead() : new StaticGet(readTarget)
-        ..fileOffset = offset;
-
-  _makeWrite(Expression value, bool voidContext) {
-    return writeTarget == null
-        ? makeInvalidWrite(value)
-        : new StaticSet(writeTarget, value)
-      ..fileOffset = offset;
-  }
-}
-
-class ReadOnlyAccessor extends Accessor {
-  Expression expression;
-  VariableDeclaration value;
-
-  ReadOnlyAccessor(this.expression, int offset) : super(offset);
-
-  _makeSimpleRead() => expression;
-
-  _makeRead() {
-    value ??= new VariableDeclaration.forValue(expression);
-    return new VariableGet(value);
-  }
-
-  _makeWrite(Expression value, bool voidContext) => makeInvalidWrite(value);
-
-  Expression _finish(Expression body) => makeLet(value, body);
-}
-
-Expression makeLet(VariableDeclaration variable, Expression body) {
-  if (variable == null) return body;
-  return new Let(variable, body);
-}
-
-Expression makeBinary(
-    Expression left, Name operator, Procedure interfaceTarget, Expression right,
-    {int offset: TreeNode.noOffset}) {
-  return new MethodInvocation(
-      left, operator, new Arguments(<Expression>[right]), interfaceTarget)
-    ..fileOffset = offset;
-}
-
-final Name _equalOperator = new Name('==');
-
-Expression buildIsNull(Expression value, {int offset: TreeNode.noOffset}) {
-  return makeBinary(value, _equalOperator, null, new NullLiteral(),
-      offset: offset);
-}
-
-VariableDeclaration makeOrReuseVariable(Expression value) {
-  // TODO: Devise a way to remember if a variable declaration was reused
-  // or is fresh (hence needs a let binding).
-  return new VariableDeclaration.forValue(value);
-}
-
-Expression wrapInvalid(Expression e) {
-  return new Let(
-      new VariableDeclaration.forValue(e), new InvalidExpression(null));
-}
diff --git a/pkg/kernel/lib/frontend/readme.md b/pkg/kernel/lib/frontend/readme.md
deleted file mode 100644
index 53037ab..0000000
--- a/pkg/kernel/lib/frontend/readme.md
+++ /dev/null
@@ -1 +0,0 @@
-Utility method to help the frontend generate kernel IR.
diff --git a/pkg/kernel/lib/frontend/super_initializers.dart b/pkg/kernel/lib/frontend/super_initializers.dart
deleted file mode 100644
index 0dd3925..0000000
--- a/pkg/kernel/lib/frontend/super_initializers.dart
+++ /dev/null
@@ -1,56 +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.
-
-/// A library to help move super calls last in the initializer list.
-library kernel.frontend.super_calls;
-
-import '../ast.dart';
-
-/// Mutates the initializer list of [node] so that its super initializer occurs
-/// last, while its arguments are evaluated at the correct place.
-///
-/// Does nothing if there is no super initializer or if it is already last.
-void moveSuperInitializerLast(Constructor node) {
-  List<Initializer> initializers = node.initializers;
-  if (initializers.isEmpty) return;
-  if (initializers.last is SuperInitializer) return;
-  int superIndex = -1;
-  for (int i = initializers.length - 1; i >= 0; --i) {
-    Initializer initializer = initializers[i];
-    if (initializer is SuperInitializer) {
-      superIndex = i;
-      break;
-    }
-  }
-  if (superIndex == -1) return;
-  SuperInitializer superCall = initializers[superIndex];
-  Arguments arguments = superCall.arguments;
-  int argumentCount = arguments.positional.length + arguments.named.length;
-
-  // We move all initializers after the super call to the place where the super
-  // call was, but reserve [argumentCount] slots before that for
-  // [LocalInitializer]s.
-  initializers.length += argumentCount;
-  initializers.setRange(
-      superIndex + argumentCount, // destination start (inclusive)
-      initializers.length - 1, // destination end (exclusive)
-      initializers, // source list
-      superIndex + 1); // source start index
-  initializers[initializers.length - 1] = superCall;
-
-  // Fill in the [argumentCount] reserved slots with the evaluation expressions
-  // of the arguments to the super constructor call.
-  int storeIndex = superIndex;
-  for (int i = 0; i < arguments.positional.length; ++i) {
-    var variable = new VariableDeclaration.forValue(arguments.positional[i]);
-    arguments.positional[i] = new VariableGet(variable)..parent = arguments;
-    initializers[storeIndex++] = new LocalInitializer(variable)..parent = node;
-  }
-  for (int i = 0; i < arguments.named.length; ++i) {
-    NamedExpression argument = arguments.named[i];
-    var variable = new VariableDeclaration.forValue(argument.value);
-    arguments.named[i].value = new VariableGet(variable)..parent = argument;
-    initializers[storeIndex++] = new LocalInitializer(variable)..parent = node;
-  }
-}
diff --git a/pkg/kernel/lib/interpreter/tools/dart_to_latex.dart b/pkg/kernel/lib/interpreter/tools/dart_to_latex.dart
index e448297..d676aeb 100644
--- a/pkg/kernel/lib/interpreter/tools/dart_to_latex.dart
+++ b/pkg/kernel/lib/interpreter/tools/dart_to_latex.dart
@@ -80,7 +80,7 @@
       : inputFile = new File(inputFilename),
         outputFile = new File(outputFilename) {
     // Clear the output file at start.
-    outputFile.writeAsStringSync("", mode: FileMode.WRITE, flush: true);
+    outputFile.writeAsStringSync("", mode: FileMode.write, flush: true);
   }
 
   //LATEX-NEXT
@@ -133,7 +133,7 @@
       outputLines.add(r"\end{verbatim}");
     }
     for (String line in outputLines) {
-      outputFile.writeAsStringSync("$line\n", mode: FileMode.APPEND);
+      outputFile.writeAsStringSync("$line\n", mode: FileMode.append);
     }
   }
 
@@ -180,7 +180,7 @@
           : endIndex;
       outputFile.writeAsStringSync(
           input.substring(latexBeginIndex, latexEndIndex) + "\n",
-          mode: FileMode.APPEND);
+          mode: FileMode.append);
       input = input.substring(endIndex);
     }
   }
diff --git a/pkg/kernel/lib/kernel.dart b/pkg/kernel/lib/kernel.dart
index 5ffbd41..aa2a903 100644
--- a/pkg/kernel/lib/kernel.dart
+++ b/pkg/kernel/lib/kernel.dart
@@ -33,6 +33,12 @@
   return component;
 }
 
+Component loadComponentSourceFromBytes(List<int> bytes, [Component component]) {
+  component ??= new Component();
+  new BinaryBuilder(bytes).readComponentSource(component);
+  return component;
+}
+
 Future writeComponentToBinary(Component component, String path) {
   var sink;
   if (path == 'null' || path == 'stdout') {
diff --git a/pkg/kernel/lib/target/targets.dart b/pkg/kernel/lib/target/targets.dart
index 1f49bf5..6b03c7e 100644
--- a/pkg/kernel/lib/target/targets.dart
+++ b/pkg/kernel/lib/target/targets.dart
@@ -9,8 +9,6 @@
 import '../transformations/treeshaker.dart' show ProgramRoot;
 import 'flutter.dart' show FlutterTarget;
 import 'vm.dart' show VmTarget;
-import 'vmcc.dart' show VmClosureConvertedTarget;
-import 'vmreify.dart' show VmGenericTypesReifiedTarget;
 
 final List<String> targetNames = targets.keys.toList();
 
@@ -36,8 +34,6 @@
 final Map<String, _TargetBuilder> targets = <String, _TargetBuilder>{
   'none': (TargetFlags flags) => new NoneTarget(flags),
   'vm': (TargetFlags flags) => new VmTarget(flags),
-  'vmcc': (TargetFlags flags) => new VmClosureConvertedTarget(flags),
-  'vmreify': (TargetFlags flags) => new VmGenericTypesReifiedTarget(flags),
   'flutter': (TargetFlags flags) => new FlutterTarget(flags),
 };
 
diff --git a/pkg/kernel/lib/target/vm.dart b/pkg/kernel/lib/target/vm.dart
index e79a78c..eea56a4 100644
--- a/pkg/kernel/lib/target/vm.dart
+++ b/pkg/kernel/lib/target/vm.dart
@@ -98,11 +98,12 @@
         new Arguments(<Expression>[
           new StringLiteral(name)..fileOffset = offset,
           _fixedLengthList(
+              coreTypes,
               coreTypes.typeClass.rawType,
               arguments.types.map((t) => new TypeLiteral(t)).toList(),
               arguments.fileOffset),
-          _fixedLengthList(
-              const DynamicType(), arguments.positional, arguments.fileOffset),
+          _fixedLengthList(coreTypes, const DynamicType(), arguments.positional,
+              arguments.fileOffset),
           new StaticInvocation(
               coreTypes.mapUnmodifiable,
               new Arguments([
@@ -115,6 +116,9 @@
                 })), keyType: coreTypes.symbolClass.rawType)
                   ..isConst = (arguments.named.length == 0)
                   ..fileOffset = arguments.fileOffset
+              ], types: [
+                coreTypes.symbolClass.rawType,
+                new DynamicType()
               ]))
             ..fileOffset = arguments.fileOffset,
           new BoolLiteral(isSuper)..fileOffset = arguments.fileOffset
@@ -156,11 +160,12 @@
                 new SymbolLiteral(name)..fileOffset = offset,
                 new IntLiteral(type)..fileOffset = offset,
                 _fixedLengthList(
+                    coreTypes,
                     coreTypes.typeClass.rawType,
                     arguments.types.map((t) => new TypeLiteral(t)).toList(),
                     arguments.fileOffset),
-                _fixedLengthList(const DynamicType(), arguments.positional,
-                    arguments.fileOffset),
+                _fixedLengthList(coreTypes, const DynamicType(),
+                    arguments.positional, arguments.fileOffset),
                 new StaticInvocation(
                     coreTypes.mapUnmodifiable,
                     new Arguments([
@@ -252,8 +257,8 @@
     return type;
   }
 
-  Expression _fixedLengthList(
-      DartType typeArgument, List<Expression> elements, int offset) {
+  Expression _fixedLengthList(CoreTypes coreTypes, DartType typeArgument,
+      List<Expression> elements, int offset) {
     // TODO(ahe): It's possible that it would be better to create a fixed-length
     // list first, and then populate it. That would create fewer objects. But as
     // this is currently only used in (statically resolved) no-such-method
@@ -264,12 +269,13 @@
       return new ListLiteral([], typeArgument: typeArgument)..isConst = true;
     }
 
-    return new MethodInvocation(
-        new ListLiteral(elements, typeArgument: typeArgument)
-          ..fileOffset = offset,
-        new Name("toList"),
-        new Arguments(<Expression>[], named: <NamedExpression>[
-          new NamedExpression("growable", new BoolLiteral(false))
+    return new StaticInvocation(
+        coreTypes.listUnmodifiableConstructor,
+        new Arguments([
+          new ListLiteral(elements, typeArgument: typeArgument)
+            ..fileOffset = offset
+        ], types: [
+          new DynamicType()
         ]));
   }
 
diff --git a/pkg/kernel/lib/target/vmcc.dart b/pkg/kernel/lib/target/vmcc.dart
deleted file mode 100644
index a5f6a14..0000000
--- a/pkg/kernel/lib/target/vmcc.dart
+++ /dev/null
@@ -1,61 +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 kernel.target.vmcc;
-
-import '../ast.dart' show Component, Library;
-import '../core_types.dart' show CoreTypes;
-import '../class_hierarchy.dart';
-import '../transformations/continuation.dart' as cont;
-import '../transformations/mixin_full_resolution.dart' as mix;
-import '../transformations/sanitize_for_vm.dart';
-import '../transformations/treeshaker.dart';
-import '../transformations/closure_conversion.dart' as cc
-    show transformComponent;
-import 'targets.dart' show TargetFlags;
-import 'vm.dart' as vm_target;
-
-// VmClosureConvertedTarget used legacy VmTarget which was superseded by
-// VmFastaTarget. Legacy transformations pipeline was pulled from VmTarget
-// into this class when VmTarget was merged with new VmFastaTarget.
-// TODO(alexmarkov): Figure out if this target is still used, and either remove
-// it or unify its transformation pipeline with new VmTarget.
-class VmClosureConvertedTarget extends vm_target.VmTarget {
-  VmClosureConvertedTarget(TargetFlags flags) : super(flags);
-
-  @override
-  String get name => "vmcc";
-
-  ClassHierarchy _hierarchy;
-
-  @override
-  void performModularTransformationsOnLibraries(
-      CoreTypes coreTypes, ClassHierarchy hierarchy, List<Library> libraries,
-      {void logger(String msg)}) {
-    var mixins = new mix.MixinFullResolution(this, coreTypes, hierarchy)
-      ..transform(libraries);
-
-    _hierarchy = mixins.hierarchy;
-  }
-
-  @override
-  void performGlobalTransformations(CoreTypes coreTypes, Component component,
-      {void logger(String msg)}) {
-    if (flags.treeShake) {
-      performTreeShaking(coreTypes, component);
-    }
-
-    cont.transformComponent(coreTypes, component, flags.syncAsync);
-
-    new SanitizeForVM().transform(component);
-
-    cc.transformComponent(coreTypes, component);
-  }
-
-  void performTreeShaking(CoreTypes coreTypes, Component component) {
-    new TreeShaker(coreTypes, _hierarchy, component,
-            strongMode: strongMode, programRoots: flags.programRoots)
-        .transform(component);
-    _hierarchy = null; // Hierarchy must be recomputed.
-  }
-}
diff --git a/pkg/kernel/lib/target/vmreify.dart b/pkg/kernel/lib/target/vmreify.dart
deleted file mode 100644
index 681c760..0000000
--- a/pkg/kernel/lib/target/vmreify.dart
+++ /dev/null
@@ -1,44 +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 kernel.target.vmreify;
-
-import '../ast.dart' show Component;
-import '../core_types.dart' show CoreTypes;
-import '../transformations/generic_types_reification.dart' as reify
-    show transformComponent;
-import 'targets.dart' show TargetFlags;
-import 'vmcc.dart' as vmcc_target;
-
-/// Specializes the kernel IR to the Dart VM with reified generic types.
-class VmGenericTypesReifiedTarget extends vmcc_target.VmClosureConvertedTarget {
-  VmGenericTypesReifiedTarget(TargetFlags flags) : super(flags);
-
-  @override
-  String get name => "vmreify";
-
-  // This is the order that bootstrap libraries are loaded according to
-  // `runtime/vm/object_store.h`.
-  List<String> get extraRequiredLibraries {
-    return new List<String>.from(super.extraRequiredLibraries)
-      ..add("${flags.kernelRuntime.resolve('reify/types.dart')}")
-      ..add("${flags.kernelRuntime.resolve('reify/declarations.dart')}")
-      ..add("${flags.kernelRuntime.resolve('reify/interceptors.dart')}");
-  }
-
-  @override
-  void performGlobalTransformations(CoreTypes coreTypes, Component component,
-      {void logger(String msg)}) {
-    super.performGlobalTransformations(coreTypes, component);
-    // TODO(dmitryas) this transformation should be made modular
-    reify.transformComponent(coreTypes, component);
-  }
-
-  // Disable tree shaking for Generic Types Reification. There are some runtime
-  // libraries that are required for the transformation and are shaken off,
-  // because they aren't invoked from the component being transformed prior to
-  // the transformation.
-  // TODO(dmitryas): remove this when the libraries are in dart:_internal
-  @override
-  void performTreeShaking(CoreTypes coreTypes, Component component) {}
-}
diff --git a/pkg/kernel/lib/transformations/closure/clone_without_body.dart b/pkg/kernel/lib/transformations/closure/clone_without_body.dart
deleted file mode 100644
index 1e4b344..0000000
--- a/pkg/kernel/lib/transformations/closure/clone_without_body.dart
+++ /dev/null
@@ -1,7 +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 kernel.transformations.closure.converter;
-
-export '../../clone.dart' show CloneWithoutBody;
diff --git a/pkg/kernel/lib/transformations/closure/context.dart b/pkg/kernel/lib/transformations/closure/context.dart
deleted file mode 100644
index ee8fc67..0000000
--- a/pkg/kernel/lib/transformations/closure/context.dart
+++ /dev/null
@@ -1,251 +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 kernel.transformations.closure.context;
-
-import '../../ast.dart'
-    show
-        Expression,
-        FunctionNode,
-        NullLiteral,
-        StringLiteral,
-        Throw,
-        TreeNode,
-        VariableDeclaration,
-        VariableGet,
-        VariableSet,
-        VectorCreation,
-        VectorGet,
-        VectorSet,
-        VectorCopy;
-
-import '../../frontend/accessors.dart' show Accessor, VariableAccessor;
-
-import 'converter.dart' show ClosureConverter;
-
-abstract class Context {
-  /// Returns a new expression for accessing this context.
-  Expression get expression;
-
-  /// Returns an accessor (or null) for accessing this context.
-  Accessor get accessor;
-
-  /// Extend the context to include [variable] initialized to [value]. For
-  /// example, this replaces the [VariableDeclaration] node of a captured local
-  /// variable.
-  ///
-  /// This may create a new context and update the `context` field of the
-  /// current [ClosureConverter].
-  // TODO(ahe): Return context instead?
-  void extend(VariableDeclaration variable, Expression value);
-
-  /// Update the initializer [value] of [variable] which was previously added
-  /// with [extend]. This is used when [value] isn't available when the context
-  /// was extended.
-  void update(VariableDeclaration variable, Expression value) {
-    throw "not supported $runtimeType";
-  }
-
-  /// Returns a new expression for reading the value of [variable] from this
-  /// context. For example, for replacing a [VariableGet] of a captured local
-  /// variable.
-  Expression lookup(VariableDeclaration variable);
-
-  /// Returns a new expression which stores [value] in [variable] in this
-  /// context. For example, for replacing a [VariableSet] of a captured local
-  /// variable.
-  Expression assign(VariableDeclaration variable, Expression value,
-      {bool voidContext: false});
-
-  /// Returns a new context whose parent is this context. The optional argument
-  /// [accessor] controls how the nested context access this context. This is
-  /// used, for example, when hoisting a local function. In this case, access
-  /// to this context can't be accessed directly via [expression]. In other
-  /// cases, for example, a for-loop, this context is still in scope and can be
-  /// accessed directly (with [accessor]).
-  Context toNestedContext([Accessor accessor]);
-
-  /// Returns a new expression which will copy this context and store the copy
-  /// in the local variable currently holding this context.
-  Expression clone() {
-    return new Throw(
-        new StringLiteral("Context clone not implemented for ${runtimeType}"));
-  }
-}
-
-class NoContext extends Context {
-  final ClosureConverter converter;
-
-  NoContext(this.converter);
-
-  Expression get expression => new NullLiteral();
-
-  Accessor get accessor => null;
-
-  void extend(VariableDeclaration variable, Expression value) {
-    converter.context = new LocalContext(converter, this)
-      ..extend(variable, value);
-  }
-
-  Expression lookup(VariableDeclaration variable) {
-    throw 'Unbound NoContext.lookup($variable)';
-  }
-
-  Expression assign(VariableDeclaration variable, Expression value,
-      {bool voidContext: false}) {
-    throw 'Unbound NoContext.assign($variable, ...)';
-  }
-
-  Context toNestedContext([Accessor accessor]) {
-    return new NestedContext(
-        converter, accessor, <List<VariableDeclaration>>[]);
-  }
-}
-
-class LocalContext extends Context {
-  final ClosureConverter converter;
-  final Context parent;
-  final VariableDeclaration self;
-  final VectorCreation vectorCreation;
-  final List<VariableDeclaration> variables = <VariableDeclaration>[];
-  final Map<VariableDeclaration, VectorSet> initializers =
-      <VariableDeclaration, VectorSet>{};
-
-  LocalContext._internal(
-      this.converter, this.parent, this.self, this.vectorCreation);
-
-  factory LocalContext(ClosureConverter converter, Context parent) {
-    converter.rewriter.insertContextDeclaration(parent.expression);
-
-    return new LocalContext._internal(
-        converter,
-        parent,
-        converter.rewriter.contextDeclaration,
-        converter.rewriter.vectorCreation);
-  }
-
-  Expression get expression => accessor.buildSimpleRead();
-
-  Accessor get accessor => new VariableAccessor(self, null, TreeNode.noOffset);
-
-  void extend(VariableDeclaration variable, Expression value) {
-    // Increase index by 2, because the type arguments vector occupies position
-    // 0, the parent occupies position 1, and all other variables are therefore
-    // shifted by 2.
-    VectorSet initializer =
-        new VectorSet(expression, variables.length + 2, value);
-    value.parent = initializer;
-
-    converter.rewriter.insertExtendContext(initializer);
-    if (variable.parent is FunctionNode) {
-      converter.rewriter.insertZeroOutParameter(variable);
-    }
-
-    ++vectorCreation.length;
-    variables.add(variable);
-    initializers[variable] = initializer;
-  }
-
-  void update(VariableDeclaration variable, Expression value) {
-    VectorSet initializer = initializers[variable];
-    initializer.value = value;
-    value.parent = initializer;
-  }
-
-  Expression lookup(VariableDeclaration variable) {
-    var index = variables.indexOf(variable);
-    // Increase index by 2 in case of success, because the type arguments vector
-    // occupies position 0, the parent occupies position 1, and all other
-    // variables are therefore shifted by 2.
-    return index == -1
-        ? parent.lookup(variable)
-        : new VectorGet(expression, index + 2);
-  }
-
-  Expression assign(VariableDeclaration variable, Expression value,
-      {bool voidContext: false}) {
-    var index = variables.indexOf(variable);
-    // Increase index by 2 in case of success, because the type arguments vector
-    // occupies position 0, the parent occupies position 1, and all other
-    // variables are therefore shifted by 2.
-    return index == -1
-        ? parent.assign(variable, value, voidContext: voidContext)
-        : new VectorSet(expression, index + 2, value);
-  }
-
-  Context toNestedContext([Accessor accessor]) {
-    accessor ??= this.accessor;
-    List<List<VariableDeclaration>> variabless = <List<VariableDeclaration>>[];
-    var current = this;
-    while (current != null && current is! NoContext) {
-      if (current is LocalContext) {
-        variabless.add(current.variables);
-        current = current.parent;
-      } else if (current is NestedContext) {
-        variabless.addAll((current as NestedContext).variabless);
-        current = null;
-      }
-    }
-    return new NestedContext(converter, accessor, variabless);
-  }
-
-  Expression clone() {
-    self.isFinal = false;
-    return new VariableSet(self, new VectorCopy(new VariableGet(self)));
-  }
-}
-
-class NestedContext extends Context {
-  final ClosureConverter converter;
-  final Accessor accessor;
-  final List<List<VariableDeclaration>> variabless;
-
-  NestedContext(this.converter, this.accessor, this.variabless);
-
-  Expression get expression {
-    return accessor?.buildSimpleRead() ?? new NullLiteral();
-  }
-
-  void extend(VariableDeclaration variable, Expression value) {
-    converter.context = new LocalContext(converter, this)
-      ..extend(variable, value);
-  }
-
-  Expression lookup(VariableDeclaration variable) {
-    Expression context = expression;
-    for (var variables in variabless) {
-      var index = variables.indexOf(variable);
-      if (index != -1) {
-        // Increase index by 2 in case of success, because the type arguments
-        // vector occupies position 0, the parent occupies item 1, and all other
-        // variables are therefore shifted by 2.
-        return new VectorGet(context, index + 2);
-      }
-      // Item 1 of a context always points to its parent.
-      context = new VectorGet(context, 1);
-    }
-    throw 'Unbound NestedContext.lookup($variable)';
-  }
-
-  Expression assign(VariableDeclaration variable, Expression value,
-      {bool voidContext: false}) {
-    Expression context = expression;
-    for (List<VariableDeclaration> variables in variabless) {
-      var index = variables.indexOf(variable);
-      if (index != -1) {
-        // Increase index by 2 in case of success, because the type arguments
-        // vector occupies position 0, the parent occupies item 1, and all other
-        // variables are therefore shifted by 2.
-        return new VectorSet(context, index + 2, value);
-      }
-      // Item 1 of a context always points to its parent.
-      context = new VectorGet(context, 1);
-    }
-    throw 'Unbound NestedContext.lookup($variable)';
-  }
-
-  Context toNestedContext([Accessor accessor]) {
-    return new NestedContext(converter, accessor ?? this.accessor, variabless);
-  }
-}
diff --git a/pkg/kernel/lib/transformations/closure/converter.dart b/pkg/kernel/lib/transformations/closure/converter.dart
deleted file mode 100644
index dcc7af9..0000000
--- a/pkg/kernel/lib/transformations/closure/converter.dart
+++ /dev/null
@@ -1,848 +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 kernel.transformations.closure.converter;
-
-import '../../ast.dart'
-    show
-        AsyncMarker,
-        Arguments,
-        Block,
-        Catch,
-        Class,
-        ClosureCreation,
-        Constructor,
-        DartType,
-        DoStatement,
-        DynamicType,
-        EmptyStatement,
-        Expression,
-        ExpressionStatement,
-        Field,
-        ForInStatement,
-        ForStatement,
-        FunctionDeclaration,
-        FunctionExpression,
-        FunctionNode,
-        FunctionType,
-        Initializer,
-        InterfaceType,
-        InvalidExpression,
-        InvocationExpression,
-        Library,
-        LocalInitializer,
-        RedirectingInitializer,
-        Member,
-        MethodInvocation,
-        Name,
-        NamedExpression,
-        NamedType,
-        NullLiteral,
-        Procedure,
-        ProcedureKind,
-        PropertyGet,
-        ReturnStatement,
-        Statement,
-        StaticInvocation,
-        ThisExpression,
-        Transformer,
-        TreeNode,
-        TypeParameter,
-        TypeParameterType,
-        VariableDeclaration,
-        VariableGet,
-        VariableSet,
-        VectorCreation,
-        WhileStatement,
-        transformList;
-
-import '../../frontend/accessors.dart' show VariableAccessor;
-
-import '../../clone.dart' show CloneVisitor;
-
-import '../../core_types.dart' show CoreTypes;
-
-import '../../type_algebra.dart' show substitute;
-
-import 'clone_without_body.dart' show CloneWithoutBody;
-
-import 'context.dart' show Context, NoContext, LocalContext;
-
-import 'info.dart' show ClosureInfo;
-
-import 'rewriter.dart' show AstRewriter, BlockRewriter, InitializerListRewriter;
-
-bool isLoop(TreeNode node) {
-  return node is WhileStatement ||
-      node is DoStatement ||
-      node is ForStatement ||
-      node is ForInStatement;
-}
-
-class ClosureConverter extends Transformer {
-  final CoreTypes coreTypes;
-
-  final Set<VariableDeclaration> capturedVariables;
-
-  // This map pairs variables that are captured with flags indicating whether
-  // they are used inside or outside an initializer. See
-  // [ClosureInfo.parameterUses].
-  final Map<VariableDeclaration, int> parameterUses;
-
-  final Map<FunctionNode, Set<TypeParameter>> capturedTypeVariables;
-  final Map<FunctionNode, VariableDeclaration> thisAccess;
-  final Map<FunctionNode, String> localNames;
-
-  /// Records place-holders for cloning contexts. See [visitForStatement].
-  final Set<InvalidExpression> contextClonePlaceHolders =
-      new Set<InvalidExpression>();
-
-  final CloneVisitor cloner = new CloneWithoutBody();
-
-  /// New members to add to [currentLibrary] after it has been
-  /// transformed. These members will not be transformed themselves.
-  final List<TreeNode> newLibraryMembers = <TreeNode>[];
-
-  /// New members to add to [currentClass] after it has been transformed. These
-  /// members will not be transformed themselves.
-  final List<Member> newClassMembers = <Member>[];
-
-  Library currentLibrary;
-
-  Class currentClass;
-
-  Member currentMember;
-
-  FunctionNode currentMemberFunction;
-
-  FunctionNode currentFunction;
-
-  Context context;
-
-  AstRewriter rewriter;
-
-  /// TODO(29181): update this comment when the type variables are restored.
-  /// Maps original type variable (aka type parameter) to a hoisted type
-  /// variable type.
-  ///
-  /// For example, consider:
-  ///
-  ///     class C<T> {
-  ///       f() => (x) => x is T;
-  ///     }
-  ///
-  /// This is currently converted to:
-  ///
-  ///    class C<T> {
-  ///      f() => new Closure#0<T>();
-  ///    }
-  ///    class Closure#0<T_> implements Function {
-  ///      call(x) => x is T_;
-  ///    }
-  ///
-  /// In this example, `typeSubstitution[T].parameter == T_` when transforming
-  /// the closure in `f`.
-  Map<TypeParameter, DartType> typeSubstitution =
-      const <TypeParameter, DartType>{};
-
-  ClosureConverter(this.coreTypes, ClosureInfo info)
-      : this.capturedVariables = info.variables,
-        this.parameterUses = info.parameterUses,
-        this.capturedTypeVariables = info.typeVariables,
-        this.thisAccess = info.thisAccess,
-        this.localNames = info.localNames;
-
-  bool get isOuterMostContext {
-    return currentFunction == null || currentMemberFunction == currentFunction;
-  }
-
-  Uri get currentFileUri {
-    if (currentMember is Constructor) return currentClass.fileUri;
-    if (currentMember is Field) return (currentMember as Field).fileUri;
-    if (currentMember is Procedure) return (currentMember as Procedure).fileUri;
-    throw "No file uri for ${currentMember.runtimeType}";
-  }
-
-  TreeNode saveContext(TreeNode f()) {
-    AstRewriter old = rewriter;
-    Context savedContext = context;
-    try {
-      return f();
-    } finally {
-      rewriter = old;
-      context = savedContext;
-    }
-  }
-
-  TreeNode visitLibrary(Library node) {
-    assert(newLibraryMembers.isEmpty);
-
-    currentLibrary = node;
-    node = super.visitLibrary(node);
-    for (TreeNode member in newLibraryMembers) {
-      if (member is Class) {
-        node.addClass(member);
-      } else {
-        node.addMember(member);
-      }
-    }
-    newLibraryMembers.clear();
-    currentLibrary = null;
-    return node;
-  }
-
-  TreeNode visitClass(Class node) {
-    assert(newClassMembers.isEmpty);
-    currentClass = node;
-    node = super.visitClass(node);
-    newClassMembers.forEach(node.addMember);
-    newClassMembers.clear();
-    currentClass = null;
-    return node;
-  }
-
-  extendContextConditionally({bool inInitializer}) {
-    return (VariableDeclaration parameter) {
-      if (!capturedVariables.contains(parameter)) return 0;
-
-      int flags = parameterUses[parameter];
-      if (flags == null) {
-        context.extend(parameter, new VariableGet(parameter));
-        return 0;
-      }
-
-      // When moving variables into the context while scanning initializers,
-      // we need to add the variable if it's captured in an initializer,
-      // whether or not it's used/captured in the body. However, in the body,
-      // we only need to add the variable into the context if it's *not*
-      // captured in an initializer.
-      if (inInitializer
-          ? (flags & ClosureInfo.INSIDE_INITIALIZER) > 0
-          : flags == ClosureInfo.OUTSIDE_INITIALIZER) {
-        context.extend(parameter, new VariableGet(parameter));
-      }
-
-      return flags;
-    };
-  }
-
-  TreeNode visitConstructor(Constructor node) {
-    assert(isEmptyContext);
-    currentMember = node;
-
-    // If we created a context for the initializers, we need to re-use that
-    // context in the body of the function. Unfortunately, the context is
-    // declared in a local initializer and local initializers aren't visible
-    // in the body of the constructor. To work around this issue, we move the
-    // body into a new constructor and make this constructor redirect to that
-    // one, passing the context as an argument to the new constructor.
-    var movingCtor = false;
-
-    // Transform initializers.
-    if (node.initializers.length > 0) {
-      var initRewriter = new InitializerListRewriter(node);
-      rewriter = initRewriter;
-      context = new NoContext(this);
-
-      final int capturedBoth =
-          ClosureInfo.OUTSIDE_INITIALIZER | ClosureInfo.INSIDE_INITIALIZER;
-
-      // TODO(karlklose): add a fine-grained analysis of captured parameters.
-      handleParam(decl) {
-        if (extendContextConditionally(inInitializer: true)(decl) ==
-            capturedBoth) {
-          movingCtor = true;
-        }
-      }
-
-      node.function.positionalParameters.forEach(handleParam);
-      node.function.namedParameters.forEach(handleParam);
-
-      transformList(node.initializers, this, node);
-      node.initializers.insertAll(0, initRewriter.prefix);
-      rewriter = null;
-    }
-
-    // Transform constructor body.
-    FunctionNode function = node.function;
-    if (function.body != null && function.body is! EmptyStatement) {
-      setupRewriterForFunctionBody(function);
-      if (!movingCtor) context = new NoContext(this);
-      VariableDeclaration self = thisAccess[currentMemberFunction];
-      if (self != null) {
-        context.extend(self, new ThisExpression());
-      }
-      node.function.accept(this);
-
-      if (movingCtor) {
-        var contextDecl = (context as LocalContext).self;
-        var newCtorName = new Name("${node.name.name}#redir");
-        var newCtor = new Constructor(node.function, name: newCtorName);
-        newClassMembers.add(newCtor);
-
-        LocalInitializer contextDeclInit = null;
-        for (var init in node.initializers) {
-          if (init is LocalInitializer && init.variable == contextDecl) {
-            contextDeclInit = init;
-          } else {
-            newCtor.initializers.add(init);
-          }
-        }
-
-        node.initializers = <Initializer>[contextDeclInit];
-
-        var cv = new CloneVisitor();
-        var oldCtorParams = function.positionalParameters
-            .map(cv.visitVariableDeclaration)
-            .toList();
-        var oldCtorNamedParams =
-            function.namedParameters.map(cv.visitVariableDeclaration).toList();
-
-        function.positionalParameters.addAll(function.namedParameters);
-        function.namedParameters = [];
-
-        var args = <Expression>[];
-        args.addAll(oldCtorParams.map((decl) => new VariableGet(decl)));
-        args.addAll(oldCtorNamedParams.map((decl) => new VariableGet(decl)));
-
-        node.function = new FunctionNode(new EmptyStatement(),
-            typeParameters: [],
-            positionalParameters: oldCtorParams,
-            namedParameters: oldCtorNamedParams,
-            requiredParameterCount: function.requiredParameterCount,
-            returnType: function.returnType,
-            asyncMarker: function.asyncMarker,
-            dartAsyncMarker: function.dartAsyncMarker);
-        node.function.parent = node;
-
-        var oldCtorDecl = cv.visitVariableDeclaration(contextDecl);
-        contextDecl.initializer = null;
-        function.positionalParameters.add(contextDecl);
-        function.requiredParameterCount++;
-
-        contextDeclInit.variable = oldCtorDecl;
-        oldCtorDecl.parent = contextDeclInit;
-
-        args.add(new VariableGet(oldCtorDecl));
-        var redirInit =
-            new RedirectingInitializer(newCtor, new Arguments(args));
-        node.initializers.add(redirInit);
-      }
-    }
-    resetContext();
-    return node;
-  }
-
-  AstRewriter makeRewriterForBody(FunctionNode function) {
-    Statement body = function.body;
-    if (body is! Block) {
-      body = new Block(<Statement>[body]);
-      function.body = function.body.parent = body;
-    }
-    return new BlockRewriter(body);
-  }
-
-  bool isObject(DartType type) {
-    return type is InterfaceType && type.classNode.supertype == null;
-  }
-
-  TreeNode visitField(Field node) {
-    currentMember = node;
-    context = new NoContext(this);
-    node = super.visitField(node);
-    context = null;
-    currentMember = null;
-    return node;
-  }
-
-  Expression handleLocalFunction(FunctionNode function) {
-    if (function.asyncMarker == AsyncMarker.SyncYielding) {
-      function.transformChildren(this);
-      return new FunctionExpression(function);
-    }
-    FunctionNode enclosingFunction = currentFunction;
-    Map<TypeParameter, DartType> enclosingTypeSubstitution = typeSubstitution;
-    currentFunction = function;
-    Statement body = function.body;
-    assert(body != null);
-
-    rewriter = makeRewriterForBody(function);
-
-    VariableDeclaration contextVariable =
-        new VariableDeclaration("#contextParameter", type: const DynamicType());
-    Context parent = context;
-    context = context.toNestedContext(
-        new VariableAccessor(contextVariable, null, TreeNode.noOffset));
-
-    Set<TypeParameter> captured =
-        capturedTypeVariables[currentFunction] ?? new Set<TypeParameter>();
-    typeSubstitution = copyTypeVariables(captured);
-
-    function.transformChildren(this);
-
-    Expression result = addClosure(function, contextVariable, parent.expression,
-        typeSubstitution, enclosingTypeSubstitution);
-    currentFunction = enclosingFunction;
-    typeSubstitution = enclosingTypeSubstitution;
-    return result;
-  }
-
-  TreeNode visitFunctionDeclaration(FunctionDeclaration node) {
-    /// Is this closure itself captured by a closure?
-    bool isCaptured = capturedVariables.contains(node.variable);
-    if (isCaptured) {
-      context.extend(node.variable, new InvalidExpression(null));
-    }
-    Context parent = context;
-    return saveContext(() {
-      Expression expression = handleLocalFunction(node.function);
-
-      if (isCaptured) {
-        parent.update(node.variable, expression);
-        return null;
-      } else {
-        node.variable.initializer = expression;
-        expression.parent = node.variable;
-        return node.variable;
-      }
-    });
-  }
-
-  TreeNode visitFunctionExpression(FunctionExpression node) {
-    return saveContext(() => handleLocalFunction(node.function));
-  }
-
-  /// Add a new procedure to the current library that looks like this:
-  ///
-  ///     static method closure#0(Vector #c, /* Parameters of [function]. */)
-  ///         → dynamic {
-  ///
-  ///       /* Context is represented by #c. */
-  ///
-  ///       /* Body of [function]. */
-  ///
-  ///     }
-  ///
-  /// Returns an invocation of the closure creation primitive that binds the
-  /// above top-level function to a context represented as Vector.
-  Expression addClosure(
-      FunctionNode function,
-      VariableDeclaration contextVariable,
-      Expression accessContext,
-      Map<TypeParameter, DartType> substitution,
-      Map<TypeParameter, DartType> enclosingTypeSubstitution) {
-    var fnTypeParams = <TypeParameter>[];
-    var fnTypeArgs = <TypeParameterType>[];
-    for (TypeParameter t in substitution.keys) {
-      var fnTypeParam = (substitution[t] as TypeParameterType).parameter;
-      fnTypeParams.add(fnTypeParam);
-      fnTypeArgs
-          .add(substitute(new TypeParameterType(t), enclosingTypeSubstitution));
-    }
-
-    function.typeParameters.insertAll(0, fnTypeParams);
-    function.positionalParameters.insert(0, contextVariable);
-    ++function.requiredParameterCount;
-    Procedure closedTopLevelFunction = new Procedure(
-        new Name(createNameForClosedTopLevelFunction(function)),
-        ProcedureKind.Method,
-        function,
-        isStatic: true,
-        fileUri: currentFileUri);
-    newLibraryMembers.add(closedTopLevelFunction);
-
-    // We need to again make new type parameters for the function's function
-    // type, and substitute them into the function type's arguments' types.
-    var closureTypeParams = <TypeParameter>[];
-    var closureTypeSubstitutionMap = copyTypeVariables(function.typeParameters);
-    for (DartType d in closureTypeSubstitutionMap.values)
-      closureTypeParams.add((d as TypeParameterType).parameter);
-
-    FunctionType closureType = new FunctionType(
-        function.positionalParameters
-            .skip(1)
-            .map((VariableDeclaration decl) =>
-                substitute(decl.type, closureTypeSubstitutionMap))
-            .toList(),
-        substitute(function.returnType, closureTypeSubstitutionMap),
-        namedParameters: function.namedParameters
-            .map((VariableDeclaration decl) => new NamedType(
-                decl.name, substitute(decl.type, closureTypeSubstitutionMap)))
-            .toList(),
-        typeParameters: closureTypeParams,
-        requiredParameterCount: function.requiredParameterCount - 1);
-
-    // If we capture type parameters but not regular variables, we still need to
-    // make a context.
-    if (capturedTypeVariables[function] != null &&
-        accessContext is NullLiteral) {
-      accessContext = new VectorCreation(1);
-    }
-
-    return new ClosureCreation(
-        closedTopLevelFunction, accessContext, closureType, fnTypeArgs);
-  }
-
-  TreeNode visitProcedure(Procedure node) {
-    assert(isEmptyContext);
-
-    currentMember = node;
-
-    FunctionNode function = node.function;
-    if (function.body != null) {
-      bool hadSingleStatementBody = function.body is! Block;
-
-      setupRewriterForFunctionBody(function);
-      // Start with no context.  This happens after setting up _currentBlock
-      // so statements can be emitted into _currentBlock if necessary.
-      context = new NoContext(this);
-
-      VariableDeclaration self = thisAccess[currentMemberFunction];
-      if (self != null) {
-        context.extend(self, new ThisExpression());
-      }
-      node.transformChildren(this);
-      resetContext();
-
-      // Here a special case is handled: the body of the procedure was a single
-      // statement and after the transformation it is a block with a single
-      // statement inside.  In this case we make this statement the body of the
-      // procedure again.  It is required to follow the conventions imposed by
-      // [addClass] in [DillLibraryBuilder].
-      // See [dill_library_builder.dart]
-      // (../../../../front_end/lib/src/fasta/dill/dill_library_builder.dart)
-      // for details.
-      if (hadSingleStatementBody && function.body is Block) {
-        Block body = function.body;
-        if (body.statements.length == 1) {
-          function.body = body.statements[0];
-          function.body.parent = function;
-        }
-      }
-    }
-
-    return node;
-  }
-
-  void setupRewriterForFunctionBody(FunctionNode function) {
-    Statement body = function.body;
-    assert(body != null);
-    currentMemberFunction = function;
-    // Ensure that the body is a block which becomes the current block.
-    rewriter = makeRewriterForBody(function);
-  }
-
-  void resetContext() {
-    rewriter = null;
-    context = null;
-    currentMemberFunction = null;
-    currentMember = null;
-  }
-
-  bool get isEmptyContext {
-    return rewriter == null && context == null;
-  }
-
-  TreeNode visitLocalInitializer(LocalInitializer node) {
-    assert(!capturedVariables.contains(node.variable));
-    node.transformChildren(this);
-    return node;
-  }
-
-  TreeNode visitFunctionNode(FunctionNode node) {
-    transformList(node.typeParameters, this, node);
-    // Initializers for optional parameters must be compile-time constants,
-    // which excludes closures. Therefore, we can avoid looking for closures in
-    // initializers of the parameters.
-    node.positionalParameters
-        .forEach(extendContextConditionally(inInitializer: false));
-    node.namedParameters
-        .forEach(extendContextConditionally(inInitializer: false));
-    assert(node.body != null);
-    node.body = node.body.accept(this);
-    node.body.parent = node;
-    return node;
-  }
-
-  TreeNode visitBlock(Block node) {
-    return saveContext(() {
-      BlockRewriter blockRewriter = rewriter = rewriter.forNestedBlock(node);
-      if (node.parent is Statement &&
-          isLoop(node.parent) &&
-          context is! NoContext) {
-        context = context.toNestedContext();
-      }
-      blockRewriter.transformStatements(this);
-      return node;
-    });
-  }
-
-  TreeNode visitVariableDeclaration(VariableDeclaration node) {
-    node.transformChildren(this);
-
-    if (!capturedVariables.contains(node)) return node;
-    if (node.initializer == null && node.parent is FunctionNode) {
-      // If the variable is a function parameter and doesn't have an
-      // initializer, just use this variable name to put it into the context.
-      context.extend(node, new VariableGet(node));
-    } else {
-      context.extend(node, node.initializer ?? new NullLiteral());
-    }
-
-    if (node.parent == currentFunction) {
-      return node;
-    } else {
-      assert(node.parent is Block);
-      // When returning null, the parent block will remove
-      // this node from its list of statements.
-      return null;
-    }
-  }
-
-  TreeNode visitVariableGet(VariableGet node) {
-    return capturedVariables.contains(node.variable)
-        ? context.lookup(node.variable)
-        : node;
-  }
-
-  TreeNode visitVariableSet(VariableSet node) {
-    node.transformChildren(this);
-
-    return capturedVariables.contains(node.variable)
-        ? context.assign(node.variable, node.value,
-            voidContext: isInVoidContext(node))
-        : node;
-  }
-
-  bool isInVoidContext(Expression node) {
-    TreeNode parent = node.parent;
-    return parent is ExpressionStatement ||
-        parent is ForStatement && parent.condition != node;
-  }
-
-  DartType visitDartType(DartType node) {
-    return substitute(node, typeSubstitution);
-  }
-
-  VariableDeclaration getReplacementLoopVariable(VariableDeclaration variable) {
-    VariableDeclaration newVariable = new VariableDeclaration(variable.name,
-        initializer: variable.initializer, type: variable.type)
-      ..flags = variable.flags;
-    variable.initializer = new VariableGet(newVariable);
-    variable.initializer.parent = variable;
-    return newVariable;
-  }
-
-  Expression cloneContext() {
-    InvalidExpression placeHolder = new InvalidExpression(null);
-    contextClonePlaceHolders.add(placeHolder);
-    return placeHolder;
-  }
-
-  TreeNode visitInvalidExpression(InvalidExpression node) {
-    return contextClonePlaceHolders.remove(node) ? context.clone() : node;
-  }
-
-  TreeNode visitForStatement(ForStatement node) {
-    if (node.variables.any(capturedVariables.contains)) {
-      // In Dart, loop variables are new variables on each iteration of the
-      // loop. This is only observable when a loop variable is captured by a
-      // closure, which is the situation we're in here. So we transform the
-      // loop.
-      //
-      // Consider the following example, where `x` is `node.variables.first`,
-      // and `#t1` is a temporary variable:
-      //
-      //     for (var x = 0; x < 10; x++) body;
-      //
-      // This is transformed to:
-      //
-      //     {
-      //       var x = 0;
-      //       for (; x < 10; clone-context, x++) body;
-      //     }
-      //
-      // `clone-context` is a place-holder that will later be replaced by an
-      // expression that clones the current closure context (see
-      // [visitInvalidExpression]).
-      return saveContext(() {
-        context = context.toNestedContext();
-        List<Statement> statements = <Statement>[];
-        statements.addAll(node.variables);
-        statements.add(node);
-        node.variables.clear();
-        node.updates.insert(0, cloneContext());
-        Block block = new Block(statements);
-        rewriter = new BlockRewriter(block);
-        return block.accept(this);
-      });
-    }
-    return super.visitForStatement(node);
-  }
-
-  TreeNode visitForInStatement(ForInStatement node) {
-    if (capturedVariables.contains(node.variable)) {
-      // In Dart, loop variables are new variables on each iteration of the
-      // loop. This is only observable when the loop variable is captured by a
-      // closure, so we need to transform the for-in loop when `node.variable`
-      // is captured.
-      //
-      // Consider the following example, where `x` is `node.variable`, and
-      // `#t1` is a temporary variable:
-      //
-      //     for (var x in expr) body;
-      //
-      // Notice that we can assume that `x` doesn't have an initializer based
-      // on invariants in the Kernel AST. This is transformed to:
-      //
-      //     for (var #t1 in expr) { var x = #t1; body; }
-      //
-      // After this, we call super to apply the normal closure conversion to
-      // the transformed for-in loop.
-      VariableDeclaration variable = node.variable;
-      VariableDeclaration newVariable = getReplacementLoopVariable(variable);
-      node.variable = newVariable;
-      newVariable.parent = node;
-      node.body = new Block(<Statement>[variable, node.body]);
-      node.body.parent = node;
-    }
-    return super.visitForInStatement(node);
-  }
-
-  TreeNode visitThisExpression(ThisExpression node) {
-    return isOuterMostContext
-        ? node
-        : context.lookup(thisAccess[currentMemberFunction]);
-  }
-
-  TreeNode visitCatch(Catch node) {
-    VariableDeclaration exception = node.exception;
-    VariableDeclaration stackTrace = node.stackTrace;
-    if (stackTrace != null && capturedVariables.contains(stackTrace)) {
-      Block block = node.body = ensureBlock(node.body);
-      block.parent = node;
-      node.stackTrace = new VariableDeclaration(null);
-      node.stackTrace.parent = node;
-      stackTrace.initializer = new VariableGet(node.stackTrace);
-      block.statements.insert(0, stackTrace);
-      stackTrace.parent = block;
-    }
-    if (exception != null && capturedVariables.contains(exception)) {
-      Block block = node.body = ensureBlock(node.body);
-      block.parent = node;
-      node.exception = new VariableDeclaration(null);
-      node.exception.parent = node;
-      exception.initializer = new VariableGet(node.exception);
-      block.statements.insert(0, exception);
-      exception.parent = block;
-    }
-    return super.visitCatch(node);
-  }
-
-  Block ensureBlock(Statement statement) {
-    return statement is Block ? statement : new Block(<Statement>[statement]);
-  }
-
-  /// Creates a function that has the same signature as `procedure.function`
-  /// and which forwards all arguments to `procedure`.
-  FunctionNode forwardFunction(
-      Procedure procedure,
-      VariableDeclaration receiver,
-      VariableDeclaration contextVariable,
-      Map<TypeParameter, DartType> substitution) {
-    CloneVisitor cloner = substitution.isEmpty
-        ? this.cloner
-        : new CloneWithoutBody(typeSubstitution: substitution);
-    FunctionNode function = procedure.function;
-    List<TypeParameter> typeParameters =
-        function.typeParameters.map(cloner.clone).toList();
-    List<VariableDeclaration> positionalParameters =
-        function.positionalParameters.map(cloner.clone).toList();
-    if (contextVariable != null) {
-      positionalParameters.insert(0, contextVariable);
-    }
-    List<VariableDeclaration> namedParameters =
-        function.namedParameters.map(cloner.clone).toList();
-
-    List<DartType> types = typeParameters
-        .map((TypeParameter parameter) => new TypeParameterType(parameter))
-        .toList();
-    List<Expression> positional = positionalParameters
-        .map((VariableDeclaration parameter) => new VariableGet(parameter))
-        .toList();
-    if (contextVariable != null) {
-      positional.removeAt(0);
-    }
-    List<NamedExpression> named =
-        namedParameters.map((VariableDeclaration parameter) {
-      return new NamedExpression(parameter.name, new VariableGet(parameter));
-    }).toList();
-
-    Arguments arguments = new Arguments(positional, types: types, named: named);
-    InvocationExpression invocation = procedure.isInstanceMember
-        ? new MethodInvocation(
-            context.lookup(receiver), procedure.name, arguments, procedure)
-        : new StaticInvocation(procedure, arguments);
-    int requiredParameterCount = function.requiredParameterCount;
-    if (contextVariable != null) {
-      ++requiredParameterCount;
-    }
-    return new FunctionNode(new ReturnStatement(invocation),
-        typeParameters: typeParameters,
-        positionalParameters: positionalParameters,
-        namedParameters: namedParameters,
-        requiredParameterCount: requiredParameterCount,
-        returnType: substitute(function.returnType, cloner.typeSubstitution));
-  }
-
-  /// Creates copies of the type variables in [original] and returns a
-  /// substitution that can be passed to [substitute] to substitute all uses of
-  /// [original] with their copies.
-  ///
-  Map<TypeParameter, DartType> copyTypeVariables(
-      Iterable<TypeParameter> original) {
-    if (original.isEmpty) return const <TypeParameter, DartType>{};
-
-    Map<TypeParameter, DartType> substitution = <TypeParameter, DartType>{};
-    for (TypeParameter t in original) {
-      substitution[t] = new TypeParameterType(new TypeParameter(t.name));
-    }
-
-    substitution.forEach((TypeParameter t, DartType copy) {
-      if (copy is TypeParameterType) {
-        copy.parameter.bound = substitute(t.bound, substitution);
-      }
-    });
-    return substitution;
-  }
-
-  String createNameForClosedTopLevelFunction(FunctionNode function) {
-    return 'closure#${localNames[function]}';
-  }
-
-  Statement forwardToThisProperty(Member node) {
-    assert(node is Field || (node is Procedure && node.isGetter));
-    return new ReturnStatement(
-        new PropertyGet(new ThisExpression(), node.name, node));
-  }
-
-  void addFieldForwarder(Name name, Field field) {
-    newClassMembers.add(new Procedure(name, ProcedureKind.Getter,
-        new FunctionNode(forwardToThisProperty(field)),
-        fileUri: currentFileUri));
-  }
-
-  Procedure copyWithBody(Procedure procedure, Statement body) {
-    Procedure copy = cloner.clone(procedure);
-    copy.function.body = body;
-    copy.function.body.parent = copy.function;
-    return copy;
-  }
-
-  void addGetterForwarder(Name name, Procedure getter) {
-    assert(getter.isGetter);
-    newClassMembers
-        .add(copyWithBody(getter, forwardToThisProperty(getter))..name = name);
-  }
-}
diff --git a/pkg/kernel/lib/transformations/closure/info.dart b/pkg/kernel/lib/transformations/closure/info.dart
deleted file mode 100644
index ffa5fd7..0000000
--- a/pkg/kernel/lib/transformations/closure/info.dart
+++ /dev/null
@@ -1,260 +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 kernel.transformations.closure.info;
-
-import '../../ast.dart'
-    show
-        Class,
-        Constructor,
-        Field,
-        FunctionDeclaration,
-        FunctionNode,
-        Member,
-        Procedure,
-        ThisExpression,
-        TypeParameter,
-        TypeParameterType,
-        VariableDeclaration,
-        VariableGet,
-        VariableSet,
-        visitList;
-
-import '../../visitor.dart' show RecursiveVisitor;
-
-class ClosureInfo extends RecursiveVisitor {
-  FunctionNode currentFunction;
-
-  final Set<VariableDeclaration> variables = new Set<VariableDeclaration>();
-
-  // For captured constructor parameters, we need to distinquish the following
-  // states:
-  //
-  // - only used inside initializers (INSIDE_INITIALIZER)
-  // - only used in body (OUTSIDE_INITIALIZER)
-  // - used in body and initializers (OUTSIDE_INITIALIZER | INSIDE_INITIALIZER)
-  static const int OUTSIDE_INITIALIZER = 1;
-  static const int INSIDE_INITIALIZER = 2;
-  int captureFlags = OUTSIDE_INITIALIZER;
-  final Map<VariableDeclaration, int> parameterUses =
-      <VariableDeclaration, int>{};
-
-  final Map<VariableDeclaration, FunctionNode> function =
-      <VariableDeclaration, FunctionNode>{};
-
-  /// Map from functions to set of type variables captured within them.
-  final Map<FunctionNode, Set<TypeParameter>> typeVariables =
-      <FunctionNode, Set<TypeParameter>>{};
-
-  /// Map from members to synthetic variables for accessing `this` in a local
-  /// function.
-  final Map<FunctionNode, VariableDeclaration> thisAccess =
-      <FunctionNode, VariableDeclaration>{};
-
-  final Set<String> currentMemberLocalNames = new Set<String>();
-
-  final Map<FunctionNode, String> localNames = <FunctionNode, String>{};
-
-  Class currentClass;
-
-  Member currentMember;
-
-  FunctionNode currentMemberFunction;
-
-  bool get isOuterMostContext {
-    return currentFunction == null || currentMemberFunction == currentFunction;
-  }
-
-  void beginMember(Member member, [FunctionNode function]) {
-    currentMemberLocalNames.clear();
-    if (function != null) {
-      localNames[function] = computeUniqueLocalName(member.name.name);
-    }
-    currentMember = member;
-    currentMemberFunction = function;
-  }
-
-  void endMember() {
-    currentMember = null;
-    currentMemberFunction = null;
-  }
-
-  visitClass(Class node) {
-    currentClass = node;
-    super.visitClass(node);
-    currentClass = null;
-  }
-
-  visitConstructor(Constructor node) {
-    /// [currentFunction] should be set to [currentMemberFunction] before
-    /// visiting the [FunctionNode] of the constructor, because initializers may
-    /// use constructor parameters and it shouldn't be treated as capturing
-    /// them.  Consider the following code:
-    ///
-    ///     class A {
-    ///       int x;
-    ///       A(int x)  /* [x] is visible in initializers and body. */
-    ///         : this.x = x {  /* Initializer. */
-    ///         /* Constructor body. */
-    ///       }
-    ///     }
-    ///
-    /// Here the parameter shouldn't be captured into a context in the
-    /// initializer.  However, [currentFunction] is `null` if not set, and
-    /// `function[node.variable]` in this case points to the [FunctionNode] of
-    /// the constructor (which is not `null`).  It leads to `x` being treated as
-    /// captured, because it's seen as used outside of the function where it is
-    /// declared.  In turn, it leads to unnecessary context creation and usage.
-    ///
-    /// Another consideration is the order of visiting children of the
-    /// constructor: [node.function] should be visited before
-    /// [node.initializers], because [node.function] contains declarations of
-    /// the parameters that may be used in the initializers.  If the nodes are
-    /// visited in another order, the encountered parameters in initializers
-    /// are treated as captured, because they are not yet associated with the
-    /// function.
-    beginMember(node, node.function);
-    saveCurrentFunction(() {
-      currentFunction = currentMemberFunction;
-
-      visitList(node.annotations, this);
-      node.name?.accept(this);
-
-      visitList(node.function.typeParameters, this);
-      visitList(node.function.positionalParameters, this);
-      visitList(node.function.namedParameters, this);
-
-      assert(captureFlags == OUTSIDE_INITIALIZER);
-      captureFlags = INSIDE_INITIALIZER;
-      visitList(node.initializers, this);
-      captureFlags = OUTSIDE_INITIALIZER;
-
-      for (var decl in node.function.positionalParameters) {
-        var use = parameterUses[decl];
-        if (use == 0) parameterUses.remove(decl);
-      }
-      for (var decl in node.function.namedParameters) {
-        var use = parameterUses[decl];
-        if (use == 0) parameterUses.remove(decl);
-      }
-
-      node.function.accept(this);
-    });
-    endMember();
-  }
-
-  visitProcedure(Procedure node) {
-    beginMember(node, node.function);
-    super.visitProcedure(node);
-    endMember();
-  }
-
-  visitField(Field node) {
-    beginMember(node);
-    super.visitField(node);
-    endMember();
-  }
-
-  String computeUniqueLocalName([String name]) {
-    if (name == null || name.isEmpty) {
-      name = "function";
-    }
-    if (currentFunction == null) {
-      if (currentMember != null) {
-        name = "${currentMember.name.name}#$name";
-      }
-      if (currentClass != null) {
-        name = "${currentClass.name}#$name";
-      }
-    } else {
-      name = "${localNames[currentFunction]}#$name";
-    }
-    int count = 1;
-    String candidate = name;
-    while (currentMemberLocalNames.contains(candidate)) {
-      candidate = "$name#${count++}";
-    }
-    currentMemberLocalNames.add(candidate);
-    return candidate;
-  }
-
-  visitFunctionDeclaration(FunctionDeclaration node) {
-    assert(!localNames.containsKey(node));
-    localNames[node.function] = computeUniqueLocalName(node.variable.name);
-    return super.visitFunctionDeclaration(node);
-  }
-
-  visitFunctionNode(FunctionNode node) {
-    localNames.putIfAbsent(node, computeUniqueLocalName);
-
-    saveCurrentFunction(() {
-      currentFunction = node;
-      node.visitChildren(this);
-    });
-
-    Set<TypeParameter> capturedTypeVariables = typeVariables[node];
-    if (capturedTypeVariables != null && !isOuterMostContext) {
-      // Propagate captured type variables to enclosing function.
-      typeVariables
-          .putIfAbsent(currentFunction, () => new Set<TypeParameter>())
-          .addAll(
-              // 't.parent == currentFunction' will be true if the type variable
-              // is defined by one of our type parameters.
-              capturedTypeVariables.where((t) => t.parent != currentFunction));
-    }
-  }
-
-  visitVariableDeclaration(VariableDeclaration node) {
-    function[node] = currentFunction;
-    node.visitChildren(this);
-  }
-
-  visitVariableGet(VariableGet node) {
-    if (function[node.variable] != currentFunction) {
-      variables.add(node.variable);
-    }
-    if (node.variable.parent.parent is Constructor) {
-      parameterUses.putIfAbsent(node.variable, () => 0);
-      parameterUses[node.variable] |= captureFlags;
-    }
-    node.visitChildren(this);
-  }
-
-  visitVariableSet(VariableSet node) {
-    if (function[node.variable] != currentFunction) {
-      variables.add(node.variable);
-    }
-    if (node.variable.parent.parent is Constructor) {
-      parameterUses.putIfAbsent(node.variable, () => 0);
-      parameterUses[node.variable] |= captureFlags;
-    }
-    node.visitChildren(this);
-  }
-
-  visitTypeParameterType(TypeParameterType node) {
-    if (!isOuterMostContext &&
-        node.parameter.parent != currentFunction &&
-        !node.parameter.isFunctionTypeTypeParameter) {
-      typeVariables
-          .putIfAbsent(currentFunction, () => new Set<TypeParameter>())
-          .add(node.parameter);
-    }
-  }
-
-  visitThisExpression(ThisExpression node) {
-    if (!isOuterMostContext) {
-      thisAccess.putIfAbsent(
-          currentMemberFunction, () => new VariableDeclaration("#self"));
-    }
-  }
-
-  saveCurrentFunction(void f()) {
-    var saved = currentFunction;
-    try {
-      f();
-    } finally {
-      currentFunction = saved;
-    }
-  }
-}
diff --git a/pkg/kernel/lib/transformations/closure/invalidate_closures.dart b/pkg/kernel/lib/transformations/closure/invalidate_closures.dart
deleted file mode 100644
index 6cbbf76..0000000
--- a/pkg/kernel/lib/transformations/closure/invalidate_closures.dart
+++ /dev/null
@@ -1,27 +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 kernel.transformations.closure.invalidate;
-
-import '../../ast.dart';
-
-class InvalidateClosures extends Transformer {
-  FunctionDeclaration visitFunctionDeclaration(FunctionDeclaration node) {
-    invalidate(node.function);
-    return node;
-  }
-
-  FunctionExpression visitFunctionExpression(FunctionExpression node) {
-    invalidate(node.function);
-    return node;
-  }
-
-  void invalidate(FunctionNode function) {
-    if (function.asyncMarker != AsyncMarker.Sync) return;
-    var position = function.location;
-    function.body = new ExpressionStatement(new Throw(
-        new StringLiteral("Calling unconverted closure at $position")))
-      ..parent = function;
-  }
-}
diff --git a/pkg/kernel/lib/transformations/closure/rewriter.dart b/pkg/kernel/lib/transformations/closure/rewriter.dart
deleted file mode 100644
index d3ae56e..0000000
--- a/pkg/kernel/lib/transformations/closure/rewriter.dart
+++ /dev/null
@@ -1,132 +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 kernel.transformations.closure.rewriter;
-
-import '../../ast.dart';
-import 'converter.dart' show ClosureConverter;
-
-/// Used by the [Context] to initialize and update the context variable
-/// used to capture the variables closed over by functions.
-abstract class AstRewriter {
-  /// The declared variable that holds the context.
-  VariableDeclaration contextDeclaration;
-
-  /// Expression that is used to initialize the vector representing the context.
-  /// It's [length] field is modified by the [extend] operation
-  VectorCreation vectorCreation;
-
-  /// Creates a new [AstRewriter] for a (nested) [Block].
-  BlockRewriter forNestedBlock(Block block);
-
-  /// Inserts an allocation of a context and initializes [contextDeclaration]
-  /// and [vectorCreation].
-  void insertContextDeclaration(Expression accessParent);
-
-  /// Inserts an expression or statement that extends the context.
-  void insertExtendContext(VectorSet extender);
-
-  /// Inserts an expression that sets a parameter to NULL, so we don't have
-  /// unnecessary references to it.
-  void insertZeroOutParameter(VariableDeclaration parameter);
-
-  void _createDeclaration() {
-    assert(contextDeclaration == null && vectorCreation == null);
-
-    // Context size is set to 2 initially, because the 0-th element of it holds
-    // the vector of type arguments that the VM creates, and the 1-st element
-    // works as a link to the parent context.
-    vectorCreation = new VectorCreation(2);
-    contextDeclaration = new VariableDeclaration.forValue(vectorCreation,
-        type: const DynamicType());
-    contextDeclaration.name = "#context";
-  }
-}
-
-/// Adds a local variable for the context and adds update [Statement]s to the
-/// current block.
-class BlockRewriter extends AstRewriter {
-  Block _currentBlock;
-  int _insertionIndex;
-
-  BlockRewriter(this._currentBlock) : _insertionIndex = 0;
-
-  BlockRewriter forNestedBlock(Block block) {
-    return _currentBlock != block ? new BlockRewriter(block) : this;
-  }
-
-  void transformStatements(ClosureConverter converter) {
-    while (_insertionIndex < _currentBlock.statements.length) {
-      var original = _currentBlock.statements[_insertionIndex];
-      var transformed = original.accept(converter);
-      assert(_currentBlock.statements[_insertionIndex] == original);
-      if (transformed == null) {
-        _currentBlock.statements.removeAt(_insertionIndex);
-      } else {
-        _currentBlock.statements[_insertionIndex++] = transformed;
-        transformed.parent = _currentBlock;
-      }
-    }
-  }
-
-  void _insertStatement(Statement statement) {
-    _currentBlock.statements.insert(_insertionIndex++, statement);
-    statement.parent = _currentBlock;
-  }
-
-  void insertContextDeclaration(Expression accessParent) {
-    _createDeclaration();
-    _insertStatement(contextDeclaration);
-    if (accessParent is! NullLiteral) {
-      // Index 1 of a context always points to the parent.
-      _insertStatement(new ExpressionStatement(
-          new VectorSet(new VariableGet(contextDeclaration), 1, accessParent)));
-    }
-  }
-
-  void insertExtendContext(VectorSet extender) {
-    _insertStatement(new ExpressionStatement(extender));
-  }
-
-  void insertZeroOutParameter(VariableDeclaration parameter) {
-    _insertStatement(
-        new ExpressionStatement(new VariableSet(parameter, new NullLiteral())));
-  }
-}
-
-class InitializerListRewriter extends AstRewriter {
-  final Constructor parentConstructor;
-  final List<Initializer> prefix = [];
-
-  InitializerListRewriter(this.parentConstructor);
-
-  @override
-  BlockRewriter forNestedBlock(Block block) {
-    return new BlockRewriter(block);
-  }
-
-  @override
-  void insertContextDeclaration(Expression accessParent) {
-    _createDeclaration();
-    var init = new LocalInitializer(contextDeclaration);
-    init.parent = parentConstructor;
-    prefix.add(init);
-  }
-
-  @override
-  void insertExtendContext(VectorSet extender) {
-    var init = new LocalInitializer(
-        new VariableDeclaration(null, initializer: extender));
-    init.parent = parentConstructor;
-    prefix.add(init);
-  }
-
-  @override
-  void insertZeroOutParameter(VariableDeclaration parameter) {
-    var init = new LocalInitializer(new VariableDeclaration(null,
-        initializer: new VariableSet(parameter, new NullLiteral())));
-    init.parent = parentConstructor;
-    prefix.add(init);
-  }
-}
diff --git a/pkg/kernel/lib/transformations/closure_conversion.dart b/pkg/kernel/lib/transformations/closure_conversion.dart
deleted file mode 100644
index d1471aa..0000000
--- a/pkg/kernel/lib/transformations/closure_conversion.dart
+++ /dev/null
@@ -1,40 +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 kernel.transformations.closure_conversion;
-
-import '../ast.dart' show Component, Library;
-
-import '../core_types.dart' show CoreTypes;
-
-import 'closure/converter.dart' show ClosureConverter;
-
-import 'closure/info.dart' show ClosureInfo;
-
-import 'closure/invalidate_closures.dart';
-
-Component transformComponent(CoreTypes coreTypes, Component component) {
-  var info = new ClosureInfo();
-  info.visitComponent(component);
-
-  var convert = new ClosureConverter(coreTypes, info);
-  component = convert.visitComponent(component);
-  return new InvalidateClosures().visitComponent(component);
-}
-
-void transformLibraries(CoreTypes coreTypes, List<Library> libraries) {
-  var info = new ClosureInfo();
-  for (var library in libraries) {
-    info.visitLibrary(library);
-  }
-
-  var convert = new ClosureConverter(coreTypes, info);
-  for (int i = 0; i < libraries.length; i++) {
-    libraries[i] = convert.visitLibrary(libraries[i]);
-  }
-  var invalidator = new InvalidateClosures();
-  for (int i = 0; i < libraries.length; i++) {
-    invalidator.visitLibrary(libraries[i]);
-  }
-}
diff --git a/pkg/kernel/lib/transformations/constants.dart b/pkg/kernel/lib/transformations/constants.dart
index 2c55885..de851c6 100644
--- a/pkg/kernel/lib/transformations/constants.dart
+++ b/pkg/kernel/lib/transformations/constants.dart
@@ -185,15 +185,19 @@
 
   void transformAnnotations(List<Expression> nodes, TreeNode parent) {
     if (evaluateAnnotations && nodes.length > 0) {
-      constantEvaluator.withNewEnvironment(() {
-        for (int i = 0; i < nodes.length; ++i) {
-          nodes[i] = tryEvaluateAndTransformWithContext(parent, nodes[i])
-            ..parent = parent;
-        }
-      });
+      transformExpressions(nodes, parent);
     }
   }
 
+  void transformExpressions(List<Expression> nodes, TreeNode parent) {
+    constantEvaluator.withNewEnvironment(() {
+      for (int i = 0; i < nodes.length; ++i) {
+        nodes[i] = tryEvaluateAndTransformWithContext(parent, nodes[i])
+          ..parent = parent;
+      }
+    });
+  }
+
   // Handle definition of constants:
 
   visitFunctionNode(FunctionNode node) {
@@ -248,7 +252,10 @@
         return null;
       }
     }
-    return super.visitVariableDeclaration(node);
+    if (node.initializer != null) {
+      node.initializer = node.initializer.accept(this)..parent = node;
+    }
+    return node;
   }
 
   visitField(Field node) {
@@ -292,6 +299,11 @@
     return super.visitStaticGet(node);
   }
 
+  visitSwitchCase(SwitchCase node) {
+    transformExpressions(node.expressions, node);
+    return super.visitSwitchCase(node);
+  }
+
   visitVariableGet(VariableGet node) {
     if (node.variable.isConst) {
       return tryEvaluateAndTransformWithContext(node, node);
@@ -409,9 +421,7 @@
   defaultTreeNode(Node node) {
     // Only a subset of the expression language is valid for constant
     // evaluation.
-    errorReporter.unimplemented(contextChain, node,
-        'Constant evaluation has no support for ${node.runtimeType} yet!');
-    throw const _AbortCurrentEvaluation();
+    throw 'Constant evaluation has no support for ${node.runtimeType} yet!';
   }
 
   visitNullLiteral(NullLiteral node) => nullConstant;
@@ -449,7 +459,7 @@
 
   visitListLiteral(ListLiteral node) {
     if (!node.isConst) {
-      errorReporter.nonConstantLiteral(contextChain, node, 'List');
+      errorReporter.nonConstLiteral(contextChain, node, 'List');
       throw const _AbortCurrentEvaluation();
     }
     final List<Constant> entries = new List<Constant>(node.expressions.length);
@@ -463,7 +473,7 @@
 
   visitMapLiteral(MapLiteral node) {
     if (!node.isConst) {
-      errorReporter.nonConstantLiteral(contextChain, node, 'Map');
+      errorReporter.nonConstLiteral(contextChain, node, 'Map');
       throw const _AbortCurrentEvaluation();
     }
     final Set<Constant> usedKeys = new Set<Constant>();
@@ -473,6 +483,9 @@
       final key = node.entries[i].key.accept(this);
       final value = node.entries[i].value.accept(this);
       if (!usedKeys.add(key)) {
+        // 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();
       }
@@ -485,23 +498,24 @@
     return canonicalize(backend.lowerMapConstant(mapConstant));
   }
 
+  visitFunctionExpression(FunctionExpression node) {
+    errorReporter.nonConstLiteral(contextChain, node, 'Function');
+    throw const _AbortCurrentEvaluation();
+  }
+
   visitConstructorInvocation(ConstructorInvocation node) {
     final Constructor constructor = node.target;
     final Class klass = constructor.enclosingClass;
     if (!constructor.isConst) {
-      errorReporter.nonConstConstructorInvocation(
-          contextChain, node, constructor);
-      throw const _AbortCurrentEvaluation();
+      throw 'The front-end should ensure we do not encounter a '
+          'constructor invocation of a non-const constructor.';
     }
-    if (constructor.function.body is! EmptyStatement) {
-      errorReporter.unreachable(contextChain, node,
-          'Constructor "$node" has non-trivial body "${constructor.function.body.runtimeType}".');
-      throw const _AbortCurrentEvaluation();
+    if (constructor.function.body != null &&
+        constructor.function.body is! EmptyStatement) {
+      throw 'Constructor "$node" has non-trivial body "${constructor.function.body.runtimeType}".';
     }
     if (klass.isAbstract) {
-      errorReporter.unreachable(contextChain, node,
-          'Constructor "$node" belongs to abstract class "${klass}".');
-      throw const _AbortCurrentEvaluation();
+      throw 'Constructor "$node" belongs to abstract class "${klass}".';
     }
 
     final typeArguments = evaluateTypeArguments(node.arguments);
@@ -587,20 +601,34 @@
               if (condition is BoolConstant) {
                 if (!condition.value) {
                   final Constant message = init.statement.message?.accept(this);
-                  errorReporter.failedAssertion(
-                      contextChain, init.statement.condition, message);
+                  if (message == null) {
+                    errorReporter.failedAssertion(
+                        contextChain, init.statement.condition, null);
+                    throw const _AbortCurrentEvaluation();
+                  } else if (message is StringConstant) {
+                    errorReporter.failedAssertion(
+                        contextChain, init.statement.condition, message.value);
+                    throw const _AbortCurrentEvaluation();
+                  }
+                  errorReporter.invalidDartType(
+                      contextChain,
+                      init.statement.message,
+                      message,
+                      typeEnvironment.stringType);
                   throw const _AbortCurrentEvaluation();
                 }
               } else {
-                errorReporter.invalidType(
-                    contextChain, init.statement.condition, condition, 'bool');
+                errorReporter.invalidDartType(
+                    contextChain,
+                    init.statement.condition,
+                    condition,
+                    typeEnvironment.boolType);
                 throw const _AbortCurrentEvaluation();
               }
             }
           } else {
-            errorReporter.unimplemented(contextChain, init,
+            throw new Exception(
                 'No support for handling initializer of type "${init.runtimeType}".');
-            throw const _AbortCurrentEvaluation();
           }
         }
       });
@@ -615,21 +643,16 @@
     final List<Constant> arguments =
         evaluatePositionalArguments(node.arguments);
 
+    // TODO(http://dartbug.com/31799): Ensure we only invoke ==/!= on
+    // null/bool/int/double/String objects.
+
     // Handle == and != first (it's common between all types).
     if (arguments.length == 1 && node.name.name == '==') {
-      // TODO(http://dartbug.com/31799): Re-enable these checks.
-      //ensurePrimitiveConstant(receiver);
       final right = arguments[0];
-      // TODO(http://dartbug.com/31799): Re-enable these checks.
-      //ensurePrimitiveConstant(right);
       return receiver == right ? trueConstant : falseConstant;
     }
     if (arguments.length == 1 && node.name.name == '!=') {
-      // TODO(http://dartbug.com/31799): Re-enable these checks.
-      //ensurePrimitiveConstant(receiver);
       final right = arguments[0];
-      // TODO(http://dartbug.com/31799): Re-enable these checks.
-      //ensurePrimitiveConstant(right);
       return receiver != right ? trueConstant : falseConstant;
     }
 
@@ -644,7 +667,12 @@
                   new StringConstant(receiver.value + other.value));
             }
             errorReporter.invalidBinaryOperandType(
-                contextChain, node, 'String', '+', 'String', '$other');
+                contextChain,
+                node,
+                receiver,
+                '+',
+                typeEnvironment.stringType,
+                other.getType(typeEnvironment));
             throw const _AbortCurrentEvaluation();
         }
       }
@@ -669,7 +697,12 @@
           }
         }
         errorReporter.invalidBinaryOperandType(
-            contextChain, node, 'bool', '${node.name.name}', 'bool', '$right');
+            contextChain,
+            node,
+            receiver,
+            '${node.name.name}',
+            typeEnvironment.boolType,
+            right.getType(typeEnvironment));
         throw const _AbortCurrentEvaluation();
       }
     } else if (receiver is IntConstant) {
@@ -710,8 +743,13 @@
               node.name.name, receiver.value, value, node);
         }
 
-        errorReporter.invalidBinaryOperandType(contextChain, node, 'int',
-            '${node.name.name}', 'int/double', '$other');
+        errorReporter.invalidBinaryOperandType(
+            contextChain,
+            node,
+            receiver,
+            '${node.name.name}',
+            typeEnvironment.numType,
+            other.getType(typeEnvironment));
         throw const _AbortCurrentEvaluation();
       }
     } else if (receiver is DoubleConstant) {
@@ -730,8 +768,13 @@
           return evaluateBinaryNumericOperation(
               node.name.name, receiver.value, value, node);
         }
-        errorReporter.invalidBinaryOperandType(contextChain, node, 'double',
-            '${node.name.name}', 'int/double', '$other');
+        errorReporter.invalidBinaryOperandType(
+            contextChain,
+            node,
+            receiver,
+            '${node.name.name}',
+            typeEnvironment.numType,
+            other.getType(typeEnvironment));
         throw const _AbortCurrentEvaluation();
       }
     }
@@ -752,7 +795,12 @@
             return right;
           }
           errorReporter.invalidBinaryOperandType(
-              contextChain, node, 'bool', '${node.operator}', 'bool', '$right');
+              contextChain,
+              node,
+              left,
+              '${node.operator}',
+              typeEnvironment.boolType,
+              right.getType(typeEnvironment));
           throw const _AbortCurrentEvaluation();
         }
         errorReporter.invalidMethodInvocation(
@@ -767,7 +815,12 @@
             return right;
           }
           errorReporter.invalidBinaryOperandType(
-              contextChain, node, 'bool', '${node.operator}', 'bool', '$right');
+              contextChain,
+              node,
+              left,
+              '${node.operator}',
+              typeEnvironment.boolType,
+              right.getType(typeEnvironment));
           throw const _AbortCurrentEvaluation();
         }
         errorReporter.invalidMethodInvocation(
@@ -789,7 +842,8 @@
     } else if (constant == falseConstant) {
       return evaluate(node.otherwise);
     } else {
-      errorReporter.invalidType(contextChain, node, constant, 'bool');
+      errorReporter.invalidDartType(
+          contextChain, node, constant, typeEnvironment.boolType);
       throw const _AbortCurrentEvaluation();
     }
   }
@@ -834,8 +888,8 @@
     if (!variable.isConst &&
         !_isFormalParameter(variable) &&
         variable.parent is! Let) {
-      errorReporter.nonConstantVariableGet(contextChain, node);
-      throw const _AbortCurrentEvaluation();
+      throw new Exception('The front-end should ensure we do not encounter a '
+          'variable get of a non-const variable.');
     }
     return env.lookupVariable(node.variable);
   }
@@ -854,9 +908,8 @@
         errorReporter.invalidStaticInvocation(contextChain, node, target);
         throw const _AbortCurrentEvaluation();
       } else {
-        errorReporter.unreachable(contextChain, node,
+        throw new Exception(
             'No support for ${target.runtimeType} in a static-get.');
-        throw const _AbortCurrentEvaluation();
       }
     });
   }
@@ -903,11 +956,7 @@
       if (parent is Library && parent == coreTypes.coreLibrary) {
         final positionalArguments = evaluatePositionalArguments(node.arguments);
         final Constant left = positionalArguments[0];
-        // TODO(http://dartbug.com/31799): Re-enable these checks.
-        //ensurePrimitiveConstant(left, node);
         final Constant right = positionalArguments[1];
-        // TODO(http://dartbug.com/31799): Re-enable these checks.
-        //ensurePrimitiveConstant(right, node);
         // Since we canonicalize constants during the evaluation, we can use
         // identical here.
         assert(left == right);
@@ -929,7 +978,8 @@
     if (constant is BoolConstant) {
       return constant == trueConstant ? falseConstant : trueConstant;
     }
-    errorReporter.invalidType(contextChain, node, constant, 'bool');
+    errorReporter.invalidDartType(
+        contextChain, node, constant, typeEnvironment.boolType);
     throw const _AbortCurrentEvaluation();
   }
 
@@ -946,16 +996,12 @@
         return canonicalize(
             new PartialInstantiationConstant(constant, node.typeArguments));
       }
-      errorReporter.unreachable(
-          contextChain,
-          node,
+      throw new Exception(
           'The number of type arguments supplied in the partial instantiation '
           'does not match the number of type arguments of the $constant.');
-      throw const _AbortCurrentEvaluation();
     }
-    errorReporter.unreachable(contextChain, node,
+    throw new Exception(
         'Only tear-off constants can be partially instantiated.');
-    throw const _AbortCurrentEvaluation();
   }
 
   // Helper methods:
@@ -985,13 +1031,11 @@
     } else if (constant is TypeLiteralConstant) {
       constantType = new InterfaceType(coreTypes.typeClass);
     } else {
-      errorReporter.unreachable(contextChain, node,
-          'No support for ${constant.runtimeType}.runtimeType');
-      throw const _AbortCurrentEvaluation();
+      throw new Exception('No support for ${constant.runtimeType}.runtimeType');
     }
 
     if (!typeEnvironment.isSubtypeOf(constantType, type)) {
-      errorReporter.invalidType(contextChain, node, constant, '$type');
+      errorReporter.invalidDartType(contextChain, node, constant, type);
       throw const _AbortCurrentEvaluation();
     }
   }
@@ -1015,7 +1059,7 @@
 
   List<Constant> evaluatePositionalArguments(Arguments arguments) {
     return arguments.positional.map((Expression node) {
-      return node.accept(this);
+      return node.accept(this) as Constant;
     }).toList();
   }
 
@@ -1053,18 +1097,6 @@
     }
   }
 
-  ensurePrimitiveConstant(Constant value, TreeNode node) {
-    if (value is! NullConstant &&
-        value is! BoolConstant &&
-        value is! IntConstant &&
-        value is! DoubleConstant &&
-        value is! StringConstant) {
-      errorReporter.invalidType(
-          contextChain, node, value, 'bool/int/double/Null/String');
-      throw const _AbortCurrentEvaluation();
-    }
-  }
-
   evaluateBinaryNumericOperation(String op, num a, num b, TreeNode node) {
     num result;
     switch (op) {
@@ -1105,8 +1137,7 @@
         return a > b ? trueConstant : falseConstant;
     }
 
-    errorReporter.invalidBinaryMethodInvocation(contextChain, node, op);
-    throw const _AbortCurrentEvaluation();
+    throw new Exception("Unexpected binary numeric operation '$op'.");
   }
 
   int _wrapAroundInteger(int value) {
@@ -1211,26 +1242,19 @@
 abstract class ErrorReporter {
   const ErrorReporter();
 
-  invalidType(List<TreeNode> context, TreeNode node, Constant receiver,
-      String expectedType);
+  invalidDartType(List<TreeNode> context, TreeNode node, Constant receiver,
+      DartType expectedType);
   invalidBinaryOperandType(List<TreeNode> context, TreeNode node,
-      String receiverType, String op, String expectedType, String actualType);
-  invalidBinaryMethodInvocation(
-      List<TreeNode> context, TreeNode node, String op);
+      Constant receiver, String op, DartType expectedType, DartType actualType);
   invalidMethodInvocation(
       List<TreeNode> context, TreeNode node, Constant receiver, String op);
   invalidStaticInvocation(
       List<TreeNode> context, TreeNode node, Procedure target);
   invalidStringInterpolationOperand(
       List<TreeNode> context, TreeNode node, Constant constant);
+  nonConstLiteral(List<TreeNode> context, TreeNode node, String klass);
   duplicateKey(List<TreeNode> context, TreeNode node, Constant key);
-  nonConstantLiteral(List<TreeNode> context, TreeNode node, String literalType);
-  nonConstantVariableGet(List<TreeNode> context, VariableGet node);
-  nonConstConstructorInvocation(
-      List<TreeNode> context, TreeNode node, Constructor target);
-  failedAssertion(List<TreeNode> context, TreeNode node, Constant message);
-  unimplemented(List<TreeNode> context, TreeNode node, String message);
-  unreachable(List<TreeNode> context, TreeNode node, String message);
+  failedAssertion(List<TreeNode> context, TreeNode node, String message);
 }
 
 abstract class ErrorReporterBase implements ErrorReporter {
@@ -1252,28 +1276,28 @@
     return node == null ? TreeNode.noOffset : node.fileOffset;
   }
 
-  invalidType(List<TreeNode> context, TreeNode node, Constant receiver,
-      String expectedType) {
+  invalidDartType(List<TreeNode> context, TreeNode node, Constant receiver,
+      DartType expectedType) {
     report(
         context,
         'Expected expression to evaluate to "$expectedType" but got "$receiver.',
         node);
   }
 
-  invalidBinaryOperandType(List<TreeNode> context, TreeNode node,
-      String receiverType, String op, String expectedType, String actualType) {
+  invalidBinaryOperandType(
+      List<TreeNode> context,
+      TreeNode node,
+      Constant receiver,
+      String op,
+      DartType expectedType,
+      DartType actualType) {
     report(
         context,
-        'Calling "$op" on "$receiverType" needs operand of type '
+        'Calling "$op" on "$receiver" needs operand of type '
         '"$expectedType" (but got "$actualType")',
         node);
   }
 
-  invalidBinaryMethodInvocation(
-      List<TreeNode> context, TreeNode node, String op) {
-    report(context, 'Cannot call "$op" on a numeric constant receiver', node);
-  }
-
   invalidMethodInvocation(
       List<TreeNode> context, TreeNode node, Constant receiver, String op) {
     report(context, 'Cannot call "$op" on "$receiver" in constant expression',
@@ -1295,6 +1319,13 @@
         node);
   }
 
+  nonConstLiteral(List<TreeNode> context, TreeNode node, String klass) {
+    report(
+        context,
+        'Cannot have a non-constant $klass literal within a const context.',
+        node);
+  }
+
   duplicateKey(List<TreeNode> context, TreeNode node, Constant key) {
     report(
         context,
@@ -1302,47 +1333,12 @@
         node);
   }
 
-  nonConstantLiteral(
-      List<TreeNode> context, TreeNode node, String literalType) {
-    report(
-        context,
-        '"$literalType" literals inside constant expressions are required to '
-        'be constant.',
-        node);
-  }
-
-  nonConstantVariableGet(List<TreeNode> context, VariableGet node) {
-    report(
-        context,
-        'The variable "${node.variable.name}" is non-const and '
-        'can therefore not be used inside a constant expression.'
-        ' (${node}, ${node.parent.parent}, )',
-        node);
-  }
-
-  nonConstConstructorInvocation(
-      List<TreeNode> context, TreeNode node, Constructor target) {
-    report(
-        context,
-        'The non-const constructor "$target" cannot be called inside a '
-        'constant expression',
-        node);
-  }
-
-  failedAssertion(List<TreeNode> context, TreeNode node, Constant message) {
+  failedAssertion(List<TreeNode> context, TreeNode node, String message) {
     report(
         context,
         'The assertion condition evaluated to "false" with message "$message"',
         node);
   }
-
-  unimplemented(List<TreeNode> context, TreeNode node, String message) {
-    report(context, 'Unimplemented: $message', node);
-  }
-
-  unreachable(List<TreeNode> context, TreeNode node, String message) {
-    report(context, 'Unreachable: $message', node);
-  }
 }
 
 class _SimpleErrorReporter extends ErrorReporterBase {
diff --git a/pkg/kernel/lib/transformations/generic_types_reification.dart b/pkg/kernel/lib/transformations/generic_types_reification.dart
deleted file mode 100644
index d79ab68..0000000
--- a/pkg/kernel/lib/transformations/generic_types_reification.dart
+++ /dev/null
@@ -1,14 +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 kernel.transformation.generic_types_reification;
-
-import '../ast.dart' show Component;
-import '../core_types.dart' show CoreTypes;
-import '../transformations/reify/reify_transformer.dart' as reify
-    show transformComponent;
-
-Component transformComponent(CoreTypes coreTypes, Component component) {
-  return reify.transformComponent(coreTypes, component);
-}
diff --git a/pkg/kernel/lib/transformations/mixin_full_resolution.dart b/pkg/kernel/lib/transformations/mixin_full_resolution.dart
index 27effdc..a2f392620 100644
--- a/pkg/kernel/lib/transformations/mixin_full_resolution.dart
+++ b/pkg/kernel/lib/transformations/mixin_full_resolution.dart
@@ -63,7 +63,8 @@
     }
 
     // We might need to update the class hierarchy.
-    hierarchy = hierarchy.applyChanges(transformedClasses);
+    hierarchy =
+        hierarchy.applyMemberChanges(transformedClasses, findDescendants: true);
 
     if (!doSuperResolution) {
       return;
diff --git a/pkg/kernel/lib/transformations/reify/analysis/program_analysis.dart b/pkg/kernel/lib/transformations/reify/analysis/program_analysis.dart
deleted file mode 100644
index df259b6..0000000
--- a/pkg/kernel/lib/transformations/reify/analysis/program_analysis.dart
+++ /dev/null
@@ -1,106 +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 kernel.transformation.reify.analysis.program_analysis;
-
-import '../asts.dart';
-import '../../../ast.dart';
-
-// TODO(karlklose): keep all predicates and derived information here and move
-// the actual data to a builder class.
-class ProgramKnowledge {
-  Map<Member, Set<TypeParameter>> _usedTypeVariables =
-      <Member, Set<TypeParameter>>{};
-
-  Map<Member, Set<DartType>> isTests = <Member, Set<DartType>>{};
-
-  Set<Class> _classTests;
-
-  /// Contains all classes that are used as the declaration of a type expression
-  /// in a type test.
-  Set<Class> get classTests {
-    if (_classTests == null) {
-      _classTests = isTests.values
-          .expand((set) => set)
-          .where((DartType type) => type is InterfaceType)
-          .map((DartType type) => (type as InterfaceType).classNode)
-          .toSet();
-    }
-    return _classTests;
-  }
-
-  recordTypeVariableUse(Expression expression, TypeParameter parameter) {
-    // TODO(karlklose): also record expression.
-    add(_usedTypeVariables, getEnclosingMember(expression), parameter);
-  }
-
-  Set<TypeParameter> usedParameters(Member member) {
-    return _usedTypeVariables[member] ?? new Set<TypeParameter>();
-  }
-
-  void recordIsTest(IsExpression node, DartType type) {
-    add(isTests, getEnclosingMember(node), type);
-  }
-
-  add(Map<dynamic, Set> map, key, value) {
-    map.putIfAbsent(key, () => new Set()).add(value);
-  }
-}
-
-typedef bool LibraryFilter(Library library);
-
-class ProgramAnalysis extends Visitor {
-  final ProgramKnowledge knowledge;
-  final LibraryFilter analyzeLibrary;
-
-  ProgramAnalysis(this.knowledge, this.analyzeLibrary);
-
-  defaultTreeNode(TreeNode node) => node.visitChildren(this);
-
-  visitLibrary(Library library) {
-    if (!analyzeLibrary(library)) {
-      return;
-    }
-    super.visitLibrary(library);
-  }
-
-  handleTypeReference(TreeNode node, DartType type) {
-    typeVariables(type).forEach((TypeParameter parameter) {
-      knowledge.recordTypeVariableUse(node, parameter);
-    });
-  }
-
-  handleInstantiation(InvocationExpression node) {
-    node.arguments.types.forEach((DartType type) {
-      handleTypeReference(node, type);
-    });
-  }
-
-  visitIsExpression(IsExpression node) {
-    knowledge.recordIsTest(node, node.type);
-    handleTypeReference(node, node.type);
-    node.visitChildren(this);
-  }
-
-  visitConstructorInvocation(ConstructorInvocation node) {
-    handleInstantiation(node);
-    node.visitChildren(this);
-  }
-
-  visitStaticInvocation(StaticInvocation node) {
-    if (node.target.kind == ProcedureKind.Factory) {
-      handleInstantiation(node);
-    }
-    node.visitChildren(this);
-  }
-}
-
-bool _analyzeAll(Library library) => true;
-
-ProgramKnowledge analyze(Component component,
-    {LibraryFilter analyzeLibrary: _analyzeAll}) {
-  ProgramKnowledge knowledge = new ProgramKnowledge();
-  component.accept(new ProgramAnalysis(knowledge, analyzeLibrary));
-  return knowledge;
-}
diff --git a/pkg/kernel/lib/transformations/reify/asts.dart b/pkg/kernel/lib/transformations/reify/asts.dart
deleted file mode 100644
index a96225f..0000000
--- a/pkg/kernel/lib/transformations/reify/asts.dart
+++ /dev/null
@@ -1,54 +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 kernel.transformations.reify.ast_helpers;
-
-import '../../ast.dart';
-
-Class getEnclosingClass(TreeNode node) {
-  TreeNode original = node;
-  while (node != null && node is! Class) {
-    node = node.parent;
-  }
-  if (node == null) {
-    throw 'internal error: enclosing class not found for $original';
-  }
-  return node;
-}
-
-Library getEnclosingLibrary(TreeNode node) {
-  TreeNode original = node;
-  while (node != null && node is! Library) {
-    node = node.parent;
-  }
-  if (node == null) {
-    throw 'internal error: enclosing library not found for $original';
-  }
-  return node;
-}
-
-Member getEnclosingMember(TreeNode node) {
-  TreeNode original = node;
-  while (node != null && node is! Member) {
-    node = node.parent;
-  }
-  if (node == null) {
-    throw 'internal error: enclosing member not found for $original';
-  }
-  return node;
-}
-
-List<TypeParameter> typeVariables(DartType type) {
-  List<TypeParameter> parameters = <TypeParameter>[];
-  collect(DartType type) {
-    if (type is InterfaceType) {
-      type.typeArguments.map(collect);
-    } else if (type is TypeParameterType) {
-      parameters.add(type.parameter);
-    }
-  }
-
-  collect(type);
-  return parameters;
-}
diff --git a/pkg/kernel/lib/transformations/reify/reify_transformer.dart b/pkg/kernel/lib/transformations/reify/reify_transformer.dart
deleted file mode 100644
index 5a0f2a5..0000000
--- a/pkg/kernel/lib/transformations/reify/reify_transformer.dart
+++ /dev/null
@@ -1,112 +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 kernel.transformations.reify.standalone_runner;
-
-import 'analysis/program_analysis.dart';
-import 'dart:io' show File, IOSink;
-
-import '../../binary/ast_to_binary.dart' show BinaryPrinter;
-
-import '../../ast.dart';
-
-import '../../kernel.dart';
-import '../../verifier.dart';
-import '../../text/ast_to_text.dart' show Printer;
-
-import 'transformation/remove_generics.dart';
-import 'transformation/transformer.dart'
-    show ReifyVisitor, RuntimeLibrary, RuntimeTypeSupportBuilder;
-
-import '../../core_types.dart' show CoreTypes;
-
-RuntimeLibrary findRuntimeTypeLibrary(Component p) {
-  Library findLibraryEndingWith(String postfix) {
-    Iterable<Library> candidates = p.libraries.where((Library l) {
-      return l.importUri.toString().endsWith(postfix);
-    });
-    if (candidates.length != 1) {
-      String howMany = candidates.isEmpty ? "No" : "Multiple";
-      throw new Exception(
-          "$howMany candidates for runtime support library found.");
-    }
-    return candidates.single;
-  }
-
-  Library types = findLibraryEndingWith("reify/types.dart");
-  Library declarations = findLibraryEndingWith("reify/declarations.dart");
-  Library interceptors = findLibraryEndingWith("reify/interceptors.dart");
-  return new RuntimeLibrary(types, declarations, interceptors);
-}
-
-Component transformComponentUsingLibraries(
-    CoreTypes coreTypes, Component component, RuntimeLibrary runtimeLibrary,
-    [Library libraryToTransform]) {
-  LibraryFilter filter = libraryToTransform != null
-      ? (Library library) => library == libraryToTransform
-      : (_) => true;
-  ProgramKnowledge knowledge = analyze(component, analyzeLibrary: filter);
-  Library mainLibrary = component.mainMethod.parent;
-  RuntimeTypeSupportBuilder builder =
-      new RuntimeTypeSupportBuilder(runtimeLibrary, coreTypes, mainLibrary);
-  ReifyVisitor transformer =
-      new ReifyVisitor(runtimeLibrary, builder, knowledge, libraryToTransform);
-  // Transform the main component.
-  component = component.accept(transformer);
-  if (!filter(runtimeLibrary.interceptorsLibrary)) {
-    // We need to transform the interceptor function in any case to make sure
-    // that the type literals in the interceptor function are rewritten.
-    runtimeLibrary.interceptorFunction.accept(transformer);
-  }
-  builder.createDeclarations();
-  component = component.accept(new Erasure(transformer));
-  // TODO(karlklose): skip checks in debug mode
-  verifyComponent(component);
-  return component;
-}
-
-Component transformComponent(CoreTypes coreTypes, Component component) {
-  RuntimeLibrary runtimeLibrary = findRuntimeTypeLibrary(component);
-  Library mainLibrary = component.mainMethod.enclosingLibrary;
-  return transformComponentUsingLibraries(
-      coreTypes, component, runtimeLibrary, mainLibrary);
-}
-
-main(List<String> arguments) async {
-  String path = arguments.first;
-  Uri output;
-  if (arguments.length > 1) {
-    output = Uri.base.resolve(arguments[1]);
-  }
-  Uri uri = Uri.base.resolve(path);
-  Component component = loadComponentFromBinary(uri.toFilePath());
-  CoreTypes coreTypes = new CoreTypes(component);
-
-  RuntimeLibrary runtimeLibrary = findRuntimeTypeLibrary(component);
-  Library mainLibrary = component.mainMethod.enclosingLibrary;
-  component = transformComponentUsingLibraries(
-      coreTypes, component, runtimeLibrary, mainLibrary);
-
-  if (output == null) {
-    // Print result
-    StringBuffer sb = new StringBuffer();
-    Printer printer = new Printer(sb);
-    printer.writeLibraryFile(mainLibrary);
-    print("$sb");
-  } else {
-    IOSink sink = new File.fromUri(output).openWrite();
-    try {
-      new BinaryPrinter(sink).writeComponentFile(component);
-    } finally {
-      await sink.close();
-    }
-    try {
-      // Check that we can read the binary file.
-      loadComponentFromBinary(output.toFilePath());
-    } catch (e) {
-      print("Error when attempting to read $output.");
-      rethrow;
-    }
-  }
-}
diff --git a/pkg/kernel/lib/transformations/reify/transformation/binding.dart b/pkg/kernel/lib/transformations/reify/transformation/binding.dart
deleted file mode 100644
index 62aa638..0000000
--- a/pkg/kernel/lib/transformations/reify/transformation/binding.dart
+++ /dev/null
@@ -1,180 +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 kernel.transformations.reify.transformation.binding;
-
-import '../../../ast.dart';
-
-class RuntimeLibrary {
-  final Library typesLibrary;
-  final Library declarationsLibrary;
-  final Library interceptorsLibrary;
-
-  final Constructor dynamicTypeConstructor;
-  final Constructor interfaceTypeConstructor;
-  final Constructor declarationClassConstructor;
-  final Constructor functionTypeConstructor;
-  final Constructor voidTypeConstructor;
-
-  // The class used to mark instances that implement `$type`.
-  final Class markerClass;
-  final Class declarationClass;
-  final Class reifiedTypeClass;
-
-  DartType get typeType => reifiedTypeClass.rawType;
-
-  final Name variablesFieldName = new Name("variables");
-
-  /// The name of the field to create for the type information. This name is
-  /// extracted from the class `HasRuntimeTypeGetter`.
-  final Name runtimeTypeName;
-
-  final Procedure asInstanceOfFunction;
-  final Procedure isSubtypeOfFunction;
-  final Procedure typeArgumentsFunction;
-  final Procedure allocateDeclarationsFunction;
-  final Procedure initFunction;
-  final Procedure interceptorFunction;
-  final Procedure reifyFunction;
-  final Procedure attachTypeFunction;
-
-  factory RuntimeLibrary(Library typesLibrary, Library declarationsLibrary,
-      Library interceptorsLibrary) {
-    Class dynamicTypeClass;
-    Class interfaceTypeClass;
-    Class declarationClass;
-    Class functionTypeClass;
-    Class voidTypeClass;
-    Class markerClass;
-    Class reifiedTypeClass;
-
-    Procedure allocateDeclarationsFunction;
-    Procedure initFunction;
-    Procedure interceptorFunction;
-    Procedure reifyFunction;
-    Procedure attachTypeFunction;
-    Procedure asInstanceOfFunction;
-    Procedure isSubtypeOfFunction;
-    Procedure typeArgumentsFunction;
-
-    for (Procedure p in interceptorsLibrary.procedures) {
-      if (p.name.name == "type") {
-        interceptorFunction = p;
-      } else if (p.name.name == "reify") {
-        reifyFunction = p;
-      } else if (p.name.name == "attachType") {
-        attachTypeFunction = p;
-      }
-    }
-    for (Class c in interceptorsLibrary.classes) {
-      if (c.name == "HasRuntimeTypeGetter") {
-        markerClass = c;
-      }
-    }
-    for (Class c in typesLibrary.classes) {
-      if (c.name == 'Dynamic') {
-        dynamicTypeClass = c;
-      } else if (c.name == 'Interface') {
-        interfaceTypeClass = c;
-      } else if (c.name == 'FunctionType') {
-        functionTypeClass = c;
-      } else if (c.name == 'Void') {
-        voidTypeClass = c;
-      } else if (c.name == 'ReifiedType') {
-        reifiedTypeClass = c;
-      }
-    }
-    for (Procedure p in typesLibrary.procedures) {
-      if (p.name.name == "asInstanceOf") {
-        asInstanceOfFunction = p;
-      } else if (p.name.name == "isSubtypeOf") {
-        isSubtypeOfFunction = p;
-      } else if (p.name.name == "getTypeArguments") {
-        typeArgumentsFunction = p;
-      }
-    }
-    for (Procedure p in declarationsLibrary.procedures) {
-      if (p.name.name == "allocateDeclarations") {
-        allocateDeclarationsFunction = p;
-      } else if (p.name.name == "init") {
-        initFunction = p;
-      }
-    }
-    for (Class c in declarationsLibrary.classes) {
-      if (c.name == 'Class') {
-        declarationClass = c;
-      }
-    }
-
-    assert(dynamicTypeClass != null);
-    assert(declarationClass != null);
-    assert(interfaceTypeClass != null);
-    assert(functionTypeClass != null);
-    assert(voidTypeClass != null);
-    assert(markerClass != null);
-    assert(declarationClass != null);
-    assert(reifiedTypeClass != null);
-    assert(allocateDeclarationsFunction != null);
-    assert(initFunction != null);
-    assert(interceptorFunction != null);
-    assert(reifyFunction != null);
-    assert(attachTypeFunction != null);
-    assert(asInstanceOfFunction != null);
-    assert(isSubtypeOfFunction != null);
-    assert(typeArgumentsFunction != null);
-
-    return new RuntimeLibrary._(
-        markerClass.procedures.single.name,
-        typesLibrary,
-        declarationsLibrary,
-        interceptorsLibrary,
-        markerClass,
-        declarationClass,
-        reifiedTypeClass,
-        dynamicTypeClass.constructors.single,
-        interfaceTypeClass.constructors.single,
-        declarationClass.constructors.single,
-        functionTypeClass.constructors.single,
-        voidTypeClass.constructors.single,
-        allocateDeclarationsFunction,
-        initFunction,
-        interceptorFunction,
-        reifyFunction,
-        attachTypeFunction,
-        asInstanceOfFunction,
-        isSubtypeOfFunction,
-        typeArgumentsFunction);
-  }
-
-  RuntimeLibrary._(
-      this.runtimeTypeName,
-      this.typesLibrary,
-      this.declarationsLibrary,
-      this.interceptorsLibrary,
-      this.markerClass,
-      this.declarationClass,
-      this.reifiedTypeClass,
-      this.dynamicTypeConstructor,
-      this.interfaceTypeConstructor,
-      this.declarationClassConstructor,
-      this.functionTypeConstructor,
-      this.voidTypeConstructor,
-      this.allocateDeclarationsFunction,
-      this.initFunction,
-      this.interceptorFunction,
-      this.reifyFunction,
-      this.attachTypeFunction,
-      this.asInstanceOfFunction,
-      this.isSubtypeOfFunction,
-      this.typeArgumentsFunction);
-
-  /// Returns `true` if [node] is defined in the runtime library.
-  bool contains(TreeNode node) {
-    while (node is! Library) {
-      node = node.parent;
-      if (node == null) return false;
-    }
-    return node == typesLibrary || node == declarationsLibrary;
-  }
-}
diff --git a/pkg/kernel/lib/transformations/reify/transformation/builder.dart b/pkg/kernel/lib/transformations/reify/transformation/builder.dart
deleted file mode 100644
index 7f0ea0e..0000000
--- a/pkg/kernel/lib/transformations/reify/transformation/builder.dart
+++ /dev/null
@@ -1,509 +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 kernel.transformations.reify.transformation.builder;
-
-import '../asts.dart';
-import '../../../ast.dart';
-import 'dart:collection' show LinkedHashMap;
-import 'binding.dart' show RuntimeLibrary;
-import '../../../core_types.dart' show CoreTypes;
-
-class Scope {
-  final Map<String, TreeNode> names = <String, TreeNode>{};
-
-  bool nameAlreadyTaken(String name, TreeNode node) {
-    TreeNode existing = names[name];
-    return existing != null && existing == node;
-  }
-
-  void add(String name, TreeNode node) {
-    assert(!nameAlreadyTaken(name, node));
-    names[name] = node;
-  }
-}
-
-class Namer {
-  final Scope scope;
-  Namer([Scope scope]) : this.scope = scope ?? new Scope();
-
-  String _getProposal(TreeNode node) {
-    if (node is Class) {
-      return node.name;
-    }
-    throw 'unsupported node: $node';
-  }
-
-  String getNameFor(TreeNode node) {
-    String base = _getProposal(node);
-    int id = 0;
-    String proposal = base;
-    while (scope.nameAlreadyTaken(proposal, node)) {
-      proposal = "$base${++id}";
-    }
-    scope.add(proposal, node);
-    return proposal;
-  }
-}
-
-class RuntimeTypeSupportBuilder {
-  // TODO(karlklose): group this together with other information about what
-  // needs to be built.
-  final LinkedHashMap<Class, int> reifiedClassIds =
-      new LinkedHashMap<Class, int>();
-
-  int currentDeclarationId = 0;
-
-  final Field declarations;
-
-  final RuntimeLibrary rtiLibrary;
-
-  final CoreTypes coreTypes;
-
-  final DartType declarationType;
-
-  RuntimeTypeSupportBuilder(
-      RuntimeLibrary rtiLibrary, CoreTypes coreTypes, Library mainLibrary)
-      : declarations = new Field(new Name(r"$declarations"),
-            isFinal: true, isStatic: true, fileUri: mainLibrary.fileUri),
-        declarationType = new InterfaceType(coreTypes.listClass,
-            <DartType>[rtiLibrary.declarationClass.rawType]),
-        rtiLibrary = rtiLibrary,
-        coreTypes = coreTypes {
-    mainLibrary.addMember(declarations);
-  }
-
-  int addDeclaration(Class cls) {
-    return reifiedClassIds.putIfAbsent(cls, () {
-      return currentDeclarationId++;
-    });
-  }
-
-  final Name indexOperatorName = new Name("[]");
-
-  MethodInvocation createArrayAccess(Expression target, int index) {
-    return new MethodInvocation(target, indexOperatorName,
-        new Arguments(<Expression>[new IntLiteral(index)]));
-  }
-
-  Expression createAccessDeclaration(Class cls) {
-    return createArrayAccess(new StaticGet(declarations), addDeclaration(cls));
-  }
-
-  Name getTypeTestTagName(Class cls) {
-    return new Name('\$is\$${cls.name}');
-  }
-
-  Name typeVariableGetterName(TypeParameter parameter) {
-    Class cls = getEnclosingClass(parameter);
-    return new Name("\$${cls.name}\$${parameter.name}");
-  }
-
-  // A call to a constructor or factory of a class that we have not transformed
-  // is wrapped in a call to `attachType`.
-  Expression attachTypeToConstructorInvocation(
-      InvocationExpression invocation, Member member) {
-    assert(member is Procedure && member.kind == ProcedureKind.Factory ||
-        member is Constructor);
-    Class targetClass = member.parent;
-    assert(targetClass != null);
-    DartType type = new InterfaceType(targetClass, invocation.arguments.types);
-    return callAttachType(invocation, type);
-  }
-
-  Expression callAttachType(Expression expression, DartType type) {
-    return new StaticInvocation(rtiLibrary.attachTypeFunction,
-        new Arguments(<Expression>[expression, createRuntimeType(type)]));
-  }
-
-  Expression createGetType(Expression receiver, {needsInterceptor: true}) {
-    if (receiver is ThisExpression || !needsInterceptor) {
-      return new PropertyGet(receiver, rtiLibrary.runtimeTypeName);
-    }
-    return new StaticInvocation(
-        rtiLibrary.interceptorFunction, new Arguments(<Expression>[receiver]));
-  }
-
-  Expression createGetTypeArguments(Expression typeObject) {
-    return new StaticInvocation(rtiLibrary.typeArgumentsFunction,
-        new Arguments(<Expression>[typeObject]));
-  }
-
-  // TODO(karlklose): consider adding a unique identifier for each test site.
-  /// `receiver.[subtypeTestName]([type])`
-  StaticInvocation createIsSubtypeOf(
-      Expression receiver, Expression typeExpression,
-      {targetHasTypeProperty: false}) {
-    Expression receiverType =
-        createGetType(receiver, needsInterceptor: !targetHasTypeProperty);
-    return new StaticInvocation(rtiLibrary.isSubtypeOfFunction,
-        new Arguments(<Expression>[receiverType, typeExpression]));
-  }
-
-  int getTypeVariableIndex(TypeParameter variable) {
-    Class c = getEnclosingClass(variable);
-    List<TypeParameter> variables = c.typeParameters;
-    for (int i = 0; i < variables.length; ++i) {
-      if (variables[i].name == variable.name) {
-        return i;
-      }
-    }
-    throw new Exception(
-        "Type variable $variable not found in enclosing class $c");
-  }
-
-  Expression createNewInterface(
-      Expression declaration, Expression typeArgumentList) {
-    List<Expression> arguments = <Expression>[declaration];
-    if (typeArgumentList != null) {
-      arguments.add(typeArgumentList);
-    }
-    return new ConstructorInvocation(
-        rtiLibrary.interfaceTypeConstructor, new Arguments(arguments));
-  }
-
-  /// Returns `true` if [types] is a list of [TypeParameterType]s that exactly
-  /// match the [TypeParameters] of the class they are defined in, i.e.,
-  ///   for all 0 <= i < cls.typeParameters.length.
-  ///     types[i].parameter == cls.typeParameters[i].
-  bool matchesTypeParameters(List<DartType> types) {
-    List<TypeParameter> parameters;
-    for (int i = 0; i < types.length; ++i) {
-      var type = types[i];
-      if (type is TypeParameterType) {
-        if (parameters == null) {
-          Class cls = getEnclosingClass(type.parameter);
-          parameters = cls.typeParameters;
-          if (parameters.length != types.length) return false;
-        }
-        if (type.parameter != parameters[i]) {
-          return false;
-        }
-      } else {
-        return false;
-      }
-    }
-    return true;
-  }
-
-  // TODO(karlklose): Refactor into visitor.
-  // TODO(karlklose): split this method in different strategies.
-  /// Creates an expression to represent a runtime type instance of type [type].
-  Expression createRuntimeType(DartType type,
-      {reifyTypeVariable: false,
-      Expression createReference(Class cls),
-      VariableDeclaration typeContext}) {
-    Expression buildReifiedTypeVariable(TypeParameterType type) {
-      Expression typeVariables = new PropertyGet(
-          createReference(type.parameter.parent),
-          rtiLibrary.variablesFieldName);
-      return createArrayAccess(
-          typeVariables, getTypeVariableIndex(type.parameter));
-    }
-
-    Expression buildDirectTypeVariableAccess(TypeParameterType variable) {
-      Class cls = getEnclosingClass(variable.parameter);
-      return extractTypeVariable(
-          cls,
-          variable.parameter,
-          getTypeVariableIndex(variable.parameter),
-          new VariableGet(typeContext));
-    }
-
-    Expression buildGetterTypeVariableAccess(TypeParameterType type) {
-      return new PropertyGet(
-          new ThisExpression(), typeVariableGetterName(type.parameter));
-    }
-
-    Expression buildTypeVariable(TypeParameterType type) {
-      if (reifyTypeVariable) {
-        assert(typeContext == null);
-        return buildReifiedTypeVariable(type);
-      } else if (typeContext != null) {
-        return buildDirectTypeVariableAccess(type);
-      } else {
-        return buildGetterTypeVariableAccess(type);
-      }
-    }
-
-    createReference ??= createAccessDeclaration;
-
-    /// Helper to make recursive invocation more readable.
-    Expression createPart(DartType type) {
-      return createRuntimeType(type,
-          reifyTypeVariable: reifyTypeVariable,
-          createReference: createReference,
-          typeContext: typeContext);
-    }
-
-    if (type is InterfaceType || type is Supertype) {
-      InterfaceType interfaceType =
-          (type is InterfaceType) ? type : (type as Supertype).asInterfaceType;
-      Class cls = interfaceType.classNode;
-      Expression declaration = createReference(cls);
-      List<DartType> typeArguments = interfaceType.typeArguments;
-      Expression typeArgumentList;
-      if (typeArguments.isNotEmpty) {
-        if (!reifyTypeVariable && matchesTypeParameters(typeArguments)) {
-          // The type argument list corresponds to the list of type parameters
-          // and we are not in "declaration emitter" mode, we can reuse the
-          // type argument vector.
-          TypeParameterType parameterType = typeArguments[0];
-          Class cls = parameterType.parameter.parent;
-          Expression typeObject = typeContext != null
-              ? new VariableGet(typeContext)
-              : createGetType(new ThisExpression());
-          typeArgumentList =
-              createGetTypeArguments(createCallAsInstanceOf(typeObject, cls));
-        } else {
-          typeArgumentList =
-              new ListLiteral(typeArguments.map(createPart).toList());
-        }
-      }
-      return createNewInterface(declaration, typeArgumentList);
-    } else if (type is DynamicType) {
-      return new ConstructorInvocation(
-          rtiLibrary.dynamicTypeConstructor, new Arguments([]),
-          isConst: true);
-    } else if (type is TypeParameterType) {
-      return buildTypeVariable(type);
-    } else if (type is FunctionType) {
-      FunctionType functionType = type;
-      Expression returnType = createPart(functionType.returnType);
-      List<Expression> encodedParameterTypes =
-          functionType.positionalParameters.map(createPart).toList();
-      List<NamedType> namedParameters = functionType.namedParameters;
-      int data;
-      if (namedParameters.isNotEmpty) {
-        for (NamedType param in namedParameters) {
-          encodedParameterTypes.add(new StringLiteral(param.name));
-          encodedParameterTypes.add(createPart(param.type));
-        }
-        data = functionType.namedParameters.length << 1 | 1;
-      } else {
-        data = (functionType.positionalParameters.length -
-                functionType.requiredParameterCount) <<
-            1;
-      }
-      Expression functionTypeExpression = new ConstructorInvocation(
-          rtiLibrary.interfaceTypeConstructor,
-          new Arguments(
-              <Expression>[createReference(coreTypes.functionClass)]));
-      Arguments arguments = new Arguments(<Expression>[
-        functionTypeExpression,
-        returnType,
-        new IntLiteral(data),
-        new ListLiteral(encodedParameterTypes)
-      ]);
-      return new ConstructorInvocation(
-          rtiLibrary.functionTypeConstructor, arguments);
-    } else if (type is VoidType) {
-      return new ConstructorInvocation(
-          rtiLibrary.voidTypeConstructor, new Arguments(<Expression>[]));
-    }
-    return new InvalidExpression(null);
-  }
-
-  Expression createCallAsInstanceOf(Expression receiver, Class cls) {
-    return new StaticInvocation(rtiLibrary.asInstanceOfFunction,
-        new Arguments(<Expression>[receiver, createAccessDeclaration(cls)]));
-  }
-
-  /// `get get$<variable-name> => <get-type>.arguments[<variable-index>]`
-  Member createTypeVariableGetter(
-      Class cls, TypeParameter variable, int index) {
-    Expression type = createGetType(new ThisExpression());
-    Expression argument = extractTypeVariable(cls, variable, index, type);
-    return new Procedure(
-        typeVariableGetterName(variable),
-        ProcedureKind.Getter,
-        new FunctionNode(new ReturnStatement(argument),
-            returnType: rtiLibrary.typeType),
-        fileUri: cls.fileUri);
-  }
-
-  Expression extractTypeVariable(
-      Class cls, TypeParameter variable, int index, Expression typeObject) {
-    Expression type = createCallAsInstanceOf(typeObject, cls);
-    Expression arguments = new StaticInvocation(
-        rtiLibrary.typeArgumentsFunction, new Arguments(<Expression>[type]));
-    // TODO(karlklose): use the global index instead of the local one.
-    return createArrayAccess(arguments, index);
-  }
-
-  void insertAsFirstArgument(Arguments arguments, Expression expression) {
-    expression.parent = arguments;
-    arguments.positional.insert(0, expression);
-  }
-
-  /// Creates a call to the `init` function that completes the definition of a
-  /// class by setting its (direct) supertypes.
-  Expression createCallInit(
-      VariableDeclaration declarations,
-      int index,
-      InterfaceType supertype,
-      List<InterfaceType> interfaces,
-      FunctionType callableType) {
-    /// Helper to create a reference to the declaration in the declaration
-    /// list instead of the field to avoid cycles if that field's
-    /// initialization depends on the class we are currently initializing.
-    Expression createReference(Class declaration) {
-      int id = reifiedClassIds[declaration];
-      return createArrayAccess(new VariableGet(declarations), id);
-    }
-
-    bool isNotMarkerInterface(InterfaceType interface) {
-      return interface.classNode != rtiLibrary.markerClass;
-    }
-
-    Expression createLocalType(DartType type) {
-      if (type == null) return null;
-      return createRuntimeType(type,
-          reifyTypeVariable: true, createReference: createReference);
-    }
-
-    Expression supertypeExpression =
-        supertype == null ? new NullLiteral() : createLocalType(supertype);
-
-    List<Expression> interfaceTypes = interfaces
-        .where(isNotMarkerInterface)
-        .map(createLocalType)
-        .toList(growable: false);
-
-    Expression callableTypeExpression = createLocalType(callableType);
-
-    List<Expression> arguments = <Expression>[
-      new VariableGet(declarations),
-      new IntLiteral(index),
-      supertypeExpression,
-    ];
-
-    if (interfaceTypes.isNotEmpty || callableTypeExpression != null) {
-      arguments.add(new ListLiteral(interfaceTypes));
-      if (callableTypeExpression != null) {
-        arguments.add(callableTypeExpression);
-      }
-    }
-
-    return new StaticInvocation(
-        rtiLibrary.initFunction, new Arguments(arguments));
-  }
-
-  Expression createDeclarationsInitializer() {
-    List<Statement> statements = <Statement>[];
-    // Call function to allocate the class declarations given the names and
-    // number of type variables of the classes.
-    Namer classNamer = new Namer();
-    List<Expression> names = <Expression>[];
-    List<Expression> parameterCount = <Expression>[];
-    reifiedClassIds.keys.forEach((Class c) {
-      names.add(new StringLiteral(classNamer.getNameFor(c)));
-      parameterCount.add(new IntLiteral(c.typeParameters.length));
-    });
-    Expression namesList = new ListLiteral(names);
-    Expression parameterCountList = new ListLiteral(parameterCount);
-    StaticInvocation callAllocate = new StaticInvocation(
-        rtiLibrary.allocateDeclarationsFunction,
-        new Arguments(<Expression>[namesList, parameterCountList]));
-
-    VariableDeclaration parameter =
-        new VariableDeclaration("d", type: declarationType);
-
-    reifiedClassIds.forEach((Class cls, int id) {
-      if (cls == rtiLibrary.markerClass) return;
-
-      // If the class declares a `call` method, translate the signature to a
-      // reified type.
-      FunctionType callableType;
-      Procedure call = cls.procedures.firstWhere(
-          (Procedure p) => p.name.name == "call",
-          orElse: () => null);
-      if (call != null) {
-        FunctionNode function = call.function;
-
-        final namedParameters = new List<NamedType>();
-        for (VariableDeclaration v in function.namedParameters) {
-          namedParameters.add(new NamedType(v.name, v.type));
-        }
-
-        List<DartType> positionalArguments = function.positionalParameters
-            .map((VariableDeclaration v) => v.type)
-            .toList();
-        callableType = new FunctionType(
-            positionalArguments, function.returnType,
-            namedParameters: namedParameters,
-            requiredParameterCount: function.requiredParameterCount);
-      }
-      statements.add(new ExpressionStatement(createCallInit(
-          parameter,
-          id,
-          cls.supertype?.asInterfaceType,
-          cls.implementedTypes
-              .map((Supertype type) => type?.asInterfaceType)
-              .toList(),
-          callableType)));
-    });
-
-    statements.add(new ReturnStatement(new VariableGet(parameter)));
-
-    Expression function = new FunctionExpression(new FunctionNode(
-        new Block(statements),
-        positionalParameters: <VariableDeclaration>[parameter],
-        returnType: declarationType));
-
-    return new MethodInvocation(
-        function, new Name("call"), new Arguments(<Expression>[callAllocate]));
-  }
-
-  void createDeclarations() {
-    /// Recursively find all referenced classes in [type].
-    void collectNewReferencedClasses(DartType type, Set<Class> newClasses) {
-      if (type is InterfaceType || type is Supertype) {
-        InterfaceType interfaceType = null;
-        if (type is InterfaceType) {
-          interfaceType = type;
-        } else {
-          interfaceType = (type as Supertype).asInterfaceType;
-        }
-        Class cls = interfaceType.classNode;
-        if (!reifiedClassIds.containsKey(cls) && !newClasses.contains(cls)) {
-          newClasses.add(cls);
-        }
-
-        interfaceType.typeArguments.forEach((DartType argument) {
-          collectNewReferencedClasses(argument, newClasses);
-        });
-      }
-      // TODO(karlklose): function types
-    }
-
-    Iterable<Class> classes = reifiedClassIds.keys;
-    while (classes.isNotEmpty) {
-      Set<Class> newClasses = new Set<Class>();
-      for (Class c in classes) {
-        collectNewReferencedClasses(c.supertype?.asInterfaceType, newClasses);
-        c.implementedTypes.forEach((Supertype supertype) {
-          collectNewReferencedClasses(supertype?.asInterfaceType, newClasses);
-        });
-      }
-      for (Class newClass in newClasses) {
-        // Make sure that there is a declaration field for the class and its
-        // library's declaration list is setup.
-        addDeclaration(newClass);
-      }
-      classes = newClasses;
-    }
-    Expression initializer = createDeclarationsInitializer();
-    initializer.parent = declarations;
-    declarations.initializer = initializer;
-    declarations.type = declarationType;
-  }
-
-  Procedure createGetter(
-      Name name, Expression expression, Class cls, DartType type) {
-    return new Procedure(name, ProcedureKind.Getter,
-        new FunctionNode(new ReturnStatement(expression), returnType: type),
-        fileUri: cls.fileUri);
-  }
-}
diff --git a/pkg/kernel/lib/transformations/reify/transformation/remove_generics.dart b/pkg/kernel/lib/transformations/reify/transformation/remove_generics.dart
deleted file mode 100644
index 25d8fe6..0000000
--- a/pkg/kernel/lib/transformations/reify/transformation/remove_generics.dart
+++ /dev/null
@@ -1,143 +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 kernel.transformations.reify.transformation.remove_generics;
-
-import '../../../ast.dart';
-import 'transformer.dart';
-
-class Erasure extends Transformer with DartTypeVisitor<DartType> {
-  final ReifyVisitor reifyVisitor;
-
-  Erasure(this.reifyVisitor);
-
-  bool removeTypeParameters(Class cls) {
-    return reifyVisitor.needsTypeInformation(cls);
-  }
-
-  TreeNode removeTypeArgumentsOfConstructorCall(ConstructorInvocation node) {
-    Class cls = node.target.parent;
-    if (removeTypeParameters(cls)) {
-      node.arguments.types.clear();
-      Constructor target = node.target;
-      target.enclosingClass.typeParameters.clear();
-    }
-    return node;
-  }
-
-  TreeNode removeTypeArgumentsOfStaticCall(StaticInvocation node) {
-    if (node.target.parent is Class) {
-      Class cls = node.target.parent;
-      if (!removeTypeParameters(cls)) {
-        return node;
-      }
-    } else {
-      // If parent is a Library, then a global procedure is invoked, and it may
-      // be a generic function, so we need to remove type arguments anyway.
-      assert(node.target.parent is Library);
-    }
-    node.arguments.types.clear();
-    Procedure target = node.target;
-    target.function.typeParameters.clear();
-    return node;
-  }
-
-  TreeNode removeTypeArgumentOfMethodInvocation(MethodInvocation node) {
-    node.arguments.types.clear();
-    return node;
-  }
-
-  @override
-  defaultDartType(DartType type) => type;
-
-  @override
-  InterfaceType visitInterfaceType(InterfaceType type) {
-    if (removeTypeParameters(type.classNode)) {
-      return new InterfaceType(type.classNode, const <DartType>[]);
-    }
-    return type;
-  }
-
-  @override
-  TypedefType visitTypedefType(TypedefType type) {
-    throw 'Typedef types not implemented in erasure';
-  }
-
-  @override
-  Supertype visitSupertype(Supertype type) {
-    if (removeTypeParameters(type.classNode)) {
-      return new Supertype(type.classNode, const <DartType>[]);
-    }
-    return type;
-  }
-
-  @override
-  FunctionType visitFunctionType(FunctionType type) {
-    bool partHasChanged = false;
-
-    DartType translate(DartType type) {
-      DartType newType = type.accept(this);
-      if (newType != type) {
-        partHasChanged = true;
-        return newType;
-      } else {
-        return type;
-      }
-    }
-
-    DartType returnType = translate(type.returnType);
-    List<DartType> positionalTypes =
-        type.positionalParameters.map(translate).toList();
-    List<NamedType> namedParameters = new List<NamedType>();
-    for (NamedType param in type.namedParameters) {
-      namedParameters.add(new NamedType(param.name, translate(param.type)));
-    }
-    if (partHasChanged) {
-      return new FunctionType(positionalTypes, returnType,
-          namedParameters: namedParameters,
-          requiredParameterCount: type.requiredParameterCount);
-    } else {
-      return type;
-    }
-  }
-
-  @override
-  DynamicType visitTypeParameterType(_) => const DynamicType();
-
-  @override
-  DartType visitDartType(DartType type) {
-    return type.accept(this);
-  }
-
-  @override
-  StaticInvocation visitStaticInvocation(StaticInvocation node) {
-    node.transformChildren(this);
-    if (node.target.kind == ProcedureKind.Factory ||
-        node.target.kind == ProcedureKind.Method) {
-      node = removeTypeArgumentsOfStaticCall(node);
-    }
-    return node;
-  }
-
-  @override
-  ConstructorInvocation visitConstructorInvocation(ConstructorInvocation node) {
-    node.transformChildren(this);
-    return removeTypeArgumentsOfConstructorCall(node);
-  }
-
-  @override
-  Class visitClass(Class node) {
-    node.transformChildren(this);
-    if (removeTypeParameters(node)) {
-      node.typeParameters.clear();
-    }
-    return node;
-  }
-
-  @override
-  Expression visitMethodInvocation(MethodInvocation node) {
-    node.transformChildren(this);
-    return removeTypeArgumentOfMethodInvocation(node);
-  }
-}
diff --git a/pkg/kernel/lib/transformations/reify/transformation/transformer.dart b/pkg/kernel/lib/transformations/reify/transformation/transformer.dart
deleted file mode 100644
index 0ca6b87..0000000
--- a/pkg/kernel/lib/transformations/reify/transformation/transformer.dart
+++ /dev/null
@@ -1,624 +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 kernel.transformations.reify.transformation.transformer;
-
-import '../analysis/program_analysis.dart';
-import '../../../ast.dart';
-import 'binding.dart' show RuntimeLibrary;
-import 'builder.dart' show RuntimeTypeSupportBuilder;
-import 'dart:collection' show LinkedHashMap;
-import '../asts.dart';
-
-export 'binding.dart' show RuntimeLibrary;
-export 'builder.dart' show RuntimeTypeSupportBuilder;
-
-enum RuntimeTypeStorage {
-  none,
-  inheritedField,
-  field,
-  getter,
-}
-
-class TransformationContext {
-  /// Describes how the runtime type is stored on the object.
-  RuntimeTypeStorage runtimeTypeStorage;
-
-  /// Field added to store the runtime type if [runtimeType] is
-  /// [RuntimeTypeStorage.field].
-  Field runtimeTypeField;
-
-  /// The parameter for the type information introduced to the constructor or
-  /// to static initializers.
-  VariableDeclaration parameter;
-
-  /// A ordered collection of fields together with their initializers rewritten
-  /// to static initializer functions that can be used in the constructor's
-  /// initializer list.
-  /// The order is important because of possible side-effects in the
-  /// initializers.
-  LinkedHashMap<Field, Procedure> initializers;
-
-  // `true` if the visitor currently is in a field initializer, a initializer
-  // list of a constructor, or the body of a factory method. In these cases,
-  // type argument access is different than in an instance context, since `this`
-  // is not available.
-  bool inInitializer = false;
-
-  String toString() => "s: ${runtimeTypeStorage} f: $runtimeTypeField,"
-      " p: $parameter, i: $inInitializer";
-}
-
-abstract class DebugTrace {
-  static const bool debugTrace = false;
-
-  static const int lineLength = 80;
-
-  TransformationContext get context;
-
-  String getNodeLevel(TreeNode node) {
-    String level = "";
-    while (node != null && node is! Library) {
-      level = " $level";
-      node = node.parent;
-    }
-    return level;
-  }
-
-  String shorten(String s) {
-    return s.length > lineLength ? s.substring(0, lineLength) : s;
-  }
-
-  void trace(TreeNode node) {
-    if (debugTrace) {
-      String nodeText = node.toString().replaceAll("\n", " ");
-      print(shorten("trace:${getNodeLevel(node)}$context"
-          " [${node.runtimeType}] $nodeText"));
-    }
-  }
-}
-
-/// Rewrites a tree to remove generic types and runtime type checks and replace
-/// them with Dart objects.
-///
-/// Runtime types are stored in a field/getter called [runtimeTypeName] on the
-/// object, which for parameterized classes is initialized in the constructor.
-//  TODO(karlklose):
-//  - add a scoped namer
-//  - rewrite types (supertypes, implemented types)
-//  - rewrite as
-class ReifyVisitor extends Transformer with DebugTrace {
-  final RuntimeLibrary rtiLibrary;
-  final RuntimeTypeSupportBuilder builder;
-  final ProgramKnowledge knowledge;
-
-  ReifyVisitor(this.rtiLibrary, this.builder, this.knowledge,
-      [this.libraryToTransform]);
-
-  /// If not null, the transformation will only be applied to classes declared
-  /// in this library.
-  final Library libraryToTransform;
-
-  // TODO(karlklose): find a way to get rid of this state in the visitor.
-  TransformationContext context;
-
-  static const String genericMethodTypeParametersName = r"$typeParameters";
-
-  bool libraryShouldBeTransformed(Library library) {
-    return libraryToTransform == null || libraryToTransform == library;
-  }
-
-  bool needsTypeInformation(Class cls) {
-    return !isObject(cls) &&
-        !rtiLibrary.contains(cls) &&
-        libraryShouldBeTransformed(cls.enclosingLibrary);
-  }
-
-  bool usesTypeGetter(Class cls) {
-    return cls.typeParameters.isEmpty;
-  }
-
-  bool isObject(Class cls) {
-    // TODO(karlklose): use [CoreTypes].
-    return "$cls" == 'dart.core::Object';
-  }
-
-  Initializer addTypeAsArgument(initializer) {
-    assert(initializer is SuperInitializer ||
-        initializer is RedirectingInitializer);
-    Class cls = getEnclosingClass(initializer.target);
-    if (needsTypeInformation(cls) && !usesTypeGetter(cls)) {
-      // If the current class uses a getter for type information, we did not add
-      // a parameter to the constructor, but we can pass `null` as the value to
-      // initialize the type field, since it will be shadowed by the getter.
-      Expression type = (context.parameter != null)
-          ? new VariableGet(context.parameter)
-          : new NullLiteral();
-      builder.insertAsFirstArgument(initializer.arguments, type);
-    }
-    return initializer;
-  }
-
-  Expression interceptInstantiation(
-      InvocationExpression invocation, Member target) {
-    Class targetClass = target.parent;
-    Library targetLibrary = targetClass.parent;
-    Library currentLibrary = getEnclosingLibrary(invocation);
-    if (libraryShouldBeTransformed(currentLibrary) &&
-        !libraryShouldBeTransformed(targetLibrary) &&
-        !rtiLibrary.contains(target)) {
-      return builder.attachTypeToConstructorInvocation(invocation, target);
-    }
-    return invocation;
-  }
-
-  Expression createRuntimeType(DartType type) {
-    if (context?.inInitializer == true) {
-      // In initializer context, the instance type is provided in
-      // `context.parameter` as there is no `this`.
-      return builder.createRuntimeType(type, typeContext: context.parameter);
-    } else {
-      return builder.createRuntimeType(type);
-    }
-  }
-
-  TreeNode defaultTreeNode(TreeNode node) {
-    trace(node);
-    return super.defaultTreeNode(node);
-  }
-
-  Expression visitStaticInvocation(StaticInvocation invocation) {
-    trace(invocation);
-
-    invocation.transformChildren(this);
-
-    Procedure target = invocation.target;
-    if (target == rtiLibrary.reifyFunction) {
-      /// Rewrite calls to reify(TypeLiteral) to a reified type.
-      TypeLiteral literal = invocation.arguments.positional.single;
-      return createRuntimeType(literal.type);
-    } else if (target.kind == ProcedureKind.Factory) {
-      // Intercept calls to factories of classes we do not transform
-      return interceptInstantiation(invocation, target);
-    }
-
-    addTypeArgumentToGenericInvocation(invocation);
-
-    return invocation;
-  }
-
-  Library visitLibrary(Library library) {
-    trace(library);
-
-    if (libraryShouldBeTransformed(library)) {
-      library.transformChildren(this);
-    }
-    return library;
-  }
-
-  Expression visitConstructorInvocation(ConstructorInvocation invocation) {
-    invocation.transformChildren(this);
-    return interceptInstantiation(invocation, invocation.target);
-  }
-
-  Member getStaticInvocationTarget(InvocationExpression invocation) {
-    if (invocation is ConstructorInvocation) {
-      return invocation.target;
-    } else if (invocation is StaticInvocation) {
-      return invocation.target;
-    } else {
-      throw "Unexpected InvocationExpression $invocation.";
-    }
-  }
-
-  bool isInstantiation(TreeNode invocation) {
-    return invocation is ConstructorInvocation ||
-        invocation is StaticInvocation &&
-            invocation.target.kind == ProcedureKind.Factory;
-  }
-
-  bool isTypeVariable(DartType type) => type is TypeParameterType;
-
-  /// Add the runtime type as an extra argument to constructor invocations.
-  Arguments visitArguments(Arguments arguments) {
-    trace(arguments);
-
-    arguments.transformChildren(this);
-    TreeNode parent = arguments.parent;
-    if (isInstantiation(parent)) {
-      Class targetClass = getEnclosingClass(getStaticInvocationTarget(parent));
-      // Do not add the extra argument if the class does not need a type member
-      // or if it can be implemented as a getter.
-      if (!needsTypeInformation(targetClass) || usesTypeGetter(targetClass)) {
-        return arguments;
-      }
-
-      List<DartType> typeArguments = arguments.types;
-
-      Expression type =
-          createRuntimeType(new InterfaceType(targetClass, typeArguments));
-
-      builder.insertAsFirstArgument(arguments, type);
-    }
-    return arguments;
-  }
-
-  Field visitField(Field field) {
-    trace(field);
-
-    visitDartType(field.type);
-    for (Expression annotation in field.annotations) {
-      annotation.accept(this);
-    }
-    // Do not visit initializers, they have already been transformed when the
-    // class was handled.
-    return field;
-  }
-
-  /// Go through all initializers of fields and record a static initializer
-  /// function, if necessary.
-  void rewriteFieldInitializers(Class cls) {
-    assert(context != null);
-    context.initializers = new LinkedHashMap<Field, Procedure>();
-    List<Field> fields = cls.fields;
-    bool initializerRewritten = false;
-    for (Field field in fields) {
-      if (!initializerRewritten && knowledge.usedParameters(field).isEmpty) {
-        // This field needs no static initializer.
-        continue;
-      }
-
-      Expression initializer = field.initializer;
-      if (initializer == null || field.isStatic) continue;
-      // Declare a new variable that holds the type information and can be
-      // used to access type variables in initializer context.
-      // TODO(karlklose): some fields do not need the parameter.
-      VariableDeclaration typeObject = new VariableDeclaration(r"$type");
-      context.parameter = typeObject;
-      context.inInitializer = true;
-      // Translate the initializer while keeping track of whether there was
-      // already an initializers that required type information in
-      // [typeVariableUsedInInitializer].
-      initializer = initializer.accept(this);
-      context.parameter = null;
-      context.inInitializer = false;
-      // Create a static initializer function from the translated initializer
-      // expression and record it.
-      Name name = new Name("\$init\$${field.name.name}");
-      Statement body = new ReturnStatement(initializer);
-      Procedure staticInitializer = new Procedure(
-          name,
-          ProcedureKind.Method,
-          new FunctionNode(body,
-              positionalParameters: <VariableDeclaration>[typeObject]),
-          isStatic: true,
-          fileUri: cls.fileUri);
-      context.initializers[field] = staticInitializer;
-      // Finally, remove the initializer from the field.
-      field.initializer = null;
-    }
-  }
-
-  bool inheritsTypeProperty(Class cls) {
-    assert(needsTypeInformation(cls));
-    Class superclass = cls.superclass;
-    return needsTypeInformation(superclass);
-  }
-
-  Class visitClass(Class cls) {
-    trace(cls);
-
-    if (needsTypeInformation(cls)) {
-      context = new TransformationContext();
-      List<TypeParameter> typeParameters = cls.typeParameters;
-      if (usesTypeGetter(cls)) {
-        assert(typeParameters.isEmpty);
-        context.runtimeTypeStorage = RuntimeTypeStorage.getter;
-        Member getter = builder.createGetter(rtiLibrary.runtimeTypeName,
-            createRuntimeType(cls.rawType), cls, rtiLibrary.typeType);
-        cls.addMember(getter);
-      } else if (!inheritsTypeProperty(cls)) {
-        context.runtimeTypeStorage = RuntimeTypeStorage.field;
-        // TODO(karlklose): should we add the field to [Object]?
-        context.runtimeTypeField = new Field(rtiLibrary.runtimeTypeName,
-            fileUri: cls.fileUri, isFinal: true, type: rtiLibrary.typeType);
-        cls.addMember(context.runtimeTypeField);
-      } else {
-        context.runtimeTypeStorage = RuntimeTypeStorage.inheritedField;
-      }
-
-      for (int i = 0; i < typeParameters.length; ++i) {
-        TypeParameter variable = typeParameters[i];
-        cls.addMember(builder.createTypeVariableGetter(cls, variable, i));
-      }
-
-      // Tag the class as supporting the runtime type getter.
-      InterfaceType interfaceTypeForSupertype =
-          new InterfaceType(rtiLibrary.markerClass);
-      cls.implementedTypes.add(new Supertype(
-          interfaceTypeForSupertype.classNode,
-          interfaceTypeForSupertype.typeArguments));
-
-      // Before transforming the parts of the class declaration, rewrite field
-      // initializers that use type variables (or that would be called after one
-      // that does) to static functions that can be used from constructors.
-      rewriteFieldInitializers(cls);
-
-      // Add properties for declaration tests.
-      for (Class test in knowledge.classTests) {
-        if (test == rtiLibrary.markerClass) continue;
-
-        Procedure tag = builder.createGetter(
-            builder.getTypeTestTagName(test),
-            new BoolLiteral(isSuperClass(test, cls)),
-            cls,
-            builder.coreTypes.boolClass.rawType);
-        cls.addMember(tag);
-      }
-
-      // Add a runtimeType getter.
-      if (!usesTypeGetter(cls) && !inheritsTypeProperty(cls)) {
-        cls.addMember(new Procedure(
-            new Name("runtimeType"),
-            ProcedureKind.Getter,
-            new FunctionNode(
-                new ReturnStatement(new DirectPropertyGet(
-                    new ThisExpression(), context.runtimeTypeField)),
-                returnType: builder.coreTypes.typeClass.rawType),
-            fileUri: cls.fileUri));
-      }
-    }
-
-    cls.transformChildren(this);
-
-    // Add the static initializer functions. They have already been transformed.
-    if (context?.initializers != null) {
-      context.initializers.forEach((_, Procedure initializer) {
-        cls.addMember(initializer);
-      });
-    }
-
-    // TODO(karlklose): clear type arguments later, the order of class
-    // transformations otherwise influences the result.
-    // cls.typeParameters.clear();
-    context = null;
-    return cls;
-  }
-
-  // TODO(karlklose): replace with a structure that can answer also the question
-  // which tags must be overriden due to different values.
-  /// Returns `true` if [a] is a declaration used in a supertype of [b].
-  bool isSuperClass(Class a, Class b) {
-    if (b == null) return false;
-    if (a == b) return true;
-
-    if (isSuperClass(a, b.superclass)) {
-      return true;
-    }
-
-    Iterable<Class> interfaceClasses = b.implementedTypes
-        .map((Supertype type) => type.classNode)
-        .where((Class cls) => cls != rtiLibrary.markerClass);
-    return interfaceClasses
-        .any((Class declaration) => isSuperClass(a, declaration));
-  }
-
-  bool isConstructorOrFactory(TreeNode node) {
-    return isFactory(node) || node is Constructor;
-  }
-
-  bool isFactory(TreeNode node) {
-    return node is Procedure && node.kind == ProcedureKind.Factory;
-  }
-
-  bool needsParameterForRuntimeType(TreeNode node) {
-    if (!isConstructorOrFactory(node)) return false;
-
-    RuntimeTypeStorage access = context.runtimeTypeStorage;
-    assert(access != RuntimeTypeStorage.none);
-    return access == RuntimeTypeStorage.field ||
-        access == RuntimeTypeStorage.inheritedField;
-  }
-
-  FunctionNode visitFunctionNode(FunctionNode node) {
-    trace(node);
-
-    addTypeArgumentToGenericDeclaration(node);
-
-    // If we have a [TransformationContext] with a runtime type field and we
-    // translate a constructor or factory, we need a parameter that the code of
-    // initializers or the factory body can use to access type arguments.
-    // The parameter field in the context will be reset in the visit-method of
-    // the parent.
-    if (context != null && needsParameterForRuntimeType(node.parent)) {
-      assert(context.parameter == null);
-      // Create the parameter and insert it as the function's first parameter.
-      context.parameter = new VariableDeclaration(
-          rtiLibrary.runtimeTypeName.name,
-          type: rtiLibrary.typeType);
-      context.parameter.parent = node;
-      node.positionalParameters.insert(0, context.parameter);
-      node.requiredParameterCount++;
-    }
-    node.transformChildren(this);
-    return node;
-  }
-
-  SuperInitializer visitSuperInitializer(SuperInitializer initializer) {
-    initializer.transformChildren(this);
-    return addTypeAsArgument(initializer);
-  }
-
-  RedirectingInitializer visitRedirectingInitializer(
-      RedirectingInitializer initializer) {
-    initializer.transformChildren(this);
-    return addTypeAsArgument(initializer);
-  }
-
-  Procedure visitProcedure(Procedure procedure) {
-    trace(procedure);
-
-    transformList(procedure.annotations, this, procedure.parent);
-    // Visit the function body in a initializing context, if it is a factory.
-    context?.inInitializer = isFactory(procedure);
-    procedure.function?.accept(this);
-    context?.inInitializer = false;
-
-    context?.parameter = null;
-    return procedure;
-  }
-
-  Constructor visitConstructor(Constructor constructor) {
-    trace(constructor);
-
-    transformList(constructor.annotations, this, constructor);
-    if (constructor.function != null) {
-      constructor.function = constructor.function.accept(this);
-      constructor.function?.parent = constructor;
-    }
-
-    context?.inInitializer = true;
-    transformList(constructor.initializers, this, constructor);
-    context?.inInitializer = false;
-
-    if (context != null) {
-      if (context.runtimeTypeStorage == RuntimeTypeStorage.field) {
-        // Initialize the runtime type field with value given in the additional
-        // constructor parameter.
-        assert(context.parameter != null);
-        Initializer initializer = new FieldInitializer(
-            context.runtimeTypeField, new VariableGet(context.parameter));
-        initializer.parent = constructor;
-        constructor.initializers.insert(0, initializer);
-      }
-      if (context.initializers != null) {
-        // For each field that needed a static initializer function, initialize
-        // the field by calling the function.
-        List<Initializer> fieldInitializers = <Initializer>[];
-        context.initializers.forEach((Field field, Procedure initializer) {
-          assert(context.parameter != null);
-          Arguments argument =
-              new Arguments(<Expression>[new VariableGet(context.parameter)]);
-          fieldInitializers.add(new FieldInitializer(
-              field, new StaticInvocation(initializer, argument)));
-        });
-        constructor.initializers.insertAll(0, fieldInitializers);
-      }
-      context.parameter = null;
-    }
-
-    return constructor;
-  }
-
-  /// Returns `true` if the given type can be tested using type test tags.
-  ///
-  /// This implies that there are no subtypes of the [type] that are not
-  /// transformed.
-  bool typeSupportsTagTest(InterfaceType type) {
-    return needsTypeInformation(type.classNode);
-  }
-
-  Expression visitIsExpression(IsExpression expression) {
-    trace(expression);
-
-    expression.transformChildren(this);
-
-    if (getEnclosingLibrary(expression) == rtiLibrary.interceptorsLibrary) {
-      // In the interceptor library we need actual is-checks at the moment.
-      return expression;
-    }
-
-    Expression target = expression.operand;
-    DartType type = expression.type;
-
-    if (type is InterfaceType && typeSupportsTagTest(type)) {
-      assert(knowledge.classTests.contains(type.classNode));
-      bool checkArguments =
-          type.typeArguments.any((DartType type) => type is! DynamicType);
-      Class declaration = type.classNode;
-      VariableDeclaration typeExpression =
-          new VariableDeclaration(null, initializer: createRuntimeType(type));
-      VariableDeclaration targetValue =
-          new VariableDeclaration(null, initializer: target);
-      Expression markerClassTest = new IsExpression(
-          new VariableGet(targetValue), rtiLibrary.markerClass.rawType);
-      Expression tagCheck = new PropertyGet(new VariableGet(targetValue),
-          builder.getTypeTestTagName(declaration));
-      Expression check = new LogicalExpression(markerClassTest, "&&", tagCheck);
-      if (checkArguments) {
-        // TODO(karlklose): support a direct argument check, we already checked
-        // the declaration.
-        Expression uninterceptedCheck = new Let(
-            typeExpression,
-            builder.createIsSubtypeOf(
-                new VariableGet(targetValue), new VariableGet(typeExpression),
-                targetHasTypeProperty: true));
-        check = new LogicalExpression(check, "&&", uninterceptedCheck);
-      }
-      return new Let(targetValue, check);
-    } else {
-      return builder.createIsSubtypeOf(target, createRuntimeType(type));
-    }
-  }
-
-  Expression visitListLiteral(ListLiteral node) {
-    trace(node);
-    node.transformChildren(this);
-    return builder.callAttachType(
-        node,
-        new InterfaceType(
-            builder.coreTypes.listClass, <DartType>[node.typeArgument]));
-  }
-
-  Expression visitMapLiteral(MapLiteral node) {
-    trace(node);
-    node.transformChildren(this);
-    return builder.callAttachType(
-        node,
-        new InterfaceType(builder.coreTypes.mapClass,
-            <DartType>[node.keyType, node.valueType]));
-  }
-
-  Expression visitMethodInvocation(MethodInvocation node) {
-    node.transformChildren(this);
-    addTypeArgumentToGenericInvocation(node);
-    return node;
-  }
-
-  bool isGenericMethod(FunctionNode node) {
-    if (node.parent is Member) {
-      Member member = node.parent;
-      if (member is Constructor ||
-          member is Procedure && member.kind == ProcedureKind.Factory) {
-        return member.enclosingClass.typeParameters.length <
-            node.typeParameters.length;
-      }
-    }
-    return node.typeParameters.isNotEmpty;
-  }
-
-  void addTypeArgumentToGenericInvocation(InvocationExpression expression) {
-    if (expression.arguments.types.length > 0) {
-      ListLiteral genericMethodTypeParameters = new ListLiteral(
-          expression.arguments.types
-              .map(createRuntimeType)
-              .toList(growable: false),
-          typeArgument: rtiLibrary.typeType);
-      expression.arguments.named.add(new NamedExpression(
-          genericMethodTypeParametersName, genericMethodTypeParameters)
-        ..parent = expression.arguments);
-    }
-  }
-
-  void addTypeArgumentToGenericDeclaration(FunctionNode node) {
-    if (isGenericMethod(node)) {
-      VariableDeclaration genericMethodTypeParameters = new VariableDeclaration(
-          genericMethodTypeParametersName,
-          type: new InterfaceType(
-              builder.coreTypes.listClass, <DartType>[rtiLibrary.typeType]));
-      genericMethodTypeParameters.parent = node;
-      node.namedParameters.insert(0, genericMethodTypeParameters);
-    }
-  }
-}
diff --git a/pkg/kernel/lib/transformations/treeshaker.dart b/pkg/kernel/lib/transformations/treeshaker.dart
index 3fd7046..d615439 100644
--- a/pkg/kernel/lib/transformations/treeshaker.dart
+++ b/pkg/kernel/lib/transformations/treeshaker.dart
@@ -94,6 +94,9 @@
 class TreeShaker {
   final CoreTypes coreTypes;
   final ClosedWorldClassHierarchy hierarchy;
+  final ClassHierarchySubtypes hierarchySubtypes;
+  final Map<Class, int> numberedClasses;
+  final List<Class> classes;
   final Component component;
   final bool strongMode;
   final List<ProgramRoot> programRoots;
@@ -213,7 +216,7 @@
   }
 
   ClassRetention getClassRetention(Class classNode) {
-    int index = hierarchy.getClassIndex(classNode);
+    int index = numberedClasses[classNode];
     return _classRetention[index];
   }
 
@@ -227,11 +230,14 @@
 
   TreeShaker._internal(this.coreTypes, this.hierarchy, this.component,
       this.strongMode, this.programRoots)
-      : this._dispatchedNames = new List<Set<Name>>(hierarchy.classes.length),
+      : this._dispatchedNames = new List<Set<Name>>(hierarchy.numberOfClasses),
         this._usedMembersWithHost =
-            new List<Set<Member>>(hierarchy.classes.length),
+            new List<Set<Member>>(hierarchy.numberOfClasses),
         this._classRetention = new List<ClassRetention>.filled(
-            hierarchy.classes.length, ClassRetention.None) {
+            hierarchy.numberOfClasses, ClassRetention.None),
+        this.hierarchySubtypes = hierarchy.computeSubtypesInformation(),
+        this.numberedClasses = createMapNumberIndex(hierarchy.classes),
+        this.classes = new List<Class>.from(hierarchy.classes) {
     _visitor = new _TreeShakerVisitor(this);
     _covariantVisitor = new _ExternalTypeVisitor(this, isCovariant: true);
     _contravariantVisitor =
@@ -246,6 +252,14 @@
     }
   }
 
+  static Map<Class, int> createMapNumberIndex(Iterable<Class> classes) {
+    Map<Class, int> result = new Map<Class, int>();
+    for (Class class_ in classes) {
+      result[class_] = result.length;
+    }
+    return result;
+  }
+
   void _build() {
     if (component.mainMethod == null) {
       throw 'Cannot perform tree shaking on a component without a main method';
@@ -271,8 +285,8 @@
     // Mark overridden members in order to preserve abstract members as
     // necessary.
     if (strongMode) {
-      for (int i = hierarchy.classes.length - 1; i >= 0; --i) {
-        Class class_ = hierarchy.classes[i];
+      for (int i = classes.length - 1; i >= 0; --i) {
+        Class class_ = classes[i];
         if (isHierarchyUsed(class_)) {
           hierarchy.forEachOverridePair(class_,
               (Member ownMember, Member superMember, bool isSetter) {
@@ -305,7 +319,7 @@
   /// Registers the given name as seen in a dynamic dispatch, and discovers used
   /// instance members accordingly.
   void _addDispatchedName(Class receiver, Name name) {
-    int index = hierarchy.getClassIndex(receiver);
+    int index = numberedClasses[receiver];
     Set<Name> receiverNames = _dispatchedNames[index] ??= new Set<Name>();
     // TODO(asgerf): make use of selector arity and getter/setter kind
     if (receiverNames.add(name)) {
@@ -332,7 +346,7 @@
           }
         }
       }
-      var subtypes = hierarchy.getSubtypesOf(receiver);
+      var subtypes = hierarchySubtypes.getSubtypesOf(receiver);
       var receiverSet = _receiversOfName[name];
       _receiversOfName[name] = receiverSet == null
           ? subtypes
@@ -358,7 +372,7 @@
   /// Registers the given class as instantiated and discovers new dispatch
   /// target candidates accordingly.
   void _addInstantiatedClass(Class classNode) {
-    int index = hierarchy.getClassIndex(classNode);
+    int index = numberedClasses[classNode];
     ClassRetention retention = _classRetention[index];
     if (retention.index < ClassRetention.Instance.index) {
       _classRetention[index] = ClassRetention.Instance;
@@ -368,7 +382,7 @@
 
   /// Register that an external subclass of the given class may be instantiated.
   void _addInstantiatedExternalSubclass(Class classNode) {
-    int index = hierarchy.getClassIndex(classNode);
+    int index = numberedClasses[classNode];
     ClassRetention retention = _classRetention[index];
     if (retention.index < ClassRetention.ExternalInstance.index) {
       _classRetention[index] = ClassRetention.ExternalInstance;
@@ -491,7 +505,7 @@
 
   /// Registers the given class as being used in a type annotation.
   void _addClassUsedInType(Class classNode) {
-    int index = hierarchy.getClassIndex(classNode);
+    int index = numberedClasses[classNode];
     ClassRetention retention = _classRetention[index];
     if (retention.index < ClassRetention.Hierarchy.index) {
       _classRetention[index] = ClassRetention.Hierarchy;
@@ -516,7 +530,7 @@
   void _addStaticNamespace(TreeNode container) {
     assert(container is Class || container is Library);
     if (container is Class) {
-      int index = hierarchy.getClassIndex(container);
+      int index = numberedClasses[container];
       var oldRetention = _classRetention[index];
       if (oldRetention == ClassRetention.None) {
         _classRetention[index] = ClassRetention.Namespace;
@@ -537,7 +551,7 @@
     }
     if (host != null) {
       // Check if the member has been seen with this host before.
-      int index = hierarchy.getClassIndex(host);
+      int index = numberedClasses[host];
       Set<Member> members = _usedMembersWithHost[index] ??= new Set<Member>();
       if (!members.add(member)) return;
       _usedMembers.putIfAbsent(member, _makeIncompleteSummary);
diff --git a/pkg/kernel/lib/vm/constants_native_effects.dart b/pkg/kernel/lib/vm/constants_native_effects.dart
index dd9078b..3678749 100644
--- a/pkg/kernel/lib/vm/constants_native_effects.dart
+++ b/pkg/kernel/lib/vm/constants_native_effects.dart
@@ -65,8 +65,9 @@
             constant is IntConstant ? constant.value : null;
         int value;
         if (defines != null) {
-          value = defines.containsKey(name)
-              ? int.parse(defines[name], onError: (_) => defaultValue)
+          final String defineValue = defines[name];
+          value = defineValue != null
+              ? (int.tryParse(defineValue) ?? defaultValue)
               : defaultValue;
         } else {
           value = new int.fromEnvironment(name, defaultValue: defaultValue);
diff --git a/pkg/kernel/pubspec.yaml b/pkg/kernel/pubspec.yaml
index 9e5e4f8..d84856f 100644
--- a/pkg/kernel/pubspec.yaml
+++ b/pkg/kernel/pubspec.yaml
@@ -1,18 +1,20 @@
 name: kernel
-version: 0.3.0-alpha.12
+# Currently, kernel API is not stable and users should
+# not depend on semver semantics when depending on this package.
+version: 0.3.0
 author: Dart Team <misc@dartlang.org>
 description: Dart IR (Intermediate Representation)
 homepage: https://github.com/dart-lang/sdk/tree/master/pkg/kernel
 environment:
-  sdk: ">=1.8.0 <2.0.0"
+  sdk: '>=2.0.0-dev.48.0 <2.0.0'
 dependencies:
   path: ^1.3.9
   args: '>=0.13.4 <2.0.0'
   logging: ^0.11.2
   package_config: ^1.0.0
 dev_dependencies:
-  analyzer: '>=0.30.0 <0.32.0'
-  front_end: 0.1.0-alpha.12
+  analyzer: '>=0.31.0 <0.33.0'
+  front_end: 0.1.0
   test: ^0.12.15+6
   stack_trace: ^1.6.6
   ansicolor: ^0.0.9
diff --git a/pkg/kernel/test/class_hierarchy_bench.dart b/pkg/kernel/test/class_hierarchy_bench.dart
index 37877d5..cab6148 100644
--- a/pkg/kernel/test/class_hierarchy_bench.dart
+++ b/pkg/kernel/test/class_hierarchy_bench.dart
@@ -60,12 +60,23 @@
     hierarchies.add(buildHierarchy());
   }
 
+  List<Class> classes = hierarchies.first.classes.toList();
+
   int currentHierarchy = 0;
   ClosedWorldClassHierarchy getClassHierarchy() {
     currentHierarchy = (currentHierarchy + 1) % hierarchies.length;
     return hierarchies[currentHierarchy];
   }
 
+  {
+    var classHierarchy = getClassHierarchy();
+    if (classHierarchy is ClosedWorldClassHierarchy) {
+      for (Class class_ in classes) {
+        classHierarchy.hasProperSubtypes(class_);
+      }
+    }
+  }
+
   Random rnd = new Random(12345);
   const int numQueryTrials = 100000;
 
@@ -76,12 +87,11 @@
   watch.reset();
   for (int i = 0; i < numQueryTrials; i++) {
     var classHierarchy = getClassHierarchy();
-    int first = rnd.nextInt(classHierarchy.classes.length);
-    int second = rnd.nextInt(classHierarchy.classes.length);
-    Class firstClass = classHierarchy.classes[first];
-    Class secondClass = classHierarchy.classes[second];
+    int first = rnd.nextInt(classes.length);
+    int second = rnd.nextInt(classes.length);
+    Class firstClass = classes[first];
+    Class secondClass = classes[second];
     classHierarchy.isSubclassOf(firstClass, secondClass);
-    classHierarchy.isSubmixtureOf(firstClass, secondClass);
     classHierarchy.isSubtypeOf(firstClass, secondClass);
     classHierarchy.getClassAsInstanceOf(firstClass, secondClass);
   }
@@ -89,10 +99,10 @@
   watch.reset();
   for (int i = 0; i < numQueryTrials; i++) {
     var classHierarchy = getClassHierarchy();
-    int first = rnd.nextInt(classHierarchy.classes.length);
-    int second = rnd.nextInt(classHierarchy.classes.length);
-    Class firstClass = classHierarchy.classes[first];
-    Class secondClass = classHierarchy.classes[second];
+    int first = rnd.nextInt(classes.length);
+    int second = rnd.nextInt(classes.length);
+    Class firstClass = classes[first];
+    Class secondClass = classes[second];
     classHierarchy.isSubclassOf(firstClass, secondClass);
   }
   int subclassQueryTime = watch.elapsedMicroseconds;
@@ -100,21 +110,10 @@
   watch.reset();
   for (int i = 0; i < numQueryTrials; i++) {
     var classHierarchy = getClassHierarchy();
-    int first = rnd.nextInt(classHierarchy.classes.length);
-    int second = rnd.nextInt(classHierarchy.classes.length);
-    Class firstClass = classHierarchy.classes[first];
-    Class secondClass = classHierarchy.classes[second];
-    classHierarchy.isSubmixtureOf(firstClass, secondClass);
-  }
-  int submixtureQueryTime = watch.elapsedMicroseconds;
-
-  watch.reset();
-  for (int i = 0; i < numQueryTrials; i++) {
-    var classHierarchy = getClassHierarchy();
-    int first = rnd.nextInt(classHierarchy.classes.length);
-    int second = rnd.nextInt(classHierarchy.classes.length);
-    Class firstClass = classHierarchy.classes[first];
-    Class secondClass = classHierarchy.classes[second];
+    int first = rnd.nextInt(classes.length);
+    int second = rnd.nextInt(classes.length);
+    Class firstClass = classes[first];
+    Class secondClass = classes[second];
     classHierarchy.isSubtypeOf(firstClass, secondClass);
   }
   int subtypeQueryTime = watch.elapsedMicroseconds;
@@ -122,10 +121,10 @@
   watch.reset();
   for (int i = 0; i < numQueryTrials; i++) {
     var classHierarchy = getClassHierarchy();
-    int first = rnd.nextInt(classHierarchy.classes.length);
-    int second = rnd.nextInt(classHierarchy.classes.length);
-    Class firstClass = classHierarchy.classes[first];
-    Class secondClass = classHierarchy.classes[second];
+    int first = rnd.nextInt(classes.length);
+    int second = rnd.nextInt(classes.length);
+    Class firstClass = classes[first];
+    Class secondClass = classes[second];
     classHierarchy.getClassAsInstanceOf(firstClass, secondClass);
   }
   int asInstanceOfQueryTime = watch.elapsedMicroseconds;
@@ -133,21 +132,18 @@
   // Estimate the overhead from test case generation.
   watch.reset();
   for (int i = 0; i < numQueryTrials; i++) {
-    var classHierarchy = getClassHierarchy();
-    int first = rnd.nextInt(classHierarchy.classes.length);
-    int second = rnd.nextInt(classHierarchy.classes.length);
-    classHierarchy.classes[first];
-    classHierarchy.classes[second];
+    int first = rnd.nextInt(classes.length);
+    int second = rnd.nextInt(classes.length);
+    classes[first];
+    classes[second];
   }
   int queryNoise = watch.elapsedMicroseconds;
 
   subclassQueryTime -= queryNoise;
-  submixtureQueryTime -= queryNoise;
   subtypeQueryTime -= queryNoise;
   asInstanceOfQueryTime -= queryNoise;
 
   String subclassPerSecond = perSecond(subclassQueryTime, numQueryTrials);
-  String submixturePerSecond = perSecond(submixtureQueryTime, numQueryTrials);
   String subtypePerSecond = perSecond(subtypeQueryTime, numQueryTrials);
   String asInstanceOfPerSecond =
       perSecond(asInstanceOfQueryTime, numQueryTrials);
@@ -156,8 +152,8 @@
   watch.reset();
   for (int i = 0; i < numQueryTrials; i++) {
     var classHierarchy = getClassHierarchy();
-    int classId = rnd.nextInt(classHierarchy.classes.length);
-    Class classNode = classHierarchy.classes[classId];
+    int classId = rnd.nextInt(classes.length);
+    Class classNode = classes[classId];
     classHierarchy.getDispatchTarget(classNode, new Name('toString'));
   }
   int dispatchToStringTime = watch.elapsedMicroseconds;
@@ -165,8 +161,8 @@
   watch.reset();
   for (int i = 0; i < numQueryTrials; i++) {
     var classHierarchy = getClassHierarchy();
-    int classId = rnd.nextInt(classHierarchy.classes.length);
-    Class classNode = classHierarchy.classes[classId];
+    int classId = rnd.nextInt(classes.length);
+    Class classNode = classes[classId];
     classHierarchy.getDispatchTarget(classNode, new Name('getFloo'));
   }
   int dispatchGenericGetTime = watch.elapsedMicroseconds;
@@ -174,8 +170,8 @@
   watch.reset();
   for (int i = 0; i < numQueryTrials; i++) {
     var classHierarchy = getClassHierarchy();
-    int classId = rnd.nextInt(classHierarchy.classes.length);
-    Class classNode = classHierarchy.classes[classId];
+    int classId = rnd.nextInt(classes.length);
+    Class classNode = classes[classId];
     for (var _ in classHierarchy.getDispatchTargets(classNode)) {}
   }
   int dispatchAllTargetsTime = watch.elapsedMicroseconds;
@@ -184,8 +180,8 @@
   watch.reset();
   for (int i = 0; i < numQueryTrials; i++) {
     var classHierarchy = getClassHierarchy();
-    int classId = rnd.nextInt(classHierarchy.classes.length);
-    Class classNode = classHierarchy.classes[classId];
+    int classId = rnd.nextInt(classes.length);
+    Class classNode = classes[classId];
     classHierarchy.getInterfaceMember(classNode, new Name('toString'));
   }
   int interfaceToStringTime = watch.elapsedMicroseconds;
@@ -193,8 +189,8 @@
   watch.reset();
   for (int i = 0; i < numQueryTrials; i++) {
     var classHierarchy = getClassHierarchy();
-    int classId = rnd.nextInt(classHierarchy.classes.length);
-    Class classNode = classHierarchy.classes[classId];
+    int classId = rnd.nextInt(classes.length);
+    Class classNode = classes[classId];
     classHierarchy.getInterfaceMember(classNode, new Name('getFloo'));
   }
   int interfaceGenericGetTime = watch.elapsedMicroseconds;
@@ -202,8 +198,8 @@
   watch.reset();
   for (int i = 0; i < numQueryTrials; i++) {
     var classHierarchy = getClassHierarchy();
-    int classId = rnd.nextInt(classHierarchy.classes.length);
-    Class classNode = classHierarchy.classes[classId];
+    int classId = rnd.nextInt(classes.length);
+    Class classNode = classes[classId];
     for (var _ in classHierarchy.getInterfaceMembers(classNode)) {}
   }
   int interfaceAllTargetsTime = watch.elapsedMicroseconds;
@@ -211,9 +207,8 @@
   // Estimate overhead from test case generation.
   watch.reset();
   for (int i = 0; i < numQueryTrials; i++) {
-    var classHierarchy = getClassHierarchy();
-    int classId = rnd.nextInt(classHierarchy.classes.length);
-    classHierarchy.classes[classId];
+    int classId = rnd.nextInt(classes.length);
+    classes[classId];
   }
   int dispatchTargetNoise = watch.elapsedMicroseconds;
 
@@ -241,7 +236,7 @@
   watch.reset();
   var classHierarchy = getClassHierarchy();
   int numberOfOverridePairs = 0;
-  for (var class_ in classHierarchy.classes) {
+  for (var class_ in classes) {
     classHierarchy.forEachOverridePair(class_, (member, supermember, isSetter) {
       ++numberOfOverridePairs;
     });
@@ -251,13 +246,18 @@
   String overridePairsPerSecond =
       perSecond(overrideTime, numberOfOverridePairs);
 
-  List<int> depth = new List(classHierarchy.classes.length);
+  Map<Class, int> classIds = new Map<Class, int>();
+  for (Class class_ in classes) {
+    classIds[class_] = classIds.length;
+  }
+
+  List<int> depth = new List(classes.length);
   for (int i = 0; i < depth.length; ++i) {
     int parentDepth = 0;
-    var classNode = classHierarchy.classes[i];
+    var classNode = classes[i];
     for (var supertype in classNode.supers) {
       var superclass = supertype.classNode;
-      int index = classHierarchy.getClassIndex(superclass);
+      int index = classIds[superclass];
       if (!(index < i)) {
         throw '${classNode.name}($i) extends ${superclass.name}($index)';
       }
@@ -271,7 +271,7 @@
   double medianDepth = median(depth);
   int totalDepth = sum(depth);
 
-  int numberOfClasses = classHierarchy.classes.length;
+  int numberOfClasses = classes.length;
   String expenseHistogram =
       classHierarchy.getExpenseHistogram().skip(1).join(' ');
 
@@ -280,7 +280,6 @@
 build.cold: $coldBuildTime ms
 build.hot:  $hotBuildTime ms
 query.isSubclassOf:                 $subclassPerSecond
-query.isSubmixtureOf:               $submixturePerSecond
 query.isSubtypeOf:                  $subtypePerSecond
 query.getClassAsInstanceOf:         $asInstanceOfPerSecond
 query.getDispatchTarget(toString):  $dispatchToStringPerSecond
diff --git a/pkg/kernel/test/class_hierarchy_self_check.dart b/pkg/kernel/test/class_hierarchy_self_check.dart
index 486db45..ed26f7b 100644
--- a/pkg/kernel/test/class_hierarchy_self_check.dart
+++ b/pkg/kernel/test/class_hierarchy_self_check.dart
@@ -19,22 +19,17 @@
 void testClassHierarchyOnComponent(Component component, {bool verbose: false}) {
   BasicClassHierarchy basic = new BasicClassHierarchy(component);
   ClosedWorldClassHierarchy classHierarchy = new ClassHierarchy(component);
-  int total = classHierarchy.classes.length;
+  int total = classHierarchy.numberOfClasses;
   int progress = 0;
   for (var class1 in classHierarchy.classes) {
     for (var class2 in classHierarchy.classes) {
       bool isSubclass = classHierarchy.isSubclassOf(class1, class2);
-      bool isSubmixture = classHierarchy.isSubmixtureOf(class1, class2);
       bool isSubtype = classHierarchy.isSubtypeOf(class1, class2);
       var asInstance = classHierarchy.getClassAsInstanceOf(class1, class2);
       if (isSubclass != basic.isSubclassOf(class1, class2)) {
         fail('isSubclassOf(${class1.name}, ${class2.name}) returned '
             '$isSubclass but should be ${!isSubclass}');
       }
-      if (isSubmixture != basic.isSubmixtureOf(class1, class2)) {
-        fail('isSubmixtureOf(${class1.name}, ${class2.name}) returned '
-            '$isSubclass but should be ${!isSubclass}');
-      }
       if (isSubtype != basic.isSubtypeOf(class1, class2)) {
         fail('isSubtypeOf(${class1.name}, ${class2.name}) returned '
             '$isSubtype but should be ${!isSubtype}');
diff --git a/pkg/kernel/test/class_hierarchy_test.dart b/pkg/kernel/test/class_hierarchy_test.dart
index b9b1dc6..439da52 100644
--- a/pkg/kernel/test/class_hierarchy_test.dart
+++ b/pkg/kernel/test/class_hierarchy_test.dart
@@ -23,9 +23,9 @@
     return new ClassHierarchy(component);
   }
 
-  void test_applyChanges() {
+  void test_applyTreeChanges() {
     var a = addClass(new Class(name: 'A', supertype: objectSuper));
-    addClass(new Class(name: 'B', supertype: a.asThisSupertype));
+    var b = addClass(new Class(name: 'B', supertype: a.asThisSupertype));
 
     _assertTestLibraryText('''
 class A {}
@@ -33,12 +33,65 @@
 ''');
 
     // No updated classes, the same hierarchy.
-    expect(hierarchy.applyChanges([]), same(hierarchy));
+    expect(hierarchy.applyTreeChanges([], []), same(hierarchy));
+    expect(hierarchy.hasProperSubtypes(a), true);
 
-    // Has updated classes, a new hierarchy.
-    var newHierarchy = hierarchy.applyChanges([a]);
-    expect(newHierarchy, isNot(same(hierarchy)));
-    expect(newHierarchy, new isInstanceOf<ClosedWorldClassHierarchy>());
+    // Has updated classes, still the same hierarchy (instance). Can answer
+    // queries about the new classes.
+    var c = new Class(name: 'C', supertype: a.asThisSupertype);
+    expect(hierarchy.applyTreeChanges([b], [c]), same(hierarchy));
+    expect(hierarchy.isSubclassOf(a, c), false);
+    expect(hierarchy.isSubclassOf(c, a), true);
+    expect(hierarchy.hasProperSubtypes(a), true);
+
+    // Remove so A should no longer be a super of anything.
+    expect(hierarchy.applyTreeChanges([c], []), same(hierarchy));
+    expect(hierarchy.hasProperSubtypes(a), false);
+  }
+
+  void test_applyMemberChanges() {
+    var methodA1 = newEmptyMethod('memberA1');
+    var methodA2 = newEmptyMethod('memberA2');
+    var methodA3 = newEmptyMethod('memberA3');
+    var methodB1 = newEmptyMethod('memberB1');
+
+    var a = addClass(new Class(
+        name: 'A', supertype: objectSuper, procedures: [methodA1, methodA2]));
+    var b = addClass(new Class(
+        name: 'B', supertype: a.asThisSupertype, procedures: [methodB1]));
+
+    _assertTestLibraryText('''
+class A {
+  method memberA1() → void {}
+  method memberA2() → void {}
+}
+class B extends self::A {
+  method memberB1() → void {}
+}
+''');
+
+    // No changes: B has memberA1, memberA2 and memberB1;
+    // A has memberA1 and memberA2
+    expect(hierarchy.getDispatchTargets(b),
+        unorderedEquals([methodA1, methodA2, methodB1]));
+    expect(
+        hierarchy.getDispatchTargets(a), unorderedEquals([methodA1, methodA2]));
+
+    // Add a member to A, but only update A.
+    a.addMember(methodA3);
+    hierarchy.applyMemberChanges([a]);
+    expect(hierarchy.getDispatchTargets(b),
+        unorderedEquals([methodA1, methodA2, methodB1]));
+    expect(hierarchy.getDispatchTargets(a),
+        unorderedEquals([methodA1, methodA2, methodA3]));
+
+    // Apply member changes again, this time telling the hierarchy to find
+    // decendants.
+    hierarchy.applyMemberChanges([a], findDescendants: true);
+    expect(hierarchy.getDispatchTargets(b),
+        unorderedEquals([methodA1, methodA2, methodA3, methodB1]));
+    expect(hierarchy.getDispatchTargets(a),
+        unorderedEquals([methodA1, methodA2, methodA3]));
   }
 
   void test_getSingleTargetForInterfaceInvocation() {
@@ -84,12 +137,13 @@
 ''');
 
     ClosedWorldClassHierarchy cwch = hierarchy as ClosedWorldClassHierarchy;
+    ClassHierarchySubtypes cwchst = cwch.computeSubtypesInformation();
 
-    expect(cwch.getSingleTargetForInterfaceInvocation(methodInA), methodInB);
-    expect(cwch.getSingleTargetForInterfaceInvocation(methodInB),
+    expect(cwchst.getSingleTargetForInterfaceInvocation(methodInA), methodInB);
+    expect(cwchst.getSingleTargetForInterfaceInvocation(methodInB),
         null); // B::foo and D::foo
-    expect(cwch.getSingleTargetForInterfaceInvocation(methodInD), methodInD);
-    expect(cwch.getSingleTargetForInterfaceInvocation(methodInE),
+    expect(cwchst.getSingleTargetForInterfaceInvocation(methodInD), methodInD);
+    expect(cwchst.getSingleTargetForInterfaceInvocation(methodInE),
         null); // no concrete subtypes
   }
 
@@ -129,15 +183,16 @@
 ''');
 
     ClosedWorldClassHierarchy cwch = hierarchy as ClosedWorldClassHierarchy;
+    ClassHierarchySubtypes cwchst = cwch.computeSubtypesInformation();
 
-    expect(cwch.getSubtypesOf(a), unorderedEquals([a, d, f, h]));
-    expect(cwch.getSubtypesOf(b), unorderedEquals([b, e, f]));
-    expect(cwch.getSubtypesOf(c), unorderedEquals([c, e, f, h]));
-    expect(cwch.getSubtypesOf(d), unorderedEquals([d]));
-    expect(cwch.getSubtypesOf(e), unorderedEquals([e, f]));
-    expect(cwch.getSubtypesOf(f), unorderedEquals([f]));
-    expect(cwch.getSubtypesOf(g), unorderedEquals([g, h]));
-    expect(cwch.getSubtypesOf(h), unorderedEquals([h]));
+    expect(cwchst.getSubtypesOf(a), unorderedEquals([a, d, f, h]));
+    expect(cwchst.getSubtypesOf(b), unorderedEquals([b, e, f]));
+    expect(cwchst.getSubtypesOf(c), unorderedEquals([c, e, f, h]));
+    expect(cwchst.getSubtypesOf(d), unorderedEquals([d]));
+    expect(cwchst.getSubtypesOf(e), unorderedEquals([e, f]));
+    expect(cwchst.getSubtypesOf(f), unorderedEquals([f]));
+    expect(cwchst.getSubtypesOf(g), unorderedEquals([g, h]));
+    expect(cwchst.getSubtypesOf(h), unorderedEquals([h]));
   }
 }
 
@@ -583,33 +638,6 @@
     expect(hierarchy.getClassAsInstanceOf(z, a), null);
   }
 
-  void test_getClassDepth() {
-    var base = addClass(new Class(name: 'base', supertype: objectSuper));
-    var extends_ =
-        addClass(new Class(name: 'extends_', supertype: base.asThisSupertype));
-    var with_ = addClass(new Class(
-        name: 'with_',
-        supertype: objectSuper,
-        mixedInType: base.asThisSupertype));
-    var implements_ = addClass(new Class(
-        name: 'implements_',
-        supertype: objectSuper,
-        implementedTypes: [base.asThisSupertype]));
-
-    _assertTestLibraryText('''
-class base {}
-class extends_ extends self::base {}
-class with_ = core::Object with self::base {}
-class implements_ implements self::base {}
-''');
-
-    expect(hierarchy.getClassDepth(objectClass), 0);
-    expect(hierarchy.getClassDepth(base), 1);
-    expect(hierarchy.getClassDepth(extends_), 2);
-    expect(hierarchy.getClassDepth(with_), 2);
-    expect(hierarchy.getClassDepth(implements_), 2);
-  }
-
   /// Copy of the tests/language/least_upper_bound_expansive_test.dart test.
   void test_getClassicLeastUpperBound_expansive() {
     var int = coreTypes.intClass.rawType;
@@ -1291,32 +1319,6 @@
     assertOrderOfClasses([c, b], [b, c]);
   }
 
-  void test_getRankedSuperclasses() {
-    var a = addImplementsClass('A', []);
-    var b = addImplementsClass('B', [a]);
-    var c = addImplementsClass('C', [a]);
-    var d = addImplementsClass('D', [c]);
-    var e = addImplementsClass('E', [b, d]);
-
-    _assertTestLibraryText('''
-class A {}
-class B implements self::A {}
-class C implements self::A {}
-class D implements self::C {}
-class E implements self::B, self::D {}
-''');
-
-    expect(hierarchy.getRankedSuperclasses(a), [a, objectClass]);
-    expect(hierarchy.getRankedSuperclasses(b), [b, a, objectClass]);
-    expect(hierarchy.getRankedSuperclasses(c), [c, a, objectClass]);
-    expect(hierarchy.getRankedSuperclasses(d), [d, c, a, objectClass]);
-    if (hierarchy.getClassIndex(b) < hierarchy.getClassIndex(c)) {
-      expect(hierarchy.getRankedSuperclasses(e), [e, d, b, c, a, objectClass]);
-    } else {
-      expect(hierarchy.getRankedSuperclasses(e), [e, d, c, b, a, objectClass]);
-    }
-  }
-
   void test_getTypeAsInstanceOf_generic_extends() {
     var int = coreTypes.intClass.rawType;
     var bool = coreTypes.boolClass.rawType;
diff --git a/pkg/kernel/test/closures/closures.status b/pkg/kernel/test/closures/closures.status
deleted file mode 100644
index 53fe05a..0000000
--- a/pkg/kernel/test/closures/closures.status
+++ /dev/null
@@ -1,3 +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.md file.
diff --git a/pkg/kernel/test/closures/suite.dart b/pkg/kernel/test/closures/suite.dart
deleted file mode 100644
index a993f2e..0000000
--- a/pkg/kernel/test/closures/suite.dart
+++ /dev/null
@@ -1,117 +0,0 @@
-// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE.md file.
-
-library test.kernel.closures.suite;
-
-import 'dart:io' show File, Platform;
-
-import 'dart:async' show Future;
-
-import 'package:kernel/core_types.dart' show CoreTypes;
-
-import 'package:testing/testing.dart'
-    show Chain, ChainContext, Result, Step, runMe, StdioProcess;
-
-import 'package:kernel/ast.dart' show Component, Library;
-
-import 'package:kernel/target/targets.dart' show Target;
-
-import 'package:front_end/src/fasta/testing/kernel_chain.dart'
-    show
-        Print,
-        MatchExpectation,
-        WriteDill,
-        ReadDill,
-        Verify,
-        Compile,
-        CompileContext;
-
-import 'package:kernel/transformations/closure_conversion.dart'
-    as closure_conversion;
-
-const String STRONG_MODE = " strong mode ";
-
-class ClosureConversionContext extends ChainContext implements CompileContext {
-  final bool strongMode;
-  Target get target => null;
-
-  final List<Step> steps;
-
-  Component platform;
-
-  ClosureConversionContext(this.strongMode, bool updateExpectations)
-      : steps = <Step>[
-          const Compile(),
-          const Print(),
-          const Verify(true),
-          const ClosureConversion(),
-          const Print(),
-          const Verify(true),
-          new MatchExpectation(".expect",
-              updateExpectations: updateExpectations),
-          const WriteDill(),
-          const ReadDill(),
-          const Run(),
-        ];
-
-  static Future<ClosureConversionContext> create(
-      Chain suite, Map<String, String> environment, bool strongMode) async {
-    bool updateExpectations = environment["updateExpectations"] == "true";
-    return new ClosureConversionContext(strongMode, updateExpectations);
-  }
-}
-
-Future<ClosureConversionContext> createContext(
-    Chain suite, Map<String, String> environment) async {
-  bool strongMode = environment.containsKey(STRONG_MODE);
-  environment["updateExpectations"] =
-      const String.fromEnvironment("updateExpectations");
-  return ClosureConversionContext.create(suite, environment, strongMode);
-}
-
-class ClosureConversion
-    extends Step<Component, Component, ClosureConversionContext> {
-  const ClosureConversion();
-
-  String get name => "closure conversion";
-
-  Future<Result<Component>> run(
-      Component component, ClosureConversionContext testContext) async {
-    try {
-      CoreTypes coreTypes = new CoreTypes(component);
-      Library library = component.libraries
-          .firstWhere((Library library) => library.importUri.scheme != "dart");
-      closure_conversion.transformLibraries(coreTypes, <Library>[library]);
-      return pass(component);
-    } catch (e, s) {
-      return crash(e, s);
-    }
-  }
-}
-
-class Run extends Step<Uri, int, ClosureConversionContext> {
-  const Run();
-
-  String get name => "run";
-
-  Future<Result<int>> run(Uri uri, ClosureConversionContext context) async {
-    final File generated = new File.fromUri(uri);
-    try {
-      Uri vm = Uri.base.resolveUri(new Uri.file(Platform.resolvedExecutable));
-      final StdioProcess process = await StdioProcess.run(vm.toFilePath(), [
-        "--reify",
-        "--reify_generic_functions",
-        "-c",
-        generated.path,
-        "Hello, World!"
-      ]);
-      print(process.output);
-      return process.toResult();
-    } finally {
-      generated.parent.delete(recursive: true);
-    }
-  }
-}
-
-main(List<String> arguments) => runMe(arguments, createContext, "testing.json");
diff --git a/pkg/kernel/test/closures/testing.json b/pkg/kernel/test/closures/testing.json
deleted file mode 100644
index 1351cd2..0000000
--- a/pkg/kernel/test/closures/testing.json
+++ /dev/null
@@ -1,28 +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.md file.",
-  "packages": "../../../../.packages",
-  "suites": [
-    {
-      "name": "closures",
-      "kind": "Chain",
-      "source": "suite.dart",
-      "path": "../../testcases/closures/",
-      "status": "closures.status",
-      "pattern": [
-        "\\.dart$"
-      ],
-      "exclude": [
-        "/test/closures/suite\\.dart$"
-      ]
-    }
-  ],
-  "analyze": {
-    "uris": [
-      "suite.dart"
-    ],
-    "exclude": [
-    ]
-  }
-}
diff --git a/pkg/kernel/test/closures_initializers/closures_initializers.status b/pkg/kernel/test/closures_initializers/closures_initializers.status
deleted file mode 100644
index 3642988..0000000
--- a/pkg/kernel/test/closures_initializers/closures_initializers.status
+++ /dev/null
@@ -1,3 +0,0 @@
-# Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
-# for details. All rights reserved. Use of this source code is governed by a
-# BSD-style license that can be found in the LICENSE.md file.
diff --git a/pkg/kernel/test/closures_initializers/suite.dart b/pkg/kernel/test/closures_initializers/suite.dart
deleted file mode 100644
index d7176d4..0000000
--- a/pkg/kernel/test/closures_initializers/suite.dart
+++ /dev/null
@@ -1,116 +0,0 @@
-// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE.md file.
-
-library test.kernel.closures.suite;
-
-import 'dart:async' show Future;
-
-import 'package:kernel/core_types.dart' show CoreTypes;
-
-import 'package:testing/testing.dart'
-    show Chain, ChainContext, Result, Step, runMe;
-
-import 'package:kernel/ast.dart' show Component, Library;
-
-import 'package:kernel/transformations/argument_extraction.dart'
-    as argument_extraction;
-
-import 'package:kernel/target/targets.dart' show Target;
-
-import 'package:kernel/transformations/closure_conversion.dart'
-    as closure_conversion;
-
-import 'package:front_end/src/fasta/testing/kernel_chain.dart'
-    show
-        Compile,
-        CompileContext,
-        Print,
-        MatchExpectation,
-        WriteDill,
-        ReadDill,
-        Verify;
-
-const String STRONG_MODE = " strong mode ";
-
-class ClosureConversionContext extends ChainContext implements CompileContext {
-  final bool strongMode;
-
-  Target get target => null;
-
-  final List<Step> steps;
-
-  ClosureConversionContext(this.strongMode, bool updateExpectations)
-      : steps = <Step>[
-          const Compile(),
-          const Print(),
-          const Verify(true),
-          const ArgumentExtraction(),
-          const Print(),
-          const Verify(true),
-          const ClosureConversion(),
-          const Print(),
-          const Verify(true),
-          new MatchExpectation(".expect",
-              updateExpectations: updateExpectations),
-          const WriteDill(),
-          const ReadDill(),
-          // TODO(29143): add `Run` step when Vectors are added to VM.
-        ];
-
-  static Future<ClosureConversionContext> create(
-      Chain suite, Map<String, String> environment) async {
-    bool strongMode = environment.containsKey(STRONG_MODE);
-    bool updateExpectations = environment["updateExpectations"] == "true";
-    return new ClosureConversionContext(strongMode, updateExpectations);
-  }
-}
-
-Future<ClosureConversionContext> createContext(
-    Chain suite, Map<String, String> environment) async {
-  environment["updateExpectations"] =
-      const String.fromEnvironment("updateExpectations");
-  return ClosureConversionContext.create(suite, environment);
-}
-
-class ArgumentExtraction
-    extends Step<Component, Component, ClosureConversionContext> {
-  const ArgumentExtraction();
-
-  String get name => "argument extraction";
-
-  Future<Result<Component>> run(
-      Component component, ClosureConversionContext context) async {
-    try {
-      CoreTypes coreTypes = new CoreTypes(component);
-      Library library = component.libraries
-          .firstWhere((Library library) => library.importUri.scheme != "dart");
-      argument_extraction.transformLibraries(coreTypes, <Library>[library]);
-      return pass(component);
-    } catch (e, s) {
-      return crash(e, s);
-    }
-  }
-}
-
-class ClosureConversion
-    extends Step<Component, Component, ClosureConversionContext> {
-  const ClosureConversion();
-
-  String get name => "closure conversion";
-
-  Future<Result<Component>> run(
-      Component component, ClosureConversionContext testContext) async {
-    try {
-      CoreTypes coreTypes = new CoreTypes(component);
-      Library library = component.libraries
-          .firstWhere((Library library) => library.importUri.scheme != "dart");
-      closure_conversion.transformLibraries(coreTypes, <Library>[library]);
-      return pass(component);
-    } catch (e, s) {
-      return crash(e, s);
-    }
-  }
-}
-
-main(List<String> arguments) => runMe(arguments, createContext, "testing.json");
diff --git a/pkg/kernel/test/closures_initializers/testing.json b/pkg/kernel/test/closures_initializers/testing.json
deleted file mode 100644
index d098a2c..0000000
--- a/pkg/kernel/test/closures_initializers/testing.json
+++ /dev/null
@@ -1,28 +0,0 @@
-{
-  "":"Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file",
-  "":"for details. All rights reserved. Use of this source code is governed by a",
-  "":"BSD-style license that can be found in the LICENSE.md file.",
-  "packages": "../../../../.packages",
-  "suites": [
-    {
-      "name": "closures_initializers",
-      "kind": "Chain",
-      "source": "suite.dart",
-      "path": "../../testcases/closures_initializers/",
-      "status": "closures_initializers.status",
-      "pattern": [
-        "\\.dart$"
-      ],
-      "exclude": [
-        "/test/closures_initializers/suite\\.dart$"
-      ]
-    }
-  ],
-  "analyze": {
-    "uris": [
-      "suite.dart"
-    ],
-    "exclude": [
-    ]
-  }
-}
diff --git a/pkg/kernel/test/closures_test.dart b/pkg/kernel/test/closures_test.dart
deleted file mode 100644
index bb0d3e2..0000000
--- a/pkg/kernel/test/closures_test.dart
+++ /dev/null
@@ -1,15 +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.md file.
-
-library test.kernel.closures_test;
-
-import 'package:test/test.dart' show Timeout, test;
-
-import 'package:testing/testing.dart' show run;
-
-main() {
-  test("closures",
-      () => run([], ["closures"], "pkg/kernel/test/closures/testing.json"),
-      timeout: new Timeout(new Duration(minutes: 5)));
-}
diff --git a/pkg/kernel/test/closures_type_vars/closures_type_vars.status b/pkg/kernel/test/closures_type_vars/closures_type_vars.status
deleted file mode 100644
index 3642988..0000000
--- a/pkg/kernel/test/closures_type_vars/closures_type_vars.status
+++ /dev/null
@@ -1,3 +0,0 @@
-# Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
-# for details. All rights reserved. Use of this source code is governed by a
-# BSD-style license that can be found in the LICENSE.md file.
diff --git a/pkg/kernel/test/closures_type_vars/suite.dart b/pkg/kernel/test/closures_type_vars/suite.dart
deleted file mode 100644
index 866bf2c..0000000
--- a/pkg/kernel/test/closures_type_vars/suite.dart
+++ /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.md file.
-
-library test.kernel.closures_type_vars.suite;
-
-import 'dart:async' show Future;
-import 'package:testing/testing.dart' show Chain, runMe;
-import '../closures/suite.dart' show ClosureConversionContext;
-
-Future<ClosureConversionContext> createContext(
-    Chain suite, Map<String, String> environment) async {
-  environment["updateExpectations"] =
-      const String.fromEnvironment("updateExpectations");
-  return ClosureConversionContext.create(
-      suite, environment, true /*strongMode*/);
-}
-
-main(List<String> arguments) => runMe(arguments, createContext, "testing.json");
diff --git a/pkg/kernel/test/closures_type_vars/testing.json b/pkg/kernel/test/closures_type_vars/testing.json
deleted file mode 100644
index f072315..0000000
--- a/pkg/kernel/test/closures_type_vars/testing.json
+++ /dev/null
@@ -1,28 +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.md file.",
-  "packages": "../../../../.packages",
-  "suites": [
-    {
-      "name": "closures_type_vars",
-      "kind": "Chain",
-      "source": "suite.dart",
-      "path": "../../testcases/closures_type_vars/",
-      "status": "closures_type_vars.status",
-      "pattern": [
-        "\\.dart$"
-      ],
-      "exclude": [
-        "/test/closures_type_vars/suite\\.dart$"
-      ]
-    }
-  ],
-  "analyze": {
-    "uris": [
-      "suite.dart"
-    ],
-    "exclude": [
-    ]
-  }
-}
diff --git a/pkg/kernel/test/metadata_test.dart b/pkg/kernel/test/metadata_test.dart
index 1fb9777..4607413 100644
--- a/pkg/kernel/test/metadata_test.dart
+++ b/pkg/kernel/test/metadata_test.dart
@@ -14,16 +14,40 @@
     show computePlatformBinariesLocation;
 
 /// Test metadata: to each node we attach a metadata that contains
-/// a reference to this node's parent and this node formatted as string.
+/// * node formatted as string
+/// * reference to its enclosing member
+/// * type representing the first type parameter of its enclosing function
 class Metadata {
-  final TreeNode parent;
-  final String self;
+  final String string;
+  final Reference _memberRef;
+  final DartType type;
+
+  Member get member => _memberRef?.asMember;
 
   Metadata.forNode(TreeNode n)
-      : parent = MetadataRepository.isSupported(n.parent) ? n.parent : null,
-        self = n.toString();
+      : this(n.toString(), getMemberReference(getMemberForMetadata(n)),
+            getTypeForMetadata(n));
 
-  Metadata(this.parent, this.self);
+  Metadata(this.string, this._memberRef, this.type);
+}
+
+Member getMemberForMetadata(TreeNode node) {
+  final parent = node.parent;
+  if (parent == null) return null;
+  if (parent is Member) return parent;
+  return getMemberForMetadata(parent);
+}
+
+DartType getTypeForMetadata(TreeNode node) {
+  final parent = node.parent;
+  if (parent == null) return const VoidType();
+  if (parent is FunctionNode) {
+    if (parent.typeParameters.isEmpty) {
+      return const VoidType();
+    }
+    return new TypeParameterType(parent.typeParameters[0]);
+  }
+  return getTypeForMetadata(parent);
 }
 
 class TestMetadataRepository extends MetadataRepository<Metadata> {
@@ -33,15 +57,21 @@
 
   final Map<TreeNode, Metadata> mapping = <TreeNode, Metadata>{};
 
-  void writeToBinary(Metadata metadata, BinarySink sink) {
-    sink.writeNodeReference(metadata.parent);
-    sink.writeByteList(utf8.encode(metadata.self));
+  void writeToBinary(Metadata metadata, Node node, BinarySink sink) {
+    expect(metadata, equals(mapping[node]));
+    sink.writeByteList(utf8.encode(metadata.string));
+    sink.writeStringReference(metadata.string);
+    sink.writeCanonicalNameReference(metadata.member?.canonicalName);
+    sink.writeDartType(metadata.type);
   }
 
-  Metadata readFromBinary(BinarySource source) {
-    final parent = source.readNodeReference();
-    final string = utf8.decode(source.readByteList());
-    return new Metadata(parent, string);
+  Metadata readFromBinary(Node node, BinarySource source) {
+    final string1 = utf8.decode(source.readByteList());
+    final string2 = source.readStringReference();
+    final memberRef = source.readCanonicalNameReference()?.reference;
+    final type = source.readDartType();
+    expect(string1, equals(string2));
+    return new Metadata(string2, memberRef, type);
   }
 }
 
@@ -92,8 +122,9 @@
       final m = repository.mapping[node];
       final expected = new Metadata.forNode(node);
 
-      expect(m.parent, equals(expected.parent));
-      expect(m.self, equals(expected.self));
+      expect(m.string, equals(expected.string));
+      expect(m.member, equals(expected.member));
+      expect(m.type, equals(expected.type));
     }
   }
 
diff --git a/pkg/kernel/test/reify/reify.status b/pkg/kernel/test/reify/reify.status
deleted file mode 100644
index f4eda9b..0000000
--- a/pkg/kernel/test/reify/reify.status
+++ /dev/null
@@ -1,21 +0,0 @@
-# Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
-# for details. All rights reserved. Use of this source code is governed by a
-# BSD-style license that can be found in the LICENSE.md file.
-
-/generic_methods_unused_parameter_test: Crash
-/generic_methods_closure_test: Crash
-/generic_methods_generic_class_tearoff_test: Crash
-/generic_methods_local_variable_declaration_test: Crash
-/generic_methods_named_parameters_test: Crash
-/generic_methods_optional_parameters_test: Crash
-/generic_methods_recursive_bound_error_test: Crash
-/generic_methods_recursive_bound_test: Crash
-/generic_methods_reuse_type_variables_test: Crash
-/generic_methods_shadowing_test: Crash
-/generic_methods_simple_is_expression_test: Crash
-/generic_methods_tearoff_specialization_test: Crash
-/generic_methods_bounds_test: Fail
-/generic_methods_dynamic_dependent_type_error_test: Fail
-/generic_methods_dynamic_simple_error_test: Fail
-/generic_methods_dynamic_test: Fail
-/generic_methods_simple_as_expression_error_test: Fail
diff --git a/pkg/kernel/test/reify/suite.dart b/pkg/kernel/test/reify/suite.dart
deleted file mode 100644
index 768fbdc..0000000
--- a/pkg/kernel/test/reify/suite.dart
+++ /dev/null
@@ -1,155 +0,0 @@
-// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE.md file.
-
-library test.kernel.reify.suite;
-
-import 'dart:async' show Future;
-
-import 'dart:io' show Platform, File;
-
-import 'package:kernel/core_types.dart' show CoreTypes;
-
-import 'package:kernel/target/targets.dart' show Target, TargetFlags, getTarget;
-
-import 'package:kernel/target/vmcc.dart' show VmClosureConvertedTarget;
-
-import 'package:front_end/src/compute_platform_binaries_location.dart'
-    show computePlatformBinariesLocation;
-
-import 'package:front_end/src/fasta/testing/kernel_chain.dart'
-    show
-        Compile,
-        CompileContext,
-        MatchExpectation,
-        Print,
-        ReadDill,
-        Verify,
-        WriteDill;
-
-import 'package:testing/testing.dart'
-    show Chain, ChainContext, Result, StdioProcess, Step, runMe;
-
-import 'package:kernel/ast.dart' show Component;
-
-import 'package:kernel/transformations/generic_types_reification.dart'
-    as generic_types_reification;
-
-class TestContext extends ChainContext implements CompileContext {
-  final Uri vm;
-  final Uri platformUri;
-  final Uri platformBinaries;
-
-  @override
-  final Target target = new NotReifiedTarget(new TargetFlags(
-      strongMode: true,
-      kernelRuntime: Platform.script.resolve("../../runtime/")));
-
-  // Strong mode is required to keep the type arguments in invocations of
-  // generic methods.
-  @override
-  bool get strongMode => true;
-
-  final List<Step> steps;
-
-  TestContext(
-      this.vm, this.platformUri, this.platformBinaries, bool updateExpectations)
-      : steps = <Step>[
-          const Compile(),
-          const Print(),
-          const Verify(true),
-          const GenericTypesReification(),
-          const Print(),
-          const Verify(true),
-          new MatchExpectation(".expect",
-              updateExpectations: updateExpectations),
-          const WriteDill(),
-          const ReadDill(),
-          const Run(),
-        ];
-}
-
-enum Environment {
-  directory,
-  file,
-}
-
-Future<TestContext> createContext(
-    Chain suite, Map<String, String> environment) async {
-  Uri vm = Uri.base.resolveUri(new Uri.file(Platform.resolvedExecutable));
-  Uri platformBinaries = computePlatformBinariesLocation();
-  Uri platform = platformBinaries.resolve("vm_platform.dill");
-  bool updateExpectations = environment["updateExpectations"] == "true";
-  return new TestContext(vm, platform, platformBinaries, updateExpectations);
-}
-
-// [NotReifiedTarget] is intended to work as the [Target] class that
-// [VmGenericTypesReifiedTarget] inherits from, but with some transformations
-// disabled. Those include tree shaking and generic types information erasure
-// passes.
-// [NotReifiedTarget] also adds the necessary runtime libraries.
-class NotReifiedTarget extends VmClosureConvertedTarget {
-  NotReifiedTarget(TargetFlags flags) : super(flags);
-
-  @override
-  String get name => "not reified target";
-
-  // Tree shaking needs to be disabled, because Generic Types Reification
-  // transformation relies on certain runtime libraries to be present in
-  // the component that is being transformed. If the tree shaker is enabled,
-  // it just deletes everything from those libraries, because they aren't
-  // used in the component being transformed prior to the transformation.
-  @override
-  void performTreeShaking(CoreTypes coreTypes, Component component) {}
-
-  // Adds the necessary runtime libraries.
-  @override
-  List<String> get extraRequiredLibraries {
-    Target reifyTarget = getTarget("vmreify", this.flags);
-    var x = reifyTarget.extraRequiredLibraries;
-    return x;
-  }
-}
-
-class GenericTypesReification extends Step<Component, Component, TestContext> {
-  const GenericTypesReification();
-
-  String get name => "generic types reification";
-
-  Future<Result<Component>> run(
-      Component component, TestContext testContext) async {
-    try {
-      CoreTypes coreTypes = new CoreTypes(component);
-      component =
-          generic_types_reification.transformComponent(coreTypes, component);
-      return pass(component);
-    } catch (e, s) {
-      return crash(e, s);
-    }
-  }
-}
-
-class Run extends Step<Uri, int, TestContext> {
-  const Run();
-
-  String get name => "run";
-
-  bool get isAsync => true;
-
-  bool get isRuntime => true;
-
-  Future<Result<int>> run(Uri uri, TestContext context) async {
-    File generated = new File.fromUri(uri);
-    StdioProcess process;
-    try {
-      var args = [generated.path];
-      process = await StdioProcess.run(context.vm.toFilePath(), args);
-      print(process.output);
-    } finally {
-      generated.parent.delete(recursive: true);
-    }
-    return process.toResult();
-  }
-}
-
-main(List<String> arguments) => runMe(arguments, createContext, "testing.json");
diff --git a/pkg/kernel/test/reify/testing.json b/pkg/kernel/test/reify/testing.json
deleted file mode 100644
index 7b9fcaa..0000000
--- a/pkg/kernel/test/reify/testing.json
+++ /dev/null
@@ -1,29 +0,0 @@
-{
-"":"Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file",
-"":"for details. All rights reserved. Use of this source code is governed by a",
-"":"BSD-style license that can be found in the LICENSE.md file.",
-  "packages": "../../../../.packages",
-  "suites": [
-    {
-      "name": "reify",
-      "kind": "Chain",
-      "source": "suite.dart",
-      "path": "../../testcases/reify",
-      "status": "reify.status",
-      "pattern": [
-        "\\.dart$"
-      ],
-      "exclude": [
-        "/test/reify/suite\\.dart$",
-        "/testcases/reify/test_base\\.dart$"
-      ]
-    }
-  ],
-  "analyze": {
-    "uris": [
-      "suite.dart"
-    ],
-    "exclude": [
-    ]
-  }
-}
diff --git a/pkg/kernel/testcases/closures/README.md b/pkg/kernel/testcases/closures/README.md
deleted file mode 100644
index 290864f..0000000
--- a/pkg/kernel/testcases/closures/README.md
+++ /dev/null
@@ -1,9 +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.
--->
-# Running tests
-
-    export DART_AOT_SDK=.../xcodebuild/DerivedSources/DebugX64/patched_sdk
-    dart -c --packages=.packages package:testing/src/run_tests.dart test/closures/testing.json
diff --git a/pkg/kernel/testcases/closures/arity.dart b/pkg/kernel/testcases/closures/arity.dart
deleted file mode 100644
index e4285d5..0000000
--- a/pkg/kernel/testcases/closures/arity.dart
+++ /dev/null
@@ -1,28 +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.
-//
-// Test that closures check their argument count.
-//
-main() {
-  var closures = [
-    (x, y, [z]) {},
-    (x, y, z) {},
-    (x, y, {z}) {},
-    (x, y, z, w, v) {}
-  ];
-  for (var c in closures) {
-    bool ok = false;
-    try {
-      c(1, 2, 3, 4);
-    } on NoSuchMethodError catch (_) {
-      ok = true;
-    }
-    if (!ok) {
-      throw new Exception("Expected an error!");
-    }
-  }
-
-  (x, y, [z]) {}(1, 2);
-  (x, y, [z]) {}(1, 2, 3);
-}
diff --git a/pkg/kernel/testcases/closures/arity.dart.expect b/pkg/kernel/testcases/closures/arity.dart.expect
deleted file mode 100644
index bc1353f..0000000
--- a/pkg/kernel/testcases/closures/arity.dart.expect
+++ /dev/null
@@ -1,27 +0,0 @@
-library;
-import self as self;
-import "dart:core" as core;
-
-static method main() → dynamic {
-  dynamic closures = <dynamic>[MakeClosure<(dynamic, dynamic, [dynamic]) → dynamic>(self::closure#main#function, null), MakeClosure<(dynamic, dynamic, dynamic) → dynamic>(self::closure#main#function#1, null), MakeClosure<(dynamic, dynamic, {z: dynamic}) → dynamic>(self::closure#main#function#2, null), MakeClosure<(dynamic, dynamic, dynamic, dynamic, dynamic) → dynamic>(self::closure#main#function#3, null)];
-  for (dynamic c in closures) {
-    core::bool ok = false;
-    try {
-      c.call(1, 2, 3, 4);
-    }
-    on core::NoSuchMethodError catch(final core::NoSuchMethodError _) {
-      ok = true;
-    }
-    if(!ok) {
-      throw core::Exception::•("Expected an error!");
-    }
-  }
-  (MakeClosure<(dynamic, dynamic, [dynamic]) → dynamic>(self::closure#main#function#4, null)).call(1, 2);
-  (MakeClosure<(dynamic, dynamic, [dynamic]) → dynamic>(self::closure#main#function#5, null)).call(1, 2, 3);
-}
-static method closure#main#function(dynamic #contextParameter, dynamic x, dynamic y, [dynamic z]) → dynamic {}
-static method closure#main#function#1(dynamic #contextParameter, dynamic x, dynamic y, dynamic z) → dynamic {}
-static method closure#main#function#2(dynamic #contextParameter, dynamic x, dynamic y, {dynamic z}) → dynamic {}
-static method closure#main#function#3(dynamic #contextParameter, dynamic x, dynamic y, dynamic z, dynamic w, dynamic v) → dynamic {}
-static method closure#main#function#4(dynamic #contextParameter, dynamic x, dynamic y, [dynamic z]) → dynamic {}
-static method closure#main#function#5(dynamic #contextParameter, dynamic x, dynamic y, [dynamic z]) → dynamic {}
diff --git a/pkg/kernel/testcases/closures/blocks.dart b/pkg/kernel/testcases/closures/blocks.dart
deleted file mode 100644
index 82e7fe6..0000000
--- a/pkg/kernel/testcases/closures/blocks.dart
+++ /dev/null
@@ -1,52 +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.
-//
-// This test checks that we don't create duplicate local contexts in the same
-// function. It's modeled after the 'startIsolateMock' function which was broken
-// in the standard library.
-class X {}
-
-typedef dynamic fn(dynamic x);
-typedef dynamic fn2(dynamic x, dynamic y);
-
-void startIsolateMock(
-    dynamic parentPort,
-    dynamic entryPoint,
-    dynamic args,
-    dynamic message,
-    dynamic isSpawnUri,
-    dynamic controlPort,
-    List<dynamic> capabilities) {
-  if (controlPort != null) {
-    controlPort.handler = (dynamic _) {};
-  }
-  if (parentPort != null) {
-    dynamic readyMessage = new List<dynamic>(2);
-    readyMessage[0] = controlPort.sendPort;
-    readyMessage[1] = capabilities;
-    capabilities = null;
-    parentPort.send(readyMessage);
-  }
-  assert(capabilities == null);
-  dynamic port = "abc";
-  port.handler = (dynamic _) {
-    port.close();
-    if (isSpawnUri) {
-      if (entryPoint is fn2) {
-        entryPoint.call(args, message);
-      } else if (entryPoint is fn) {
-        entryPoint.call(args);
-      } else {
-        entryPoint.call();
-      }
-    } else {
-      entryPoint.call(message);
-    }
-  };
-  port.sendPort.send(null);
-}
-
-main() {
-  // No code here -- we just check that duplicate contexts aren't created above.
-}
diff --git a/pkg/kernel/testcases/closures/blocks.dart.expect b/pkg/kernel/testcases/closures/blocks.dart.expect
deleted file mode 100644
index 89fec93..0000000
--- a/pkg/kernel/testcases/closures/blocks.dart.expect
+++ /dev/null
@@ -1,56 +0,0 @@
-library;
-import self as self;
-import "dart:core" as core;
-
-typedef fn = (dynamic) → dynamic;
-typedef fn2 = (dynamic, dynamic) → dynamic;
-class X extends core::Object {
-  synthetic constructor •() → void
-    : super core::Object::•()
-    ;
-}
-static method startIsolateMock(dynamic parentPort, dynamic entryPoint, dynamic args, dynamic message, dynamic isSpawnUri, dynamic controlPort, core::List<dynamic> capabilities) → void {
-  final dynamic #context = MakeVector(7);
-  #context[2] = entryPoint;
-  entryPoint = null;
-  #context[3] = args;
-  args = null;
-  #context[4] = message;
-  message = null;
-  #context[5] = isSpawnUri;
-  isSpawnUri = null;
-  if(!controlPort.==(null)) {
-    controlPort.handler = MakeClosure<(dynamic) → dynamic>(self::closure#startIsolateMock#function, #context);
-  }
-  if(!parentPort.==(null)) {
-    dynamic readyMessage = core::List::_internal<dynamic>(2);
-    readyMessage.[]=(0, controlPort.sendPort);
-    readyMessage.[]=(1, capabilities);
-    capabilities = null;
-    parentPort.send(readyMessage);
-  }
-  assert(capabilities.==(null));
-  #context[6] = "abc";
-  (#context[6]).handler = MakeClosure<(dynamic) → dynamic>(self::closure#startIsolateMock#function#1, #context);
-  (#context[6]).sendPort.send(null);
-}
-static method main() → dynamic {}
-static method closure#startIsolateMock#function(dynamic #contextParameter, dynamic _) → dynamic {}
-static method closure#startIsolateMock#function#1(dynamic #contextParameter, dynamic _) → dynamic {
-  (#contextParameter[6]).close();
-  if(#contextParameter[5]) {
-    if((#contextParameter[2]) is (dynamic, dynamic) → dynamic) {
-      (#contextParameter[2]).call(#contextParameter[3], #contextParameter[4]);
-    }
-    else
-      if((#contextParameter[2]) is (dynamic) → dynamic) {
-        (#contextParameter[2]).call(#contextParameter[3]);
-      }
-      else {
-        (#contextParameter[2]).call();
-      }
-  }
-  else {
-    (#contextParameter[2]).call(#contextParameter[4]);
-  }
-}
diff --git a/pkg/kernel/testcases/closures/capture_closure.dart b/pkg/kernel/testcases/closures/capture_closure.dart
deleted file mode 100644
index cdfadf5..0000000
--- a/pkg/kernel/testcases/closures/capture_closure.dart
+++ /dev/null
@@ -1,9 +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.md file.
-
-main(arguments) {
-  f() => null;
-  g() => f();
-  g();
-}
diff --git a/pkg/kernel/testcases/closures/capture_closure.dart.expect b/pkg/kernel/testcases/closures/capture_closure.dart.expect
deleted file mode 100644
index 6019607..0000000
--- a/pkg/kernel/testcases/closures/capture_closure.dart.expect
+++ /dev/null
@@ -1,15 +0,0 @@
-library;
-import self as self;
-
-static method main(dynamic arguments) → dynamic {
-  final dynamic #context = MakeVector(3);
-  #context[2] = MakeClosure<() → dynamic>(self::closure#main#f, #context);
-  final () → dynamic g = MakeClosure<() → dynamic>(self::closure#main#g, #context);
-  g.call();
-}
-static method closure#main#f(dynamic #contextParameter) → dynamic {
-  return null;
-}
-static method closure#main#g(dynamic #contextParameter) → dynamic {
-  return (#contextParameter[2]).call();
-}
diff --git a/pkg/kernel/testcases/closures/capture_closure_parameter.dart b/pkg/kernel/testcases/closures/capture_closure_parameter.dart
deleted file mode 100644
index 9d14c08..0000000
--- a/pkg/kernel/testcases/closures/capture_closure_parameter.dart
+++ /dev/null
@@ -1,15 +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.md file.
-
-main(List<String> arguments) {
-  foo(x) {
-    bar() {
-      print(x);
-    }
-
-    return bar;
-  }
-
-  foo(arguments[0])();
-}
diff --git a/pkg/kernel/testcases/closures/capture_closure_parameter.dart.expect b/pkg/kernel/testcases/closures/capture_closure_parameter.dart.expect
deleted file mode 100644
index 636ef9e..0000000
--- a/pkg/kernel/testcases/closures/capture_closure_parameter.dart.expect
+++ /dev/null
@@ -1,19 +0,0 @@
-library;
-import self as self;
-import "dart:core" as core;
-
-static method main(core::List<core::String> arguments) → dynamic {
-  final (dynamic) → dynamic foo = MakeClosure<(dynamic) → dynamic>(self::closure#main#foo, null);
-  foo.call(arguments.[](0)).call();
-}
-static method closure#main#foo#bar(dynamic #contextParameter) → dynamic {
-  core::print(#contextParameter[2]);
-}
-static method closure#main#foo(dynamic #contextParameter, dynamic x) → dynamic {
-  final dynamic #context = MakeVector(3);
-  #context[1] = #contextParameter;
-  #context[2] = x;
-  x = null;
-  final () → dynamic bar = MakeClosure<() → dynamic>(self::closure#main#foo#bar, #context);
-  return bar;
-}
diff --git a/pkg/kernel/testcases/closures/capture_this.dart b/pkg/kernel/testcases/closures/capture_this.dart
deleted file mode 100644
index bde384d..0000000
--- a/pkg/kernel/testcases/closures/capture_this.dart
+++ /dev/null
@@ -1,18 +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.md file.
-
-class C {
-  var x;
-  m() => (v) => x = v;
-  f() => () => () => x;
-}
-
-main() {
-  C c = new C();
-  c.x = 41;
-  c.m()(42);
-  if (42 != c.x) throw "Unexpected value in c.x: ${c.x}";
-  var result = c.f()()();
-  if (42 != result) throw "Unexpected value from c.f()()(): $result";
-}
diff --git a/pkg/kernel/testcases/closures/capture_this.dart.expect b/pkg/kernel/testcases/closures/capture_this.dart.expect
deleted file mode 100644
index c12586a..0000000
--- a/pkg/kernel/testcases/closures/capture_this.dart.expect
+++ /dev/null
@@ -1,39 +0,0 @@
-library;
-import self as self;
-import "dart:core" as core;
-
-class C extends core::Object {
-  field dynamic x = null;
-  synthetic constructor •() → void
-    : super core::Object::•()
-    ;
-  method m() → dynamic {
-    final dynamic #context = MakeVector(3);
-    #context[2] = this;
-    return MakeClosure<(dynamic) → dynamic>(self::closure#C#m#function, #context);
-  }
-  method f() → dynamic {
-    final dynamic #context = MakeVector(3);
-    #context[2] = this;
-    return MakeClosure<() → dynamic>(self::closure#C#f#function, #context);
-  }
-}
-static method main() → dynamic {
-  self::C c = new self::C::•();
-  c.x = 41;
-  c.m().call(42);
-  if(!42.==(c.x))
-    throw "Unexpected value in c.x: ${c.x}";
-  dynamic result = c.f().call().call();
-  if(!42.==(result))
-    throw "Unexpected value from c.f()()(): ${result}";
-}
-static method closure#C#m#function(dynamic #contextParameter, dynamic v) → dynamic {
-  return (#contextParameter[2]).x = v;
-}
-static method closure#C#f#function#function(dynamic #contextParameter) → dynamic {
-  return (#contextParameter[2]).x;
-}
-static method closure#C#f#function(dynamic #contextParameter) → dynamic {
-  return MakeClosure<() → dynamic>(self::closure#C#f#function#function, #contextParameter);
-}
diff --git a/pkg/kernel/testcases/closures/captured_class_type_vars.dart b/pkg/kernel/testcases/closures/captured_class_type_vars.dart
deleted file mode 100644
index 5767a93..0000000
--- a/pkg/kernel/testcases/closures/captured_class_type_vars.dart
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE.md file.
-
-class Isgen<B> {
-  getfn() {
-    return (x) => x is B;
-  }
-}
-
-main() {
-  int x = 3;
-  var isgen = new Isgen<String>();
-  var iser = isgen.getfn();
-  assert(!iser(x));
-}
diff --git a/pkg/kernel/testcases/closures/captured_class_type_vars.dart.expect b/pkg/kernel/testcases/closures/captured_class_type_vars.dart.expect
deleted file mode 100644
index 479559a..0000000
--- a/pkg/kernel/testcases/closures/captured_class_type_vars.dart.expect
+++ /dev/null
@@ -1,21 +0,0 @@
-library;
-import self as self;
-import "dart:core" as core;
-
-class Isgen<B extends core::Object> extends core::Object {
-  synthetic constructor •() → void
-    : super core::Object::•()
-    ;
-  method getfn() → dynamic {
-    return MakeClosure<<B extends core::Object>(dynamic) → dynamic, self::Isgen::B>(self::closure#Isgen#getfn#function, MakeVector(1));
-  }
-}
-static method main() → dynamic {
-  core::int x = 3;
-  dynamic isgen = new self::Isgen::•<core::String>();
-  dynamic iser = isgen.getfn();
-  assert(!iser.call(x));
-}
-static method closure#Isgen#getfn#function<B extends core::Object>(dynamic #contextParameter, dynamic x) → dynamic {
-  return x is self::closure#Isgen#getfn#function::B;
-}
diff --git a/pkg/kernel/testcases/closures/catch.dart b/pkg/kernel/testcases/closures/catch.dart
deleted file mode 100644
index dcf383c..0000000
--- a/pkg/kernel/testcases/closures/catch.dart
+++ /dev/null
@@ -1,17 +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.md file.
-
-main() {
-  var c;
-  try {
-    throw "Fisk";
-  } on String catch (e, s) {
-    c = () {
-      print(e);
-      if (s != null) print(s);
-    };
-  }
-  c();
-  print("TEST PASSED");
-}
diff --git a/pkg/kernel/testcases/closures/catch.dart.expect b/pkg/kernel/testcases/closures/catch.dart.expect
deleted file mode 100644
index 572da81..0000000
--- a/pkg/kernel/testcases/closures/catch.dart.expect
+++ /dev/null
@@ -1,23 +0,0 @@
-library;
-import self as self;
-import "dart:core" as core;
-
-static method main() → dynamic {
-  dynamic c;
-  try {
-    throw "Fisk";
-  }
-  on core::String catch(dynamic #t1, dynamic #t2) {
-    final dynamic #context = MakeVector(4);
-    #context[2] = #t1;
-    #context[3] = #t2;
-    c = MakeClosure<() → dynamic>(self::closure#main#function, #context);
-  }
-  c.call();
-  core::print("TEST PASSED");
-}
-static method closure#main#function(dynamic #contextParameter) → dynamic {
-  core::print(#contextParameter[2]);
-  if(!(#contextParameter[3]).==(null))
-    core::print(#contextParameter[3]);
-}
diff --git a/pkg/kernel/testcases/closures/closure_in_constructor.dart b/pkg/kernel/testcases/closures/closure_in_constructor.dart
deleted file mode 100644
index e864ed4..0000000
--- a/pkg/kernel/testcases/closures/closure_in_constructor.dart
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE.md file.
-
-class C1 {
-  var x;
-  C1(y) : x = (() => print('Hello $y'));
-}
-
-class C2 {
-  var x;
-  C2(y) {
-    x = () => print('Hello $y');
-  }
-}
-
-main() {
-  new C1('hest').x();
-  new C2('naebdyr').x();
-}
diff --git a/pkg/kernel/testcases/closures/closure_in_constructor.dart.expect b/pkg/kernel/testcases/closures/closure_in_constructor.dart.expect
deleted file mode 100644
index 8046f99..0000000
--- a/pkg/kernel/testcases/closures/closure_in_constructor.dart.expect
+++ /dev/null
@@ -1,30 +0,0 @@
-library;
-import self as self;
-import "dart:core" as core;
-
-class C1 extends core::Object {
-  field dynamic x;
-  constructor •(dynamic y) → void
-    : final dynamic #context = MakeVector(3), dynamic #t1 = #context[2] = y, dynamic #t2 = y = null, self::C1::x = MakeClosure<() → dynamic>(self::closure#C1#function#function, #context), super core::Object::•()
-    ;
-}
-class C2 extends core::Object {
-  field dynamic x = null;
-  constructor •(dynamic y) → void
-    : super core::Object::•() {
-    final dynamic #context = MakeVector(3);
-    #context[2] = y;
-    y = null;
-    this.x = MakeClosure<() → dynamic>(self::closure#C2#function#function, #context);
-  }
-}
-static method main() → dynamic {
-  new self::C1::•("hest").x();
-  new self::C2::•("naebdyr").x();
-}
-static method closure#C1#function#function(dynamic #contextParameter) → dynamic {
-  return core::print("Hello ${#contextParameter[2]}");
-}
-static method closure#C2#function#function(dynamic #contextParameter) → dynamic {
-  return core::print("Hello ${#contextParameter[2]}");
-}
diff --git a/pkg/kernel/testcases/closures/closure_in_initializer.dart b/pkg/kernel/testcases/closures/closure_in_initializer.dart
deleted file mode 100644
index 14a94dd..0000000
--- a/pkg/kernel/testcases/closures/closure_in_initializer.dart
+++ /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.md file.
-
-class C {
-  var t;
-  C.foo(f, x) : t = (() => f(x)) {
-    x = 1;
-    print(x);
-  }
-}
-
-main() {
-  print(0);
-  var c = new C.foo((x) => print('hest${x}'), 0);
-  print(2);
-  c.t();
-  print(3);
-}
diff --git a/pkg/kernel/testcases/closures/closure_in_initializer.dart.expect b/pkg/kernel/testcases/closures/closure_in_initializer.dart.expect
deleted file mode 100644
index 520a509..0000000
--- a/pkg/kernel/testcases/closures/closure_in_initializer.dart.expect
+++ /dev/null
@@ -1,28 +0,0 @@
-library;
-import self as self;
-import "dart:core" as core;
-
-class C extends core::Object {
-  field dynamic t;
-  constructor foo(dynamic f, dynamic x) → void
-    : final dynamic #context = MakeVector(4), this self::C::foo#redir(f, x, #context)
-    ;
-  constructor foo#redir(dynamic f, dynamic x, final dynamic #context) → void
-    : dynamic #t1 = #context[2] = f, dynamic #t2 = f = null, dynamic #t3 = #context[3] = x, dynamic #t4 = x = null, self::C::t = MakeClosure<() → dynamic>(self::closure#C#foo#function, #context), super core::Object::•() {
-    #context[3] = 1;
-    core::print(#context[3]);
-  }
-}
-static method main() → dynamic {
-  core::print(0);
-  dynamic c = new self::C::foo(MakeClosure<(dynamic) → dynamic>(self::closure#main#function, null), 0);
-  core::print(2);
-  c.t();
-  core::print(3);
-}
-static method closure#C#foo#function(dynamic #contextParameter) → dynamic {
-  return (#contextParameter[2]).call(#contextParameter[3]);
-}
-static method closure#main#function(dynamic #contextParameter, dynamic x) → dynamic {
-  return core::print("hest${x}");
-}
diff --git a/pkg/kernel/testcases/closures/closure_in_initializer_closure.dart b/pkg/kernel/testcases/closures/closure_in_initializer_closure.dart
deleted file mode 100644
index 1cf175d..0000000
--- a/pkg/kernel/testcases/closures/closure_in_initializer_closure.dart
+++ /dev/null
@@ -1,26 +0,0 @@
-// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE.md file.
-
-class C {
-  var t;
-  C.foo(f)
-      : t = (() {
-          var prefix;
-          var g = (x) {
-            f("$prefix$x");
-          };
-          prefix = 'hest';
-          return g;
-        }) {
-    print(1);
-  }
-}
-
-main() {
-  print(0);
-  var c = new C.foo((x) => print(x));
-  print(2);
-  c.t()('fisk');
-  print(3);
-}
diff --git a/pkg/kernel/testcases/closures/closure_in_initializer_closure.dart.expect b/pkg/kernel/testcases/closures/closure_in_initializer_closure.dart.expect
deleted file mode 100644
index d056bab..0000000
--- a/pkg/kernel/testcases/closures/closure_in_initializer_closure.dart.expect
+++ /dev/null
@@ -1,32 +0,0 @@
-library;
-import self as self;
-import "dart:core" as core;
-
-class C extends core::Object {
-  field dynamic t;
-  constructor foo(dynamic f) → void
-    : final dynamic #context = MakeVector(3), dynamic #t1 = #context[2] = f, dynamic #t2 = f = null, self::C::t = MakeClosure<() → dynamic>(self::closure#C#foo#function, #context), super core::Object::•() {
-    core::print(1);
-  }
-}
-static method main() → dynamic {
-  core::print(0);
-  dynamic c = new self::C::foo(MakeClosure<(dynamic) → dynamic>(self::closure#main#function, null));
-  core::print(2);
-  c.t().call("fisk");
-  core::print(3);
-}
-static method closure#C#foo#function#function(dynamic #contextParameter, dynamic x) → dynamic {
-  (#contextParameter[1][2]).call("${#contextParameter[2]}${x}");
-}
-static method closure#C#foo#function(dynamic #contextParameter) → dynamic {
-  final dynamic #context = MakeVector(3);
-  #context[1] = #contextParameter;
-  #context[2] = null;
-  dynamic g = MakeClosure<(dynamic) → dynamic>(self::closure#C#foo#function#function, #context);
-  #context[2] = "hest";
-  return g;
-}
-static method closure#main#function(dynamic #contextParameter, dynamic x) → dynamic {
-  return core::print(x);
-}
diff --git a/pkg/kernel/testcases/closures/closure_types.dart b/pkg/kernel/testcases/closures/closure_types.dart
deleted file mode 100644
index 86fc3e0..0000000
--- a/pkg/kernel/testcases/closures/closure_types.dart
+++ /dev/null
@@ -1,55 +0,0 @@
-// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE.md file.
-//
-// This tests checks that the runtime types of converted closures are asessed
-// correctly in is-tests.
-
-class C<T> {
-  void getf() {
-    T fn(T x) {
-      return x;
-    }
-
-    ;
-    return fn;
-  }
-}
-
-typedef void ct(int x);
-
-void test_c() {
-  var x = new C<int>().getf();
-  assert(x is ct);
-
-  var y = new C<String>().getf();
-  assert(y is! ct);
-}
-
-class D<T> {
-  void getf<S>() {
-    T fn(S y) {
-      return null;
-    }
-
-    return fn;
-  }
-}
-
-typedef String dt(int x);
-
-void test_d() {
-  var x = new D<String>().getf<int>();
-  assert(x is dt);
-
-  var y = new D<int>().getf<int>();
-  assert(y is! dt);
-
-  var z = new D<int>().getf<String>();
-  assert(z is! dt);
-}
-
-main() {
-  test_c();
-  test_d();
-}
diff --git a/pkg/kernel/testcases/closures/closure_types.dart.expect b/pkg/kernel/testcases/closures/closure_types.dart.expect
deleted file mode 100644
index f9ad232..0000000
--- a/pkg/kernel/testcases/closures/closure_types.dart.expect
+++ /dev/null
@@ -1,49 +0,0 @@
-library;
-import self as self;
-import "dart:core" as core;
-
-typedef ct = (core::int) → void;
-typedef dt = (core::int) → core::String;
-class C<T extends core::Object> extends core::Object {
-  synthetic constructor •() → void
-    : super core::Object::•()
-    ;
-  method getf() → void {
-    final (self::C::T) → self::C::T fn = MakeClosure<<T extends core::Object>(T) → T, self::C::T>(self::closure#C#getf#fn, MakeVector(1));
-    ;
-    return fn;
-  }
-}
-class D<T extends core::Object> extends core::Object {
-  synthetic constructor •() → void
-    : super core::Object::•()
-    ;
-  method getf() → void {
-    final (dynamic) → self::D::T fn = MakeClosure<<T extends core::Object>(dynamic) → T, self::D::T>(self::closure#D#getf#fn, MakeVector(1));
-    return fn;
-  }
-}
-static method test_c() → void {
-  dynamic x = new self::C::•<core::int>().getf();
-  assert(x is (core::int) → void);
-  dynamic y = new self::C::•<core::String>().getf();
-  assert(!(y is (core::int) → void));
-}
-static method test_d() → void {
-  dynamic x = new self::D::•<core::String>().getf();
-  assert(x is (core::int) → core::String);
-  dynamic y = new self::D::•<core::int>().getf();
-  assert(!(y is (core::int) → core::String));
-  dynamic z = new self::D::•<core::int>().getf();
-  assert(!(z is (core::int) → core::String));
-}
-static method main() → dynamic {
-  self::test_c();
-  self::test_d();
-}
-static method closure#C#getf#fn<T extends core::Object>(dynamic #contextParameter, self::closure#C#getf#fn::T x) → self::closure#C#getf#fn::T {
-  return x;
-}
-static method closure#D#getf#fn<T extends core::Object>(dynamic #contextParameter, dynamic y) → self::closure#D#getf#fn::T {
-  return null;
-}
diff --git a/pkg/kernel/testcases/closures/closures.dart b/pkg/kernel/testcases/closures/closures.dart
deleted file mode 100644
index 545ad55..0000000
--- a/pkg/kernel/testcases/closures/closures.dart
+++ /dev/null
@@ -1,14 +0,0 @@
-// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE.md file.
-
-var f;
-
-foo() {
-  print(f(0));
-}
-
-main(arguments) {
-  f = (x) => arguments[x];
-  foo();
-}
diff --git a/pkg/kernel/testcases/closures/closures.dart.expect b/pkg/kernel/testcases/closures/closures.dart.expect
deleted file mode 100644
index c853baa..0000000
--- a/pkg/kernel/testcases/closures/closures.dart.expect
+++ /dev/null
@@ -1,18 +0,0 @@
-library;
-import self as self;
-import "dart:core" as core;
-
-static field dynamic f;
-static method foo() → dynamic {
-  core::print(self::f.call(0));
-}
-static method main(dynamic arguments) → dynamic {
-  final dynamic #context = MakeVector(3);
-  #context[2] = arguments;
-  arguments = null;
-  self::f = MakeClosure<(dynamic) → dynamic>(self::closure#main#function, #context);
-  self::foo();
-}
-static method closure#main#function(dynamic #contextParameter, dynamic x) → dynamic {
-  return (#contextParameter[2]).[](x);
-}
diff --git a/pkg/kernel/testcases/closures/contexts_in_field_initializers.dart b/pkg/kernel/testcases/closures/contexts_in_field_initializers.dart
deleted file mode 100644
index 36fc5c1..0000000
--- a/pkg/kernel/testcases/closures/contexts_in_field_initializers.dart
+++ /dev/null
@@ -1,31 +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.
-
-// The purpose of this test is to detect that no unnecessary contexts are
-// created when a constructor parameter is used in its field initializers.  No
-// contexts should be created either in the initializer or in the constructor
-// body.
-
-class X {}
-
-class A {
-  X x;
-  A(this.x) {}
-}
-
-class B {
-  X x;
-  B(X x) : x = x {
-    fn() {
-      print(x);
-    }
-
-    fn();
-  }
-}
-
-main() {
-  A a = new A(new X());
-  B b = new B(new X());
-}
diff --git a/pkg/kernel/testcases/closures/contexts_in_field_initializers.dart.expect b/pkg/kernel/testcases/closures/contexts_in_field_initializers.dart.expect
deleted file mode 100644
index 9a8f039..0000000
--- a/pkg/kernel/testcases/closures/contexts_in_field_initializers.dart.expect
+++ /dev/null
@@ -1,32 +0,0 @@
-library;
-import self as self;
-import "dart:core" as core;
-
-class X extends core::Object {
-  synthetic constructor •() → void
-    : super core::Object::•()
-    ;
-}
-class A extends core::Object {
-  field self::X x;
-  constructor •(self::X x) → void
-    : self::A::x = x, super core::Object::•() {}
-}
-class B extends core::Object {
-  field self::X x;
-  constructor •(self::X x) → void
-    : final dynamic #context = MakeVector(3), this self::B::#redir(x, #context)
-    ;
-  constructor #redir(self::X x, final dynamic #context) → void
-    : dynamic #t1 = #context[2] = x, dynamic #t2 = x = null, self::B::x = #context[2], super core::Object::•() {
-    final () → dynamic fn = MakeClosure<() → dynamic>(self::closure#B#function#fn, #context);
-    fn.call();
-  }
-}
-static method main() → dynamic {
-  self::A a = new self::A::•(new self::X::•());
-  self::B b = new self::B::•(new self::X::•());
-}
-static method closure#B#function#fn(dynamic #contextParameter) → dynamic {
-  core::print(#contextParameter[2]);
-}
diff --git a/pkg/kernel/testcases/closures/contexts_in_super_initializers.dart b/pkg/kernel/testcases/closures/contexts_in_super_initializers.dart
deleted file mode 100644
index 528b76b..0000000
--- a/pkg/kernel/testcases/closures/contexts_in_super_initializers.dart
+++ /dev/null
@@ -1,26 +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.
-
-// The purpose of this test is to detect that no unnecessary contexts are
-// created when a constructor parameter is used in its super initializer.  No
-// contexts should be created either in the initializer list or in the
-// constructor body.
-
-class X {}
-
-class Y {}
-
-class A {
-  X x;
-  Y y;
-  A(this.x, this.y);
-}
-
-class B extends A {
-  B(X x, Y y) : super(x, y) {}
-}
-
-main() {
-  B b = new B(new X(), new Y());
-}
diff --git a/pkg/kernel/testcases/closures/contexts_in_super_initializers.dart.expect b/pkg/kernel/testcases/closures/contexts_in_super_initializers.dart.expect
deleted file mode 100644
index 3fb0a71..0000000
--- a/pkg/kernel/testcases/closures/contexts_in_super_initializers.dart.expect
+++ /dev/null
@@ -1,28 +0,0 @@
-library;
-import self as self;
-import "dart:core" as core;
-
-class X extends core::Object {
-  synthetic constructor •() → void
-    : super core::Object::•()
-    ;
-}
-class Y extends core::Object {
-  synthetic constructor •() → void
-    : super core::Object::•()
-    ;
-}
-class A extends core::Object {
-  field self::X x;
-  field self::Y y;
-  constructor •(self::X x, self::Y y) → void
-    : self::A::x = x, self::A::y = y, super core::Object::•()
-    ;
-}
-class B extends self::A {
-  constructor •(self::X x, self::Y y) → void
-    : super self::A::•(x, y) {}
-}
-static method main() → dynamic {
-  self::B b = new self::B::•(new self::X::•(), new self::Y::•());
-}
diff --git a/pkg/kernel/testcases/closures/field.dart b/pkg/kernel/testcases/closures/field.dart
deleted file mode 100644
index 910a128..0000000
--- a/pkg/kernel/testcases/closures/field.dart
+++ /dev/null
@@ -1,25 +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.md file.
-
-var x = () => "x";
-
-class C<T> {
-  var v = (x) => x is T;
-
-  final y = () => "y";
-
-  static final z = () => "z";
-}
-
-main() {
-  if (!new C<String>().v("")) throw "C<String>.v false on String";
-  if (new C<String>().v(0)) throw "C<String>.v true on int";
-  if (new C<String>().v(null)) throw "C<String>.v true on null";
-  if (new C<int>().v("")) throw "C<int>.v true on String";
-  if (!new C<int>().v(0)) throw "C<int>.v false on int";
-  if (new C<int>().v(null)) throw "C<int>.v true on null";
-  if ("x" != x()) throw "x";
-  if ("y" != new C<String>().y()) throw "y";
-  if ("z" != C.z()) throw "z";
-}
diff --git a/pkg/kernel/testcases/closures/field.dart.expect b/pkg/kernel/testcases/closures/field.dart.expect
deleted file mode 100644
index 7136b0c9..0000000
--- a/pkg/kernel/testcases/closures/field.dart.expect
+++ /dev/null
@@ -1,45 +0,0 @@
-library;
-import self as self;
-import "dart:core" as core;
-
-class C<T extends core::Object> extends core::Object {
-  field dynamic v = MakeClosure<<T extends core::Object>(dynamic) → dynamic, self::C::T>(self::closure#C#v#function, MakeVector(1));
-  final field dynamic y = MakeClosure<() → dynamic>(self::closure#C#y#function, null);
-  static final field dynamic z = MakeClosure<() → dynamic>(self::closure#C#z#function, null);
-  synthetic constructor •() → void
-    : super core::Object::•()
-    ;
-}
-static field dynamic x = MakeClosure<() → dynamic>(self::closure#x#function, null);
-static method main() → dynamic {
-  if(!new self::C::•<core::String>().v(""))
-    throw "C<String>.v false on String";
-  if(new self::C::•<core::String>().v(0))
-    throw "C<String>.v true on int";
-  if(new self::C::•<core::String>().v(null))
-    throw "C<String>.v true on null";
-  if(new self::C::•<core::int>().v(""))
-    throw "C<int>.v true on String";
-  if(!new self::C::•<core::int>().v(0))
-    throw "C<int>.v false on int";
-  if(new self::C::•<core::int>().v(null))
-    throw "C<int>.v true on null";
-  if(!"x".==(self::x.call()))
-    throw "x";
-  if(!"y".==(new self::C::•<core::String>().y()))
-    throw "y";
-  if(!"z".==(self::C::z.call()))
-    throw "z";
-}
-static method closure#C#v#function<T extends core::Object>(dynamic #contextParameter, dynamic x) → dynamic {
-  return x is self::closure#C#v#function::T;
-}
-static method closure#C#y#function(dynamic #contextParameter) → dynamic {
-  return "y";
-}
-static method closure#C#z#function(dynamic #contextParameter) → dynamic {
-  return "z";
-}
-static method closure#x#function(dynamic #contextParameter) → dynamic {
-  return "x";
-}
diff --git a/pkg/kernel/testcases/closures/for_in_closure.dart b/pkg/kernel/testcases/closures/for_in_closure.dart
deleted file mode 100644
index 7dab558..0000000
--- a/pkg/kernel/testcases/closures/for_in_closure.dart
+++ /dev/null
@@ -1,22 +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.md file.
-
-const numbers = const <int>[0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
-
-main() {
-  var closures = [];
-  var captured_outside = 0;
-  for (int i in numbers) {
-    closures.add(() => i + captured_outside);
-  }
-  int sum = 0;
-  for (Function f in closures) {
-    sum += f();
-  }
-  // This formula is credited to Gauss. Search for "Gauss adding 1 to 100".
-  int expectedSum = (numbers.length - 1) * numbers.length ~/ 2;
-  if (expectedSum != sum) {
-    throw new Exception("Unexpected sum = $sum != $expectedSum");
-  }
-}
diff --git a/pkg/kernel/testcases/closures/for_in_closure.dart.expect b/pkg/kernel/testcases/closures/for_in_closure.dart.expect
deleted file mode 100644
index e3180e4..0000000
--- a/pkg/kernel/testcases/closures/for_in_closure.dart.expect
+++ /dev/null
@@ -1,29 +0,0 @@
-library;
-import self as self;
-import "dart:core" as core;
-
-static const field dynamic numbers = const <core::int>[0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
-static method main() → dynamic {
-  dynamic closures = <dynamic>[];
-  final dynamic #context = MakeVector(3);
-  #context[2] = 0;
-  for (core::int i in self::numbers) {
-    final dynamic #context = MakeVector(3);
-    #context[1] = #context;
-    #context[2] = i;
-    {
-      closures.add(MakeClosure<() → dynamic>(self::closure#main#function, #context));
-    }
-  }
-  core::int sum = 0;
-  for (core::Function f in closures) {
-    sum = sum.+(f.call());
-  }
-  core::int expectedSum = self::numbers.length.-(1).*(self::numbers.length).~/(2);
-  if(!expectedSum.==(sum)) {
-    throw core::Exception::•("Unexpected sum = ${sum} != ${expectedSum}");
-  }
-}
-static method closure#main#function(dynamic #contextParameter) → dynamic {
-  return (#contextParameter[2]).+(#contextParameter[1][2]);
-}
diff --git a/pkg/kernel/testcases/closures/for_loop.dart b/pkg/kernel/testcases/closures/for_loop.dart
deleted file mode 100644
index f7b4249..0000000
--- a/pkg/kernel/testcases/closures/for_loop.dart
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE.md file.
-
-const int max = 100;
-
-main() {
-  var closures = [];
-  var closures2 = [];
-  var last;
-  for (int i = 0; i < max; i++) {
-    closures.add(() => last = i);
-    closures2.add(() {
-      if (last != max - 1) throw "last: $last != ${max - 1}";
-    });
-  }
-  int sum = 0;
-  for (Function f in closures) {
-    sum += f();
-  }
-  for (Function f in closures2) {
-    f();
-  }
-  // This formula is credited to Gauss. Search for "Gauss adding 1 to 100".
-  int expectedSum = (max - 1) * max ~/ 2;
-  if (expectedSum != sum) {
-    throw new Exception("Unexpected sum = $sum != $expectedSum");
-  }
-}
diff --git a/pkg/kernel/testcases/closures/for_loop.dart.expect b/pkg/kernel/testcases/closures/for_loop.dart.expect
deleted file mode 100644
index 9334b7b..0000000
--- a/pkg/kernel/testcases/closures/for_loop.dart.expect
+++ /dev/null
@@ -1,38 +0,0 @@
-library;
-import self as self;
-import "dart:core" as core;
-
-static const field core::int max = 100;
-static method main() → dynamic {
-  dynamic closures = <dynamic>[];
-  dynamic closures2 = <dynamic>[];
-  final dynamic #context = MakeVector(3);
-  #context[2] = null;
-  {
-    dynamic #context = MakeVector(3);
-    #context[1] = #context;
-    #context[2] = 0;
-    for (; (#context[2]).<(self::max); #context = CopyVector(#context), #context[2] = (#context[2]).+(1)) {
-      closures.add(MakeClosure<() → dynamic>(self::closure#main#function, #context));
-      closures2.add(MakeClosure<() → dynamic>(self::closure#main#function#1, #context));
-    }
-  }
-  core::int sum = 0;
-  for (core::Function f in closures) {
-    sum = sum.+(f.call());
-  }
-  for (core::Function f in closures2) {
-    f.call();
-  }
-  core::int expectedSum = self::max.-(1).*(self::max).~/(2);
-  if(!expectedSum.==(sum)) {
-    throw core::Exception::•("Unexpected sum = ${sum} != ${expectedSum}");
-  }
-}
-static method closure#main#function(dynamic #contextParameter) → dynamic {
-  return #contextParameter[1][2] = #contextParameter[2];
-}
-static method closure#main#function#1(dynamic #contextParameter) → dynamic {
-  if(!(#contextParameter[1][2]).==(self::max.-(1)))
-    throw "last: ${#contextParameter[1][2]} != ${self::max.-(1)}";
-}
diff --git a/pkg/kernel/testcases/closures/for_variable_capture_test.dart b/pkg/kernel/testcases/closures/for_variable_capture_test.dart
deleted file mode 100644
index 1841576..0000000
--- a/pkg/kernel/testcases/closures/for_variable_capture_test.dart
+++ /dev/null
@@ -1,15 +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.
-
-main() {
-  var closure;
-  for (var i = 0, fn = () => i; i < 3; i++) {
-    i += 1;
-    closure = fn;
-  }
-  var x = closure();
-  if (x != 1) {
-    throw "Expected 1, but got $x.";
-  }
-}
diff --git a/pkg/kernel/testcases/closures/for_variable_capture_test.dart.expect b/pkg/kernel/testcases/closures/for_variable_capture_test.dart.expect
deleted file mode 100644
index dd1dffc..0000000
--- a/pkg/kernel/testcases/closures/for_variable_capture_test.dart.expect
+++ /dev/null
@@ -1,22 +0,0 @@
-library;
-import self as self;
-
-static method main() → dynamic {
-  dynamic closure;
-  {
-    dynamic #context = MakeVector(3);
-    #context[2] = 0;
-    dynamic fn = MakeClosure<() → dynamic>(self::closure#main#function, #context);
-    for (; (#context[2]).<(3); #context = CopyVector(#context), #context[2] = (#context[2]).+(1)) {
-      #context[2] = (#context[2]).+(1);
-      closure = fn;
-    }
-  }
-  dynamic x = closure.call();
-  if(!x.==(1)) {
-    throw "Expected 1, but got ${x}.";
-  }
-}
-static method closure#main#function(dynamic #contextParameter) → dynamic {
-  return #contextParameter[2];
-}
diff --git a/pkg/kernel/testcases/closures/instance_tear_off.dart b/pkg/kernel/testcases/closures/instance_tear_off.dart
deleted file mode 100644
index a0c4ce8..0000000
--- a/pkg/kernel/testcases/closures/instance_tear_off.dart
+++ /dev/null
@@ -1,65 +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.md file.
-
-class C {
-  var f = () => "f";
-  get g => (x) => "g($x)";
-  a() => "a";
-  b(x) => x;
-  c(x, [y = 2]) => x + y;
-  d(x, {y: 2}) => x + y;
-}
-
-/// This class doesn't use its type variable.
-class D<T> {
-  var f = () => "f";
-  get g => (x) => "g($x)";
-  a() => "a";
-  b(x) => x;
-  c(x, [y = 2]) => x + y;
-  d(x, {y: 2}) => x + y;
-}
-
-/// This class uses its type variable.
-class E<T> {
-  var f = () => "f";
-  get g => (T x) => "g($x)";
-  a() => "a";
-  b(T x) => x;
-  c(T x, [T y = 2]) => x + y;
-  d(T x, {T y: 2}) => x + y;
-}
-
-expect(expected, actual) {
-  print("Expecting '$expected' and got '$actual'");
-  if (expected != actual) {
-    print("Expected '$expected' but got '$actual'");
-    throw "Expected '$expected' but got '$actual'";
-  }
-}
-
-test(o) {
-  expect("f", o.f());
-  expect("f", (o.f)());
-  expect("g(42)", o.g(42));
-  expect("g(42)", (o.g)(42));
-  expect("a", o.a());
-  expect("a", (o.a)());
-  expect(42, o.b(42));
-  expect(42, (o.b)(42));
-  expect(42, o.c(40));
-  expect(42, (o.c)(40));
-  expect(87, o.c(80, 7));
-  expect(87, (o.c)(80, 7));
-  expect(42, o.d(40));
-  expect(42, (o.d)(40));
-  expect(87, o.d(80, y: 7));
-  expect(87, (o.d)(80, y: 7));
-}
-
-main(arguments) {
-  test(new C());
-  test(new D<int>());
-  test(new E<int>());
-}
diff --git a/pkg/kernel/testcases/closures/instance_tear_off.dart.expect b/pkg/kernel/testcases/closures/instance_tear_off.dart.expect
deleted file mode 100644
index e0f8e77..0000000
--- a/pkg/kernel/testcases/closures/instance_tear_off.dart.expect
+++ /dev/null
@@ -1,100 +0,0 @@
-library;
-import self as self;
-import "dart:core" as core;
-
-class C extends core::Object {
-  field dynamic f = MakeClosure<() → dynamic>(self::closure#C#f#function, null);
-  synthetic constructor •() → void
-    : super core::Object::•()
-    ;
-  get g() → dynamic
-    return MakeClosure<(dynamic) → dynamic>(self::closure#C#g#function, null);
-  method a() → dynamic
-    return "a";
-  method b(dynamic x) → dynamic
-    return x;
-  method c(dynamic x, [dynamic y = 2]) → dynamic
-    return x.+(y);
-  method d(dynamic x, {dynamic y = 2}) → dynamic
-    return x.+(y);
-}
-class D<T extends core::Object> extends core::Object {
-  field dynamic f = MakeClosure<() → dynamic>(self::closure#D#f#function, null);
-  synthetic constructor •() → void
-    : super core::Object::•()
-    ;
-  get g() → dynamic
-    return MakeClosure<(dynamic) → dynamic>(self::closure#D#g#function, null);
-  method a() → dynamic
-    return "a";
-  method b(dynamic x) → dynamic
-    return x;
-  method c(dynamic x, [dynamic y = 2]) → dynamic
-    return x.+(y);
-  method d(dynamic x, {dynamic y = 2}) → dynamic
-    return x.+(y);
-}
-class E<T extends core::Object> extends core::Object {
-  field dynamic f = MakeClosure<() → dynamic>(self::closure#E#f#function, null);
-  synthetic constructor •() → void
-    : super core::Object::•()
-    ;
-  get g() → dynamic
-    return MakeClosure<<T extends core::Object>(T) → dynamic, self::E::T>(self::closure#E#g#function, MakeVector(1));
-  method a() → dynamic
-    return "a";
-  method b(self::E::T x) → dynamic
-    return x;
-  method c(self::E::T x, [self::E::T y = 2]) → dynamic
-    return x.+(y);
-  method d(self::E::T x, {self::E::T y = 2}) → dynamic
-    return x.+(y);
-}
-static method expect(dynamic expected, dynamic actual) → dynamic {
-  core::print("Expecting '${expected}' and got '${actual}'");
-  if(!expected.==(actual)) {
-    core::print("Expected '${expected}' but got '${actual}'");
-    throw "Expected '${expected}' but got '${actual}'";
-  }
-}
-static method test(dynamic o) → dynamic {
-  self::expect("f", o.f());
-  self::expect("f", o.f.call());
-  self::expect("g(42)", o.g(42));
-  self::expect("g(42)", o.g.call(42));
-  self::expect("a", o.a());
-  self::expect("a", o.a.call());
-  self::expect(42, o.b(42));
-  self::expect(42, o.b.call(42));
-  self::expect(42, o.c(40));
-  self::expect(42, o.c.call(40));
-  self::expect(87, o.c(80, 7));
-  self::expect(87, o.c.call(80, 7));
-  self::expect(42, o.d(40));
-  self::expect(42, o.d.call(40));
-  self::expect(87, o.d(80, y: 7));
-  self::expect(87, o.d.call(80, y: 7));
-}
-static method main(dynamic arguments) → dynamic {
-  self::test(new self::C::•());
-  self::test(new self::D::•<core::int>());
-  self::test(new self::E::•<core::int>());
-}
-static method closure#C#g#function(dynamic #contextParameter, dynamic x) → dynamic {
-  return "g(${x})";
-}
-static method closure#C#f#function(dynamic #contextParameter) → dynamic {
-  return "f";
-}
-static method closure#D#g#function(dynamic #contextParameter, dynamic x) → dynamic {
-  return "g(${x})";
-}
-static method closure#D#f#function(dynamic #contextParameter) → dynamic {
-  return "f";
-}
-static method closure#E#g#function<T extends core::Object>(dynamic #contextParameter, self::closure#E#g#function::T x) → dynamic {
-  return "g(${x})";
-}
-static method closure#E#f#function(dynamic #contextParameter) → dynamic {
-  return "f";
-}
diff --git a/pkg/kernel/testcases/closures/loop2.dart b/pkg/kernel/testcases/closures/loop2.dart
deleted file mode 100644
index 2069f03..0000000
--- a/pkg/kernel/testcases/closures/loop2.dart
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-//
-// Check that a variable declared and captured inside a loop is given a separate
-// context for each iteration of the loop, so changes to the variable in
-// subsequent iterations are not visible to closures capturing it in prior
-// iterations.
-
-void doit(int x) {
-  final int max = 10;
-  final double expectedSum = ((max - 1) * max) / 2;
-
-  int counter = 0;
-  var calls = [];
-  while (counter < max) {
-    int pos = counter;
-    calls.add(() => pos + x);
-    counter++;
-  }
-
-  double sum = 0.0;
-  for (var c in calls) sum += c();
-  if (sum != expectedSum)
-    throw new Exception("Unexpected sum = $sum != $expectedSum");
-}
-
-void main() {
-  doit(0);
-}
diff --git a/pkg/kernel/testcases/closures/loop2.dart.expect b/pkg/kernel/testcases/closures/loop2.dart.expect
deleted file mode 100644
index ad312b1..0000000
--- a/pkg/kernel/testcases/closures/loop2.dart.expect
+++ /dev/null
@@ -1,31 +0,0 @@
-library;
-import self as self;
-import "dart:core" as core;
-
-static method doit(core::int x) → void {
-  final dynamic #context = MakeVector(3);
-  #context[2] = x;
-  x = null;
-  final core::int max = 10;
-  final core::double expectedSum = max.-(1).*(max)./(2);
-  core::int counter = 0;
-  dynamic calls = <dynamic>[];
-  while (counter.<(max)) {
-    final dynamic #context = MakeVector(3);
-    #context[1] = #context;
-    #context[2] = counter;
-    calls.add(MakeClosure<() → dynamic>(self::closure#doit#function, #context));
-    counter = counter.+(1);
-  }
-  core::double sum = 0.0;
-  for (dynamic c in calls)
-    sum = sum.+(c.call());
-  if(!sum.==(expectedSum))
-    throw core::Exception::•("Unexpected sum = ${sum} != ${expectedSum}");
-}
-static method main() → void {
-  self::doit(0);
-}
-static method closure#doit#function(dynamic #contextParameter) → dynamic {
-  return (#contextParameter[2]).+(#contextParameter[1][2]);
-}
diff --git a/pkg/kernel/testcases/closures/named_closure.dart b/pkg/kernel/testcases/closures/named_closure.dart
deleted file mode 100644
index 8040e78..0000000
--- a/pkg/kernel/testcases/closures/named_closure.dart
+++ /dev/null
@@ -1,15 +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.md file.
-
-var f;
-
-foo() {
-  print(f(0));
-}
-
-main(arguments) {
-  g(x) => arguments[x];
-  f = g;
-  foo();
-}
diff --git a/pkg/kernel/testcases/closures/named_closure.dart.expect b/pkg/kernel/testcases/closures/named_closure.dart.expect
deleted file mode 100644
index 83b9e8e..0000000
--- a/pkg/kernel/testcases/closures/named_closure.dart.expect
+++ /dev/null
@@ -1,19 +0,0 @@
-library;
-import self as self;
-import "dart:core" as core;
-
-static field dynamic f;
-static method foo() → dynamic {
-  core::print(self::f.call(0));
-}
-static method main(dynamic arguments) → dynamic {
-  final dynamic #context = MakeVector(3);
-  #context[2] = arguments;
-  arguments = null;
-  final (dynamic) → dynamic g = MakeClosure<(dynamic) → dynamic>(self::closure#main#g, #context);
-  self::f = g;
-  self::foo();
-}
-static method closure#main#g(dynamic #contextParameter, dynamic x) → dynamic {
-  return (#contextParameter[2]).[](x);
-}
diff --git a/pkg/kernel/testcases/closures/non_void_context.dart b/pkg/kernel/testcases/closures/non_void_context.dart
deleted file mode 100644
index 0987ab5..0000000
--- a/pkg/kernel/testcases/closures/non_void_context.dart
+++ /dev/null
@@ -1,28 +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.md file.
-
-var v;
-
-main(arguments) {
-  var w;
-  ((x) => v = w = x)(87);
-  if (v != 87) {
-    throw "Unexpected value in v: $v";
-  }
-  if (w != 87) {
-    throw "Unexpected value in w: $w";
-  }
-  v = true;
-  (() {
-    for (; w = v;) {
-      v = false;
-    }
-  })();
-  if (v != false) {
-    throw "Unexpected value in v: $v";
-  }
-  if (w != false) {
-    throw "Unexpected value in w: $w";
-  }
-}
diff --git a/pkg/kernel/testcases/closures/non_void_context.dart.expect b/pkg/kernel/testcases/closures/non_void_context.dart.expect
deleted file mode 100644
index 7e1df31..0000000
--- a/pkg/kernel/testcases/closures/non_void_context.dart.expect
+++ /dev/null
@@ -1,31 +0,0 @@
-library;
-import self as self;
-
-static field dynamic v;
-static method main(dynamic arguments) → dynamic {
-  final dynamic #context = MakeVector(3);
-  #context[2] = null;
-  (MakeClosure<(dynamic) → dynamic>(self::closure#main#function, #context)).call(87);
-  if(!self::v.==(87)) {
-    throw "Unexpected value in v: ${self::v}";
-  }
-  if(!(#context[2]).==(87)) {
-    throw "Unexpected value in w: ${#context[2]}";
-  }
-  self::v = true;
-  (MakeClosure<() → dynamic>(self::closure#main#function#1, #context)).call();
-  if(!self::v.==(false)) {
-    throw "Unexpected value in v: ${self::v}";
-  }
-  if(!(#context[2]).==(false)) {
-    throw "Unexpected value in w: ${#context[2]}";
-  }
-}
-static method closure#main#function(dynamic #contextParameter, dynamic x) → dynamic {
-  return self::v = #contextParameter[2] = x;
-}
-static method closure#main#function#1(dynamic #contextParameter) → dynamic {
-  for (; #contextParameter[2] = self::v; ) {
-    self::v = false;
-  }
-}
diff --git a/pkg/kernel/testcases/closures/static_tear_off.dart b/pkg/kernel/testcases/closures/static_tear_off.dart
deleted file mode 100644
index 29de7c7..0000000
--- a/pkg/kernel/testcases/closures/static_tear_off.dart
+++ /dev/null
@@ -1,48 +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.md file.
-
-f_1_1_no_default(a, [b]) => a + b;
-
-f_1_1_default(a, [b = 2]) => a + b;
-
-f_1_b_no_default(a, {b}) => a + b;
-
-f_1_b_default(a, {b: 2}) => a + b;
-
-test_1_1(Function f, bool hasDefault) {
-  var result = f(40, 2);
-  if (42 != result) throw "Unexpected result: $result";
-  test_1(f, hasDefault);
-}
-
-test_1_b(Function f, bool hasDefault) {
-  var result = f(40, b: 2);
-  if (42 != result) throw "Unexpected result: $result";
-  test_1(f, hasDefault);
-}
-
-test_1(Function f, bool hasDefault) {
-  var result = 0;
-  bool threw = true;
-  try {
-    result = f(40);
-    threw = false;
-  } catch (_) {
-    // Ignored.
-  }
-  if (hasDefault) {
-    if (threw) throw "Unexpected exception.";
-    if (42 != result) throw "Unexpected result: $result.";
-  } else {
-    if (!threw) throw "Expected exception missing.";
-    if (0 != result) throw "Unexpected result: $result.";
-  }
-}
-
-main(arguments) {
-  test_1_1(f_1_1_no_default, false);
-  test_1_1(f_1_1_default, true);
-  test_1_b(f_1_b_no_default, false);
-  test_1_b(f_1_b_default, true);
-}
diff --git a/pkg/kernel/testcases/closures/static_tear_off.dart.expect b/pkg/kernel/testcases/closures/static_tear_off.dart.expect
deleted file mode 100644
index 7eed6c1..0000000
--- a/pkg/kernel/testcases/closures/static_tear_off.dart.expect
+++ /dev/null
@@ -1,52 +0,0 @@
-library;
-import self as self;
-import "dart:core" as core;
-
-static method f_1_1_no_default(dynamic a, [dynamic b = null]) → dynamic
-  return a.+(b);
-static method f_1_1_default(dynamic a, [dynamic b = 2]) → dynamic
-  return a.+(b);
-static method f_1_b_no_default(dynamic a, {dynamic b = null}) → dynamic
-  return a.+(b);
-static method f_1_b_default(dynamic a, {dynamic b = 2}) → dynamic
-  return a.+(b);
-static method test_1_1(core::Function f, core::bool hasDefault) → dynamic {
-  dynamic result = f.call(40, 2);
-  if(!42.==(result))
-    throw "Unexpected result: ${result}";
-  self::test_1(f, hasDefault);
-}
-static method test_1_b(core::Function f, core::bool hasDefault) → dynamic {
-  dynamic result = f.call(40, b: 2);
-  if(!42.==(result))
-    throw "Unexpected result: ${result}";
-  self::test_1(f, hasDefault);
-}
-static method test_1(core::Function f, core::bool hasDefault) → dynamic {
-  dynamic result = 0;
-  core::bool threw = true;
-  try {
-    result = f.call(40);
-    threw = false;
-  }
-  on dynamic catch(final dynamic _) {
-  }
-  if(hasDefault) {
-    if(threw)
-      throw "Unexpected exception.";
-    if(!42.==(result))
-      throw "Unexpected result: ${result}.";
-  }
-  else {
-    if(!threw)
-      throw "Expected exception missing.";
-    if(!0.==(result))
-      throw "Unexpected result: ${result}.";
-  }
-}
-static method main(dynamic arguments) → dynamic {
-  self::test_1_1(self::f_1_1_no_default, false);
-  self::test_1_1(self::f_1_1_default, true);
-  self::test_1_b(self::f_1_b_no_default, false);
-  self::test_1_b(self::f_1_b_default, true);
-}
diff --git a/pkg/kernel/testcases/closures/syncstar.dart b/pkg/kernel/testcases/closures/syncstar.dart
deleted file mode 100644
index 9dd0543..0000000
--- a/pkg/kernel/testcases/closures/syncstar.dart
+++ /dev/null
@@ -1,24 +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.
-//
-// This tests that the wrapper function around converted closures in the VM
-// doesn't break when the context parameter is captured (since async
-// transformations introduces an additional closure here).
-
-range(int high) {
-  iter(int low) sync* {
-    while (high-- > low) yield high;
-  }
-
-  return iter;
-}
-
-main() {
-  var sum = 0;
-  for (var x in range(10)(2)) sum += x;
-
-  if (sum != 44) {
-    throw new Exception("Incorrect output.");
-  }
-}
diff --git a/pkg/kernel/testcases/closures/syncstar.dart.expect b/pkg/kernel/testcases/closures/syncstar.dart.expect
deleted file mode 100644
index d107c33..0000000
--- a/pkg/kernel/testcases/closures/syncstar.dart.expect
+++ /dev/null
@@ -1,37 +0,0 @@
-library;
-import self as self;
-import "dart:core" as core;
-
-static method range(core::int high) → dynamic {
-  final dynamic #context = MakeVector(3);
-  #context[2] = high;
-  high = null;
-  final (core::int) → dynamic iter = MakeClosure<(core::int) → dynamic>(self::closure#range#iter, #context);
-  return iter;
-}
-static method main() → dynamic {
-  dynamic sum = 0;
-  for (dynamic x in self::range(10).call(2))
-    sum = sum.+(x);
-  if(!sum.==(44)) {
-    throw core::Exception::•("Incorrect output.");
-  }
-}
-static method closure#range#iter(dynamic #contextParameter, core::int low) → dynamic /* originally sync* */ {
-  final dynamic #context = MakeVector(3);
-  #context[1] = #contextParameter;
-  #context[2] = low;
-  low = null;
-  dynamic :await_jump_var = 0;
-  dynamic :await_ctx_var;
-  dynamic :sync_op = (core::Iterator<dynamic> :iterator) → core::bool yielding {
-    {
-      while ((let final dynamic #t1 = #contextParameter[2] in let final dynamic #t2 = #contextParameter[2] = #t1.-(1) in #t1).>(#context[2])) {
-        :iterator._current = #context[1][2];
-        [yield] true;
-      }
-    }
-    return false;
-  };
-  return new core::_SyncIterable::•(:sync_op);
-}
diff --git a/pkg/kernel/testcases/closures/uncaptured_for_in_loop.dart b/pkg/kernel/testcases/closures/uncaptured_for_in_loop.dart
deleted file mode 100644
index 8c60816..0000000
--- a/pkg/kernel/testcases/closures/uncaptured_for_in_loop.dart
+++ /dev/null
@@ -1,22 +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.md file.
-
-const numbers = const <int>[0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
-
-main() {
-  var closures = [];
-  for (int i in numbers) {
-    int j = i;
-    closures.add(() => j);
-  }
-  int sum = 0;
-  for (Function f in closures) {
-    sum += f();
-  }
-  // This formula is credited to Gauss. Search for "Gauss adding 1 to 100".
-  int expectedSum = (numbers.length - 1) * numbers.length ~/ 2;
-  if (expectedSum != sum) {
-    throw new Exception("Unexpected sum = $sum != $expectedSum");
-  }
-}
diff --git a/pkg/kernel/testcases/closures/uncaptured_for_in_loop.dart.expect b/pkg/kernel/testcases/closures/uncaptured_for_in_loop.dart.expect
deleted file mode 100644
index 84f45e3..0000000
--- a/pkg/kernel/testcases/closures/uncaptured_for_in_loop.dart.expect
+++ /dev/null
@@ -1,24 +0,0 @@
-library;
-import self as self;
-import "dart:core" as core;
-
-static const field dynamic numbers = const <core::int>[0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
-static method main() → dynamic {
-  dynamic closures = <dynamic>[];
-  for (core::int i in self::numbers) {
-    final dynamic #context = MakeVector(3);
-    #context[2] = i;
-    closures.add(MakeClosure<() → dynamic>(self::closure#main#function, #context));
-  }
-  core::int sum = 0;
-  for (core::Function f in closures) {
-    sum = sum.+(f.call());
-  }
-  core::int expectedSum = self::numbers.length.-(1).*(self::numbers.length).~/(2);
-  if(!expectedSum.==(sum)) {
-    throw core::Exception::•("Unexpected sum = ${sum} != ${expectedSum}");
-  }
-}
-static method closure#main#function(dynamic #contextParameter) → dynamic {
-  return #contextParameter[2];
-}
diff --git a/pkg/kernel/testcases/closures_initializers/initializers.dart b/pkg/kernel/testcases/closures_initializers/initializers.dart
deleted file mode 100644
index 290fa98..0000000
--- a/pkg/kernel/testcases/closures_initializers/initializers.dart
+++ /dev/null
@@ -1,52 +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.
-
-// The purpose of this test is to detect that closures in [LocalInitializer]s
-// and [FieldInitializer]s are properly converted. This test assumes that
-// [ArgumentExtractionForTesting] transformer was run before closure conversion.
-// It should introduce one [LocalInitializer] for each argument passed to a
-// field initializer for a field ending in "_li". If such argument contains a
-// closure, it would appear in a [LocalInitializer]. The [FieldInitializer]
-// example requires no such elaboration.
-
-class X {}
-
-// Closure in field initializer.
-//
-class A {
-  X foo;
-  A(X i) : foo = ((() => i)());
-}
-
-// Closure in super initializer.
-//
-class S extends A {
-  S(X i) : super((() => i)());
-}
-
-// Closure in local initializer.
-//
-class S2 {
-  X foo_li;
-  S2(X foo) : foo_li = (() => foo)();
-}
-
-// Closure in redirecting initializer.
-//
-class B {
-  X foo;
-  B.named(X foo) {}
-  B(X foo) : this.named((() => foo)());
-}
-
-main() {
-  A a = new A(new X());
-  a.foo; // To prevent dartanalyzer from marking [a] as unused.
-  B b = new B(new X());
-  b.foo;
-  S s = new S(new X());
-  s.foo;
-  S2 s2 = new S2(new X());
-  s2.foo_li;
-}
diff --git a/pkg/kernel/testcases/closures_initializers/initializers.dart.expect b/pkg/kernel/testcases/closures_initializers/initializers.dart.expect
deleted file mode 100644
index b97b4f0..0000000
--- a/pkg/kernel/testcases/closures_initializers/initializers.dart.expect
+++ /dev/null
@@ -1,56 +0,0 @@
-library;
-import self as self;
-import "dart:core" as core;
-
-class X extends core::Object {
-  constructor •() → void
-    : super core::Object::•()
-    ;
-}
-class A extends core::Object {
-  field self::X foo;
-  constructor •(self::X i) → void
-    : final Vector #context = MakeVector(2), dynamic #t1 = #context[1] = i, self::A::foo = (MakeClosure<() → dynamic>(self::closure#A#function#function, #context)).call(), super core::Object::•()
-    ;
-}
-class S extends self::A {
-  constructor •(self::X i) → void
-    : final Vector #context = MakeVector(2), dynamic #t2 = #context[1] = i, super self::A::•((MakeClosure<() → dynamic>(self::closure#S#function#function, #context)).call())
-    ;
-}
-class S2 extends core::Object {
-  field self::X foo_li;
-  constructor •(self::X foo) → void
-    : final Vector #context = MakeVector(2), dynamic #t3 = #context[1] = foo, dynamic #li_0 = (MakeClosure<() → dynamic>(self::closure#S2#function#function, #context)).call(), self::S2::foo_li = #li_0, super core::Object::•()
-    ;
-}
-class B extends core::Object {
-  field self::X foo = null;
-  constructor named(self::X foo) → void
-    : super core::Object::•() {}
-  constructor •(self::X foo) → void
-    : final Vector #context = MakeVector(2), dynamic #t4 = #context[1] = foo, this self::B::named((MakeClosure<() → dynamic>(self::closure#B#function#function, #context)).call())
-    ;
-}
-static method main() → dynamic {
-  self::A a = new self::A::•(new self::X::•());
-  a.foo;
-  self::B b = new self::B::•(new self::X::•());
-  b.foo;
-  self::S s = new self::S::•(new self::X::•());
-  s.foo;
-  self::S2 s2 = new self::S2::•(new self::X::•());
-  s2.foo_li;
-}
-static method closure#A#function#function(Vector #contextParameter) → dynamic {
-  return #contextParameter[1];
-}
-static method closure#S#function#function(Vector #contextParameter) → dynamic {
-  return #contextParameter[1];
-}
-static method closure#S2#function#function(Vector #contextParameter) → dynamic {
-  return #contextParameter[1];
-}
-static method closure#B#function#function(Vector #contextParameter) → dynamic {
-  return #contextParameter[1];
-}
diff --git a/pkg/kernel/testcases/closures_initializers/local_initializers.dart.expect b/pkg/kernel/testcases/closures_initializers/local_initializers.dart.expect
deleted file mode 100644
index d4eb340..0000000
--- a/pkg/kernel/testcases/closures_initializers/local_initializers.dart.expect
+++ /dev/null
@@ -1,35 +0,0 @@
-library;
-import self as self;
-import "dart:core" as core;
-
-class X extends core::Object {
-  constructor •() → void
-    : super core::Object::•()
-    ;
-}
-class A extends core::Object {
-  field self::X foo;
-  constructor •(self::X i) → void
-    : self::A::foo = let final Vector #context = MakeVector(2) in let dynamic #t1 = #context[1] = i in (MakeClosure<() → dynamic>(self::closure#A#function#function, #context)).call(), super core::Object::•()
-    ;
-}
-class B extends core::Object {
-  field self::X foo = null;
-  constructor named(self::X foo) → void
-    : super core::Object::•() {}
-  constructor •(self::X foo) → void
-    : dynamic extracted#0 = let final Vector #context = MakeVector(2) in let dynamic #t2 = #context[1] = foo in (MakeClosure<() → dynamic>(self::closure#B#function#function, #context)).call(), this self::B::named(extracted#0)
-    ;
-}
-static method main() → dynamic {
-  self::A a = new self::A::•(new self::X::•());
-  a.foo;
-  self::B b = new self::B::•(new self::X::•());
-  b.foo;
-}
-static method closure#A#function#function(Vector #contextParameter) → dynamic {
-  return #contextParameter[1];
-}
-static method closure#B#function#function(Vector #contextParameter) → dynamic {
-  return #contextParameter[1];
-}
diff --git a/pkg/kernel/testcases/closures_type_vars/type_variables.dart b/pkg/kernel/testcases/closures_type_vars/type_variables.dart
deleted file mode 100644
index 2de2994..0000000
--- a/pkg/kernel/testcases/closures_type_vars/type_variables.dart
+++ /dev/null
@@ -1,50 +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.md file.
-
-class C<T, S> {
-  foo(S s) => (T x) {
-        T y = x;
-        Object z = y;
-        C<T, S> self = this;
-        return z as T;
-      };
-
-  bar() {
-    C<T, S> self = this;
-  }
-
-  baz() {
-    return () => () => new C<T, S>();
-  }
-
-  factory C() {
-    local() {
-      C<T, S> self = new C<T, S>.internal();
-      return self;
-    }
-
-    return local();
-  }
-  C.internal();
-}
-
-fn<A>(A x) {
-  var fn2 = (A x2) {
-    var l = <A>[];
-    l.add(x2);
-    return l;
-  };
-  return fn2(x);
-}
-
-main(arguments) {
-  print(new C<String, String>().foo(null)(arguments.first));
-  dynamic c = new C<int, int>().baz()()();
-  if (c is! C<int, int>) throw "$c fails type test 'is C<int, int>'";
-  if (c is C<String, String>) {
-    throw "$c passes type test 'is C<String, String>'";
-  }
-  print(c);
-  print(fn<int>(3));
-}
diff --git a/pkg/kernel/testcases/closures_type_vars/type_variables.dart.expect b/pkg/kernel/testcases/closures_type_vars/type_variables.dart.expect
deleted file mode 100644
index 0eafb09..0000000
--- a/pkg/kernel/testcases/closures_type_vars/type_variables.dart.expect
+++ /dev/null
@@ -1,60 +0,0 @@
-library;
-import self as self;
-import "dart:core" as core;
-
-class C<T extends core::Object, S extends core::Object> extends core::Object {
-  constructor internal() → void
-    : super core::Object::•()
-    ;
-  method foo(self::C::S s) → dynamic {
-    final Vector #context = MakeVector(3);
-    #context[2] = this;
-    return MakeClosure<<T extends core::Object, S extends core::Object>(T) → T, self::C::T, self::C::S>(self::closure#C#foo#function, #context);
-  }
-  method bar() → dynamic {
-    self::C<self::C::T, self::C::S> self = this;
-  }
-  method baz() → dynamic {
-    return MakeClosure<<T extends core::Object, S extends core::Object>() → () → self::C<T, S>, self::C::T, self::C::S>(self::closure#C#baz#function, MakeVector(1));
-  }
-  static factory •<T extends core::Object, S extends core::Object>() → self::C<self::C::•::T, self::C::•::S> {
-    final <T extends core::Object, S extends core::Object>() → self::C<self::C::•::T, self::C::•::S> local = MakeClosure<<T extends core::Object, S extends core::Object>() → self::C<T, S>, self::C::•::T, self::C::•::S>(self::closure#C#function#local, MakeVector(1));
-    return local.call();
-  }
-}
-static method fn<A extends core::Object>(self::fn::A x) → dynamic {
-  <A extends core::Object>(self::fn::A) → core::List<self::fn::A> fn2 = MakeClosure<<A extends core::Object>(A) → core::List<A>, self::fn::A>(self::closure#fn#function, MakeVector(1));
-  return fn2.call(x);
-}
-static method main(dynamic arguments) → dynamic {
-  core::print(self::C::•<core::String, core::String>().{self::C::foo}(null).call(arguments.first));
-  dynamic c = self::C::•<core::int, core::int>().{self::C::baz}().call().call();
-  if(!(c is self::C<core::int, core::int>))
-    throw "${c} fails type test 'is C<int, int>'";
-  if(c is self::C<core::String, core::String>) {
-    throw "${c{self::C<core::String, core::String>}} passes type test 'is C<String, String>'";
-  }
-  core::print(c);
-  core::print(self::fn<core::int>(3));
-}
-static method closure#C#foo#function<T extends core::Object, S extends core::Object>(Vector #contextParameter, self::closure#C#foo#function::T x) → self::closure#C#foo#function::T {
-  self::closure#C#foo#function::T y = x;
-  core::Object z = y;
-  self::C<self::closure#C#foo#function::T, self::closure#C#foo#function::S> self = #contextParameter[2];
-  return z as self::closure#C#foo#function::T;
-}
-static method closure#C#baz#function#function<T extends core::Object, S extends core::Object>(Vector #contextParameter) → self::C<self::closure#C#baz#function#function::T, self::closure#C#baz#function#function::S> {
-  return self::C::•<self::closure#C#baz#function#function::T, self::closure#C#baz#function#function::S>();
-}
-static method closure#C#baz#function<T extends core::Object, S extends core::Object>(Vector #contextParameter) → () → self::C<self::closure#C#baz#function::T, self::closure#C#baz#function::S> {
-  return MakeClosure<<T extends core::Object, S extends core::Object>() → self::C<T, S>, self::closure#C#baz#function::T, self::closure#C#baz#function::S>(self::closure#C#baz#function#function, #contextParameter);
-}
-static method closure#C#function#local<T extends core::Object, S extends core::Object>(Vector #contextParameter) → self::C<self::closure#C#function#local::T, self::closure#C#function#local::S> {
-  self::C<self::closure#C#function#local::T, self::closure#C#function#local::S> self = new self::C::internal<self::closure#C#function#local::T, self::closure#C#function#local::S>();
-  return self;
-}
-static method closure#fn#function<A extends core::Object>(Vector #contextParameter, self::closure#fn#function::A x2) → core::List<self::closure#fn#function::A> {
-  core::List<self::closure#fn#function::A> l = <self::closure#fn#function::A>[];
-  l.{core::List::add}(x2);
-  return l;
-}
diff --git a/pkg/kernel/testcases/reify/closure2_test.dart b/pkg/kernel/testcases/reify/closure2_test.dart
deleted file mode 100644
index e44aef9..0000000
--- a/pkg/kernel/testcases/reify/closure2_test.dart
+++ /dev/null
@@ -1,22 +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 closure2_test;
-
-import 'test_base.dart';
-
-class A<T> {
-  fun() => (o) => o is T;
-}
-
-class X {}
-
-class Y {}
-
-main() {
-  var tester = new A<X>().fun();
-
-  expectTrue(tester(new X()));
-  expectFalse(tester(new Y()));
-}
diff --git a/pkg/kernel/testcases/reify/closure2_test.dart.expect b/pkg/kernel/testcases/reify/closure2_test.dart.expect
deleted file mode 100644
index 3c547f5..0000000
--- a/pkg/kernel/testcases/reify/closure2_test.dart.expect
+++ /dev/null
@@ -1,85 +0,0 @@
-library closure2_test;
-import self as self;
-import "dart:core" as core;
-import "../../runtime/reify/interceptors.dart" as int;
-import "../../runtime/reify/types.dart" as typ;
-import "dart:mock" as mock;
-import "./test_base.dart" as tes;
-import "../../runtime/reify/declarations.dart" as dec;
-
-class A extends core::Object implements int::HasRuntimeTypeGetter {
-  final field typ::ReifiedType $type;
-  constructor •(typ::ReifiedType $type) → void
-    : self::A::$type = $type, super core::Object::•()
-    ;
-  method fun() → dynamic {
-    return new self::Closure#A#fun#function::•(new typ::Interface::•(self::$declarations.[](1), typ::getTypeArguments(typ::asInstanceOf(this.$type, self::$declarations.[](0)))), null);
-  }
-  get $A$T() → typ::ReifiedType
-    return typ::getTypeArguments(typ::asInstanceOf(this.$type, self::$declarations.[](0))).[](0);
-  get runtimeType() → core::Type
-    return this.{=self::A::$type};
-}
-class X extends core::Object implements int::HasRuntimeTypeGetter {
-  constructor •() → void
-    : super core::Object::•()
-    ;
-  get $type() → typ::ReifiedType
-    return new typ::Interface::•(self::$declarations.[](2));
-}
-class Y extends core::Object implements int::HasRuntimeTypeGetter {
-  constructor •() → void
-    : super core::Object::•()
-    ;
-  get $type() → typ::ReifiedType
-    return new typ::Interface::•(self::$declarations.[](3));
-}
-class Closure#A#fun#function extends core::Object implements core::Function, int::HasRuntimeTypeGetter {
-  field core::String note = "This is temporary. The VM doesn't need closure classes.";
-  field mock::Context context;
-  final field typ::ReifiedType $type;
-  constructor •(typ::ReifiedType $type, final mock::Context context) → dynamic
-    : self::Closure#A#fun#function::$type = $type, self::Closure#A#fun#function::context = context
-    ;
-  method call(dynamic o) → core::bool {
-    "This is a temporary solution. In the VM, this will become an additional parameter.";
-    final mock::Context #contextParameter = this.{self::Closure#A#fun#function::context};
-    return typ::isSubtypeOf(int::type(o), this.$Closure#A#fun#function$T);
-  }
-  get $Closure#A#fun#function$T() → typ::ReifiedType
-    return typ::getTypeArguments(typ::asInstanceOf(this.$type, self::$declarations.[](1))).[](0);
-  get runtimeType() → core::Type
-    return this.{=self::Closure#A#fun#function::$type};
-}
-static final field core::List<dec::Class> $declarations = (core::List<dec::Class> d) → core::List<dec::Class> {
-  dec::init(d, 0, new typ::Interface::•(d.[](17)));
-  dec::init(d, 1, new typ::Interface::•(d.[](17)), <dynamic>[new typ::Interface::•(d.[](19))], new typ::FunctionType::•(new typ::Interface::•(d.[](19)), new typ::Interface::•(d.[](5)), 0, <dynamic>[const typ::Dynamic::•()]));
-  dec::init(d, 2, new typ::Interface::•(d.[](17)));
-  dec::init(d, 3, new typ::Interface::•(d.[](17)));
-  dec::init(d, 4, new typ::Interface::•(d.[](17)));
-  dec::init(d, 5, new typ::Interface::•(d.[](17)));
-  dec::init(d, 6, new typ::Interface::•(d.[](17)), <dynamic>[new typ::Interface::•(d.[](20), <dynamic>[new typ::Interface::•(d.[](6))]), new typ::Interface::•(d.[](21))]);
-  dec::init(d, 7, new typ::Interface::•(d.[](22)));
-  dec::init(d, 8, new typ::Interface::•(d.[](22)));
-  dec::init(d, 9, new typ::Interface::•(d.[](17)));
-  dec::init(d, 10, new typ::Interface::•(d.[](23)));
-  dec::init(d, 11, new typ::Interface::•(d.[](23)));
-  dec::init(d, 12, new typ::Interface::•(d.[](23)));
-  dec::init(d, 13, new typ::Interface::•(d.[](23)));
-  dec::init(d, 14, new typ::Interface::•(d.[](17)), <dynamic>[new typ::Interface::•(d.[](24))]);
-  dec::init(d, 15, new typ::Interface::•(d.[](16)));
-  dec::init(d, 16, new typ::Interface::•(d.[](23)));
-  dec::init(d, 17, null);
-  dec::init(d, 19, new typ::Interface::•(d.[](17)));
-  dec::init(d, 20, new typ::Interface::•(d.[](17)));
-  dec::init(d, 21, new typ::Interface::•(d.[](17)));
-  dec::init(d, 22, new typ::Interface::•(d.[](17)), <dynamic>[new typ::Interface::•(d.[](20), <dynamic>[new typ::Interface::•(d.[](22))])]);
-  dec::init(d, 23, new typ::Interface::•(d.[](17)));
-  dec::init(d, 24, new typ::Interface::•(d.[](17)));
-  return d;
-}.call(dec::allocateDeclarations(<dynamic>["A", "Closure#A#fun#function", "X", "Y", "Null", "bool", "String", "int", "double", "Type", "AbstractClassInstantiationError", "NoSuchMethodError", "CyclicInitializationError", "UnsupportedError", "IntegerDivisionByZeroException", "RangeError", "ArgumentError", "Object", "HasRuntimeTypeGetter", "Function", "Comparable", "Pattern", "num", "Error", "Exception"], <dynamic>[1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0]));
-static method main() → dynamic {
-  dynamic tester = new self::A::•(new typ::Interface::•(self::$declarations.[](0), <dynamic>[new typ::Interface::•(self::$declarations.[](2))])).{self::A::fun}();
-  tes::expectTrue(tester.call(new self::X::•()));
-  tes::expectFalse(tester.call(new self::Y::•()));
-}
diff --git a/pkg/kernel/testcases/reify/closure_test.dart b/pkg/kernel/testcases/reify/closure_test.dart
deleted file mode 100644
index 17206bc..0000000
--- a/pkg/kernel/testcases/reify/closure_test.dart
+++ /dev/null
@@ -1,49 +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 closure_test;
-
-import 'test_base.dart';
-
-class A {}
-
-class B {}
-
-typedef B A2B(A a);
-typedef A B2A(B b);
-
-bar(A a) {
-  return null;
-}
-
-B baz(a) {
-  return null;
-}
-
-main() {
-  B foo(A a) {
-    return null;
-  }
-
-  A qux(B b) {
-    return null;
-  }
-
-  expectTrue(foo is A2B);
-  expectTrue(qux is! A2B);
-  expectTrue(foo is! B2A);
-  expectTrue(qux is B2A);
-
-  expectTrue(bar is A2B);
-  expectTrue(bar is! B2A);
-  expectTrue(baz is A2B);
-  expectTrue(baz is! B2A);
-
-  var rab = bar;
-  var zab = baz;
-  expectTrue(rab is A2B);
-  expectTrue(rab is! B2A);
-  expectTrue(zab is A2B);
-  expectTrue(zab is! B2A);
-}
diff --git a/pkg/kernel/testcases/reify/closure_test.dart.expect b/pkg/kernel/testcases/reify/closure_test.dart.expect
deleted file mode 100644
index 0b759eb..0000000
--- a/pkg/kernel/testcases/reify/closure_test.dart.expect
+++ /dev/null
@@ -1,122 +0,0 @@
-library closure_test;
-import self as self;
-import "dart:core" as core;
-import "../../runtime/reify/interceptors.dart" as int;
-import "../../runtime/reify/types.dart" as typ;
-import "dart:mock" as mock;
-import "./test_base.dart" as tes;
-import "../../runtime/reify/declarations.dart" as dec;
-
-class A extends core::Object implements int::HasRuntimeTypeGetter {
-  constructor •() → void
-    : super core::Object::•()
-    ;
-  get $type() → typ::ReifiedType
-    return new typ::Interface::•(self::$declarations.[](0));
-}
-class B extends core::Object implements int::HasRuntimeTypeGetter {
-  constructor •() → void
-    : super core::Object::•()
-    ;
-  get $type() → typ::ReifiedType
-    return new typ::Interface::•(self::$declarations.[](1));
-}
-class Closure#main#foo extends core::Object implements core::Function, int::HasRuntimeTypeGetter {
-  field core::String note = "This is temporary. The VM doesn't need closure classes.";
-  field mock::Context context;
-  constructor •(final mock::Context context) → dynamic
-    : self::Closure#main#foo::context = context
-    ;
-  method call(self::A a) → self::B {
-    "This is a temporary solution. In the VM, this will become an additional parameter.";
-    final mock::Context #contextParameter = this.{self::Closure#main#foo::context};
-    return null;
-  }
-  get $type() → typ::ReifiedType
-    return new typ::Interface::•(self::$declarations.[](2));
-}
-class Closure#main#qux extends core::Object implements core::Function, int::HasRuntimeTypeGetter {
-  field core::String note = "This is temporary. The VM doesn't need closure classes.";
-  field mock::Context context;
-  constructor •(final mock::Context context) → dynamic
-    : self::Closure#main#qux::context = context
-    ;
-  method call(self::B b) → self::A {
-    "This is a temporary solution. In the VM, this will become an additional parameter.";
-    final mock::Context #contextParameter = this.{self::Closure#main#qux::context};
-    return null;
-  }
-  get $type() → typ::ReifiedType
-    return new typ::Interface::•(self::$declarations.[](3));
-}
-class Closure#bar extends core::Object implements core::Function, int::HasRuntimeTypeGetter {
-  field core::String note = "This is temporary. The VM doesn't need closure classes.";
-  constructor •() → dynamic
-    ;
-  method call(self::A a) → dynamic
-    return self::bar(a);
-  get $type() → typ::ReifiedType
-    return new typ::Interface::•(self::$declarations.[](4));
-}
-class Closure#baz extends core::Object implements core::Function, int::HasRuntimeTypeGetter {
-  field core::String note = "This is temporary. The VM doesn't need closure classes.";
-  constructor •() → dynamic
-    ;
-  method call(dynamic a) → self::B
-    return self::baz(a);
-  get $type() → typ::ReifiedType
-    return new typ::Interface::•(self::$declarations.[](5));
-}
-static final field core::List<dec::Class> $declarations = (core::List<dec::Class> d) → core::List<dec::Class> {
-  dec::init(d, 0, new typ::Interface::•(d.[](20)));
-  dec::init(d, 1, new typ::Interface::•(d.[](20)));
-  dec::init(d, 2, new typ::Interface::•(d.[](20)), <dynamic>[new typ::Interface::•(d.[](6))], new typ::FunctionType::•(new typ::Interface::•(d.[](6)), new typ::Interface::•(d.[](1)), 0, <dynamic>[new typ::Interface::•(d.[](0))]));
-  dec::init(d, 3, new typ::Interface::•(d.[](20)), <dynamic>[new typ::Interface::•(d.[](6))], new typ::FunctionType::•(new typ::Interface::•(d.[](6)), new typ::Interface::•(d.[](0)), 0, <dynamic>[new typ::Interface::•(d.[](1))]));
-  dec::init(d, 4, new typ::Interface::•(d.[](20)), <dynamic>[new typ::Interface::•(d.[](6))], new typ::FunctionType::•(new typ::Interface::•(d.[](6)), const typ::Dynamic::•(), 0, <dynamic>[new typ::Interface::•(d.[](0))]));
-  dec::init(d, 5, new typ::Interface::•(d.[](20)), <dynamic>[new typ::Interface::•(d.[](6))], new typ::FunctionType::•(new typ::Interface::•(d.[](6)), new typ::Interface::•(d.[](1)), 0, <dynamic>[const typ::Dynamic::•()]));
-  dec::init(d, 6, new typ::Interface::•(d.[](20)));
-  dec::init(d, 7, new typ::Interface::•(d.[](20)));
-  dec::init(d, 8, new typ::Interface::•(d.[](20)));
-  dec::init(d, 9, new typ::Interface::•(d.[](20)), <dynamic>[new typ::Interface::•(d.[](22), <dynamic>[new typ::Interface::•(d.[](9))]), new typ::Interface::•(d.[](23))]);
-  dec::init(d, 10, new typ::Interface::•(d.[](24)));
-  dec::init(d, 11, new typ::Interface::•(d.[](24)));
-  dec::init(d, 12, new typ::Interface::•(d.[](20)));
-  dec::init(d, 13, new typ::Interface::•(d.[](25)));
-  dec::init(d, 14, new typ::Interface::•(d.[](25)));
-  dec::init(d, 15, new typ::Interface::•(d.[](25)));
-  dec::init(d, 16, new typ::Interface::•(d.[](25)));
-  dec::init(d, 17, new typ::Interface::•(d.[](20)), <dynamic>[new typ::Interface::•(d.[](26))]);
-  dec::init(d, 18, new typ::Interface::•(d.[](19)));
-  dec::init(d, 19, new typ::Interface::•(d.[](25)));
-  dec::init(d, 20, null);
-  dec::init(d, 22, new typ::Interface::•(d.[](20)));
-  dec::init(d, 23, new typ::Interface::•(d.[](20)));
-  dec::init(d, 24, new typ::Interface::•(d.[](20)), <dynamic>[new typ::Interface::•(d.[](22), <dynamic>[new typ::Interface::•(d.[](24))])]);
-  dec::init(d, 25, new typ::Interface::•(d.[](20)));
-  dec::init(d, 26, new typ::Interface::•(d.[](20)));
-  return d;
-}.call(dec::allocateDeclarations(<dynamic>["A", "B", "Closure#main#foo", "Closure#main#qux", "Closure#bar", "Closure#baz", "Function", "Null", "bool", "String", "int", "double", "Type", "AbstractClassInstantiationError", "NoSuchMethodError", "CyclicInitializationError", "UnsupportedError", "IntegerDivisionByZeroException", "RangeError", "ArgumentError", "Object", "HasRuntimeTypeGetter", "Comparable", "Pattern", "num", "Error", "Exception"], <dynamic>[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0]));
-static method bar(self::A a) → dynamic {
-  return null;
-}
-static method baz(dynamic a) → self::B {
-  return null;
-}
-static method main() → dynamic {
-  final (self::A) → self::B foo = new self::Closure#main#foo::•(null);
-  final (self::B) → self::A qux = new self::Closure#main#qux::•(null);
-  tes::expectTrue(typ::isSubtypeOf(int::type(foo), new typ::FunctionType::•(new typ::Interface::•(self::$declarations.[](6)), new typ::Interface::•(self::$declarations.[](1)), 0, <dynamic>[new typ::Interface::•(self::$declarations.[](0))])));
-  tes::expectTrue(!typ::isSubtypeOf(int::type(qux), new typ::FunctionType::•(new typ::Interface::•(self::$declarations.[](6)), new typ::Interface::•(self::$declarations.[](1)), 0, <dynamic>[new typ::Interface::•(self::$declarations.[](0))])));
-  tes::expectTrue(!typ::isSubtypeOf(int::type(foo), new typ::FunctionType::•(new typ::Interface::•(self::$declarations.[](6)), new typ::Interface::•(self::$declarations.[](0)), 0, <dynamic>[new typ::Interface::•(self::$declarations.[](1))])));
-  tes::expectTrue(typ::isSubtypeOf(int::type(qux), new typ::FunctionType::•(new typ::Interface::•(self::$declarations.[](6)), new typ::Interface::•(self::$declarations.[](0)), 0, <dynamic>[new typ::Interface::•(self::$declarations.[](1))])));
-  tes::expectTrue(typ::isSubtypeOf(int::type(new self::Closure#bar::•()), new typ::FunctionType::•(new typ::Interface::•(self::$declarations.[](6)), new typ::Interface::•(self::$declarations.[](1)), 0, <dynamic>[new typ::Interface::•(self::$declarations.[](0))])));
-  tes::expectTrue(!typ::isSubtypeOf(int::type(new self::Closure#bar::•()), new typ::FunctionType::•(new typ::Interface::•(self::$declarations.[](6)), new typ::Interface::•(self::$declarations.[](0)), 0, <dynamic>[new typ::Interface::•(self::$declarations.[](1))])));
-  tes::expectTrue(typ::isSubtypeOf(int::type(new self::Closure#baz::•()), new typ::FunctionType::•(new typ::Interface::•(self::$declarations.[](6)), new typ::Interface::•(self::$declarations.[](1)), 0, <dynamic>[new typ::Interface::•(self::$declarations.[](0))])));
-  tes::expectTrue(!typ::isSubtypeOf(int::type(new self::Closure#baz::•()), new typ::FunctionType::•(new typ::Interface::•(self::$declarations.[](6)), new typ::Interface::•(self::$declarations.[](0)), 0, <dynamic>[new typ::Interface::•(self::$declarations.[](1))])));
-  (self::A) → dynamic rab = new self::Closure#bar::•();
-  (dynamic) → self::B zab = new self::Closure#baz::•();
-  tes::expectTrue(typ::isSubtypeOf(int::type(rab), new typ::FunctionType::•(new typ::Interface::•(self::$declarations.[](6)), new typ::Interface::•(self::$declarations.[](1)), 0, <dynamic>[new typ::Interface::•(self::$declarations.[](0))])));
-  tes::expectTrue(!typ::isSubtypeOf(int::type(rab), new typ::FunctionType::•(new typ::Interface::•(self::$declarations.[](6)), new typ::Interface::•(self::$declarations.[](0)), 0, <dynamic>[new typ::Interface::•(self::$declarations.[](1))])));
-  tes::expectTrue(typ::isSubtypeOf(int::type(zab), new typ::FunctionType::•(new typ::Interface::•(self::$declarations.[](6)), new typ::Interface::•(self::$declarations.[](1)), 0, <dynamic>[new typ::Interface::•(self::$declarations.[](0))])));
-  tes::expectTrue(!typ::isSubtypeOf(int::type(zab), new typ::FunctionType::•(new typ::Interface::•(self::$declarations.[](6)), new typ::Interface::•(self::$declarations.[](0)), 0, <dynamic>[new typ::Interface::•(self::$declarations.[](1))])));
-}
diff --git a/pkg/kernel/testcases/reify/factories_test.dart b/pkg/kernel/testcases/reify/factories_test.dart
deleted file mode 100644
index 805df85..0000000
--- a/pkg/kernel/testcases/reify/factories_test.dart
+++ /dev/null
@@ -1,40 +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 factories_test;
-
-import 'test_base.dart';
-
-class A<T> {
-  factory A() {
-    return new B<T>();
-  }
-
-  factory A.named() {
-    return new A<T>.internal();
-  }
-
-  factory A.forward() = A<T>.internal;
-
-  A.internal();
-}
-
-class B<T> extends A<T> {
-  B() : super.internal();
-}
-
-class X {}
-
-class Y {}
-
-main() {
-  expectTrue(new A<X>.named() is A<X>);
-  expectTrue(new A<X>.named() is! A<Y>);
-  expectTrue(new A<X>.forward() is A<X>);
-  expectTrue(new A<X>.forward() is! A<Y>);
-  expectTrue(new A<X>() is B<X>);
-  expectTrue(new A<X>() is! B<Y>);
-  expectTrue(new A<X>.named() is! B<X>);
-  expectTrue(new A<X>.forward() is! B<X>);
-}
diff --git a/pkg/kernel/testcases/reify/factories_test.dart.expect b/pkg/kernel/testcases/reify/factories_test.dart.expect
deleted file mode 100644
index de736e8..0000000
--- a/pkg/kernel/testcases/reify/factories_test.dart.expect
+++ /dev/null
@@ -1,97 +0,0 @@
-library factories_test;
-import self as self;
-import "dart:core" as core;
-import "../../runtime/reify/interceptors.dart" as int;
-import "../../runtime/reify/types.dart" as typ;
-import "./test_base.dart" as tes;
-import "../../runtime/reify/declarations.dart" as dec;
-
-class A extends core::Object implements int::HasRuntimeTypeGetter {
-  final field typ::ReifiedType $type;
-  constructor internal(typ::ReifiedType $type) → void
-    : self::A::$type = $type, super core::Object::•()
-    ;
-  static factory •(typ::ReifiedType $type) → self::A {
-    return new self::B::•(new typ::Interface::•(self::$declarations.[](1), <dynamic>[typ::getTypeArguments(typ::asInstanceOf($type, self::$declarations.[](0))).[](0)]));
-  }
-  static factory named(typ::ReifiedType $type) → self::A {
-    return new self::A::internal(new typ::Interface::•(self::$declarations.[](0), <dynamic>[typ::getTypeArguments(typ::asInstanceOf($type, self::$declarations.[](0))).[](0)]));
-  }
-  get $A$T() → typ::ReifiedType
-    return typ::getTypeArguments(typ::asInstanceOf(this.$type, self::$declarations.[](0))).[](0);
-  get $is$A() → core::bool
-    return true;
-  get $is$B() → core::bool
-    return false;
-  get runtimeType() → core::Type
-    return this.{=self::A::$type};
-}
-class B extends self::A implements int::HasRuntimeTypeGetter {
-  constructor •(typ::ReifiedType $type) → void
-    : super self::A::internal($type)
-    ;
-  get $B$T() → typ::ReifiedType
-    return typ::getTypeArguments(typ::asInstanceOf(this.$type, self::$declarations.[](1))).[](0);
-  get $is$A() → core::bool
-    return true;
-  get $is$B() → core::bool
-    return true;
-}
-class X extends core::Object implements int::HasRuntimeTypeGetter {
-  constructor •() → void
-    : super core::Object::•()
-    ;
-  get $type() → typ::ReifiedType
-    return new typ::Interface::•(self::$declarations.[](2));
-  get $is$A() → core::bool
-    return false;
-  get $is$B() → core::bool
-    return false;
-}
-class Y extends core::Object implements int::HasRuntimeTypeGetter {
-  constructor •() → void
-    : super core::Object::•()
-    ;
-  get $type() → typ::ReifiedType
-    return new typ::Interface::•(self::$declarations.[](3));
-  get $is$A() → core::bool
-    return false;
-  get $is$B() → core::bool
-    return false;
-}
-static final field core::List<dec::Class> $declarations = (core::List<dec::Class> d) → core::List<dec::Class> {
-  dec::init(d, 0, new typ::Interface::•(d.[](17)));
-  dec::init(d, 1, new typ::Interface::•(d.[](0), <dynamic>[d.[](1).variables.[](0)]));
-  dec::init(d, 2, new typ::Interface::•(d.[](17)));
-  dec::init(d, 3, new typ::Interface::•(d.[](17)));
-  dec::init(d, 4, new typ::Interface::•(d.[](17)));
-  dec::init(d, 5, new typ::Interface::•(d.[](17)));
-  dec::init(d, 6, new typ::Interface::•(d.[](17)), <dynamic>[new typ::Interface::•(d.[](19), <dynamic>[new typ::Interface::•(d.[](6))]), new typ::Interface::•(d.[](20))]);
-  dec::init(d, 7, new typ::Interface::•(d.[](21)));
-  dec::init(d, 8, new typ::Interface::•(d.[](21)));
-  dec::init(d, 9, new typ::Interface::•(d.[](17)));
-  dec::init(d, 10, new typ::Interface::•(d.[](22)));
-  dec::init(d, 11, new typ::Interface::•(d.[](22)));
-  dec::init(d, 12, new typ::Interface::•(d.[](22)));
-  dec::init(d, 13, new typ::Interface::•(d.[](22)));
-  dec::init(d, 14, new typ::Interface::•(d.[](17)), <dynamic>[new typ::Interface::•(d.[](23))]);
-  dec::init(d, 15, new typ::Interface::•(d.[](16)));
-  dec::init(d, 16, new typ::Interface::•(d.[](22)));
-  dec::init(d, 17, null);
-  dec::init(d, 19, new typ::Interface::•(d.[](17)));
-  dec::init(d, 20, new typ::Interface::•(d.[](17)));
-  dec::init(d, 21, new typ::Interface::•(d.[](17)), <dynamic>[new typ::Interface::•(d.[](19), <dynamic>[new typ::Interface::•(d.[](21))])]);
-  dec::init(d, 22, new typ::Interface::•(d.[](17)));
-  dec::init(d, 23, new typ::Interface::•(d.[](17)));
-  return d;
-}.call(dec::allocateDeclarations(<dynamic>["A", "B", "X", "Y", "Null", "bool", "String", "int", "double", "Type", "AbstractClassInstantiationError", "NoSuchMethodError", "CyclicInitializationError", "UnsupportedError", "IntegerDivisionByZeroException", "RangeError", "ArgumentError", "Object", "HasRuntimeTypeGetter", "Comparable", "Pattern", "num", "Error", "Exception"], <dynamic>[1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0]));
-static method main() → dynamic {
-  tes::expectTrue(let dynamic #t1 = self::A::named(new typ::Interface::•(self::$declarations.[](0), <dynamic>[new typ::Interface::•(self::$declarations.[](2))])) in #t1 is int::HasRuntimeTypeGetter && #t1.$is$A && (let dynamic #t2 = new typ::Interface::•(self::$declarations.[](0), <dynamic>[new typ::Interface::•(self::$declarations.[](2))]) in typ::isSubtypeOf(#t1.$type, #t2)));
-  tes::expectTrue(!(let dynamic #t3 = self::A::named(new typ::Interface::•(self::$declarations.[](0), <dynamic>[new typ::Interface::•(self::$declarations.[](2))])) in #t3 is int::HasRuntimeTypeGetter && #t3.$is$A && (let dynamic #t4 = new typ::Interface::•(self::$declarations.[](0), <dynamic>[new typ::Interface::•(self::$declarations.[](3))]) in typ::isSubtypeOf(#t3.$type, #t4))));
-  tes::expectTrue(let dynamic #t5 = new self::A::internal(new typ::Interface::•(self::$declarations.[](0), <dynamic>[new typ::Interface::•(self::$declarations.[](2))])) in #t5 is int::HasRuntimeTypeGetter && #t5.$is$A && (let dynamic #t6 = new typ::Interface::•(self::$declarations.[](0), <dynamic>[new typ::Interface::•(self::$declarations.[](2))]) in typ::isSubtypeOf(#t5.$type, #t6)));
-  tes::expectTrue(!(let dynamic #t7 = new self::A::internal(new typ::Interface::•(self::$declarations.[](0), <dynamic>[new typ::Interface::•(self::$declarations.[](2))])) in #t7 is int::HasRuntimeTypeGetter && #t7.$is$A && (let dynamic #t8 = new typ::Interface::•(self::$declarations.[](0), <dynamic>[new typ::Interface::•(self::$declarations.[](3))]) in typ::isSubtypeOf(#t7.$type, #t8))));
-  tes::expectTrue(let dynamic #t9 = self::A::•(new typ::Interface::•(self::$declarations.[](0), <dynamic>[new typ::Interface::•(self::$declarations.[](2))])) in #t9 is int::HasRuntimeTypeGetter && #t9.$is$B && (let dynamic #t10 = new typ::Interface::•(self::$declarations.[](1), <dynamic>[new typ::Interface::•(self::$declarations.[](2))]) in typ::isSubtypeOf(#t9.$type, #t10)));
-  tes::expectTrue(!(let dynamic #t11 = self::A::•(new typ::Interface::•(self::$declarations.[](0), <dynamic>[new typ::Interface::•(self::$declarations.[](2))])) in #t11 is int::HasRuntimeTypeGetter && #t11.$is$B && (let dynamic #t12 = new typ::Interface::•(self::$declarations.[](1), <dynamic>[new typ::Interface::•(self::$declarations.[](3))]) in typ::isSubtypeOf(#t11.$type, #t12))));
-  tes::expectTrue(!(let dynamic #t13 = self::A::named(new typ::Interface::•(self::$declarations.[](0), <dynamic>[new typ::Interface::•(self::$declarations.[](2))])) in #t13 is int::HasRuntimeTypeGetter && #t13.$is$B && (let dynamic #t14 = new typ::Interface::•(self::$declarations.[](1), <dynamic>[new typ::Interface::•(self::$declarations.[](2))]) in typ::isSubtypeOf(#t13.$type, #t14))));
-  tes::expectTrue(!(let dynamic #t15 = new self::A::internal(new typ::Interface::•(self::$declarations.[](0), <dynamic>[new typ::Interface::•(self::$declarations.[](2))])) in #t15 is int::HasRuntimeTypeGetter && #t15.$is$B && (let dynamic #t16 = new typ::Interface::•(self::$declarations.[](1), <dynamic>[new typ::Interface::•(self::$declarations.[](2))]) in typ::isSubtypeOf(#t15.$type, #t16))));
-}
diff --git a/pkg/kernel/testcases/reify/field_initializer2_test.dart b/pkg/kernel/testcases/reify/field_initializer2_test.dart
deleted file mode 100644
index 47db808..0000000
--- a/pkg/kernel/testcases/reify/field_initializer2_test.dart
+++ /dev/null
@@ -1,24 +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 field_initializer2_test;
-
-import 'test_base.dart';
-
-class A<T> {}
-
-class B<T> {
-  var x = new A<T>();
-  var y;
-  B() : y = new A<T>();
-}
-
-main() {
-  var b = new B<A>();
-  expectTrue(b.x is A<A>);
-  expectTrue(b.y is A<A>);
-
-  expectFalse(b.x is A<B>);
-  expectFalse(b.y is A<B>);
-}
diff --git a/pkg/kernel/testcases/reify/field_initializer2_test.dart.expect b/pkg/kernel/testcases/reify/field_initializer2_test.dart.expect
deleted file mode 100644
index 93f4456..0000000
--- a/pkg/kernel/testcases/reify/field_initializer2_test.dart.expect
+++ /dev/null
@@ -1,70 +0,0 @@
-library field_initializer2_test;
-import self as self;
-import "dart:core" as core;
-import "../../runtime/reify/interceptors.dart" as int;
-import "../../runtime/reify/types.dart" as typ;
-import "./test_base.dart" as tes;
-import "../../runtime/reify/declarations.dart" as dec;
-
-class A extends core::Object implements int::HasRuntimeTypeGetter {
-  final field typ::ReifiedType $type;
-  constructor •(typ::ReifiedType $type) → void
-    : self::A::$type = $type, super core::Object::•()
-    ;
-  get $A$T() → typ::ReifiedType
-    return typ::getTypeArguments(typ::asInstanceOf(this.$type, self::$declarations.[](0))).[](0);
-  get $is$A() → core::bool
-    return true;
-  get runtimeType() → core::Type
-    return this.{=self::A::$type};
-}
-class B extends core::Object implements int::HasRuntimeTypeGetter {
-  field self::A x;
-  field dynamic y;
-  final field typ::ReifiedType $type;
-  constructor •(typ::ReifiedType $type) → void
-    : self::B::x = self::B::$init$x($type), self::B::$type = $type, self::B::y = new self::A::•(new typ::Interface::•(self::$declarations.[](0), typ::getTypeArguments(typ::asInstanceOf($type, self::$declarations.[](1))))), super core::Object::•()
-    ;
-  set x$cc(self::A x_) → dynamic {
-    this.{=self::B::x} = x_ as self::A;
-  }
-  get $B$T() → typ::ReifiedType
-    return typ::getTypeArguments(typ::asInstanceOf(this.$type, self::$declarations.[](1))).[](0);
-  get $is$A() → core::bool
-    return false;
-  get runtimeType() → core::Type
-    return this.{=self::B::$type};
-  static method $init$x(dynamic $type) → dynamic
-    return new self::A::•(new typ::Interface::•(self::$declarations.[](0), typ::getTypeArguments(typ::asInstanceOf($type, self::$declarations.[](1)))));
-}
-static final field core::List<dec::Class> $declarations = (core::List<dec::Class> d) → core::List<dec::Class> {
-  dec::init(d, 0, new typ::Interface::•(d.[](15)));
-  dec::init(d, 1, new typ::Interface::•(d.[](15)));
-  dec::init(d, 2, new typ::Interface::•(d.[](15)));
-  dec::init(d, 3, new typ::Interface::•(d.[](15)));
-  dec::init(d, 4, new typ::Interface::•(d.[](15)), <dynamic>[new typ::Interface::•(d.[](17), <dynamic>[new typ::Interface::•(d.[](4))]), new typ::Interface::•(d.[](18))]);
-  dec::init(d, 5, new typ::Interface::•(d.[](19)));
-  dec::init(d, 6, new typ::Interface::•(d.[](19)));
-  dec::init(d, 7, new typ::Interface::•(d.[](15)));
-  dec::init(d, 8, new typ::Interface::•(d.[](20)));
-  dec::init(d, 9, new typ::Interface::•(d.[](20)));
-  dec::init(d, 10, new typ::Interface::•(d.[](20)));
-  dec::init(d, 11, new typ::Interface::•(d.[](20)));
-  dec::init(d, 12, new typ::Interface::•(d.[](15)), <dynamic>[new typ::Interface::•(d.[](21))]);
-  dec::init(d, 13, new typ::Interface::•(d.[](14)));
-  dec::init(d, 14, new typ::Interface::•(d.[](20)));
-  dec::init(d, 15, null);
-  dec::init(d, 17, new typ::Interface::•(d.[](15)));
-  dec::init(d, 18, new typ::Interface::•(d.[](15)));
-  dec::init(d, 19, new typ::Interface::•(d.[](15)), <dynamic>[new typ::Interface::•(d.[](17), <dynamic>[new typ::Interface::•(d.[](19))])]);
-  dec::init(d, 20, new typ::Interface::•(d.[](15)));
-  dec::init(d, 21, new typ::Interface::•(d.[](15)));
-  return d;
-}.call(dec::allocateDeclarations(<dynamic>["A", "B", "Null", "bool", "String", "int", "double", "Type", "AbstractClassInstantiationError", "NoSuchMethodError", "CyclicInitializationError", "UnsupportedError", "IntegerDivisionByZeroException", "RangeError", "ArgumentError", "Object", "HasRuntimeTypeGetter", "Comparable", "Pattern", "num", "Error", "Exception"], <dynamic>[1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0]));
-static method main() → dynamic {
-  self::B b = new self::B::•(new typ::Interface::•(self::$declarations.[](1), <dynamic>[new typ::Interface::•(self::$declarations.[](0), <dynamic>[const typ::Dynamic::•()])]));
-  tes::expectTrue(let dynamic #t1 = b.{self::B::x} in #t1 is int::HasRuntimeTypeGetter && #t1.$is$A && (let dynamic #t2 = new typ::Interface::•(self::$declarations.[](0), <dynamic>[new typ::Interface::•(self::$declarations.[](0), <dynamic>[const typ::Dynamic::•()])]) in typ::isSubtypeOf(#t1.$type, #t2)));
-  tes::expectTrue(let dynamic #t3 = b.{self::B::y} in #t3 is int::HasRuntimeTypeGetter && #t3.$is$A && (let dynamic #t4 = new typ::Interface::•(self::$declarations.[](0), <dynamic>[new typ::Interface::•(self::$declarations.[](0), <dynamic>[const typ::Dynamic::•()])]) in typ::isSubtypeOf(#t3.$type, #t4)));
-  tes::expectFalse(let dynamic #t5 = b.{self::B::x} in #t5 is int::HasRuntimeTypeGetter && #t5.$is$A && (let dynamic #t6 = new typ::Interface::•(self::$declarations.[](0), <dynamic>[new typ::Interface::•(self::$declarations.[](1), <dynamic>[const typ::Dynamic::•()])]) in typ::isSubtypeOf(#t5.$type, #t6)));
-  tes::expectFalse(let dynamic #t7 = b.{self::B::y} in #t7 is int::HasRuntimeTypeGetter && #t7.$is$A && (let dynamic #t8 = new typ::Interface::•(self::$declarations.[](0), <dynamic>[new typ::Interface::•(self::$declarations.[](1), <dynamic>[const typ::Dynamic::•()])]) in typ::isSubtypeOf(#t7.$type, #t8)));
-}
diff --git a/pkg/kernel/testcases/reify/field_initializer_test.dart b/pkg/kernel/testcases/reify/field_initializer_test.dart
deleted file mode 100644
index d1e4c9c..0000000
--- a/pkg/kernel/testcases/reify/field_initializer_test.dart
+++ /dev/null
@@ -1,40 +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 field_initializer_test;
-
-import 'test_base.dart';
-
-p(x) {
-  write(x);
-  return x;
-}
-
-class A<T> {
-  var a1 = p("a1");
-  var a2;
-
-  A() : a2 = p("a2") {
-    p("A");
-  }
-}
-
-class B<T> extends A<T> {
-  var b1 = p("b1");
-  var b2 = p("b2");
-  var b3;
-  var b4;
-
-  B()
-      : b3 = p("b3"),
-        b4 = p("b4"),
-        super() {
-    p("B");
-  }
-}
-
-main() {
-  var b = new B();
-  expectOutput("b1\nb2\nb3\nb4\na1\na2\nA\nB");
-}
diff --git a/pkg/kernel/testcases/reify/field_initializer_test.dart.expect b/pkg/kernel/testcases/reify/field_initializer_test.dart.expect
deleted file mode 100644
index 8490bf3..0000000
--- a/pkg/kernel/testcases/reify/field_initializer_test.dart.expect
+++ /dev/null
@@ -1,65 +0,0 @@
-library field_initializer_test;
-import self as self;
-import "dart:core" as core;
-import "../../runtime/reify/interceptors.dart" as int;
-import "../../runtime/reify/types.dart" as typ;
-import "./test_base.dart" as tes;
-import "../../runtime/reify/declarations.dart" as dec;
-
-class A extends core::Object implements int::HasRuntimeTypeGetter {
-  field dynamic a1 = self::p("a1");
-  field dynamic a2;
-  final field typ::ReifiedType $type;
-  constructor •(typ::ReifiedType $type) → void
-    : self::A::$type = $type, self::A::a2 = self::p("a2"), super core::Object::•() {
-    self::p("A");
-  }
-  get $A$T() → typ::ReifiedType
-    return typ::getTypeArguments(typ::asInstanceOf(this.$type, self::$declarations.[](0))).[](0);
-  get runtimeType() → core::Type
-    return this.{=self::A::$type};
-}
-class B extends self::A implements int::HasRuntimeTypeGetter {
-  field dynamic b1 = self::p("b1");
-  field dynamic b2 = self::p("b2");
-  field dynamic b3;
-  field dynamic b4;
-  constructor •(typ::ReifiedType $type) → void
-    : self::B::b3 = self::p("b3"), self::B::b4 = self::p("b4"), super self::A::•($type) {
-    self::p("B");
-  }
-  get $B$T() → typ::ReifiedType
-    return typ::getTypeArguments(typ::asInstanceOf(this.$type, self::$declarations.[](1))).[](0);
-}
-static final field core::List<dec::Class> $declarations = (core::List<dec::Class> d) → core::List<dec::Class> {
-  dec::init(d, 0, new typ::Interface::•(d.[](15)));
-  dec::init(d, 1, new typ::Interface::•(d.[](0), <dynamic>[d.[](1).variables.[](0)]));
-  dec::init(d, 2, new typ::Interface::•(d.[](15)));
-  dec::init(d, 3, new typ::Interface::•(d.[](15)));
-  dec::init(d, 4, new typ::Interface::•(d.[](15)), <dynamic>[new typ::Interface::•(d.[](17), <dynamic>[new typ::Interface::•(d.[](4))]), new typ::Interface::•(d.[](18))]);
-  dec::init(d, 5, new typ::Interface::•(d.[](19)));
-  dec::init(d, 6, new typ::Interface::•(d.[](19)));
-  dec::init(d, 7, new typ::Interface::•(d.[](15)));
-  dec::init(d, 8, new typ::Interface::•(d.[](20)));
-  dec::init(d, 9, new typ::Interface::•(d.[](20)));
-  dec::init(d, 10, new typ::Interface::•(d.[](20)));
-  dec::init(d, 11, new typ::Interface::•(d.[](20)));
-  dec::init(d, 12, new typ::Interface::•(d.[](15)), <dynamic>[new typ::Interface::•(d.[](21))]);
-  dec::init(d, 13, new typ::Interface::•(d.[](14)));
-  dec::init(d, 14, new typ::Interface::•(d.[](20)));
-  dec::init(d, 15, null);
-  dec::init(d, 17, new typ::Interface::•(d.[](15)));
-  dec::init(d, 18, new typ::Interface::•(d.[](15)));
-  dec::init(d, 19, new typ::Interface::•(d.[](15)), <dynamic>[new typ::Interface::•(d.[](17), <dynamic>[new typ::Interface::•(d.[](19))])]);
-  dec::init(d, 20, new typ::Interface::•(d.[](15)));
-  dec::init(d, 21, new typ::Interface::•(d.[](15)));
-  return d;
-}.call(dec::allocateDeclarations(<dynamic>["A", "B", "Null", "bool", "String", "int", "double", "Type", "AbstractClassInstantiationError", "NoSuchMethodError", "CyclicInitializationError", "UnsupportedError", "IntegerDivisionByZeroException", "RangeError", "ArgumentError", "Object", "HasRuntimeTypeGetter", "Comparable", "Pattern", "num", "Error", "Exception"], <dynamic>[1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0]));
-static method p(dynamic x) → dynamic {
-  tes::write(x);
-  return x;
-}
-static method main() → dynamic {
-  self::B b = new self::B::•(new typ::Interface::•(self::$declarations.[](1), <dynamic>[const typ::Dynamic::•()]));
-  tes::expectOutput("b1\nb2\nb3\nb4\na1\na2\nA\nB");
-}
diff --git a/pkg/kernel/testcases/reify/function_type_test.dart b/pkg/kernel/testcases/reify/function_type_test.dart
deleted file mode 100644
index b67b743..0000000
--- a/pkg/kernel/testcases/reify/function_type_test.dart
+++ /dev/null
@@ -1,266 +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 function_type_test;
-
-import 'test_base.dart';
-
-class A {}
-
-class B extends A {}
-
-class C extends A {}
-
-class D implements Function {
-  B call(A a) {
-    return null;
-  }
-}
-
-class ER0P1 {
-  void call([A a]) {}
-}
-
-class ER1P0 {
-  void call(A a) {}
-}
-
-class ER1P1 {
-  void call(A a, [B b]) {}
-}
-
-class ER1P2 {
-  void call(A a, [B b, C c]) {}
-}
-
-class ER2P1 {
-  void call(A a, B b, [C c]) {}
-}
-
-class ER0N1 {
-  void call({A a}) {}
-}
-
-class ER1N0 {
-  void call(A a) {}
-}
-
-class ER1N1 {
-  void call(A a, {B b}) {}
-}
-
-class ER1N2 {
-  void call(A a, {B b, C c}) {}
-}
-
-class ER2N1 {
-  void call(A a, B b, {C c}) {}
-}
-
-class ER0N8 {
-  void call({kE, ii, oP, Ij, pA, zD, aZ, UU}) {}
-}
-
-C foo(A a) {
-  return null;
-}
-
-typedef B A2B(A a);
-
-typedef C C2C(C c);
-
-typedef void R0P1([A a]);
-typedef void R1P0(A a);
-typedef void R1P1(A a, [B b]);
-typedef void R1P2(A a, [B b, C c]);
-typedef void R2P1(A a, B b, [C c]);
-
-typedef void R0N1({A a});
-typedef void R1N0(A a);
-typedef void R1N1(A a, {B b});
-typedef void R1N2(A a, {B b, C c});
-typedef void R2N1(A a, B b, {C c});
-
-typedef void R0N8({aZ, oP, Ij, kE, pA, zD, UU, ii});
-
-void test(x) {
-  write(x is Function);
-  write(x is A2B);
-  write(x is C2C);
-
-  write(x is R0P1);
-  write(x is R1P0);
-  write(x is R1P1);
-  write(x is R1P2);
-  write(x is R2P1);
-
-  write(x is R0N1);
-  write(x is R1N0);
-  write(x is R1N1);
-  write(x is R1N2);
-  write(x is R2N1);
-}
-
-main() {
-  test(new D());
-  for (var c in [
-    new ER0P1(),
-    new ER1P0(),
-    new ER1P1(),
-    new ER1P2(),
-    new ER2P1(),
-    new ER0N1(),
-    new ER1N0(),
-    new ER1N1(),
-    new ER1N2(),
-    new ER2N1()
-  ]) {
-    test(c);
-  }
-
-  expectOutput("""
-true
-true
-false
-false
-true
-false
-false
-false
-false
-true
-false
-false
-false
-true
-false
-false
-true
-true
-false
-false
-false
-false
-true
-false
-false
-false
-true
-false
-false
-false
-true
-false
-false
-false
-false
-true
-false
-false
-false
-true
-false
-false
-false
-true
-true
-false
-false
-false
-true
-false
-false
-false
-true
-false
-false
-false
-true
-true
-true
-true
-false
-true
-false
-false
-false
-true
-false
-false
-false
-false
-false
-false
-true
-false
-false
-false
-false
-false
-true
-false
-false
-false
-false
-false
-false
-false
-true
-false
-false
-false
-false
-true
-false
-false
-false
-true
-false
-false
-false
-false
-true
-false
-false
-false
-true
-false
-false
-false
-true
-false
-false
-false
-false
-true
-true
-false
-false
-true
-false
-false
-false
-true
-false
-false
-false
-false
-true
-true
-true
-false
-true
-false
-false
-false
-false
-false
-false
-false
-false
-false
-false
-false
-true""");
-}
diff --git a/pkg/kernel/testcases/reify/function_type_test.dart.expect b/pkg/kernel/testcases/reify/function_type_test.dart.expect
deleted file mode 100644
index c953f80..0000000
--- a/pkg/kernel/testcases/reify/function_type_test.dart.expect
+++ /dev/null
@@ -1,223 +0,0 @@
-library function_type_test;
-import self as self;
-import "dart:core" as core;
-import "../../runtime/reify/interceptors.dart" as int;
-import "../../runtime/reify/types.dart" as typ;
-import "./test_base.dart" as tes;
-import "../../runtime/reify/declarations.dart" as dec;
-
-class A extends core::Object implements int::HasRuntimeTypeGetter {
-  constructor •() → void
-    : super core::Object::•()
-    ;
-  get $type() → typ::ReifiedType
-    return new typ::Interface::•(self::$declarations.[](0));
-  get $is$Function() → core::bool
-    return false;
-}
-class B extends self::A implements int::HasRuntimeTypeGetter {
-  constructor •() → void
-    : super self::A::•()
-    ;
-  get $type() → typ::ReifiedType
-    return new typ::Interface::•(self::$declarations.[](1));
-  get $is$Function() → core::bool
-    return false;
-}
-class C extends self::A implements int::HasRuntimeTypeGetter {
-  constructor •() → void
-    : super self::A::•()
-    ;
-  get $type() → typ::ReifiedType
-    return new typ::Interface::•(self::$declarations.[](2));
-  get $is$Function() → core::bool
-    return false;
-}
-class D extends core::Object implements core::Function, int::HasRuntimeTypeGetter {
-  constructor •() → void
-    : super core::Object::•()
-    ;
-  method call(self::A a) → self::B {
-    return null;
-  }
-  get $type() → typ::ReifiedType
-    return new typ::Interface::•(self::$declarations.[](3));
-  get $is$Function() → core::bool
-    return true;
-}
-class ER0P1 extends core::Object implements int::HasRuntimeTypeGetter {
-  constructor •() → void
-    : super core::Object::•()
-    ;
-  method call([self::A a]) → void {}
-  get $type() → typ::ReifiedType
-    return new typ::Interface::•(self::$declarations.[](4));
-  get $is$Function() → core::bool
-    return false;
-}
-class ER1P0 extends core::Object implements int::HasRuntimeTypeGetter {
-  constructor •() → void
-    : super core::Object::•()
-    ;
-  method call(self::A a) → void {}
-  get $type() → typ::ReifiedType
-    return new typ::Interface::•(self::$declarations.[](5));
-  get $is$Function() → core::bool
-    return false;
-}
-class ER1P1 extends core::Object implements int::HasRuntimeTypeGetter {
-  constructor •() → void
-    : super core::Object::•()
-    ;
-  method call(self::A a, [self::B b]) → void {}
-  get $type() → typ::ReifiedType
-    return new typ::Interface::•(self::$declarations.[](6));
-  get $is$Function() → core::bool
-    return false;
-}
-class ER1P2 extends core::Object implements int::HasRuntimeTypeGetter {
-  constructor •() → void
-    : super core::Object::•()
-    ;
-  method call(self::A a, [self::B b, self::C c]) → void {}
-  get $type() → typ::ReifiedType
-    return new typ::Interface::•(self::$declarations.[](7));
-  get $is$Function() → core::bool
-    return false;
-}
-class ER2P1 extends core::Object implements int::HasRuntimeTypeGetter {
-  constructor •() → void
-    : super core::Object::•()
-    ;
-  method call(self::A a, self::B b, [self::C c]) → void {}
-  get $type() → typ::ReifiedType
-    return new typ::Interface::•(self::$declarations.[](8));
-  get $is$Function() → core::bool
-    return false;
-}
-class ER0N1 extends core::Object implements int::HasRuntimeTypeGetter {
-  constructor •() → void
-    : super core::Object::•()
-    ;
-  method call({self::A a}) → void {}
-  get $type() → typ::ReifiedType
-    return new typ::Interface::•(self::$declarations.[](9));
-  get $is$Function() → core::bool
-    return false;
-}
-class ER1N0 extends core::Object implements int::HasRuntimeTypeGetter {
-  constructor •() → void
-    : super core::Object::•()
-    ;
-  method call(self::A a) → void {}
-  get $type() → typ::ReifiedType
-    return new typ::Interface::•(self::$declarations.[](10));
-  get $is$Function() → core::bool
-    return false;
-}
-class ER1N1 extends core::Object implements int::HasRuntimeTypeGetter {
-  constructor •() → void
-    : super core::Object::•()
-    ;
-  method call(self::A a, {self::B b}) → void {}
-  get $type() → typ::ReifiedType
-    return new typ::Interface::•(self::$declarations.[](11));
-  get $is$Function() → core::bool
-    return false;
-}
-class ER1N2 extends core::Object implements int::HasRuntimeTypeGetter {
-  constructor •() → void
-    : super core::Object::•()
-    ;
-  method call(self::A a, {self::B b, self::C c}) → void {}
-  get $type() → typ::ReifiedType
-    return new typ::Interface::•(self::$declarations.[](12));
-  get $is$Function() → core::bool
-    return false;
-}
-class ER2N1 extends core::Object implements int::HasRuntimeTypeGetter {
-  constructor •() → void
-    : super core::Object::•()
-    ;
-  method call(self::A a, self::B b, {self::C c}) → void {}
-  get $type() → typ::ReifiedType
-    return new typ::Interface::•(self::$declarations.[](13));
-  get $is$Function() → core::bool
-    return false;
-}
-class ER0N8 extends core::Object implements int::HasRuntimeTypeGetter {
-  constructor •() → void
-    : super core::Object::•()
-    ;
-  method call({dynamic kE, dynamic ii, dynamic oP, dynamic Ij, dynamic pA, dynamic zD, dynamic aZ, dynamic UU}) → void {}
-  get $type() → typ::ReifiedType
-    return new typ::Interface::•(self::$declarations.[](14));
-  get $is$Function() → core::bool
-    return false;
-}
-static final field core::List<dec::Class> $declarations = (core::List<dec::Class> d) → core::List<dec::Class> {
-  dec::init(d, 0, new typ::Interface::•(d.[](17)));
-  dec::init(d, 1, new typ::Interface::•(d.[](0)));
-  dec::init(d, 2, new typ::Interface::•(d.[](0)));
-  dec::init(d, 3, new typ::Interface::•(d.[](17)), <dynamic>[new typ::Interface::•(d.[](15))], new typ::FunctionType::•(new typ::Interface::•(d.[](15)), new typ::Interface::•(d.[](1)), 0, <dynamic>[new typ::Interface::•(d.[](0))]));
-  dec::init(d, 4, new typ::Interface::•(d.[](17)), <dynamic>[], new typ::FunctionType::•(new typ::Interface::•(d.[](15)), new typ::Void::•(), 2, <dynamic>[new typ::Interface::•(d.[](0))]));
-  dec::init(d, 5, new typ::Interface::•(d.[](17)), <dynamic>[], new typ::FunctionType::•(new typ::Interface::•(d.[](15)), new typ::Void::•(), 0, <dynamic>[new typ::Interface::•(d.[](0))]));
-  dec::init(d, 6, new typ::Interface::•(d.[](17)), <dynamic>[], new typ::FunctionType::•(new typ::Interface::•(d.[](15)), new typ::Void::•(), 2, <dynamic>[new typ::Interface::•(d.[](0)), new typ::Interface::•(d.[](1))]));
-  dec::init(d, 7, new typ::Interface::•(d.[](17)), <dynamic>[], new typ::FunctionType::•(new typ::Interface::•(d.[](15)), new typ::Void::•(), 4, <dynamic>[new typ::Interface::•(d.[](0)), new typ::Interface::•(d.[](1)), new typ::Interface::•(d.[](2))]));
-  dec::init(d, 8, new typ::Interface::•(d.[](17)), <dynamic>[], new typ::FunctionType::•(new typ::Interface::•(d.[](15)), new typ::Void::•(), 2, <dynamic>[new typ::Interface::•(d.[](0)), new typ::Interface::•(d.[](1)), new typ::Interface::•(d.[](2))]));
-  dec::init(d, 9, new typ::Interface::•(d.[](17)), <dynamic>[], new typ::FunctionType::•(new typ::Interface::•(d.[](15)), new typ::Void::•(), 3, <dynamic>["a", new typ::Interface::•(d.[](0))]));
-  dec::init(d, 10, new typ::Interface::•(d.[](17)), <dynamic>[], new typ::FunctionType::•(new typ::Interface::•(d.[](15)), new typ::Void::•(), 0, <dynamic>[new typ::Interface::•(d.[](0))]));
-  dec::init(d, 11, new typ::Interface::•(d.[](17)), <dynamic>[], new typ::FunctionType::•(new typ::Interface::•(d.[](15)), new typ::Void::•(), 3, <dynamic>[new typ::Interface::•(d.[](0)), "b", new typ::Interface::•(d.[](1))]));
-  dec::init(d, 12, new typ::Interface::•(d.[](17)), <dynamic>[], new typ::FunctionType::•(new typ::Interface::•(d.[](15)), new typ::Void::•(), 5, <dynamic>[new typ::Interface::•(d.[](0)), "b", new typ::Interface::•(d.[](1)), "c", new typ::Interface::•(d.[](2))]));
-  dec::init(d, 13, new typ::Interface::•(d.[](17)), <dynamic>[], new typ::FunctionType::•(new typ::Interface::•(d.[](15)), new typ::Void::•(), 3, <dynamic>[new typ::Interface::•(d.[](0)), new typ::Interface::•(d.[](1)), "c", new typ::Interface::•(d.[](2))]));
-  dec::init(d, 14, new typ::Interface::•(d.[](17)), <dynamic>[], new typ::FunctionType::•(new typ::Interface::•(d.[](15)), new typ::Void::•(), 17, <dynamic>["kE", const typ::Dynamic::•(), "ii", const typ::Dynamic::•(), "oP", const typ::Dynamic::•(), "Ij", const typ::Dynamic::•(), "pA", const typ::Dynamic::•(), "zD", const typ::Dynamic::•(), "aZ", const typ::Dynamic::•(), "UU", const typ::Dynamic::•()]));
-  dec::init(d, 15, new typ::Interface::•(d.[](17)));
-  dec::init(d, 16, new typ::Interface::•(d.[](17)), <dynamic>[new typ::Interface::•(d.[](32), <dynamic>[d.[](16).variables.[](0)])]);
-  dec::init(d, 17, null);
-  dec::init(d, 18, new typ::Interface::•(d.[](17)));
-  dec::init(d, 19, new typ::Interface::•(d.[](17)));
-  dec::init(d, 20, new typ::Interface::•(d.[](17)), <dynamic>[new typ::Interface::•(d.[](33), <dynamic>[new typ::Interface::•(d.[](20))]), new typ::Interface::•(d.[](34))]);
-  dec::init(d, 21, new typ::Interface::•(d.[](35)));
-  dec::init(d, 22, new typ::Interface::•(d.[](35)));
-  dec::init(d, 23, new typ::Interface::•(d.[](17)));
-  dec::init(d, 24, new typ::Interface::•(d.[](36)));
-  dec::init(d, 25, new typ::Interface::•(d.[](36)));
-  dec::init(d, 26, new typ::Interface::•(d.[](36)));
-  dec::init(d, 27, new typ::Interface::•(d.[](36)));
-  dec::init(d, 28, new typ::Interface::•(d.[](17)), <dynamic>[new typ::Interface::•(d.[](37))]);
-  dec::init(d, 29, new typ::Interface::•(d.[](30)));
-  dec::init(d, 30, new typ::Interface::•(d.[](36)));
-  dec::init(d, 32, new typ::Interface::•(d.[](38), <dynamic>[d.[](32).variables.[](0)]));
-  dec::init(d, 33, new typ::Interface::•(d.[](17)));
-  dec::init(d, 34, new typ::Interface::•(d.[](17)));
-  dec::init(d, 35, new typ::Interface::•(d.[](17)), <dynamic>[new typ::Interface::•(d.[](33), <dynamic>[new typ::Interface::•(d.[](35))])]);
-  dec::init(d, 36, new typ::Interface::•(d.[](17)));
-  dec::init(d, 37, new typ::Interface::•(d.[](17)));
-  dec::init(d, 38, new typ::Interface::•(d.[](17)));
-  return d;
-}.call(dec::allocateDeclarations(<dynamic>["A", "B", "C", "D", "ER0P1", "ER1P0", "ER1P1", "ER1P2", "ER2P1", "ER0N1", "ER1N0", "ER1N1", "ER1N2", "ER2N1", "ER0N8", "Function", "List", "Object", "Null", "bool", "String", "int", "double", "Type", "AbstractClassInstantiationError", "NoSuchMethodError", "CyclicInitializationError", "UnsupportedError", "IntegerDivisionByZeroException", "RangeError", "ArgumentError", "HasRuntimeTypeGetter", "EfficientLengthIterable", "Comparable", "Pattern", "num", "Error", "Exception", "Iterable"], <dynamic>[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1]));
-static method foo(self::A a) → self::C {
-  return null;
-}
-static method test(dynamic x) → void {
-  tes::write(typ::isSubtypeOf(int::type(x), new typ::Interface::•(self::$declarations.[](15))));
-  tes::write(typ::isSubtypeOf(int::type(x), new typ::FunctionType::•(new typ::Interface::•(self::$declarations.[](15)), new typ::Interface::•(self::$declarations.[](1)), 0, <dynamic>[new typ::Interface::•(self::$declarations.[](0))])));
-  tes::write(typ::isSubtypeOf(int::type(x), new typ::FunctionType::•(new typ::Interface::•(self::$declarations.[](15)), new typ::Interface::•(self::$declarations.[](2)), 0, <dynamic>[new typ::Interface::•(self::$declarations.[](2))])));
-  tes::write(typ::isSubtypeOf(int::type(x), new typ::FunctionType::•(new typ::Interface::•(self::$declarations.[](15)), new typ::Void::•(), 2, <dynamic>[new typ::Interface::•(self::$declarations.[](0))])));
-  tes::write(typ::isSubtypeOf(int::type(x), new typ::FunctionType::•(new typ::Interface::•(self::$declarations.[](15)), new typ::Void::•(), 0, <dynamic>[new typ::Interface::•(self::$declarations.[](0))])));
-  tes::write(typ::isSubtypeOf(int::type(x), new typ::FunctionType::•(new typ::Interface::•(self::$declarations.[](15)), new typ::Void::•(), 2, <dynamic>[new typ::Interface::•(self::$declarations.[](0)), new typ::Interface::•(self::$declarations.[](1))])));
-  tes::write(typ::isSubtypeOf(int::type(x), new typ::FunctionType::•(new typ::Interface::•(self::$declarations.[](15)), new typ::Void::•(), 4, <dynamic>[new typ::Interface::•(self::$declarations.[](0)), new typ::Interface::•(self::$declarations.[](1)), new typ::Interface::•(self::$declarations.[](2))])));
-  tes::write(typ::isSubtypeOf(int::type(x), new typ::FunctionType::•(new typ::Interface::•(self::$declarations.[](15)), new typ::Void::•(), 2, <dynamic>[new typ::Interface::•(self::$declarations.[](0)), new typ::Interface::•(self::$declarations.[](1)), new typ::Interface::•(self::$declarations.[](2))])));
-  tes::write(typ::isSubtypeOf(int::type(x), new typ::FunctionType::•(new typ::Interface::•(self::$declarations.[](15)), new typ::Void::•(), 3, <dynamic>["a", new typ::Interface::•(self::$declarations.[](0))])));
-  tes::write(typ::isSubtypeOf(int::type(x), new typ::FunctionType::•(new typ::Interface::•(self::$declarations.[](15)), new typ::Void::•(), 0, <dynamic>[new typ::Interface::•(self::$declarations.[](0))])));
-  tes::write(typ::isSubtypeOf(int::type(x), new typ::FunctionType::•(new typ::Interface::•(self::$declarations.[](15)), new typ::Void::•(), 3, <dynamic>[new typ::Interface::•(self::$declarations.[](0)), "b", new typ::Interface::•(self::$declarations.[](1))])));
-  tes::write(typ::isSubtypeOf(int::type(x), new typ::FunctionType::•(new typ::Interface::•(self::$declarations.[](15)), new typ::Void::•(), 5, <dynamic>[new typ::Interface::•(self::$declarations.[](0)), "b", new typ::Interface::•(self::$declarations.[](1)), "c", new typ::Interface::•(self::$declarations.[](2))])));
-  tes::write(typ::isSubtypeOf(int::type(x), new typ::FunctionType::•(new typ::Interface::•(self::$declarations.[](15)), new typ::Void::•(), 3, <dynamic>[new typ::Interface::•(self::$declarations.[](0)), new typ::Interface::•(self::$declarations.[](1)), "c", new typ::Interface::•(self::$declarations.[](2))])));
-}
-static method main() → dynamic {
-  self::test(new self::D::•());
-  for (core::Object c in int::attachType(<core::Object>[new self::ER0P1::•(), new self::ER1P0::•(), new self::ER1P1::•(), new self::ER1P2::•(), new self::ER2P1::•(), new self::ER0N1::•(), new self::ER1N0::•(), new self::ER1N1::•(), new self::ER1N2::•(), new self::ER2N1::•()], new typ::Interface::•(self::$declarations.[](16), <dynamic>[new typ::Interface::•(self::$declarations.[](17))]))) {
-    self::test(c);
-  }
-  tes::expectOutput("true\ntrue\nfalse\nfalse\ntrue\nfalse\nfalse\nfalse\nfalse\ntrue\nfalse\nfalse\nfalse\ntrue\nfalse\nfalse\ntrue\ntrue\nfalse\nfalse\nfalse\nfalse\ntrue\nfalse\nfalse\nfalse\ntrue\nfalse\nfalse\nfalse\ntrue\nfalse\nfalse\nfalse\nfalse\ntrue\nfalse\nfalse\nfalse\ntrue\nfalse\nfalse\nfalse\ntrue\ntrue\nfalse\nfalse\nfalse\ntrue\nfalse\nfalse\nfalse\ntrue\nfalse\nfalse\nfalse\ntrue\ntrue\ntrue\ntrue\nfalse\ntrue\nfalse\nfalse\nfalse\ntrue\nfalse\nfalse\nfalse\nfalse\nfalse\nfalse\ntrue\nfalse\nfalse\nfalse\nfalse\nfalse\ntrue\nfalse\nfalse\nfalse\nfalse\nfalse\nfalse\nfalse\ntrue\nfalse\nfalse\nfalse\nfalse\ntrue\nfalse\nfalse\nfalse\ntrue\nfalse\nfalse\nfalse\nfalse\ntrue\nfalse\nfalse\nfalse\ntrue\nfalse\nfalse\nfalse\ntrue\nfalse\nfalse\nfalse\nfalse\ntrue\ntrue\nfalse\nfalse\ntrue\nfalse\nfalse\nfalse\ntrue\nfalse\nfalse\nfalse\nfalse\ntrue\ntrue\ntrue\nfalse\ntrue\nfalse\nfalse\nfalse\nfalse\nfalse\nfalse\nfalse\nfalse\nfalse\nfalse\nfalse\ntrue");
-}
diff --git a/pkg/kernel/testcases/reify/generic_methods_bounds_test.dart b/pkg/kernel/testcases/reify/generic_methods_bounds_test.dart
deleted file mode 100644
index 4007e5c..0000000
--- a/pkg/kernel/testcases/reify/generic_methods_bounds_test.dart
+++ /dev/null
@@ -1,23 +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.
-
-// Test that a dynamic call to a generic function checks the type argument
-// against its bound.
-
-library generic_methods_bounds_test;
-
-import "test_base.dart";
-
-class A {}
-
-class B {}
-
-class C {
-  void fun<T extends A>(T t) {}
-}
-
-main() {
-  dynamic obj = new C();
-  expectThrows(() => obj.fun<B>(new B()), (e) => e is TypeError);
-}
diff --git a/pkg/kernel/testcases/reify/generic_methods_bounds_test.dart.expect b/pkg/kernel/testcases/reify/generic_methods_bounds_test.dart.expect
deleted file mode 100644
index 9d9796a..0000000
--- a/pkg/kernel/testcases/reify/generic_methods_bounds_test.dart.expect
+++ /dev/null
@@ -1,105 +0,0 @@
-library generic_methods_bounds_test;
-import self as self;
-import "dart:core" as core;
-import "../../runtime/reify/interceptors.dart" as int;
-import "../../runtime/reify/types.dart" as typ;
-import "dart:mock" as mock;
-import "./test_base.dart" as tes;
-import "../../runtime/reify/declarations.dart" as dec;
-
-class A extends core::Object implements int::HasRuntimeTypeGetter {
-  constructor •() → void
-    : super core::Object::•()
-    ;
-  get $type() → typ::ReifiedType
-    return new typ::Interface::•(self::$declarations.[](0));
-  get $is$TypeError() → core::bool
-    return false;
-}
-class B extends core::Object implements int::HasRuntimeTypeGetter {
-  constructor •() → void
-    : super core::Object::•()
-    ;
-  get $type() → typ::ReifiedType
-    return new typ::Interface::•(self::$declarations.[](1));
-  get $is$TypeError() → core::bool
-    return false;
-}
-class C extends core::Object implements int::HasRuntimeTypeGetter {
-  constructor •() → void
-    : super core::Object::•()
-    ;
-  method fun<T extends self::A>(dynamic t, {core::List<typ::ReifiedType> $typeParameters}) → void {}
-  get $type() → typ::ReifiedType
-    return new typ::Interface::•(self::$declarations.[](2));
-  get $is$TypeError() → core::bool
-    return false;
-}
-class Closure#main#function extends core::Object implements core::Function, int::HasRuntimeTypeGetter {
-  field core::String note = "This is temporary. The VM doesn't need closure classes.";
-  field mock::Context context;
-  constructor •(final mock::Context context) → dynamic
-    : self::Closure#main#function::context = context
-    ;
-  method call() → dynamic {
-    "This is a temporary solution. In the VM, this will become an additional parameter.";
-    final mock::Context #contextParameter = this.{self::Closure#main#function::context};
-    return #contextParameter.[](0).fun(new self::B::•(), $typeParameters: <typ::ReifiedType>[new typ::Interface::•(self::$declarations.[](1))]);
-  }
-  get $type() → typ::ReifiedType
-    return new typ::Interface::•(self::$declarations.[](3));
-  get $is$TypeError() → core::bool
-    return false;
-}
-class Closure#main#function#1 extends core::Object implements core::Function, int::HasRuntimeTypeGetter {
-  field core::String note = "This is temporary. The VM doesn't need closure classes.";
-  field mock::Context context;
-  constructor •(final mock::Context context) → dynamic
-    : self::Closure#main#function#1::context = context
-    ;
-  method call(dynamic e) → core::bool {
-    "This is a temporary solution. In the VM, this will become an additional parameter.";
-    final mock::Context #contextParameter = this.{self::Closure#main#function#1::context};
-    return typ::isSubtypeOf(int::type(e), new typ::Interface::•(self::$declarations.[](5)));
-  }
-  get $type() → typ::ReifiedType
-    return new typ::Interface::•(self::$declarations.[](4));
-  get $is$TypeError() → core::bool
-    return false;
-}
-static final field core::List<dec::Class> $declarations = (core::List<dec::Class> d) → core::List<dec::Class> {
-  dec::init(d, 0, new typ::Interface::•(d.[](20)));
-  dec::init(d, 1, new typ::Interface::•(d.[](20)));
-  dec::init(d, 2, new typ::Interface::•(d.[](20)));
-  dec::init(d, 3, new typ::Interface::•(d.[](20)), <dynamic>[new typ::Interface::•(d.[](22))], new typ::FunctionType::•(new typ::Interface::•(d.[](22)), const typ::Dynamic::•(), 0, <dynamic>[]));
-  dec::init(d, 4, new typ::Interface::•(d.[](20)), <dynamic>[new typ::Interface::•(d.[](22))], new typ::FunctionType::•(new typ::Interface::•(d.[](22)), new typ::Interface::•(d.[](8)), 0, <dynamic>[const typ::Dynamic::•()]));
-  dec::init(d, 5, new typ::Interface::•(d.[](23)));
-  dec::init(d, 6, new typ::Interface::•(d.[](20)));
-  dec::init(d, 7, new typ::Interface::•(d.[](20)));
-  dec::init(d, 8, new typ::Interface::•(d.[](20)));
-  dec::init(d, 9, new typ::Interface::•(d.[](20)), <dynamic>[new typ::Interface::•(d.[](24), <dynamic>[new typ::Interface::•(d.[](9))]), new typ::Interface::•(d.[](25))]);
-  dec::init(d, 10, new typ::Interface::•(d.[](26)));
-  dec::init(d, 11, new typ::Interface::•(d.[](26)));
-  dec::init(d, 12, new typ::Interface::•(d.[](20)));
-  dec::init(d, 13, new typ::Interface::•(d.[](27)));
-  dec::init(d, 14, new typ::Interface::•(d.[](27)));
-  dec::init(d, 15, new typ::Interface::•(d.[](27)));
-  dec::init(d, 16, new typ::Interface::•(d.[](27)));
-  dec::init(d, 17, new typ::Interface::•(d.[](20)), <dynamic>[new typ::Interface::•(d.[](28))]);
-  dec::init(d, 18, new typ::Interface::•(d.[](19)));
-  dec::init(d, 19, new typ::Interface::•(d.[](27)));
-  dec::init(d, 20, null);
-  dec::init(d, 22, new typ::Interface::•(d.[](20)));
-  dec::init(d, 23, new typ::Interface::•(d.[](27)));
-  dec::init(d, 24, new typ::Interface::•(d.[](20)));
-  dec::init(d, 25, new typ::Interface::•(d.[](20)));
-  dec::init(d, 26, new typ::Interface::•(d.[](20)), <dynamic>[new typ::Interface::•(d.[](24), <dynamic>[new typ::Interface::•(d.[](26))])]);
-  dec::init(d, 27, new typ::Interface::•(d.[](20)));
-  dec::init(d, 28, new typ::Interface::•(d.[](20)));
-  return d;
-}.call(dec::allocateDeclarations(<dynamic>["A", "B", "C", "Closure#main#function", "Closure#main#function#1", "TypeError", "Context", "Null", "bool", "String", "int", "double", "Type", "AbstractClassInstantiationError", "NoSuchMethodError", "CyclicInitializationError", "UnsupportedError", "IntegerDivisionByZeroException", "RangeError", "ArgumentError", "Object", "HasRuntimeTypeGetter", "Function", "AssertionError", "Comparable", "Pattern", "num", "Error", "Exception"], <dynamic>[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0]));
-static method main() → dynamic {
-  final mock::Context #context = int::attachType(new mock::Context::•(1), new typ::Interface::•(self::$declarations.[](6)));
-  #context.[]=(0, new self::C::•());
-  tes::expectThrows(new self::Closure#main#function::•(#context), new self::Closure#main#function#1::•(#context));
-}
diff --git a/pkg/kernel/testcases/reify/generic_methods_closure_test.dart b/pkg/kernel/testcases/reify/generic_methods_closure_test.dart
deleted file mode 100644
index 0304499..0000000
--- a/pkg/kernel/testcases/reify/generic_methods_closure_test.dart
+++ /dev/null
@@ -1,41 +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.
-
-// Test that a generic closure is correctly constructed.
-
-library generic_methods_closure_test;
-
-import "test_base.dart";
-
-class A {}
-
-class I<T> {}
-
-class B extends I<B> {}
-
-void fun<T>(List<T> list) {
-  var helper1 = <S>(List<S> list) {
-    if (list.length > 0) {
-      expectTrue(list[0] is S);
-    }
-    expectTrue(list is List<S>);
-    expectTrue(list is List<T>);
-  };
-
-  void helper2<S>(List<S> list) {
-    if (list.length > 0) {
-      expectTrue(list[0] is S);
-    }
-    expectTrue(list is List<S>);
-    expectTrue(list is List<T>);
-  }
-
-  helper1<T>(list);
-  helper2<T>(list);
-}
-
-main() {
-  List<B> list = <B>[new B()];
-  fun<B>(list);
-}
diff --git a/pkg/kernel/testcases/reify/generic_methods_dynamic_dependent_type_error_test.dart b/pkg/kernel/testcases/reify/generic_methods_dynamic_dependent_type_error_test.dart
deleted file mode 100644
index 92ec7bd..0000000
--- a/pkg/kernel/testcases/reify/generic_methods_dynamic_dependent_type_error_test.dart
+++ /dev/null
@@ -1,26 +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.
-
-// Test that if the type of a parameter of a generic method depends on type
-// parameter, the type of the passed argument is checked at runtime if the
-// receiver is dynamic, and an exception is thrown.
-
-library generic_methods_dynamic_dependent_type_error_test;
-
-import "test_base.dart";
-
-class A {}
-
-class B {}
-
-class C {
-  List<T> bar<T>(Iterable<T> t) => <T>[t.first];
-}
-
-main() {
-  C c = new C();
-  dynamic obj = c;
-
-  expectThrows(() => obj.bar<A>(<B>[new B()]), (e) => e is TypeError);
-}
diff --git a/pkg/kernel/testcases/reify/generic_methods_dynamic_dependent_type_error_test.dart.expect b/pkg/kernel/testcases/reify/generic_methods_dynamic_dependent_type_error_test.dart.expect
deleted file mode 100644
index d1d47ac..0000000
--- a/pkg/kernel/testcases/reify/generic_methods_dynamic_dependent_type_error_test.dart.expect
+++ /dev/null
@@ -1,111 +0,0 @@
-library generic_methods_dynamic_dependent_type_error_test;
-import self as self;
-import "dart:core" as core;
-import "../../runtime/reify/interceptors.dart" as int;
-import "../../runtime/reify/types.dart" as typ;
-import "dart:mock" as mock;
-import "./test_base.dart" as tes;
-import "../../runtime/reify/declarations.dart" as dec;
-
-class A extends core::Object implements int::HasRuntimeTypeGetter {
-  constructor •() → void
-    : super core::Object::•()
-    ;
-  get $type() → typ::ReifiedType
-    return new typ::Interface::•(self::$declarations.[](0));
-  get $is$TypeError() → core::bool
-    return false;
-}
-class B extends core::Object implements int::HasRuntimeTypeGetter {
-  constructor •() → void
-    : super core::Object::•()
-    ;
-  get $type() → typ::ReifiedType
-    return new typ::Interface::•(self::$declarations.[](1));
-  get $is$TypeError() → core::bool
-    return false;
-}
-class C extends core::Object implements int::HasRuntimeTypeGetter {
-  constructor •() → void
-    : super core::Object::•()
-    ;
-  method bar<T extends core::Object>(core::Iterable<self::C::bar::T> t, {core::List<typ::ReifiedType> $typeParameters}) → core::List<self::C::bar::T> {
-    return int::attachType(<dynamic>[t.{core::Iterable::first}], new typ::Interface::•(self::$declarations.[](3), <dynamic>[this.$C$T]));
-  }
-  get $type() → typ::ReifiedType
-    return new typ::Interface::•(self::$declarations.[](2));
-  get $is$TypeError() → core::bool
-    return false;
-}
-class Closure#main#function extends core::Object implements core::Function, int::HasRuntimeTypeGetter {
-  field core::String note = "This is temporary. The VM doesn't need closure classes.";
-  field mock::Context context;
-  constructor •(final mock::Context context) → dynamic
-    : self::Closure#main#function::context = context
-    ;
-  method call() → dynamic {
-    "This is a temporary solution. In the VM, this will become an additional parameter.";
-    final mock::Context #contextParameter = this.{self::Closure#main#function::context};
-    return #contextParameter.[](0).bar(int::attachType(<self::B>[new self::B::•()], new typ::Interface::•(self::$declarations.[](3), <dynamic>[new typ::Interface::•(self::$declarations.[](1))])), $typeParameters: <typ::ReifiedType>[new typ::Interface::•(self::$declarations.[](0))]);
-  }
-  get $type() → typ::ReifiedType
-    return new typ::Interface::•(self::$declarations.[](4));
-  get $is$TypeError() → core::bool
-    return false;
-}
-class Closure#main#function#1 extends core::Object implements core::Function, int::HasRuntimeTypeGetter {
-  field core::String note = "This is temporary. The VM doesn't need closure classes.";
-  field mock::Context context;
-  constructor •(final mock::Context context) → dynamic
-    : self::Closure#main#function#1::context = context
-    ;
-  method call(dynamic e) → core::bool {
-    "This is a temporary solution. In the VM, this will become an additional parameter.";
-    final mock::Context #contextParameter = this.{self::Closure#main#function#1::context};
-    return typ::isSubtypeOf(int::type(e), new typ::Interface::•(self::$declarations.[](6)));
-  }
-  get $type() → typ::ReifiedType
-    return new typ::Interface::•(self::$declarations.[](5));
-  get $is$TypeError() → core::bool
-    return false;
-}
-static final field core::List<dec::Class> $declarations = (core::List<dec::Class> d) → core::List<dec::Class> {
-  dec::init(d, 0, new typ::Interface::•(d.[](21)));
-  dec::init(d, 1, new typ::Interface::•(d.[](21)));
-  dec::init(d, 2, new typ::Interface::•(d.[](21)));
-  dec::init(d, 3, new typ::Interface::•(d.[](21)), <dynamic>[new typ::Interface::•(d.[](23), <dynamic>[d.[](3).variables.[](0)])]);
-  dec::init(d, 4, new typ::Interface::•(d.[](21)), <dynamic>[new typ::Interface::•(d.[](24))], new typ::FunctionType::•(new typ::Interface::•(d.[](24)), const typ::Dynamic::•(), 0, <dynamic>[]));
-  dec::init(d, 5, new typ::Interface::•(d.[](21)), <dynamic>[new typ::Interface::•(d.[](24))], new typ::FunctionType::•(new typ::Interface::•(d.[](24)), new typ::Interface::•(d.[](9)), 0, <dynamic>[const typ::Dynamic::•()]));
-  dec::init(d, 6, new typ::Interface::•(d.[](25)));
-  dec::init(d, 7, new typ::Interface::•(d.[](21)));
-  dec::init(d, 8, new typ::Interface::•(d.[](21)));
-  dec::init(d, 9, new typ::Interface::•(d.[](21)));
-  dec::init(d, 10, new typ::Interface::•(d.[](21)), <dynamic>[new typ::Interface::•(d.[](26), <dynamic>[new typ::Interface::•(d.[](10))]), new typ::Interface::•(d.[](27))]);
-  dec::init(d, 11, new typ::Interface::•(d.[](28)));
-  dec::init(d, 12, new typ::Interface::•(d.[](28)));
-  dec::init(d, 13, new typ::Interface::•(d.[](21)));
-  dec::init(d, 14, new typ::Interface::•(d.[](29)));
-  dec::init(d, 15, new typ::Interface::•(d.[](29)));
-  dec::init(d, 16, new typ::Interface::•(d.[](29)));
-  dec::init(d, 17, new typ::Interface::•(d.[](29)));
-  dec::init(d, 18, new typ::Interface::•(d.[](21)), <dynamic>[new typ::Interface::•(d.[](30))]);
-  dec::init(d, 19, new typ::Interface::•(d.[](20)));
-  dec::init(d, 20, new typ::Interface::•(d.[](29)));
-  dec::init(d, 21, null);
-  dec::init(d, 23, new typ::Interface::•(d.[](31), <dynamic>[d.[](23).variables.[](0)]));
-  dec::init(d, 24, new typ::Interface::•(d.[](21)));
-  dec::init(d, 25, new typ::Interface::•(d.[](29)));
-  dec::init(d, 26, new typ::Interface::•(d.[](21)));
-  dec::init(d, 27, new typ::Interface::•(d.[](21)));
-  dec::init(d, 28, new typ::Interface::•(d.[](21)), <dynamic>[new typ::Interface::•(d.[](26), <dynamic>[new typ::Interface::•(d.[](28))])]);
-  dec::init(d, 29, new typ::Interface::•(d.[](21)));
-  dec::init(d, 30, new typ::Interface::•(d.[](21)));
-  dec::init(d, 31, new typ::Interface::•(d.[](21)));
-  return d;
-}.call(dec::allocateDeclarations(<dynamic>["A", "B", "C", "List", "Closure#main#function", "Closure#main#function#1", "TypeError", "Context", "Null", "bool", "String", "int", "double", "Type", "AbstractClassInstantiationError", "NoSuchMethodError", "CyclicInitializationError", "UnsupportedError", "IntegerDivisionByZeroException", "RangeError", "ArgumentError", "Object", "HasRuntimeTypeGetter", "EfficientLengthIterable", "Function", "AssertionError", "Comparable", "Pattern", "num", "Error", "Exception", "Iterable"], <dynamic>[0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1]));
-static method main() → dynamic {
-  self::C c = new self::C::•();
-  final mock::Context #context = int::attachType(new mock::Context::•(1), new typ::Interface::•(self::$declarations.[](7)));
-  #context.[]=(0, c);
-  tes::expectThrows(new self::Closure#main#function::•(#context), new self::Closure#main#function#1::•(#context));
-}
diff --git a/pkg/kernel/testcases/reify/generic_methods_dynamic_simple_error_test.dart b/pkg/kernel/testcases/reify/generic_methods_dynamic_simple_error_test.dart
deleted file mode 100644
index 0b47476..0000000
--- a/pkg/kernel/testcases/reify/generic_methods_dynamic_simple_error_test.dart
+++ /dev/null
@@ -1,27 +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.
-
-// Test that if the type of a parameter of a generic method is a type parameter,
-// the type of the passed argument is checked at runtime if the receiver is
-// dynamic, and an exception is thrown.
-
-library generic_methods_dynamic_simple_error_test;
-
-import "test_base.dart";
-
-class A {}
-
-class B {}
-
-class C {
-  T foo<T>(T t) => t;
-}
-
-main() {
-  B b = new B();
-  C c = new C();
-  dynamic obj = c;
-
-  expectThrows(() => obj.foo<A>(b), (e) => e is TypeError);
-}
diff --git a/pkg/kernel/testcases/reify/generic_methods_dynamic_simple_error_test.dart.expect b/pkg/kernel/testcases/reify/generic_methods_dynamic_simple_error_test.dart.expect
deleted file mode 100644
index 91f35f8..0000000
--- a/pkg/kernel/testcases/reify/generic_methods_dynamic_simple_error_test.dart.expect
+++ /dev/null
@@ -1,109 +0,0 @@
-library generic_methods_dynamic_simple_error_test;
-import self as self;
-import "dart:core" as core;
-import "../../runtime/reify/interceptors.dart" as int;
-import "../../runtime/reify/types.dart" as typ;
-import "dart:mock" as mock;
-import "./test_base.dart" as tes;
-import "../../runtime/reify/declarations.dart" as dec;
-
-class A extends core::Object implements int::HasRuntimeTypeGetter {
-  constructor •() → void
-    : super core::Object::•()
-    ;
-  get $type() → typ::ReifiedType
-    return new typ::Interface::•(self::$declarations.[](0));
-  get $is$TypeError() → core::bool
-    return false;
-}
-class B extends core::Object implements int::HasRuntimeTypeGetter {
-  constructor •() → void
-    : super core::Object::•()
-    ;
-  get $type() → typ::ReifiedType
-    return new typ::Interface::•(self::$declarations.[](1));
-  get $is$TypeError() → core::bool
-    return false;
-}
-class C extends core::Object implements int::HasRuntimeTypeGetter {
-  constructor •() → void
-    : super core::Object::•()
-    ;
-  method foo<T extends core::Object>(dynamic t, {core::List<typ::ReifiedType> $typeParameters}) → dynamic {
-    return t;
-  }
-  get $type() → typ::ReifiedType
-    return new typ::Interface::•(self::$declarations.[](2));
-  get $is$TypeError() → core::bool
-    return false;
-}
-class Closure#main#function extends core::Object implements core::Function, int::HasRuntimeTypeGetter {
-  field core::String note = "This is temporary. The VM doesn't need closure classes.";
-  field mock::Context context;
-  constructor •(final mock::Context context) → dynamic
-    : self::Closure#main#function::context = context
-    ;
-  method call() → dynamic {
-    "This is a temporary solution. In the VM, this will become an additional parameter.";
-    final mock::Context #contextParameter = this.{self::Closure#main#function::context};
-    return #contextParameter.[](1).foo(#contextParameter.[](0), $typeParameters: <typ::ReifiedType>[new typ::Interface::•(self::$declarations.[](0))]);
-  }
-  get $type() → typ::ReifiedType
-    return new typ::Interface::•(self::$declarations.[](3));
-  get $is$TypeError() → core::bool
-    return false;
-}
-class Closure#main#function#1 extends core::Object implements core::Function, int::HasRuntimeTypeGetter {
-  field core::String note = "This is temporary. The VM doesn't need closure classes.";
-  field mock::Context context;
-  constructor •(final mock::Context context) → dynamic
-    : self::Closure#main#function#1::context = context
-    ;
-  method call(dynamic e) → core::bool {
-    "This is a temporary solution. In the VM, this will become an additional parameter.";
-    final mock::Context #contextParameter = this.{self::Closure#main#function#1::context};
-    return typ::isSubtypeOf(int::type(e), new typ::Interface::•(self::$declarations.[](5)));
-  }
-  get $type() → typ::ReifiedType
-    return new typ::Interface::•(self::$declarations.[](4));
-  get $is$TypeError() → core::bool
-    return false;
-}
-static final field core::List<dec::Class> $declarations = (core::List<dec::Class> d) → core::List<dec::Class> {
-  dec::init(d, 0, new typ::Interface::•(d.[](20)));
-  dec::init(d, 1, new typ::Interface::•(d.[](20)));
-  dec::init(d, 2, new typ::Interface::•(d.[](20)));
-  dec::init(d, 3, new typ::Interface::•(d.[](20)), <dynamic>[new typ::Interface::•(d.[](22))], new typ::FunctionType::•(new typ::Interface::•(d.[](22)), const typ::Dynamic::•(), 0, <dynamic>[]));
-  dec::init(d, 4, new typ::Interface::•(d.[](20)), <dynamic>[new typ::Interface::•(d.[](22))], new typ::FunctionType::•(new typ::Interface::•(d.[](22)), new typ::Interface::•(d.[](8)), 0, <dynamic>[const typ::Dynamic::•()]));
-  dec::init(d, 5, new typ::Interface::•(d.[](23)));
-  dec::init(d, 6, new typ::Interface::•(d.[](20)));
-  dec::init(d, 7, new typ::Interface::•(d.[](20)));
-  dec::init(d, 8, new typ::Interface::•(d.[](20)));
-  dec::init(d, 9, new typ::Interface::•(d.[](20)), <dynamic>[new typ::Interface::•(d.[](24), <dynamic>[new typ::Interface::•(d.[](9))]), new typ::Interface::•(d.[](25))]);
-  dec::init(d, 10, new typ::Interface::•(d.[](26)));
-  dec::init(d, 11, new typ::Interface::•(d.[](26)));
-  dec::init(d, 12, new typ::Interface::•(d.[](20)));
-  dec::init(d, 13, new typ::Interface::•(d.[](27)));
-  dec::init(d, 14, new typ::Interface::•(d.[](27)));
-  dec::init(d, 15, new typ::Interface::•(d.[](27)));
-  dec::init(d, 16, new typ::Interface::•(d.[](27)));
-  dec::init(d, 17, new typ::Interface::•(d.[](20)), <dynamic>[new typ::Interface::•(d.[](28))]);
-  dec::init(d, 18, new typ::Interface::•(d.[](19)));
-  dec::init(d, 19, new typ::Interface::•(d.[](27)));
-  dec::init(d, 20, null);
-  dec::init(d, 22, new typ::Interface::•(d.[](20)));
-  dec::init(d, 23, new typ::Interface::•(d.[](27)));
-  dec::init(d, 24, new typ::Interface::•(d.[](20)));
-  dec::init(d, 25, new typ::Interface::•(d.[](20)));
-  dec::init(d, 26, new typ::Interface::•(d.[](20)), <dynamic>[new typ::Interface::•(d.[](24), <dynamic>[new typ::Interface::•(d.[](26))])]);
-  dec::init(d, 27, new typ::Interface::•(d.[](20)));
-  dec::init(d, 28, new typ::Interface::•(d.[](20)));
-  return d;
-}.call(dec::allocateDeclarations(<dynamic>["A", "B", "C", "Closure#main#function", "Closure#main#function#1", "TypeError", "Context", "Null", "bool", "String", "int", "double", "Type", "AbstractClassInstantiationError", "NoSuchMethodError", "CyclicInitializationError", "UnsupportedError", "IntegerDivisionByZeroException", "RangeError", "ArgumentError", "Object", "HasRuntimeTypeGetter", "Function", "AssertionError", "Comparable", "Pattern", "num", "Error", "Exception"], <dynamic>[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0]));
-static method main() → dynamic {
-  final mock::Context #context = int::attachType(new mock::Context::•(2), new typ::Interface::•(self::$declarations.[](6)));
-  #context.[]=(0, new self::B::•());
-  self::C c = new self::C::•();
-  #context.[]=(1, c);
-  tes::expectThrows(new self::Closure#main#function::•(#context), new self::Closure#main#function#1::•(#context));
-}
diff --git a/pkg/kernel/testcases/reify/generic_methods_dynamic_test.dart b/pkg/kernel/testcases/reify/generic_methods_dynamic_test.dart
deleted file mode 100644
index 33f8b90..0000000
--- a/pkg/kernel/testcases/reify/generic_methods_dynamic_test.dart
+++ /dev/null
@@ -1,38 +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.
-
-// Test that if the type of a parameter of a generic method depends on a type
-// parameter, the type of the passed argument is checked at runtime if the
-// receiver is dynamic. The checks should pass if the variables are declared
-// correctly.
-
-library generic_methods_dynamic_test;
-
-import "test_base.dart";
-
-class A {}
-
-class B {}
-
-class C {
-  T foo<T>(T t) => t;
-  List<T> bar<T>(Iterable<T> t) => <T>[t.first];
-}
-
-main() {
-  B b = new B();
-  C c = new C();
-  dynamic obj = c;
-
-  expectTrue(c.foo<B>(b) == b);
-  expectTrue(obj.foo<B>(b) == b);
-
-  dynamic x = c.bar<B>(<B>[new B()]);
-  expectTrue(x is List<B>);
-  expectTrue(x.length == 1);
-
-  dynamic y = obj.bar<B>(<B>[new B()]);
-  expectTrue(y is List<B>);
-  expectTrue(y.length == 1);
-}
diff --git a/pkg/kernel/testcases/reify/generic_methods_dynamic_test.dart.expect b/pkg/kernel/testcases/reify/generic_methods_dynamic_test.dart.expect
deleted file mode 100644
index cca42f8..0000000
--- a/pkg/kernel/testcases/reify/generic_methods_dynamic_test.dart.expect
+++ /dev/null
@@ -1,82 +0,0 @@
-library generic_methods_dynamic_test;
-import self as self;
-import "dart:core" as core;
-import "../../runtime/reify/interceptors.dart" as int;
-import "../../runtime/reify/types.dart" as typ;
-import "./test_base.dart" as tes;
-import "../../runtime/reify/declarations.dart" as dec;
-
-class A extends core::Object implements int::HasRuntimeTypeGetter {
-  constructor •() → void
-    : super core::Object::•()
-    ;
-  get $type() → typ::ReifiedType
-    return new typ::Interface::•(self::$declarations.[](0));
-  get $is$List() → core::bool
-    return false;
-}
-class B extends core::Object implements int::HasRuntimeTypeGetter {
-  constructor •() → void
-    : super core::Object::•()
-    ;
-  get $type() → typ::ReifiedType
-    return new typ::Interface::•(self::$declarations.[](1));
-  get $is$List() → core::bool
-    return false;
-}
-class C extends core::Object implements int::HasRuntimeTypeGetter {
-  constructor •() → void
-    : super core::Object::•()
-    ;
-  method foo<T extends core::Object>(dynamic t, {core::List<typ::ReifiedType> $typeParameters}) → dynamic {
-    return t;
-  }
-  method bar<T extends core::Object>(core::Iterable<self::C::bar::T> t, {core::List<typ::ReifiedType> $typeParameters}) → core::List<self::C::bar::T> {
-    return int::attachType(<dynamic>[t.{core::Iterable::first}], new typ::Interface::•(self::$declarations.[](3), <dynamic>[this.$C$T]));
-  }
-  get $type() → typ::ReifiedType
-    return new typ::Interface::•(self::$declarations.[](2));
-  get $is$List() → core::bool
-    return false;
-}
-static final field core::List<dec::Class> $declarations = (core::List<dec::Class> d) → core::List<dec::Class> {
-  dec::init(d, 0, new typ::Interface::•(d.[](17)));
-  dec::init(d, 1, new typ::Interface::•(d.[](17)));
-  dec::init(d, 2, new typ::Interface::•(d.[](17)));
-  dec::init(d, 3, new typ::Interface::•(d.[](17)), <dynamic>[new typ::Interface::•(d.[](19), <dynamic>[d.[](3).variables.[](0)])]);
-  dec::init(d, 4, new typ::Interface::•(d.[](17)));
-  dec::init(d, 5, new typ::Interface::•(d.[](17)));
-  dec::init(d, 6, new typ::Interface::•(d.[](17)), <dynamic>[new typ::Interface::•(d.[](20), <dynamic>[new typ::Interface::•(d.[](6))]), new typ::Interface::•(d.[](21))]);
-  dec::init(d, 7, new typ::Interface::•(d.[](22)));
-  dec::init(d, 8, new typ::Interface::•(d.[](22)));
-  dec::init(d, 9, new typ::Interface::•(d.[](17)));
-  dec::init(d, 10, new typ::Interface::•(d.[](23)));
-  dec::init(d, 11, new typ::Interface::•(d.[](23)));
-  dec::init(d, 12, new typ::Interface::•(d.[](23)));
-  dec::init(d, 13, new typ::Interface::•(d.[](23)));
-  dec::init(d, 14, new typ::Interface::•(d.[](17)), <dynamic>[new typ::Interface::•(d.[](24))]);
-  dec::init(d, 15, new typ::Interface::•(d.[](16)));
-  dec::init(d, 16, new typ::Interface::•(d.[](23)));
-  dec::init(d, 17, null);
-  dec::init(d, 19, new typ::Interface::•(d.[](25), <dynamic>[d.[](19).variables.[](0)]));
-  dec::init(d, 20, new typ::Interface::•(d.[](17)));
-  dec::init(d, 21, new typ::Interface::•(d.[](17)));
-  dec::init(d, 22, new typ::Interface::•(d.[](17)), <dynamic>[new typ::Interface::•(d.[](20), <dynamic>[new typ::Interface::•(d.[](22))])]);
-  dec::init(d, 23, new typ::Interface::•(d.[](17)));
-  dec::init(d, 24, new typ::Interface::•(d.[](17)));
-  dec::init(d, 25, new typ::Interface::•(d.[](17)));
-  return d;
-}.call(dec::allocateDeclarations(<dynamic>["A", "B", "C", "List", "Null", "bool", "String", "int", "double", "Type", "AbstractClassInstantiationError", "NoSuchMethodError", "CyclicInitializationError", "UnsupportedError", "IntegerDivisionByZeroException", "RangeError", "ArgumentError", "Object", "HasRuntimeTypeGetter", "EfficientLengthIterable", "Comparable", "Pattern", "num", "Error", "Exception", "Iterable"], <dynamic>[0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1]));
-static method main() → dynamic {
-  self::B b = new self::B::•();
-  self::C c = new self::C::•();
-  dynamic obj = c;
-  tes::expectTrue(c.{self::C::foo}(b, $typeParameters: <typ::ReifiedType>[new typ::Interface::•(self::$declarations.[](1))]).{core::Object::==}(b));
-  tes::expectTrue(obj.foo(b, $typeParameters: <typ::ReifiedType>[new typ::Interface::•(self::$declarations.[](1))]).==(b));
-  dynamic x = c.{self::C::bar}(int::attachType(<self::B>[new self::B::•()], new typ::Interface::•(self::$declarations.[](3), <dynamic>[new typ::Interface::•(self::$declarations.[](1))])), $typeParameters: <typ::ReifiedType>[new typ::Interface::•(self::$declarations.[](1))]);
-  tes::expectTrue(typ::isSubtypeOf(int::type(x), new typ::Interface::•(self::$declarations.[](3), <dynamic>[new typ::Interface::•(self::$declarations.[](1))])));
-  tes::expectTrue(x.length.==(1));
-  dynamic y = obj.bar(int::attachType(<self::B>[new self::B::•()], new typ::Interface::•(self::$declarations.[](3), <dynamic>[new typ::Interface::•(self::$declarations.[](1))])), $typeParameters: <typ::ReifiedType>[new typ::Interface::•(self::$declarations.[](1))]);
-  tes::expectTrue(typ::isSubtypeOf(int::type(y), new typ::Interface::•(self::$declarations.[](3), <dynamic>[new typ::Interface::•(self::$declarations.[](1))])));
-  tes::expectTrue(y.length.==(1));
-}
diff --git a/pkg/kernel/testcases/reify/generic_methods_generic_class_tearoff_test.dart b/pkg/kernel/testcases/reify/generic_methods_generic_class_tearoff_test.dart
deleted file mode 100644
index 377af7b..0000000
--- a/pkg/kernel/testcases/reify/generic_methods_generic_class_tearoff_test.dart
+++ /dev/null
@@ -1,43 +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.
-
-// Test that a torn off method of a generic class is not a generic method,
-// and that it is correctly specialized.
-
-library generic_methods_generic_class_tearoff_test;
-
-import "test_base.dart";
-
-class A<T> {
-  T fun(T t) => t;
-}
-
-typedef Int2Int = int Function(int);
-typedef String2String = String Function(String);
-typedef Object2Object = Object Function(Object);
-typedef GenericMethod = T Function<T>(T);
-
-main() {
-  A<int> x = new A<int>();
-  var f = x.fun; // The type of f should be 'int Function(Object)'.
-  A<String> y = new A<String>();
-  var g = y.fun; // The type of g should be 'String Function(Object)'.
-  A z = new A();
-  var h = z.fun; // The type of h should be 'dynamic Function(Object)'.
-
-  expectTrue(f is Int2Int);
-  expectTrue(f is! String2String);
-  expectTrue(f is Object2Object);
-  expectTrue(f is! GenericMethod);
-
-  expectTrue(g is! Int2Int);
-  expectTrue(g is String2String);
-  expectTrue(g is Object2Object);
-  expectTrue(g is! GenericMethod);
-
-  expectTrue(h is! Int2Int);
-  expectTrue(h is! String2String);
-  expectTrue(h is Object2Object);
-  expectTrue(h is! GenericMethod);
-}
diff --git a/pkg/kernel/testcases/reify/generic_methods_local_variable_declaration_test.dart b/pkg/kernel/testcases/reify/generic_methods_local_variable_declaration_test.dart
deleted file mode 100644
index 211f58a..0000000
--- a/pkg/kernel/testcases/reify/generic_methods_local_variable_declaration_test.dart
+++ /dev/null
@@ -1,50 +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.
-
-// Test that a type variable can be used to declare local variables, and that
-// these local variables are of correct type.
-
-library generic_methods_local_variable_declaration_test;
-
-import "test_base.dart";
-
-class X {}
-
-abstract class Generator<T> {
-  T generate();
-}
-
-class A implements Generator<A> {
-  generate() {
-    return new A();
-  }
-
-  String toString() => "instance of A";
-}
-
-class B implements Generator<B> {
-  generate() {
-    return new B();
-  }
-
-  String toString() => "instance of B";
-}
-
-String fun<T extends Generator<T>>(T t) {
-  T another = t.generate();
-  String anotherName = "$another";
-
-  expectTrue(another is T);
-  expectTrue(another is Generator<T>);
-
-  return anotherName;
-}
-
-main() {
-  A a = new A();
-  B b = new B();
-
-  expectTrue(fun<A>(a) == "instance of A");
-  expectTrue(fun<B>(b) == "instance of B");
-}
diff --git a/pkg/kernel/testcases/reify/generic_methods_named_parameters_test.dart b/pkg/kernel/testcases/reify/generic_methods_named_parameters_test.dart
deleted file mode 100644
index 05804da..0000000
--- a/pkg/kernel/testcases/reify/generic_methods_named_parameters_test.dart
+++ /dev/null
@@ -1,41 +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.
-
-// Test that generic methods with named parameters are of correct type.
-
-library generic_methods_named_parameters_test;
-
-import "test_base.dart";
-
-typedef FunObjObj = Object Function<T>(Object, {Object y});
-typedef FunTypObj = Object Function<T>(T, {Object y});
-typedef FunObjTyp = Object Function<T>(Object, {T y});
-typedef FunTypTyp = Object Function<T>(T, {T y});
-
-Object funObjObj<T>(Object x, {Object y}) => x;
-Object funTypObj<T>(T x, {Object y}) => y;
-Object funObjTyp<T>(Object x, {T y}) => x;
-Object funTypTyp<T>(T x, {T y}) => null;
-
-main() {
-  expectTrue(funObjObj is FunObjObj);
-  expectTrue(funObjObj is FunTypObj);
-  expectTrue(funObjObj is FunObjTyp);
-  expectTrue(funObjObj is FunTypTyp);
-
-  expectTrue(funTypObj is! FunObjObj);
-  expectTrue(funTypObj is FunTypObj);
-  expectTrue(funTypObj is! FunObjTyp);
-  expectTrue(funTypObj is FunTypTyp);
-
-  expectTrue(funObjTyp is! FunObjObj);
-  expectTrue(funObjTyp is! FunTypObj);
-  expectTrue(funObjTyp is FunObjTyp);
-  expectTrue(funObjTyp is FunTypTyp);
-
-  expectTrue(funTypTyp is! FunObjObj);
-  expectTrue(funTypTyp is! FunTypObj);
-  expectTrue(funTypTyp is! FunObjTyp);
-  expectTrue(funTypTyp is FunTypTyp);
-}
diff --git a/pkg/kernel/testcases/reify/generic_methods_optional_parameters_test.dart b/pkg/kernel/testcases/reify/generic_methods_optional_parameters_test.dart
deleted file mode 100644
index 8b5f106..0000000
--- a/pkg/kernel/testcases/reify/generic_methods_optional_parameters_test.dart
+++ /dev/null
@@ -1,41 +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.
-
-// Test that generic methods with optional parameters are of correct type.
-
-library generic_methods_optional_parameters_test;
-
-import "test_base.dart";
-
-typedef FunObjObj = Object Function<T>(Object, [Object]);
-typedef FunTypObj = Object Function<T>(T, [Object]);
-typedef FunObjTyp = Object Function<T>(Object, [T]);
-typedef FunTypTyp = Object Function<T>(T, [T]);
-
-Object funObjObj<T>(Object x, [Object y]) => x;
-Object funTypObj<T>(T x, [Object y]) => y;
-Object funObjTyp<T>(Object x, [T y]) => x;
-Object funTypTyp<T>(T x, [T y]) => null;
-
-main() {
-  expectTrue(funObjObj is FunObjObj);
-  expectTrue(funObjObj is FunTypObj);
-  expectTrue(funObjObj is FunObjTyp);
-  expectTrue(funObjObj is FunTypTyp);
-
-  expectTrue(funTypObj is! FunObjObj);
-  expectTrue(funTypObj is FunTypObj);
-  expectTrue(funTypObj is! FunObjTyp);
-  expectTrue(funTypObj is FunTypTyp);
-
-  expectTrue(funObjTyp is! FunObjObj);
-  expectTrue(funObjTyp is! FunTypObj);
-  expectTrue(funObjTyp is FunObjTyp);
-  expectTrue(funObjTyp is FunTypTyp);
-
-  expectTrue(funTypTyp is! FunObjObj);
-  expectTrue(funTypTyp is! FunTypObj);
-  expectTrue(funTypTyp is! FunObjTyp);
-  expectTrue(funTypTyp is FunTypTyp);
-}
diff --git a/pkg/kernel/testcases/reify/generic_methods_overriding_contravariance_test.dart b/pkg/kernel/testcases/reify/generic_methods_overriding_contravariance_test.dart
deleted file mode 100644
index 5d1da65..0000000
--- a/pkg/kernel/testcases/reify/generic_methods_overriding_contravariance_test.dart
+++ /dev/null
@@ -1,34 +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.
-
-// Test that generic methods can be overridden using the bound of a type
-// variable as the type of the parameter in the overloaded method.
-
-library generic_methods_overriding_contravariance_test;
-
-import "test_base.dart";
-
-class X {}
-
-class Y extends X {}
-
-class Z extends Y {}
-
-class C {
-  String fun<T extends Y>(T t) => "C";
-}
-
-class E extends C {
-  String fun<T extends Y>(Y y) => "E";
-}
-
-main() {
-  Y y = new Y();
-
-  C c = new C();
-  E e = new E();
-
-  expectTrue(c.fun<Y>(y) == "C");
-  expectTrue(e.fun<Y>(y) == "E");
-}
diff --git a/pkg/kernel/testcases/reify/generic_methods_overriding_contravariance_test.dart.expect b/pkg/kernel/testcases/reify/generic_methods_overriding_contravariance_test.dart.expect
deleted file mode 100644
index c8cdab6..0000000
--- a/pkg/kernel/testcases/reify/generic_methods_overriding_contravariance_test.dart.expect
+++ /dev/null
@@ -1,83 +0,0 @@
-library generic_methods_overriding_contravariance_test;
-import self as self;
-import "dart:core" as core;
-import "../../runtime/reify/interceptors.dart" as int;
-import "../../runtime/reify/types.dart" as typ;
-import "./test_base.dart" as tes;
-import "../../runtime/reify/declarations.dart" as dec;
-
-class X extends core::Object implements int::HasRuntimeTypeGetter {
-  constructor •() → void
-    : super core::Object::•()
-    ;
-  get $type() → typ::ReifiedType
-    return new typ::Interface::•(self::$declarations.[](0));
-}
-class Y extends self::X implements int::HasRuntimeTypeGetter {
-  constructor •() → void
-    : super self::X::•()
-    ;
-  get $type() → typ::ReifiedType
-    return new typ::Interface::•(self::$declarations.[](1));
-}
-class Z extends self::Y implements int::HasRuntimeTypeGetter {
-  constructor •() → void
-    : super self::Y::•()
-    ;
-  get $type() → typ::ReifiedType
-    return new typ::Interface::•(self::$declarations.[](2));
-}
-class C extends core::Object implements int::HasRuntimeTypeGetter {
-  constructor •() → void
-    : super core::Object::•()
-    ;
-  method fun<T extends self::Y>(dynamic t, {core::List<typ::ReifiedType> $typeParameters}) → core::String {
-    return "C";
-  }
-  get $type() → typ::ReifiedType
-    return new typ::Interface::•(self::$declarations.[](3));
-}
-class E extends self::C implements int::HasRuntimeTypeGetter {
-  constructor •() → void
-    : super self::C::•()
-    ;
-  method fun<T extends self::Y>(self::Y y, {core::List<typ::ReifiedType> $typeParameters}) → core::String {
-    return "E";
-  }
-  get $type() → typ::ReifiedType
-    return new typ::Interface::•(self::$declarations.[](4));
-}
-static final field core::List<dec::Class> $declarations = (core::List<dec::Class> d) → core::List<dec::Class> {
-  dec::init(d, 0, new typ::Interface::•(d.[](18)));
-  dec::init(d, 1, new typ::Interface::•(d.[](0)));
-  dec::init(d, 2, new typ::Interface::•(d.[](1)));
-  dec::init(d, 3, new typ::Interface::•(d.[](18)));
-  dec::init(d, 4, new typ::Interface::•(d.[](3)));
-  dec::init(d, 5, new typ::Interface::•(d.[](18)));
-  dec::init(d, 6, new typ::Interface::•(d.[](18)));
-  dec::init(d, 7, new typ::Interface::•(d.[](18)), <dynamic>[new typ::Interface::•(d.[](20), <dynamic>[new typ::Interface::•(d.[](7))]), new typ::Interface::•(d.[](21))]);
-  dec::init(d, 8, new typ::Interface::•(d.[](22)));
-  dec::init(d, 9, new typ::Interface::•(d.[](22)));
-  dec::init(d, 10, new typ::Interface::•(d.[](18)));
-  dec::init(d, 11, new typ::Interface::•(d.[](23)));
-  dec::init(d, 12, new typ::Interface::•(d.[](23)));
-  dec::init(d, 13, new typ::Interface::•(d.[](23)));
-  dec::init(d, 14, new typ::Interface::•(d.[](23)));
-  dec::init(d, 15, new typ::Interface::•(d.[](18)), <dynamic>[new typ::Interface::•(d.[](24))]);
-  dec::init(d, 16, new typ::Interface::•(d.[](17)));
-  dec::init(d, 17, new typ::Interface::•(d.[](23)));
-  dec::init(d, 18, null);
-  dec::init(d, 20, new typ::Interface::•(d.[](18)));
-  dec::init(d, 21, new typ::Interface::•(d.[](18)));
-  dec::init(d, 22, new typ::Interface::•(d.[](18)), <dynamic>[new typ::Interface::•(d.[](20), <dynamic>[new typ::Interface::•(d.[](22))])]);
-  dec::init(d, 23, new typ::Interface::•(d.[](18)));
-  dec::init(d, 24, new typ::Interface::•(d.[](18)));
-  return d;
-}.call(dec::allocateDeclarations(<dynamic>["X", "Y", "Z", "C", "E", "Null", "bool", "String", "int", "double", "Type", "AbstractClassInstantiationError", "NoSuchMethodError", "CyclicInitializationError", "UnsupportedError", "IntegerDivisionByZeroException", "RangeError", "ArgumentError", "Object", "HasRuntimeTypeGetter", "Comparable", "Pattern", "num", "Error", "Exception"], <dynamic>[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0]));
-static method main() → dynamic {
-  self::Y y = new self::Y::•();
-  self::C c = new self::C::•();
-  self::E e = new self::E::•();
-  tes::expectTrue(c.{self::C::fun}(y, $typeParameters: <typ::ReifiedType>[new typ::Interface::•(self::$declarations.[](1))]).{core::String::==}("C"));
-  tes::expectTrue(e.{self::E::fun}(y, $typeParameters: <typ::ReifiedType>[new typ::Interface::•(self::$declarations.[](1))]).{core::String::==}("E"));
-}
diff --git a/pkg/kernel/testcases/reify/generic_methods_overriding_test.dart b/pkg/kernel/testcases/reify/generic_methods_overriding_test.dart
deleted file mode 100644
index 2d742e5..0000000
--- a/pkg/kernel/testcases/reify/generic_methods_overriding_test.dart
+++ /dev/null
@@ -1,31 +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.
-
-// Test that generic methods can be overridden.
-
-library generic_methods_overriding_test;
-
-import "test_base.dart";
-
-class X {}
-
-class Y extends X {}
-
-class C {
-  String fun<T extends Y>(T t) => "C";
-}
-
-class D extends C {
-  String fun<T extends Y>(T t) => "D";
-}
-
-main() {
-  Y y = new Y();
-
-  C c = new C();
-  D d = new D();
-
-  expectTrue(c.fun<Y>(y) == "C");
-  expectTrue(d.fun<Y>(y) == "D");
-}
diff --git a/pkg/kernel/testcases/reify/generic_methods_overriding_test.dart.expect b/pkg/kernel/testcases/reify/generic_methods_overriding_test.dart.expect
deleted file mode 100644
index 25d5120..0000000
--- a/pkg/kernel/testcases/reify/generic_methods_overriding_test.dart.expect
+++ /dev/null
@@ -1,75 +0,0 @@
-library generic_methods_overriding_test;
-import self as self;
-import "dart:core" as core;
-import "../../runtime/reify/interceptors.dart" as int;
-import "../../runtime/reify/types.dart" as typ;
-import "./test_base.dart" as tes;
-import "../../runtime/reify/declarations.dart" as dec;
-
-class X extends core::Object implements int::HasRuntimeTypeGetter {
-  constructor •() → void
-    : super core::Object::•()
-    ;
-  get $type() → typ::ReifiedType
-    return new typ::Interface::•(self::$declarations.[](0));
-}
-class Y extends self::X implements int::HasRuntimeTypeGetter {
-  constructor •() → void
-    : super self::X::•()
-    ;
-  get $type() → typ::ReifiedType
-    return new typ::Interface::•(self::$declarations.[](1));
-}
-class C extends core::Object implements int::HasRuntimeTypeGetter {
-  constructor •() → void
-    : super core::Object::•()
-    ;
-  method fun<T extends self::Y>(dynamic t, {core::List<typ::ReifiedType> $typeParameters}) → core::String {
-    return "C";
-  }
-  get $type() → typ::ReifiedType
-    return new typ::Interface::•(self::$declarations.[](2));
-}
-class D extends self::C implements int::HasRuntimeTypeGetter {
-  constructor •() → void
-    : super self::C::•()
-    ;
-  method fun<T extends self::Y>(dynamic t, {core::List<typ::ReifiedType> $typeParameters}) → core::String {
-    return "D";
-  }
-  get $type() → typ::ReifiedType
-    return new typ::Interface::•(self::$declarations.[](3));
-}
-static final field core::List<dec::Class> $declarations = (core::List<dec::Class> d) → core::List<dec::Class> {
-  dec::init(d, 0, new typ::Interface::•(d.[](17)));
-  dec::init(d, 1, new typ::Interface::•(d.[](0)));
-  dec::init(d, 2, new typ::Interface::•(d.[](17)));
-  dec::init(d, 3, new typ::Interface::•(d.[](2)));
-  dec::init(d, 4, new typ::Interface::•(d.[](17)));
-  dec::init(d, 5, new typ::Interface::•(d.[](17)));
-  dec::init(d, 6, new typ::Interface::•(d.[](17)), <dynamic>[new typ::Interface::•(d.[](19), <dynamic>[new typ::Interface::•(d.[](6))]), new typ::Interface::•(d.[](20))]);
-  dec::init(d, 7, new typ::Interface::•(d.[](21)));
-  dec::init(d, 8, new typ::Interface::•(d.[](21)));
-  dec::init(d, 9, new typ::Interface::•(d.[](17)));
-  dec::init(d, 10, new typ::Interface::•(d.[](22)));
-  dec::init(d, 11, new typ::Interface::•(d.[](22)));
-  dec::init(d, 12, new typ::Interface::•(d.[](22)));
-  dec::init(d, 13, new typ::Interface::•(d.[](22)));
-  dec::init(d, 14, new typ::Interface::•(d.[](17)), <dynamic>[new typ::Interface::•(d.[](23))]);
-  dec::init(d, 15, new typ::Interface::•(d.[](16)));
-  dec::init(d, 16, new typ::Interface::•(d.[](22)));
-  dec::init(d, 17, null);
-  dec::init(d, 19, new typ::Interface::•(d.[](17)));
-  dec::init(d, 20, new typ::Interface::•(d.[](17)));
-  dec::init(d, 21, new typ::Interface::•(d.[](17)), <dynamic>[new typ::Interface::•(d.[](19), <dynamic>[new typ::Interface::•(d.[](21))])]);
-  dec::init(d, 22, new typ::Interface::•(d.[](17)));
-  dec::init(d, 23, new typ::Interface::•(d.[](17)));
-  return d;
-}.call(dec::allocateDeclarations(<dynamic>["X", "Y", "C", "D", "Null", "bool", "String", "int", "double", "Type", "AbstractClassInstantiationError", "NoSuchMethodError", "CyclicInitializationError", "UnsupportedError", "IntegerDivisionByZeroException", "RangeError", "ArgumentError", "Object", "HasRuntimeTypeGetter", "Comparable", "Pattern", "num", "Error", "Exception"], <dynamic>[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0]));
-static method main() → dynamic {
-  self::Y y = new self::Y::•();
-  self::C c = new self::C::•();
-  self::D d = new self::D::•();
-  tes::expectTrue(c.{self::C::fun}(y, $typeParameters: <typ::ReifiedType>[new typ::Interface::•(self::$declarations.[](1))]).{core::String::==}("C"));
-  tes::expectTrue(d.{self::D::fun}(y, $typeParameters: <typ::ReifiedType>[new typ::Interface::•(self::$declarations.[](1))]).{core::String::==}("D"));
-}
diff --git a/pkg/kernel/testcases/reify/generic_methods_overriding_type_propagation2_test.dart b/pkg/kernel/testcases/reify/generic_methods_overriding_type_propagation2_test.dart
deleted file mode 100644
index 5aa081a..0000000
--- a/pkg/kernel/testcases/reify/generic_methods_overriding_type_propagation2_test.dart
+++ /dev/null
@@ -1,46 +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.
-
-// Test that generic methods that have bounds on type parameters can be
-// overridden, and that type propagation can be used in such methods.
-
-library generic_methods_overriding_type_propagation2_test;
-
-import "test_base.dart";
-
-class X {}
-
-class Y extends X {}
-
-class Z extends Y {}
-
-class C {
-  String fun<T extends Y>(T t) => "C";
-}
-
-class F extends C {
-  String foobar(Z z) {
-    return "FZ";
-  }
-
-  String fun<T extends Y>(T t) {
-    if (t is Z) {
-      return this.foobar(t);
-    }
-    return "FY";
-  }
-}
-
-main() {
-  Y y = new Y();
-  Z z = new Z();
-
-  C c = new C();
-  F f = new F();
-
-  expectTrue(c.fun<Y>(y) == "C");
-
-  expectTrue(f.fun<Y>(y) == "FY");
-  expectTrue(f.fun<Z>(z) == "FZ");
-}
diff --git a/pkg/kernel/testcases/reify/generic_methods_overriding_type_propagation2_test.dart.expect b/pkg/kernel/testcases/reify/generic_methods_overriding_type_propagation2_test.dart.expect
deleted file mode 100644
index ed69cfe..0000000
--- a/pkg/kernel/testcases/reify/generic_methods_overriding_type_propagation2_test.dart.expect
+++ /dev/null
@@ -1,101 +0,0 @@
-library generic_methods_overriding_type_propagation2_test;
-import self as self;
-import "dart:core" as core;
-import "../../runtime/reify/interceptors.dart" as int;
-import "../../runtime/reify/types.dart" as typ;
-import "./test_base.dart" as tes;
-import "../../runtime/reify/declarations.dart" as dec;
-
-class X extends core::Object implements int::HasRuntimeTypeGetter {
-  constructor •() → void
-    : super core::Object::•()
-    ;
-  get $type() → typ::ReifiedType
-    return new typ::Interface::•(self::$declarations.[](0));
-  get $is$Z() → core::bool
-    return false;
-}
-class Y extends self::X implements int::HasRuntimeTypeGetter {
-  constructor •() → void
-    : super self::X::•()
-    ;
-  get $type() → typ::ReifiedType
-    return new typ::Interface::•(self::$declarations.[](1));
-  get $is$Z() → core::bool
-    return false;
-}
-class Z extends self::Y implements int::HasRuntimeTypeGetter {
-  constructor •() → void
-    : super self::Y::•()
-    ;
-  get $type() → typ::ReifiedType
-    return new typ::Interface::•(self::$declarations.[](2));
-  get $is$Z() → core::bool
-    return true;
-}
-class C extends core::Object implements int::HasRuntimeTypeGetter {
-  constructor •() → void
-    : super core::Object::•()
-    ;
-  method fun<T extends self::Y>(dynamic t, {core::List<typ::ReifiedType> $typeParameters}) → core::String {
-    return "C";
-  }
-  get $type() → typ::ReifiedType
-    return new typ::Interface::•(self::$declarations.[](3));
-  get $is$Z() → core::bool
-    return false;
-}
-class F extends self::C implements int::HasRuntimeTypeGetter {
-  constructor •() → void
-    : super self::C::•()
-    ;
-  method foobar(self::Z z) → core::String {
-    return "FZ";
-  }
-  method fun<T extends self::Y>(dynamic t, {core::List<typ::ReifiedType> $typeParameters}) → core::String {
-    if(let dynamic #t1 = t in #t1 is int::HasRuntimeTypeGetter && #t1.$is$Z) {
-      return this.{self::F::foobar}(t{self::Z});
-    }
-    return "FY";
-  }
-  get $type() → typ::ReifiedType
-    return new typ::Interface::•(self::$declarations.[](4));
-  get $is$Z() → core::bool
-    return false;
-}
-static final field core::List<dec::Class> $declarations = (core::List<dec::Class> d) → core::List<dec::Class> {
-  dec::init(d, 0, new typ::Interface::•(d.[](18)));
-  dec::init(d, 1, new typ::Interface::•(d.[](0)));
-  dec::init(d, 2, new typ::Interface::•(d.[](1)));
-  dec::init(d, 3, new typ::Interface::•(d.[](18)));
-  dec::init(d, 4, new typ::Interface::•(d.[](3)));
-  dec::init(d, 5, new typ::Interface::•(d.[](18)));
-  dec::init(d, 6, new typ::Interface::•(d.[](18)));
-  dec::init(d, 7, new typ::Interface::•(d.[](18)), <dynamic>[new typ::Interface::•(d.[](20), <dynamic>[new typ::Interface::•(d.[](7))]), new typ::Interface::•(d.[](21))]);
-  dec::init(d, 8, new typ::Interface::•(d.[](22)));
-  dec::init(d, 9, new typ::Interface::•(d.[](22)));
-  dec::init(d, 10, new typ::Interface::•(d.[](18)));
-  dec::init(d, 11, new typ::Interface::•(d.[](23)));
-  dec::init(d, 12, new typ::Interface::•(d.[](23)));
-  dec::init(d, 13, new typ::Interface::•(d.[](23)));
-  dec::init(d, 14, new typ::Interface::•(d.[](23)));
-  dec::init(d, 15, new typ::Interface::•(d.[](18)), <dynamic>[new typ::Interface::•(d.[](24))]);
-  dec::init(d, 16, new typ::Interface::•(d.[](17)));
-  dec::init(d, 17, new typ::Interface::•(d.[](23)));
-  dec::init(d, 18, null);
-  dec::init(d, 20, new typ::Interface::•(d.[](18)));
-  dec::init(d, 21, new typ::Interface::•(d.[](18)));
-  dec::init(d, 22, new typ::Interface::•(d.[](18)), <dynamic>[new typ::Interface::•(d.[](20), <dynamic>[new typ::Interface::•(d.[](22))])]);
-  dec::init(d, 23, new typ::Interface::•(d.[](18)));
-  dec::init(d, 24, new typ::Interface::•(d.[](18)));
-  return d;
-}.call(dec::allocateDeclarations(<dynamic>["X", "Y", "Z", "C", "F", "Null", "bool", "String", "int", "double", "Type", "AbstractClassInstantiationError", "NoSuchMethodError", "CyclicInitializationError", "UnsupportedError", "IntegerDivisionByZeroException", "RangeError", "ArgumentError", "Object", "HasRuntimeTypeGetter", "Comparable", "Pattern", "num", "Error", "Exception"], <dynamic>[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0]));
-static method main() → dynamic {
-  self::Y y = new self::Y::•();
-  self::Z z = new self::Z::•();
-  self::C c = new self::C::•();
-  self::F f = new self::F::•();
-  tes::expectTrue(c.{self::C::fun}(y, $typeParameters: <typ::ReifiedType>[new typ::Interface::•(self::$declarations.[](1))]).{core::String::==}("C"));
-  tes::expectTrue(f.{self::F::fun}(y, $typeParameters: <typ::ReifiedType>[new typ::Interface::•(self::$declarations.[](1))]).{core::String::==}("FY"));
-  tes::expectTrue(f.{self::F::fun}(z, $typeParameters: <typ::ReifiedType>[new typ::Interface::•(self::$declarations.[](2))]).{core::String::==}("FZ"));
-}
diff --git a/pkg/kernel/testcases/reify/generic_methods_overriding_type_propagation_test.dart b/pkg/kernel/testcases/reify/generic_methods_overriding_type_propagation_test.dart
deleted file mode 100644
index 974948a..0000000
--- a/pkg/kernel/testcases/reify/generic_methods_overriding_type_propagation_test.dart
+++ /dev/null
@@ -1,46 +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.
-
-// Test that generic methods that have bounds on type parameters can be
-// overridden, and that type propagation can be used in such methods.
-
-library generic_methods_overriding_type_propagation_test;
-
-import "test_base.dart";
-
-class X {}
-
-class Y extends X {}
-
-class Z extends Y {}
-
-class C {
-  String fun<T extends Y>(T t) => "C";
-}
-
-class F extends C {
-  String foobar(Z z) {
-    return "FZ";
-  }
-
-  String fun<T extends Y>(T t) {
-    if (t is Z) {
-      return this.foobar(t as Z);
-    }
-    return "FY";
-  }
-}
-
-main() {
-  Y y = new Y();
-  Z z = new Z();
-
-  C c = new C();
-  F f = new F();
-
-  expectTrue(c.fun<Y>(y) == "C");
-
-  expectTrue(f.fun<Y>(y) == "FY");
-  expectTrue(f.fun<Z>(z) == "FZ");
-}
diff --git a/pkg/kernel/testcases/reify/generic_methods_overriding_type_propagation_test.dart.expect b/pkg/kernel/testcases/reify/generic_methods_overriding_type_propagation_test.dart.expect
deleted file mode 100644
index fb2d894..0000000
--- a/pkg/kernel/testcases/reify/generic_methods_overriding_type_propagation_test.dart.expect
+++ /dev/null
@@ -1,101 +0,0 @@
-library generic_methods_overriding_type_propagation_test;
-import self as self;
-import "dart:core" as core;
-import "../../runtime/reify/interceptors.dart" as int;
-import "../../runtime/reify/types.dart" as typ;
-import "./test_base.dart" as tes;
-import "../../runtime/reify/declarations.dart" as dec;
-
-class X extends core::Object implements int::HasRuntimeTypeGetter {
-  constructor •() → void
-    : super core::Object::•()
-    ;
-  get $type() → typ::ReifiedType
-    return new typ::Interface::•(self::$declarations.[](0));
-  get $is$Z() → core::bool
-    return false;
-}
-class Y extends self::X implements int::HasRuntimeTypeGetter {
-  constructor •() → void
-    : super self::X::•()
-    ;
-  get $type() → typ::ReifiedType
-    return new typ::Interface::•(self::$declarations.[](1));
-  get $is$Z() → core::bool
-    return false;
-}
-class Z extends self::Y implements int::HasRuntimeTypeGetter {
-  constructor •() → void
-    : super self::Y::•()
-    ;
-  get $type() → typ::ReifiedType
-    return new typ::Interface::•(self::$declarations.[](2));
-  get $is$Z() → core::bool
-    return true;
-}
-class C extends core::Object implements int::HasRuntimeTypeGetter {
-  constructor •() → void
-    : super core::Object::•()
-    ;
-  method fun<T extends self::Y>(dynamic t, {core::List<typ::ReifiedType> $typeParameters}) → core::String {
-    return "C";
-  }
-  get $type() → typ::ReifiedType
-    return new typ::Interface::•(self::$declarations.[](3));
-  get $is$Z() → core::bool
-    return false;
-}
-class F extends self::C implements int::HasRuntimeTypeGetter {
-  constructor •() → void
-    : super self::C::•()
-    ;
-  method foobar(self::Z z) → core::String {
-    return "FZ";
-  }
-  method fun<T extends self::Y>(dynamic t, {core::List<typ::ReifiedType> $typeParameters}) → core::String {
-    if(let dynamic #t1 = t in #t1 is int::HasRuntimeTypeGetter && #t1.$is$Z) {
-      return this.{self::F::foobar}(t{self::Z} as self::Z);
-    }
-    return "FY";
-  }
-  get $type() → typ::ReifiedType
-    return new typ::Interface::•(self::$declarations.[](4));
-  get $is$Z() → core::bool
-    return false;
-}
-static final field core::List<dec::Class> $declarations = (core::List<dec::Class> d) → core::List<dec::Class> {
-  dec::init(d, 0, new typ::Interface::•(d.[](18)));
-  dec::init(d, 1, new typ::Interface::•(d.[](0)));
-  dec::init(d, 2, new typ::Interface::•(d.[](1)));
-  dec::init(d, 3, new typ::Interface::•(d.[](18)));
-  dec::init(d, 4, new typ::Interface::•(d.[](3)));
-  dec::init(d, 5, new typ::Interface::•(d.[](18)));
-  dec::init(d, 6, new typ::Interface::•(d.[](18)));
-  dec::init(d, 7, new typ::Interface::•(d.[](18)), <dynamic>[new typ::Interface::•(d.[](20), <dynamic>[new typ::Interface::•(d.[](7))]), new typ::Interface::•(d.[](21))]);
-  dec::init(d, 8, new typ::Interface::•(d.[](22)));
-  dec::init(d, 9, new typ::Interface::•(d.[](22)));
-  dec::init(d, 10, new typ::Interface::•(d.[](18)));
-  dec::init(d, 11, new typ::Interface::•(d.[](23)));
-  dec::init(d, 12, new typ::Interface::•(d.[](23)));
-  dec::init(d, 13, new typ::Interface::•(d.[](23)));
-  dec::init(d, 14, new typ::Interface::•(d.[](23)));
-  dec::init(d, 15, new typ::Interface::•(d.[](18)), <dynamic>[new typ::Interface::•(d.[](24))]);
-  dec::init(d, 16, new typ::Interface::•(d.[](17)));
-  dec::init(d, 17, new typ::Interface::•(d.[](23)));
-  dec::init(d, 18, null);
-  dec::init(d, 20, new typ::Interface::•(d.[](18)));
-  dec::init(d, 21, new typ::Interface::•(d.[](18)));
-  dec::init(d, 22, new typ::Interface::•(d.[](18)), <dynamic>[new typ::Interface::•(d.[](20), <dynamic>[new typ::Interface::•(d.[](22))])]);
-  dec::init(d, 23, new typ::Interface::•(d.[](18)));
-  dec::init(d, 24, new typ::Interface::•(d.[](18)));
-  return d;
-}.call(dec::allocateDeclarations(<dynamic>["X", "Y", "Z", "C", "F", "Null", "bool", "String", "int", "double", "Type", "AbstractClassInstantiationError", "NoSuchMethodError", "CyclicInitializationError", "UnsupportedError", "IntegerDivisionByZeroException", "RangeError", "ArgumentError", "Object", "HasRuntimeTypeGetter", "Comparable", "Pattern", "num", "Error", "Exception"], <dynamic>[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0]));
-static method main() → dynamic {
-  self::Y y = new self::Y::•();
-  self::Z z = new self::Z::•();
-  self::C c = new self::C::•();
-  self::F f = new self::F::•();
-  tes::expectTrue(c.{self::C::fun}(y, $typeParameters: <typ::ReifiedType>[new typ::Interface::•(self::$declarations.[](1))]).{core::String::==}("C"));
-  tes::expectTrue(f.{self::F::fun}(y, $typeParameters: <typ::ReifiedType>[new typ::Interface::•(self::$declarations.[](1))]).{core::String::==}("FY"));
-  tes::expectTrue(f.{self::F::fun}(z, $typeParameters: <typ::ReifiedType>[new typ::Interface::•(self::$declarations.[](2))]).{core::String::==}("FZ"));
-}
diff --git a/pkg/kernel/testcases/reify/generic_methods_recursive_bound_error_test.dart b/pkg/kernel/testcases/reify/generic_methods_recursive_bound_error_test.dart
deleted file mode 100644
index c90957d..0000000
--- a/pkg/kernel/testcases/reify/generic_methods_recursive_bound_error_test.dart
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// Test that F-bounded quantification works for generic methods, and that types
-// that are passed to generic methods in dynamic calls are checked for being
-// recursively defined. An exception should be thrown if the type doesn't meet
-// the expectation.
-
-library generic_methods_recursive_bound_error_test;
-
-import "test_base.dart";
-
-abstract class I<T> {
-  bool fun(T x);
-}
-
-void foo<T extends I<T>>(List<T> a) {
-  if (a.length > 1) {
-    a[0].fun(a[1]);
-  }
-}
-
-class C implements I<C> {
-  bool fun(C c) => true;
-}
-
-main() {
-  dynamic bar = foo;
-  List<int> list = <int>[4, 2];
-  // The type int does not extend I<int>.
-  expectThrows(() => bar<int>(list), (e) => e is TypeError);
-}
diff --git a/pkg/kernel/testcases/reify/generic_methods_recursive_bound_test.dart b/pkg/kernel/testcases/reify/generic_methods_recursive_bound_test.dart
deleted file mode 100644
index e6cbcf3..0000000
--- a/pkg/kernel/testcases/reify/generic_methods_recursive_bound_test.dart
+++ /dev/null
@@ -1,28 +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.
-
-// Test that F-bounded quantification works for generic methods.
-
-library generic_methods_recursive_bound_test;
-
-import "test_base.dart";
-
-abstract class I<T> {
-  bool fun(T x);
-}
-
-int foo<T extends I<T>>(List<T> a) {
-  if (a.length > 1) {
-    a[0].fun(a[1]);
-  }
-  return a.length;
-}
-
-class C implements I<C> {
-  bool fun(C c) => true;
-}
-
-main() {
-  expectTrue(foo<C>(<C>[new C(), new C()]) == 2);
-}
diff --git a/pkg/kernel/testcases/reify/generic_methods_reuse_type_variables_test.dart b/pkg/kernel/testcases/reify/generic_methods_reuse_type_variables_test.dart
deleted file mode 100644
index f21305f..0000000
--- a/pkg/kernel/testcases/reify/generic_methods_reuse_type_variables_test.dart
+++ /dev/null
@@ -1,21 +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.
-
-// Test that type parameter can be passed as a type argument in a definition of
-// a local variable, and that this local variable is correctly constructed.
-
-library generic_methods_reuse_type_variables_test;
-
-import "test_base.dart";
-
-int fun<T extends String>(T t) {
-  List<T> list = <T>[t, t, t];
-  expectTrue(list is List<String>);
-  expectTrue(list is! List<int>);
-  return list.length;
-}
-
-main() {
-  expectTrue(fun<String>("foo") == 3);
-}
diff --git a/pkg/kernel/testcases/reify/generic_methods_shadowing_test.dart b/pkg/kernel/testcases/reify/generic_methods_shadowing_test.dart
deleted file mode 100644
index e13e1e6..0000000
--- a/pkg/kernel/testcases/reify/generic_methods_shadowing_test.dart
+++ /dev/null
@@ -1,26 +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.
-
-// Test that type parameters in generic methods can be shadowed.
-
-library generic_methods_shadowing_test;
-
-import "test_base.dart";
-
-class X {}
-
-class Y {}
-
-bool foo<T, S>(T t, S s) {
-  // The type parameter T of bar shadows the type parameter T of foo.
-  bool bar<T>(T t) {
-    return t is T && t is S;
-  }
-
-  return bar<S>(s);
-}
-
-main() {
-  expectTrue(foo<X, Y>(new X(), new Y()));
-}
diff --git a/pkg/kernel/testcases/reify/generic_methods_simple_as_expression_error_test.dart b/pkg/kernel/testcases/reify/generic_methods_simple_as_expression_error_test.dart
deleted file mode 100644
index 1b89821..0000000
--- a/pkg/kernel/testcases/reify/generic_methods_simple_as_expression_error_test.dart
+++ /dev/null
@@ -1,18 +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.
-
-// Test that type parameters in generic methods can be used in as-expressions,
-// and that an exception is thrown if the cast can't be made.
-
-library generic_methods_simple_as_expression_error_test;
-
-import "test_base.dart";
-
-T cast<T>(dynamic obj) {
-  return obj as T;
-}
-
-main() {
-  expectThrows(() => cast<String>(42), (e) => e is CastError);
-}
diff --git a/pkg/kernel/testcases/reify/generic_methods_simple_as_expression_error_test.dart.expect b/pkg/kernel/testcases/reify/generic_methods_simple_as_expression_error_test.dart.expect
deleted file mode 100644
index 9dea62b..0000000
--- a/pkg/kernel/testcases/reify/generic_methods_simple_as_expression_error_test.dart.expect
+++ /dev/null
@@ -1,73 +0,0 @@
-library generic_methods_simple_as_expression_error_test;
-import self as self;
-import "dart:core" as core;
-import "../../runtime/reify/interceptors.dart" as int;
-import "dart:mock" as mock;
-import "../../runtime/reify/types.dart" as typ;
-import "./test_base.dart" as tes;
-import "../../runtime/reify/declarations.dart" as dec;
-
-class Closure#main#function extends core::Object implements core::Function, int::HasRuntimeTypeGetter {
-  field core::String note = "This is temporary. The VM doesn't need closure classes.";
-  field mock::Context context;
-  constructor •(final mock::Context context) → dynamic
-    : self::Closure#main#function::context = context
-    ;
-  method call() → core::String {
-    "This is a temporary solution. In the VM, this will become an additional parameter.";
-    final mock::Context #contextParameter = this.{self::Closure#main#function::context};
-    return self::cast(42, $typeParameters: <typ::ReifiedType>[new typ::Interface::•(self::$declarations.[](1))]);
-  }
-  get $type() → typ::ReifiedType
-    return new typ::Interface::•(self::$declarations.[](0));
-  get $is$CastError() → core::bool
-    return false;
-}
-class Closure#main#function#1 extends core::Object implements core::Function, int::HasRuntimeTypeGetter {
-  field core::String note = "This is temporary. The VM doesn't need closure classes.";
-  field mock::Context context;
-  constructor •(final mock::Context context) → dynamic
-    : self::Closure#main#function#1::context = context
-    ;
-  method call(dynamic e) → core::bool {
-    "This is a temporary solution. In the VM, this will become an additional parameter.";
-    final mock::Context #contextParameter = this.{self::Closure#main#function#1::context};
-    return typ::isSubtypeOf(int::type(e), new typ::Interface::•(self::$declarations.[](3)));
-  }
-  get $type() → typ::ReifiedType
-    return new typ::Interface::•(self::$declarations.[](2));
-  get $is$CastError() → core::bool
-    return false;
-}
-static final field core::List<dec::Class> $declarations = (core::List<dec::Class> d) → core::List<dec::Class> {
-  dec::init(d, 0, new typ::Interface::•(d.[](16)), <dynamic>[new typ::Interface::•(d.[](17))], new typ::FunctionType::•(new typ::Interface::•(d.[](17)), new typ::Interface::•(d.[](1)), 0, <dynamic>[]));
-  dec::init(d, 1, new typ::Interface::•(d.[](16)), <dynamic>[new typ::Interface::•(d.[](19), <dynamic>[new typ::Interface::•(d.[](1))]), new typ::Interface::•(d.[](20))]);
-  dec::init(d, 2, new typ::Interface::•(d.[](16)), <dynamic>[new typ::Interface::•(d.[](17))], new typ::FunctionType::•(new typ::Interface::•(d.[](17)), new typ::Interface::•(d.[](5)), 0, <dynamic>[const typ::Dynamic::•()]));
-  dec::init(d, 3, new typ::Interface::•(d.[](21)));
-  dec::init(d, 4, new typ::Interface::•(d.[](16)));
-  dec::init(d, 5, new typ::Interface::•(d.[](16)));
-  dec::init(d, 6, new typ::Interface::•(d.[](22)));
-  dec::init(d, 7, new typ::Interface::•(d.[](22)));
-  dec::init(d, 8, new typ::Interface::•(d.[](16)));
-  dec::init(d, 9, new typ::Interface::•(d.[](21)));
-  dec::init(d, 10, new typ::Interface::•(d.[](21)));
-  dec::init(d, 11, new typ::Interface::•(d.[](21)));
-  dec::init(d, 12, new typ::Interface::•(d.[](21)));
-  dec::init(d, 13, new typ::Interface::•(d.[](16)), <dynamic>[new typ::Interface::•(d.[](23))]);
-  dec::init(d, 14, new typ::Interface::•(d.[](15)));
-  dec::init(d, 15, new typ::Interface::•(d.[](21)));
-  dec::init(d, 16, null);
-  dec::init(d, 17, new typ::Interface::•(d.[](16)));
-  dec::init(d, 19, new typ::Interface::•(d.[](16)));
-  dec::init(d, 20, new typ::Interface::•(d.[](16)));
-  dec::init(d, 21, new typ::Interface::•(d.[](16)));
-  dec::init(d, 22, new typ::Interface::•(d.[](16)), <dynamic>[new typ::Interface::•(d.[](19), <dynamic>[new typ::Interface::•(d.[](22))])]);
-  dec::init(d, 23, new typ::Interface::•(d.[](16)));
-  return d;
-}.call(dec::allocateDeclarations(<dynamic>["Closure#main#function", "String", "Closure#main#function#1", "CastError", "Null", "bool", "int", "double", "Type", "AbstractClassInstantiationError", "NoSuchMethodError", "CyclicInitializationError", "UnsupportedError", "IntegerDivisionByZeroException", "RangeError", "ArgumentError", "Object", "Function", "HasRuntimeTypeGetter", "Comparable", "Pattern", "Error", "num", "Exception"], <dynamic>[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0]));
-static method cast(dynamic obj, {core::List<typ::ReifiedType> $typeParameters}) → dynamic {
-  return obj as dynamic;
-}
-static method main() → dynamic {
-  tes::expectThrows(new self::Closure#main#function::•(null), new self::Closure#main#function#1::•(null));
-}
diff --git a/pkg/kernel/testcases/reify/generic_methods_simple_as_expression_test.dart b/pkg/kernel/testcases/reify/generic_methods_simple_as_expression_test.dart
deleted file mode 100644
index b668d77..0000000
--- a/pkg/kernel/testcases/reify/generic_methods_simple_as_expression_test.dart
+++ /dev/null
@@ -1,17 +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.
-
-// Test that type parameters in generic methods can be used in as-expressions.
-
-library generic_methods_simple_as_expression_test;
-
-import "test_base.dart";
-
-T cast<T>(dynamic obj) {
-  return obj as T;
-}
-
-main() {
-  expectTrue(cast<num>(42) == 42);
-}
diff --git a/pkg/kernel/testcases/reify/generic_methods_simple_as_expression_test.dart.expect b/pkg/kernel/testcases/reify/generic_methods_simple_as_expression_test.dart.expect
deleted file mode 100644
index b7cab5c..0000000
--- a/pkg/kernel/testcases/reify/generic_methods_simple_as_expression_test.dart.expect
+++ /dev/null
@@ -1,35 +0,0 @@
-library generic_methods_simple_as_expression_test;
-import self as self;
-import "dart:core" as core;
-import "../../runtime/reify/types.dart" as typ;
-import "./test_base.dart" as tes;
-import "../../runtime/reify/declarations.dart" as dec;
-
-static final field core::List<dec::Class> $declarations = (core::List<dec::Class> d) → core::List<dec::Class> {
-  dec::init(d, 0, new typ::Interface::•(d.[](14)), <dynamic>[new typ::Interface::•(d.[](15), <dynamic>[new typ::Interface::•(d.[](0))])]);
-  dec::init(d, 1, new typ::Interface::•(d.[](14)));
-  dec::init(d, 2, new typ::Interface::•(d.[](14)));
-  dec::init(d, 3, new typ::Interface::•(d.[](14)), <dynamic>[new typ::Interface::•(d.[](15), <dynamic>[new typ::Interface::•(d.[](3))]), new typ::Interface::•(d.[](16))]);
-  dec::init(d, 4, new typ::Interface::•(d.[](0)));
-  dec::init(d, 5, new typ::Interface::•(d.[](0)));
-  dec::init(d, 6, new typ::Interface::•(d.[](14)));
-  dec::init(d, 7, new typ::Interface::•(d.[](17)));
-  dec::init(d, 8, new typ::Interface::•(d.[](17)));
-  dec::init(d, 9, new typ::Interface::•(d.[](17)));
-  dec::init(d, 10, new typ::Interface::•(d.[](17)));
-  dec::init(d, 11, new typ::Interface::•(d.[](14)), <dynamic>[new typ::Interface::•(d.[](18))]);
-  dec::init(d, 12, new typ::Interface::•(d.[](13)));
-  dec::init(d, 13, new typ::Interface::•(d.[](17)));
-  dec::init(d, 14, null);
-  dec::init(d, 15, new typ::Interface::•(d.[](14)));
-  dec::init(d, 16, new typ::Interface::•(d.[](14)));
-  dec::init(d, 17, new typ::Interface::•(d.[](14)));
-  dec::init(d, 18, new typ::Interface::•(d.[](14)));
-  return d;
-}.call(dec::allocateDeclarations(<dynamic>["num", "Null", "bool", "String", "int", "double", "Type", "AbstractClassInstantiationError", "NoSuchMethodError", "CyclicInitializationError", "UnsupportedError", "IntegerDivisionByZeroException", "RangeError", "ArgumentError", "Object", "Comparable", "Pattern", "Error", "Exception"], <dynamic>[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0]));
-static method cast(dynamic obj, {core::List<typ::ReifiedType> $typeParameters}) → dynamic {
-  return obj as dynamic;
-}
-static method main() → dynamic {
-  tes::expectTrue(self::cast(42, $typeParameters: <typ::ReifiedType>[new typ::Interface::•(self::$declarations.[](0))]).{core::num::==}(42));
-}
diff --git a/pkg/kernel/testcases/reify/generic_methods_simple_is_expression_test.dart b/pkg/kernel/testcases/reify/generic_methods_simple_is_expression_test.dart
deleted file mode 100644
index 66dcb70..0000000
--- a/pkg/kernel/testcases/reify/generic_methods_simple_is_expression_test.dart
+++ /dev/null
@@ -1,18 +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.
-
-// Test that type parameters in generic methods can be used in is-expressions.
-
-library generic_methods_simple_is_expression_test;
-
-import "test_base.dart";
-
-bool fun<T>(int n) {
-  return n is T;
-}
-
-main() {
-  expectTrue(fun<int>(42));
-  expectFalse(fun<String>(42));
-}
diff --git a/pkg/kernel/testcases/reify/generic_methods_simple_test.dart b/pkg/kernel/testcases/reify/generic_methods_simple_test.dart
deleted file mode 100644
index f2e13d8..0000000
--- a/pkg/kernel/testcases/reify/generic_methods_simple_test.dart
+++ /dev/null
@@ -1,15 +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 generic_methods_simple_test;
-
-import 'test_base.dart';
-
-bool fun<T>(int s) {
-  return true;
-}
-
-main() {
-  expectTrue(fun<double>(2));
-}
diff --git a/pkg/kernel/testcases/reify/generic_methods_simple_test.dart.expect b/pkg/kernel/testcases/reify/generic_methods_simple_test.dart.expect
deleted file mode 100644
index 53c2725..0000000
--- a/pkg/kernel/testcases/reify/generic_methods_simple_test.dart.expect
+++ /dev/null
@@ -1,35 +0,0 @@
-library generic_methods_simple_test;
-import self as self;
-import "dart:core" as core;
-import "../../runtime/reify/types.dart" as typ;
-import "./test_base.dart" as tes;
-import "../../runtime/reify/declarations.dart" as dec;
-
-static final field core::List<dec::Class> $declarations = (core::List<dec::Class> d) → core::List<dec::Class> {
-  dec::init(d, 0, new typ::Interface::•(d.[](13)));
-  dec::init(d, 1, new typ::Interface::•(d.[](14)));
-  dec::init(d, 2, new typ::Interface::•(d.[](14)));
-  dec::init(d, 3, new typ::Interface::•(d.[](14)), <dynamic>[new typ::Interface::•(d.[](15), <dynamic>[new typ::Interface::•(d.[](3))]), new typ::Interface::•(d.[](16))]);
-  dec::init(d, 4, new typ::Interface::•(d.[](13)));
-  dec::init(d, 5, new typ::Interface::•(d.[](14)));
-  dec::init(d, 6, new typ::Interface::•(d.[](17)));
-  dec::init(d, 7, new typ::Interface::•(d.[](17)));
-  dec::init(d, 8, new typ::Interface::•(d.[](17)));
-  dec::init(d, 9, new typ::Interface::•(d.[](17)));
-  dec::init(d, 10, new typ::Interface::•(d.[](14)), <dynamic>[new typ::Interface::•(d.[](18))]);
-  dec::init(d, 11, new typ::Interface::•(d.[](12)));
-  dec::init(d, 12, new typ::Interface::•(d.[](17)));
-  dec::init(d, 13, new typ::Interface::•(d.[](14)), <dynamic>[new typ::Interface::•(d.[](15), <dynamic>[new typ::Interface::•(d.[](13))])]);
-  dec::init(d, 14, null);
-  dec::init(d, 15, new typ::Interface::•(d.[](14)));
-  dec::init(d, 16, new typ::Interface::•(d.[](14)));
-  dec::init(d, 17, new typ::Interface::•(d.[](14)));
-  dec::init(d, 18, new typ::Interface::•(d.[](14)));
-  return d;
-}.call(dec::allocateDeclarations(<dynamic>["double", "Null", "bool", "String", "int", "Type", "AbstractClassInstantiationError", "NoSuchMethodError", "CyclicInitializationError", "UnsupportedError", "IntegerDivisionByZeroException", "RangeError", "ArgumentError", "num", "Object", "Comparable", "Pattern", "Error", "Exception"], <dynamic>[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0]));
-static method fun(core::int s, {core::List<typ::ReifiedType> $typeParameters}) → core::bool {
-  return true;
-}
-static method main() → dynamic {
-  tes::expectTrue(self::fun(2, $typeParameters: <typ::ReifiedType>[new typ::Interface::•(self::$declarations.[](0))]));
-}
diff --git a/pkg/kernel/testcases/reify/generic_methods_tearoff_specialization_test.dart b/pkg/kernel/testcases/reify/generic_methods_tearoff_specialization_test.dart
deleted file mode 100644
index 2424ecd..0000000
--- a/pkg/kernel/testcases/reify/generic_methods_tearoff_specialization_test.dart
+++ /dev/null
@@ -1,47 +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.
-
-// Test that generic methods can be specialized after being torn off, and that
-// their specialized versions are correctly constructed.
-
-library generic_methods_tearoff_specialization_test;
-
-import "test_base.dart";
-
-class A {
-  T fun<T>(T t) => t;
-}
-
-typedef Int2Int = int Function(int);
-typedef String2String = String Function(String);
-typedef Object2Object = Object Function(Object);
-typedef GenericMethod = T Function<T>(T);
-
-main() {
-  A a = new A();
-  Int2Int f = a.fun;
-  String2String g = a.fun;
-  Object2Object h = a.fun;
-  var generic = a.fun;
-
-  expectTrue(f is Int2Int);
-  expectTrue(f is! String2String);
-  expectTrue(f is! Object2Object);
-  expectTrue(f is! GenericMethod);
-
-  expectTrue(g is! Int2Int);
-  expectTrue(g is String2String);
-  expectTrue(g is! Object2Object);
-  expectTrue(g is! GenericMethod);
-
-  expectTrue(h is! Int2Int);
-  expectTrue(h is! String2String);
-  expectTrue(h is Object2Object);
-  expectTrue(g is! GenericMethod);
-
-  expectTrue(generic is! Int2Int);
-  expectTrue(generic is! String2String);
-  expectTrue(generic is! Object2Object);
-  expectTrue(generic is GenericMethod);
-}
diff --git a/pkg/kernel/testcases/reify/generic_methods_unused_parameter_test.dart b/pkg/kernel/testcases/reify/generic_methods_unused_parameter_test.dart
deleted file mode 100644
index 3c52eea..0000000
--- a/pkg/kernel/testcases/reify/generic_methods_unused_parameter_test.dart
+++ /dev/null
@@ -1,89 +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.
-
-// Test that generic methods with unused parameters aren't treated as
-// non-generic methods, but can be specialized as such.
-
-library generic_methods_unused_parameter_test;
-
-import "test_base.dart";
-
-typedef Fun = int Function();
-typedef FunReq = int Function(int);
-typedef FunOpt = int Function([int]);
-typedef FunReqOpt = int Function(int, [int]);
-typedef FunNam = int Function({int p});
-typedef FunReqNam = int Function(int, {int p});
-
-typedef FunTyp = int Function<T>();
-typedef FunTypReq = int Function<T>(int);
-typedef FunTypOpt = int Function<T>([int]);
-typedef FunTypReqOpt = int Function<T>(int, [int]);
-typedef FunTypNam = int Function<T>({int p});
-typedef FunTypReqNam = int Function<T>(int, {int p});
-
-int fun() {}
-int funReq(int x) => x;
-int funOpt([int y]) => y ?? 42;
-int funReqOpt(int x, [int y]) => x;
-int funNam({int p}) => p ?? 42;
-int funReqNam(int x, {int p}) => x;
-
-int funTyp<T>() {}
-int funTypReq<T>(int x) => x;
-int funTypOpt<T>([int y]) => y ?? 42;
-int funTypReqOpt<T>(int x, [int y]) => x;
-int funTypNam<T>({int p}) => p ?? 42;
-int funTypReqNam<T>(int x, {int p}) => x;
-
-main() {
-  Fun varFun = funTyp;
-  FunReq varFunReq = funTypReq;
-  FunOpt varFunOpt = funTypOpt;
-  FunReqOpt varFunReqOpt = funTypReqOpt;
-  FunNam varFunNam = funTypNam;
-  FunReqNam varFunReqNam = funTypReqNam;
-
-  expectTrue(fun is Fun);
-  expectTrue(fun is! FunTyp);
-  expectTrue(funTyp is! Fun);
-  expectTrue(funTyp is FunTyp);
-  expectTrue(varFun is Fun);
-  expectTrue(varFun is! FunTyp);
-
-  expectTrue(funReq is FunReq);
-  expectTrue(funReq is! FunTypReq);
-  expectTrue(funTypReq is! FunReq);
-  expectTrue(funTypReq is FunTypReq);
-  expectTrue(varFunReq is FunReq);
-  expectTrue(varFunReq is! FunTypReq);
-
-  expectTrue(funOpt is FunOpt);
-  expectTrue(funOpt is! FunTypOpt);
-  expectTrue(funTypOpt is! FunOpt);
-  expectTrue(funTypOpt is FunTypOpt);
-  expectTrue(varFunOpt is FunOpt);
-  expectTrue(varFunOpt is! FunTypOpt);
-
-  expectTrue(funReqOpt is FunReqOpt);
-  expectTrue(funReqOpt is! FunTypReqOpt);
-  expectTrue(funTypReqOpt is! FunReqOpt);
-  expectTrue(funTypReqOpt is FunTypReqOpt);
-  expectTrue(varFunReqOpt is FunReqOpt);
-  expectTrue(varFunReqOpt is! FunTypReqOpt);
-
-  expectTrue(funNam is FunNam);
-  expectTrue(funNam is! FunTypNam);
-  expectTrue(funTypNam is! FunNam);
-  expectTrue(funTypNam is FunTypNam);
-  expectTrue(varFunNam is FunNam);
-  expectTrue(varFunNam is! FunTypNam);
-
-  expectTrue(funReqNam is FunReqNam);
-  expectTrue(funReqNam is! FunTypReqNam);
-  expectTrue(funTypReqNam is! FunReqNam);
-  expectTrue(funTypReqNam is FunTypReqNam);
-  expectTrue(varFunReqNam is FunReqNam);
-  expectTrue(varFunReqNam is! FunTypReqNam);
-}
diff --git a/pkg/kernel/testcases/reify/is1_test.dart b/pkg/kernel/testcases/reify/is1_test.dart
deleted file mode 100644
index e84dae9..0000000
--- a/pkg/kernel/testcases/reify/is1_test.dart
+++ /dev/null
@@ -1,27 +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 is1_test;
-
-import 'test_base.dart';
-
-class N {}
-
-class I extends N {}
-
-class D extends N {}
-
-class A<T> {}
-
-main() {
-  var x = new A<I>();
-  expectTrue(x is A<N>);
-  expectTrue(x is A<I>);
-  expectFalse(x is A<D>);
-
-  var y = new A();
-  expectTrue(y is A<N>);
-  expectTrue(y is A<I>);
-  expectTrue(y is A<D>);
-}
diff --git a/pkg/kernel/testcases/reify/is1_test.dart.expect b/pkg/kernel/testcases/reify/is1_test.dart.expect
deleted file mode 100644
index 020cdc3..0000000
--- a/pkg/kernel/testcases/reify/is1_test.dart.expect
+++ /dev/null
@@ -1,83 +0,0 @@
-library is1_test;
-import self as self;
-import "dart:core" as core;
-import "../../runtime/reify/interceptors.dart" as int;
-import "../../runtime/reify/types.dart" as typ;
-import "./test_base.dart" as tes;
-import "../../runtime/reify/declarations.dart" as dec;
-
-class N extends core::Object implements int::HasRuntimeTypeGetter {
-  constructor •() → void
-    : super core::Object::•()
-    ;
-  get $type() → typ::ReifiedType
-    return new typ::Interface::•(self::$declarations.[](0));
-  get $is$A() → core::bool
-    return false;
-}
-class I extends self::N implements int::HasRuntimeTypeGetter {
-  constructor •() → void
-    : super self::N::•()
-    ;
-  get $type() → typ::ReifiedType
-    return new typ::Interface::•(self::$declarations.[](1));
-  get $is$A() → core::bool
-    return false;
-}
-class D extends self::N implements int::HasRuntimeTypeGetter {
-  constructor •() → void
-    : super self::N::•()
-    ;
-  get $type() → typ::ReifiedType
-    return new typ::Interface::•(self::$declarations.[](2));
-  get $is$A() → core::bool
-    return false;
-}
-class A extends core::Object implements int::HasRuntimeTypeGetter {
-  final field typ::ReifiedType $type;
-  constructor •(typ::ReifiedType $type) → void
-    : self::A::$type = $type, super core::Object::•()
-    ;
-  get $A$T() → typ::ReifiedType
-    return typ::getTypeArguments(typ::asInstanceOf(this.$type, self::$declarations.[](3))).[](0);
-  get $is$A() → core::bool
-    return true;
-  get runtimeType() → core::Type
-    return this.{=self::A::$type};
-}
-static final field core::List<dec::Class> $declarations = (core::List<dec::Class> d) → core::List<dec::Class> {
-  dec::init(d, 0, new typ::Interface::•(d.[](17)));
-  dec::init(d, 1, new typ::Interface::•(d.[](0)));
-  dec::init(d, 2, new typ::Interface::•(d.[](0)));
-  dec::init(d, 3, new typ::Interface::•(d.[](17)));
-  dec::init(d, 4, new typ::Interface::•(d.[](17)));
-  dec::init(d, 5, new typ::Interface::•(d.[](17)));
-  dec::init(d, 6, new typ::Interface::•(d.[](17)), <dynamic>[new typ::Interface::•(d.[](19), <dynamic>[new typ::Interface::•(d.[](6))]), new typ::Interface::•(d.[](20))]);
-  dec::init(d, 7, new typ::Interface::•(d.[](21)));
-  dec::init(d, 8, new typ::Interface::•(d.[](21)));
-  dec::init(d, 9, new typ::Interface::•(d.[](17)));
-  dec::init(d, 10, new typ::Interface::•(d.[](22)));
-  dec::init(d, 11, new typ::Interface::•(d.[](22)));
-  dec::init(d, 12, new typ::Interface::•(d.[](22)));
-  dec::init(d, 13, new typ::Interface::•(d.[](22)));
-  dec::init(d, 14, new typ::Interface::•(d.[](17)), <dynamic>[new typ::Interface::•(d.[](23))]);
-  dec::init(d, 15, new typ::Interface::•(d.[](16)));
-  dec::init(d, 16, new typ::Interface::•(d.[](22)));
-  dec::init(d, 17, null);
-  dec::init(d, 19, new typ::Interface::•(d.[](17)));
-  dec::init(d, 20, new typ::Interface::•(d.[](17)));
-  dec::init(d, 21, new typ::Interface::•(d.[](17)), <dynamic>[new typ::Interface::•(d.[](19), <dynamic>[new typ::Interface::•(d.[](21))])]);
-  dec::init(d, 22, new typ::Interface::•(d.[](17)));
-  dec::init(d, 23, new typ::Interface::•(d.[](17)));
-  return d;
-}.call(dec::allocateDeclarations(<dynamic>["N", "I", "D", "A", "Null", "bool", "String", "int", "double", "Type", "AbstractClassInstantiationError", "NoSuchMethodError", "CyclicInitializationError", "UnsupportedError", "IntegerDivisionByZeroException", "RangeError", "ArgumentError", "Object", "HasRuntimeTypeGetter", "Comparable", "Pattern", "num", "Error", "Exception"], <dynamic>[0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0]));
-static method main() → dynamic {
-  self::A x = new self::A::•(new typ::Interface::•(self::$declarations.[](3), <dynamic>[new typ::Interface::•(self::$declarations.[](1))]));
-  tes::expectTrue(let dynamic #t1 = x in #t1 is int::HasRuntimeTypeGetter && #t1.$is$A && (let dynamic #t2 = new typ::Interface::•(self::$declarations.[](3), <dynamic>[new typ::Interface::•(self::$declarations.[](0))]) in typ::isSubtypeOf(#t1.$type, #t2)));
-  tes::expectTrue(let dynamic #t3 = x in #t3 is int::HasRuntimeTypeGetter && #t3.$is$A && (let dynamic #t4 = new typ::Interface::•(self::$declarations.[](3), <dynamic>[new typ::Interface::•(self::$declarations.[](1))]) in typ::isSubtypeOf(#t3.$type, #t4)));
-  tes::expectFalse(let dynamic #t5 = x in #t5 is int::HasRuntimeTypeGetter && #t5.$is$A && (let dynamic #t6 = new typ::Interface::•(self::$declarations.[](3), <dynamic>[new typ::Interface::•(self::$declarations.[](2))]) in typ::isSubtypeOf(#t5.$type, #t6)));
-  self::A y = new self::A::•(new typ::Interface::•(self::$declarations.[](3), <dynamic>[const typ::Dynamic::•()]));
-  tes::expectTrue(let dynamic #t7 = y in #t7 is int::HasRuntimeTypeGetter && #t7.$is$A && (let dynamic #t8 = new typ::Interface::•(self::$declarations.[](3), <dynamic>[new typ::Interface::•(self::$declarations.[](0))]) in typ::isSubtypeOf(#t7.$type, #t8)));
-  tes::expectTrue(let dynamic #t9 = y in #t9 is int::HasRuntimeTypeGetter && #t9.$is$A && (let dynamic #t10 = new typ::Interface::•(self::$declarations.[](3), <dynamic>[new typ::Interface::•(self::$declarations.[](1))]) in typ::isSubtypeOf(#t9.$type, #t10)));
-  tes::expectTrue(let dynamic #t11 = y in #t11 is int::HasRuntimeTypeGetter && #t11.$is$A && (let dynamic #t12 = new typ::Interface::•(self::$declarations.[](3), <dynamic>[new typ::Interface::•(self::$declarations.[](2))]) in typ::isSubtypeOf(#t11.$type, #t12)));
-}
diff --git a/pkg/kernel/testcases/reify/literals_test.dart b/pkg/kernel/testcases/reify/literals_test.dart
deleted file mode 100644
index 6b820dd..0000000
--- a/pkg/kernel/testcases/reify/literals_test.dart
+++ /dev/null
@@ -1,20 +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 literals_test;
-
-import 'test_base.dart';
-
-class A {}
-
-class B {}
-
-main() {
-  expectTrue(<A>[] is List<A>);
-  expectTrue(<A>[] is! List<B>);
-
-  expectTrue(<A, B>{} is Map<A, B>);
-  expectTrue(<A, B>{} is! Map<A, A>);
-  expectTrue(<A, B>{} is! Map<B, B>);
-}
diff --git a/pkg/kernel/testcases/reify/literals_test.dart.expect b/pkg/kernel/testcases/reify/literals_test.dart.expect
deleted file mode 100644
index 3d0d11d..0000000
--- a/pkg/kernel/testcases/reify/literals_test.dart.expect
+++ /dev/null
@@ -1,65 +0,0 @@
-library literals_test;
-import self as self;
-import "dart:core" as core;
-import "../../runtime/reify/interceptors.dart" as int;
-import "../../runtime/reify/types.dart" as typ;
-import "./test_base.dart" as tes;
-import "../../runtime/reify/declarations.dart" as dec;
-
-class A extends core::Object implements int::HasRuntimeTypeGetter {
-  constructor •() → void
-    : super core::Object::•()
-    ;
-  get $type() → typ::ReifiedType
-    return new typ::Interface::•(self::$declarations.[](0));
-  get $is$List() → core::bool
-    return false;
-  get $is$Map() → core::bool
-    return false;
-}
-class B extends core::Object implements int::HasRuntimeTypeGetter {
-  constructor •() → void
-    : super core::Object::•()
-    ;
-  get $type() → typ::ReifiedType
-    return new typ::Interface::•(self::$declarations.[](1));
-  get $is$List() → core::bool
-    return false;
-  get $is$Map() → core::bool
-    return false;
-}
-static final field core::List<dec::Class> $declarations = (core::List<dec::Class> d) → core::List<dec::Class> {
-  dec::init(d, 0, new typ::Interface::•(d.[](17)));
-  dec::init(d, 1, new typ::Interface::•(d.[](17)));
-  dec::init(d, 2, new typ::Interface::•(d.[](17)), <dynamic>[new typ::Interface::•(d.[](19), <dynamic>[d.[](2).variables.[](0)])]);
-  dec::init(d, 3, new typ::Interface::•(d.[](17)));
-  dec::init(d, 4, new typ::Interface::•(d.[](17)));
-  dec::init(d, 5, new typ::Interface::•(d.[](17)));
-  dec::init(d, 6, new typ::Interface::•(d.[](17)), <dynamic>[new typ::Interface::•(d.[](20), <dynamic>[new typ::Interface::•(d.[](6))]), new typ::Interface::•(d.[](21))]);
-  dec::init(d, 7, new typ::Interface::•(d.[](22)));
-  dec::init(d, 8, new typ::Interface::•(d.[](22)));
-  dec::init(d, 9, new typ::Interface::•(d.[](17)));
-  dec::init(d, 10, new typ::Interface::•(d.[](23)));
-  dec::init(d, 11, new typ::Interface::•(d.[](23)));
-  dec::init(d, 12, new typ::Interface::•(d.[](23)));
-  dec::init(d, 13, new typ::Interface::•(d.[](23)));
-  dec::init(d, 14, new typ::Interface::•(d.[](17)), <dynamic>[new typ::Interface::•(d.[](24))]);
-  dec::init(d, 15, new typ::Interface::•(d.[](16)));
-  dec::init(d, 16, new typ::Interface::•(d.[](23)));
-  dec::init(d, 17, null);
-  dec::init(d, 19, new typ::Interface::•(d.[](25), <dynamic>[d.[](19).variables.[](0)]));
-  dec::init(d, 20, new typ::Interface::•(d.[](17)));
-  dec::init(d, 21, new typ::Interface::•(d.[](17)));
-  dec::init(d, 22, new typ::Interface::•(d.[](17)), <dynamic>[new typ::Interface::•(d.[](20), <dynamic>[new typ::Interface::•(d.[](22))])]);
-  dec::init(d, 23, new typ::Interface::•(d.[](17)));
-  dec::init(d, 24, new typ::Interface::•(d.[](17)));
-  dec::init(d, 25, new typ::Interface::•(d.[](17)));
-  return d;
-}.call(dec::allocateDeclarations(<dynamic>["A", "B", "List", "Map", "Null", "bool", "String", "int", "double", "Type", "AbstractClassInstantiationError", "NoSuchMethodError", "CyclicInitializationError", "UnsupportedError", "IntegerDivisionByZeroException", "RangeError", "ArgumentError", "Object", "HasRuntimeTypeGetter", "EfficientLengthIterable", "Comparable", "Pattern", "num", "Error", "Exception", "Iterable"], <dynamic>[0, 0, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1]));
-static method main() → dynamic {
-  tes::expectTrue(typ::isSubtypeOf(int::type(int::attachType(<self::A>[], new typ::Interface::•(self::$declarations.[](2), <dynamic>[new typ::Interface::•(self::$declarations.[](0))]))), new typ::Interface::•(self::$declarations.[](2), <dynamic>[new typ::Interface::•(self::$declarations.[](0))])));
-  tes::expectTrue(!typ::isSubtypeOf(int::type(int::attachType(<self::A>[], new typ::Interface::•(self::$declarations.[](2), <dynamic>[new typ::Interface::•(self::$declarations.[](0))]))), new typ::Interface::•(self::$declarations.[](2), <dynamic>[new typ::Interface::•(self::$declarations.[](1))])));
-  tes::expectTrue(typ::isSubtypeOf(int::type(int::attachType(<self::A, self::B>{}, new typ::Interface::•(self::$declarations.[](3), <dynamic>[new typ::Interface::•(self::$declarations.[](0)), new typ::Interface::•(self::$declarations.[](1))]))), new typ::Interface::•(self::$declarations.[](3), <dynamic>[new typ::Interface::•(self::$declarations.[](0)), new typ::Interface::•(self::$declarations.[](1))])));
-  tes::expectTrue(!typ::isSubtypeOf(int::type(int::attachType(<self::A, self::B>{}, new typ::Interface::•(self::$declarations.[](3), <dynamic>[new typ::Interface::•(self::$declarations.[](0)), new typ::Interface::•(self::$declarations.[](1))]))), new typ::Interface::•(self::$declarations.[](3), <dynamic>[new typ::Interface::•(self::$declarations.[](0)), new typ::Interface::•(self::$declarations.[](0))])));
-  tes::expectTrue(!typ::isSubtypeOf(int::type(int::attachType(<self::A, self::B>{}, new typ::Interface::•(self::$declarations.[](3), <dynamic>[new typ::Interface::•(self::$declarations.[](0)), new typ::Interface::•(self::$declarations.[](1))]))), new typ::Interface::•(self::$declarations.[](3), <dynamic>[new typ::Interface::•(self::$declarations.[](1)), new typ::Interface::•(self::$declarations.[](1))])));
-}
diff --git a/pkg/kernel/testcases/reify/multiple_variables_test.dart b/pkg/kernel/testcases/reify/multiple_variables_test.dart
deleted file mode 100644
index 5c33c33..0000000
--- a/pkg/kernel/testcases/reify/multiple_variables_test.dart
+++ /dev/null
@@ -1,11 +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 multiple_variables_test;
-
-import '../../runtime/reify/types.dart' as rti;
-
-class X<A, B, C, D, E> {}
-
-main() {}
diff --git a/pkg/kernel/testcases/reify/multiple_variables_test.dart.expect b/pkg/kernel/testcases/reify/multiple_variables_test.dart.expect
deleted file mode 100644
index 9b1dccf..0000000
--- a/pkg/kernel/testcases/reify/multiple_variables_test.dart.expect
+++ /dev/null
@@ -1,49 +0,0 @@
-library multiple_variables_test;
-import self as self;
-import "dart:core" as core;
-import "../../runtime/reify/interceptors.dart" as int;
-import "../../runtime/reify/types.dart" as typ;
-import "../../runtime/reify/declarations.dart" as dec;
-
-class X extends core::Object implements int::HasRuntimeTypeGetter {
-  final field typ::ReifiedType $type;
-  constructor •(typ::ReifiedType $type) → void
-    : self::X::$type = $type, super core::Object::•()
-    ;
-  get $X$A() → typ::ReifiedType
-    return typ::getTypeArguments(typ::asInstanceOf(this.$type, self::$declarations.[](0))).[](0);
-  get $X$B() → typ::ReifiedType
-    return typ::getTypeArguments(typ::asInstanceOf(this.$type, self::$declarations.[](0))).[](1);
-  get $X$C() → typ::ReifiedType
-    return typ::getTypeArguments(typ::asInstanceOf(this.$type, self::$declarations.[](0))).[](2);
-  get $X$D() → typ::ReifiedType
-    return typ::getTypeArguments(typ::asInstanceOf(this.$type, self::$declarations.[](0))).[](3);
-  get $X$E() → typ::ReifiedType
-    return typ::getTypeArguments(typ::asInstanceOf(this.$type, self::$declarations.[](0))).[](4);
-  get runtimeType() → core::Type
-    return this.{=self::X::$type};
-}
-static final field core::List<dec::Class> $declarations = (core::List<dec::Class> d) → core::List<dec::Class> {
-  dec::init(d, 0, new typ::Interface::•(d.[](14)));
-  dec::init(d, 1, new typ::Interface::•(d.[](14)));
-  dec::init(d, 2, new typ::Interface::•(d.[](14)));
-  dec::init(d, 3, new typ::Interface::•(d.[](14)), <dynamic>[new typ::Interface::•(d.[](16), <dynamic>[new typ::Interface::•(d.[](3))]), new typ::Interface::•(d.[](17))]);
-  dec::init(d, 4, new typ::Interface::•(d.[](18)));
-  dec::init(d, 5, new typ::Interface::•(d.[](18)));
-  dec::init(d, 6, new typ::Interface::•(d.[](14)));
-  dec::init(d, 7, new typ::Interface::•(d.[](19)));
-  dec::init(d, 8, new typ::Interface::•(d.[](19)));
-  dec::init(d, 9, new typ::Interface::•(d.[](19)));
-  dec::init(d, 10, new typ::Interface::•(d.[](19)));
-  dec::init(d, 11, new typ::Interface::•(d.[](14)), <dynamic>[new typ::Interface::•(d.[](20))]);
-  dec::init(d, 12, new typ::Interface::•(d.[](13)));
-  dec::init(d, 13, new typ::Interface::•(d.[](19)));
-  dec::init(d, 14, null);
-  dec::init(d, 16, new typ::Interface::•(d.[](14)));
-  dec::init(d, 17, new typ::Interface::•(d.[](14)));
-  dec::init(d, 18, new typ::Interface::•(d.[](14)), <dynamic>[new typ::Interface::•(d.[](16), <dynamic>[new typ::Interface::•(d.[](18))])]);
-  dec::init(d, 19, new typ::Interface::•(d.[](14)));
-  dec::init(d, 20, new typ::Interface::•(d.[](14)));
-  return d;
-}.call(dec::allocateDeclarations(<dynamic>["X", "Null", "bool", "String", "int", "double", "Type", "AbstractClassInstantiationError", "NoSuchMethodError", "CyclicInitializationError", "UnsupportedError", "IntegerDivisionByZeroException", "RangeError", "ArgumentError", "Object", "HasRuntimeTypeGetter", "Comparable", "Pattern", "num", "Error", "Exception"], <dynamic>[5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0]));
-static method main() → dynamic {}
diff --git a/pkg/kernel/testcases/reify/native_types_test.dart b/pkg/kernel/testcases/reify/native_types_test.dart
deleted file mode 100644
index 738b151..0000000
--- a/pkg/kernel/testcases/reify/native_types_test.dart
+++ /dev/null
@@ -1,51 +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 native_types;
-
-import 'test_base.dart';
-
-abstract class C {}
-
-class D {}
-
-var foo = bar;
-var bar = foo;
-
-main() {
-  expectTrue(1 is int);
-  expectTrue(1 is! double);
-
-  expectTrue(new List<int>() is List<int>);
-  expectTrue(new List<int>() is! List<double>);
-  expectTrue("hest" is String);
-  expectTrue("hest" is! int);
-
-  expectTrue(null is! String);
-  expectTrue(null is dynamic);
-  expectTrue(null is Object);
-
-  expectTrue(true is bool);
-  expectTrue(true is! int);
-
-  // Test error and exception classes
-  expectThrows(() => new C(), (e) => e is AbstractClassInstantiationError);
-
-  /// 01: static type warning
-
-  expectThrows(() => new D().foo(), (e) => e is NoSuchMethodError);
-
-  /// 02: static type warning
-
-  expectThrows(() => foo, (e) => e is CyclicInitializationError);
-
-  expectThrows(() => [][1], (e) => e is RangeError);
-
-  expectTrue(new UnsupportedError("") is UnsupportedError);
-
-  expectTrue(new ArgumentError() is ArgumentError);
-
-  expectTrue(
-      new IntegerDivisionByZeroException() is IntegerDivisionByZeroException);
-}
diff --git a/pkg/kernel/testcases/reify/native_types_test.dart.expect b/pkg/kernel/testcases/reify/native_types_test.dart.expect
deleted file mode 100644
index ca0fa91..0000000
--- a/pkg/kernel/testcases/reify/native_types_test.dart.expect
+++ /dev/null
@@ -1,453 +0,0 @@
-library native_types;
-import self as self;
-import "dart:core" as core;
-import "../../runtime/reify/interceptors.dart" as int;
-import "../../runtime/reify/types.dart" as typ;
-import "dart:mock" as mock;
-import "./test_base.dart" as tes;
-import "../../runtime/reify/declarations.dart" as dec;
-
-abstract class C extends core::Object implements int::HasRuntimeTypeGetter {
-  constructor •() → void
-    : super core::Object::•()
-    ;
-  get $type() → typ::ReifiedType
-    return new typ::Interface::•(self::$declarations.[](0));
-  get $is$AbstractClassInstantiationError() → core::bool
-    return false;
-  get $is$NoSuchMethodError() → core::bool
-    return false;
-  get $is$CyclicInitializationError() → core::bool
-    return false;
-  get $is$RangeError() → core::bool
-    return false;
-  get $is$int() → core::bool
-    return false;
-  get $is$double() → core::bool
-    return false;
-  get $is$List() → core::bool
-    return false;
-  get $is$String() → core::bool
-    return false;
-  get $is$Object() → core::bool
-    return true;
-  get $is$bool() → core::bool
-    return false;
-  get $is$UnsupportedError() → core::bool
-    return false;
-  get $is$ArgumentError() → core::bool
-    return false;
-  get $is$IntegerDivisionByZeroException() → core::bool
-    return false;
-}
-class D extends core::Object implements int::HasRuntimeTypeGetter {
-  constructor •() → void
-    : super core::Object::•()
-    ;
-  get $type() → typ::ReifiedType
-    return new typ::Interface::•(self::$declarations.[](1));
-  get $is$AbstractClassInstantiationError() → core::bool
-    return false;
-  get $is$NoSuchMethodError() → core::bool
-    return false;
-  get $is$CyclicInitializationError() → core::bool
-    return false;
-  get $is$RangeError() → core::bool
-    return false;
-  get $is$int() → core::bool
-    return false;
-  get $is$double() → core::bool
-    return false;
-  get $is$List() → core::bool
-    return false;
-  get $is$String() → core::bool
-    return false;
-  get $is$Object() → core::bool
-    return true;
-  get $is$bool() → core::bool
-    return false;
-  get $is$UnsupportedError() → core::bool
-    return false;
-  get $is$ArgumentError() → core::bool
-    return false;
-  get $is$IntegerDivisionByZeroException() → core::bool
-    return false;
-}
-class Closure#main#function extends core::Object implements core::Function, int::HasRuntimeTypeGetter {
-  field core::String note = "This is temporary. The VM doesn't need closure classes.";
-  field mock::Context context;
-  constructor •(final mock::Context context) → dynamic
-    : self::Closure#main#function::context = context
-    ;
-  method call() → self::C {
-    "This is a temporary solution. In the VM, this will become an additional parameter.";
-    final mock::Context #contextParameter = this.{self::Closure#main#function::context};
-    return throw int::attachType(new core::AbstractClassInstantiationError::•("C"), new typ::Interface::•(self::$declarations.[](3)));
-  }
-  get $type() → typ::ReifiedType
-    return new typ::Interface::•(self::$declarations.[](2));
-  get $is$AbstractClassInstantiationError() → core::bool
-    return false;
-  get $is$NoSuchMethodError() → core::bool
-    return false;
-  get $is$CyclicInitializationError() → core::bool
-    return false;
-  get $is$RangeError() → core::bool
-    return false;
-  get $is$int() → core::bool
-    return false;
-  get $is$double() → core::bool
-    return false;
-  get $is$List() → core::bool
-    return false;
-  get $is$String() → core::bool
-    return false;
-  get $is$Object() → core::bool
-    return true;
-  get $is$bool() → core::bool
-    return false;
-  get $is$UnsupportedError() → core::bool
-    return false;
-  get $is$ArgumentError() → core::bool
-    return false;
-  get $is$IntegerDivisionByZeroException() → core::bool
-    return false;
-}
-class Closure#main#function#1 extends core::Object implements core::Function, int::HasRuntimeTypeGetter {
-  field core::String note = "This is temporary. The VM doesn't need closure classes.";
-  field mock::Context context;
-  constructor •(final mock::Context context) → dynamic
-    : self::Closure#main#function#1::context = context
-    ;
-  method call(dynamic e) → core::bool {
-    "This is a temporary solution. In the VM, this will become an additional parameter.";
-    final mock::Context #contextParameter = this.{self::Closure#main#function#1::context};
-    return typ::isSubtypeOf(int::type(e), new typ::Interface::•(self::$declarations.[](3)));
-  }
-  get $type() → typ::ReifiedType
-    return new typ::Interface::•(self::$declarations.[](4));
-  get $is$AbstractClassInstantiationError() → core::bool
-    return false;
-  get $is$NoSuchMethodError() → core::bool
-    return false;
-  get $is$CyclicInitializationError() → core::bool
-    return false;
-  get $is$RangeError() → core::bool
-    return false;
-  get $is$int() → core::bool
-    return false;
-  get $is$double() → core::bool
-    return false;
-  get $is$List() → core::bool
-    return false;
-  get $is$String() → core::bool
-    return false;
-  get $is$Object() → core::bool
-    return true;
-  get $is$bool() → core::bool
-    return false;
-  get $is$UnsupportedError() → core::bool
-    return false;
-  get $is$ArgumentError() → core::bool
-    return false;
-  get $is$IntegerDivisionByZeroException() → core::bool
-    return false;
-}
-class Closure#main#function#2 extends core::Object implements core::Function, int::HasRuntimeTypeGetter {
-  field core::String note = "This is temporary. The VM doesn't need closure classes.";
-  field mock::Context context;
-  constructor •(final mock::Context context) → dynamic
-    : self::Closure#main#function#2::context = context
-    ;
-  method call() → dynamic {
-    "This is a temporary solution. In the VM, this will become an additional parameter.";
-    final mock::Context #contextParameter = this.{self::Closure#main#function#2::context};
-    return new self::D::•().foo();
-  }
-  get $type() → typ::ReifiedType
-    return new typ::Interface::•(self::$declarations.[](5));
-  get $is$AbstractClassInstantiationError() → core::bool
-    return false;
-  get $is$NoSuchMethodError() → core::bool
-    return false;
-  get $is$CyclicInitializationError() → core::bool
-    return false;
-  get $is$RangeError() → core::bool
-    return false;
-  get $is$int() → core::bool
-    return false;
-  get $is$double() → core::bool
-    return false;
-  get $is$List() → core::bool
-    return false;
-  get $is$String() → core::bool
-    return false;
-  get $is$Object() → core::bool
-    return true;
-  get $is$bool() → core::bool
-    return false;
-  get $is$UnsupportedError() → core::bool
-    return false;
-  get $is$ArgumentError() → core::bool
-    return false;
-  get $is$IntegerDivisionByZeroException() → core::bool
-    return false;
-}
-class Closure#main#function#3 extends core::Object implements core::Function, int::HasRuntimeTypeGetter {
-  field core::String note = "This is temporary. The VM doesn't need closure classes.";
-  field mock::Context context;
-  constructor •(final mock::Context context) → dynamic
-    : self::Closure#main#function#3::context = context
-    ;
-  method call(dynamic e) → core::bool {
-    "This is a temporary solution. In the VM, this will become an additional parameter.";
-    final mock::Context #contextParameter = this.{self::Closure#main#function#3::context};
-    return typ::isSubtypeOf(int::type(e), new typ::Interface::•(self::$declarations.[](7)));
-  }
-  get $type() → typ::ReifiedType
-    return new typ::Interface::•(self::$declarations.[](6));
-  get $is$AbstractClassInstantiationError() → core::bool
-    return false;
-  get $is$NoSuchMethodError() → core::bool
-    return false;
-  get $is$CyclicInitializationError() → core::bool
-    return false;
-  get $is$RangeError() → core::bool
-    return false;
-  get $is$int() → core::bool
-    return false;
-  get $is$double() → core::bool
-    return false;
-  get $is$List() → core::bool
-    return false;
-  get $is$String() → core::bool
-    return false;
-  get $is$Object() → core::bool
-    return true;
-  get $is$bool() → core::bool
-    return false;
-  get $is$UnsupportedError() → core::bool
-    return false;
-  get $is$ArgumentError() → core::bool
-    return false;
-  get $is$IntegerDivisionByZeroException() → core::bool
-    return false;
-}
-class Closure#main#function#4 extends core::Object implements core::Function, int::HasRuntimeTypeGetter {
-  field core::String note = "This is temporary. The VM doesn't need closure classes.";
-  field mock::Context context;
-  constructor •(final mock::Context context) → dynamic
-    : self::Closure#main#function#4::context = context
-    ;
-  method call() → dynamic {
-    "This is a temporary solution. In the VM, this will become an additional parameter.";
-    final mock::Context #contextParameter = this.{self::Closure#main#function#4::context};
-    return self::foo;
-  }
-  get $type() → typ::ReifiedType
-    return new typ::Interface::•(self::$declarations.[](8));
-  get $is$AbstractClassInstantiationError() → core::bool
-    return false;
-  get $is$NoSuchMethodError() → core::bool
-    return false;
-  get $is$CyclicInitializationError() → core::bool
-    return false;
-  get $is$RangeError() → core::bool
-    return false;
-  get $is$int() → core::bool
-    return false;
-  get $is$double() → core::bool
-    return false;
-  get $is$List() → core::bool
-    return false;
-  get $is$String() → core::bool
-    return false;
-  get $is$Object() → core::bool
-    return true;
-  get $is$bool() → core::bool
-    return false;
-  get $is$UnsupportedError() → core::bool
-    return false;
-  get $is$ArgumentError() → core::bool
-    return false;
-  get $is$IntegerDivisionByZeroException() → core::bool
-    return false;
-}
-class Closure#main#function#5 extends core::Object implements core::Function, int::HasRuntimeTypeGetter {
-  field core::String note = "This is temporary. The VM doesn't need closure classes.";
-  field mock::Context context;
-  constructor •(final mock::Context context) → dynamic
-    : self::Closure#main#function#5::context = context
-    ;
-  method call(dynamic e) → core::bool {
-    "This is a temporary solution. In the VM, this will become an additional parameter.";
-    final mock::Context #contextParameter = this.{self::Closure#main#function#5::context};
-    return typ::isSubtypeOf(int::type(e), new typ::Interface::•(self::$declarations.[](10)));
-  }
-  get $type() → typ::ReifiedType
-    return new typ::Interface::•(self::$declarations.[](9));
-  get $is$AbstractClassInstantiationError() → core::bool
-    return false;
-  get $is$NoSuchMethodError() → core::bool
-    return false;
-  get $is$CyclicInitializationError() → core::bool
-    return false;
-  get $is$RangeError() → core::bool
-    return false;
-  get $is$int() → core::bool
-    return false;
-  get $is$double() → core::bool
-    return false;
-  get $is$List() → core::bool
-    return false;
-  get $is$String() → core::bool
-    return false;
-  get $is$Object() → core::bool
-    return true;
-  get $is$bool() → core::bool
-    return false;
-  get $is$UnsupportedError() → core::bool
-    return false;
-  get $is$ArgumentError() → core::bool
-    return false;
-  get $is$IntegerDivisionByZeroException() → core::bool
-    return false;
-}
-class Closure#main#function#6 extends core::Object implements core::Function, int::HasRuntimeTypeGetter {
-  field core::String note = "This is temporary. The VM doesn't need closure classes.";
-  field mock::Context context;
-  constructor •(final mock::Context context) → dynamic
-    : self::Closure#main#function#6::context = context
-    ;
-  method call() → dynamic {
-    "This is a temporary solution. In the VM, this will become an additional parameter.";
-    final mock::Context #contextParameter = this.{self::Closure#main#function#6::context};
-    return int::attachType(<dynamic>[], new typ::Interface::•(self::$declarations.[](12), <dynamic>[const typ::Dynamic::•()])).{core::List::[]}(1);
-  }
-  get $type() → typ::ReifiedType
-    return new typ::Interface::•(self::$declarations.[](11));
-  get $is$AbstractClassInstantiationError() → core::bool
-    return false;
-  get $is$NoSuchMethodError() → core::bool
-    return false;
-  get $is$CyclicInitializationError() → core::bool
-    return false;
-  get $is$RangeError() → core::bool
-    return false;
-  get $is$int() → core::bool
-    return false;
-  get $is$double() → core::bool
-    return false;
-  get $is$List() → core::bool
-    return false;
-  get $is$String() → core::bool
-    return false;
-  get $is$Object() → core::bool
-    return true;
-  get $is$bool() → core::bool
-    return false;
-  get $is$UnsupportedError() → core::bool
-    return false;
-  get $is$ArgumentError() → core::bool
-    return false;
-  get $is$IntegerDivisionByZeroException() → core::bool
-    return false;
-}
-class Closure#main#function#7 extends core::Object implements core::Function, int::HasRuntimeTypeGetter {
-  field core::String note = "This is temporary. The VM doesn't need closure classes.";
-  field mock::Context context;
-  constructor •(final mock::Context context) → dynamic
-    : self::Closure#main#function#7::context = context
-    ;
-  method call(dynamic e) → core::bool {
-    "This is a temporary solution. In the VM, this will become an additional parameter.";
-    final mock::Context #contextParameter = this.{self::Closure#main#function#7::context};
-    return typ::isSubtypeOf(int::type(e), new typ::Interface::•(self::$declarations.[](14)));
-  }
-  get $type() → typ::ReifiedType
-    return new typ::Interface::•(self::$declarations.[](13));
-  get $is$AbstractClassInstantiationError() → core::bool
-    return false;
-  get $is$NoSuchMethodError() → core::bool
-    return false;
-  get $is$CyclicInitializationError() → core::bool
-    return false;
-  get $is$RangeError() → core::bool
-    return false;
-  get $is$int() → core::bool
-    return false;
-  get $is$double() → core::bool
-    return false;
-  get $is$List() → core::bool
-    return false;
-  get $is$String() → core::bool
-    return false;
-  get $is$Object() → core::bool
-    return true;
-  get $is$bool() → core::bool
-    return false;
-  get $is$UnsupportedError() → core::bool
-    return false;
-  get $is$ArgumentError() → core::bool
-    return false;
-  get $is$IntegerDivisionByZeroException() → core::bool
-    return false;
-}
-static field dynamic foo = self::bar;
-static field dynamic bar = self::foo;
-static final field core::List<dec::Class> $declarations = (core::List<dec::Class> d) → core::List<dec::Class> {
-  dec::init(d, 0, new typ::Interface::•(d.[](18)));
-  dec::init(d, 1, new typ::Interface::•(d.[](18)));
-  dec::init(d, 2, new typ::Interface::•(d.[](18)), <dynamic>[new typ::Interface::•(d.[](26))], new typ::FunctionType::•(new typ::Interface::•(d.[](26)), new typ::Interface::•(d.[](0)), 0, <dynamic>[]));
-  dec::init(d, 3, new typ::Interface::•(d.[](27)));
-  dec::init(d, 4, new typ::Interface::•(d.[](18)), <dynamic>[new typ::Interface::•(d.[](26))], new typ::FunctionType::•(new typ::Interface::•(d.[](26)), new typ::Interface::•(d.[](19)), 0, <dynamic>[const typ::Dynamic::•()]));
-  dec::init(d, 5, new typ::Interface::•(d.[](18)), <dynamic>[new typ::Interface::•(d.[](26))], new typ::FunctionType::•(new typ::Interface::•(d.[](26)), const typ::Dynamic::•(), 0, <dynamic>[]));
-  dec::init(d, 6, new typ::Interface::•(d.[](18)), <dynamic>[new typ::Interface::•(d.[](26))], new typ::FunctionType::•(new typ::Interface::•(d.[](26)), new typ::Interface::•(d.[](19)), 0, <dynamic>[const typ::Dynamic::•()]));
-  dec::init(d, 7, new typ::Interface::•(d.[](27)));
-  dec::init(d, 8, new typ::Interface::•(d.[](18)), <dynamic>[new typ::Interface::•(d.[](26))], new typ::FunctionType::•(new typ::Interface::•(d.[](26)), const typ::Dynamic::•(), 0, <dynamic>[]));
-  dec::init(d, 9, new typ::Interface::•(d.[](18)), <dynamic>[new typ::Interface::•(d.[](26))], new typ::FunctionType::•(new typ::Interface::•(d.[](26)), new typ::Interface::•(d.[](19)), 0, <dynamic>[const typ::Dynamic::•()]));
-  dec::init(d, 10, new typ::Interface::•(d.[](27)));
-  dec::init(d, 11, new typ::Interface::•(d.[](18)), <dynamic>[new typ::Interface::•(d.[](26))], new typ::FunctionType::•(new typ::Interface::•(d.[](26)), const typ::Dynamic::•(), 0, <dynamic>[]));
-  dec::init(d, 12, new typ::Interface::•(d.[](18)), <dynamic>[new typ::Interface::•(d.[](28), <dynamic>[d.[](12).variables.[](0)])]);
-  dec::init(d, 13, new typ::Interface::•(d.[](18)), <dynamic>[new typ::Interface::•(d.[](26))], new typ::FunctionType::•(new typ::Interface::•(d.[](26)), new typ::Interface::•(d.[](19)), 0, <dynamic>[const typ::Dynamic::•()]));
-  dec::init(d, 14, new typ::Interface::•(d.[](21)));
-  dec::init(d, 15, new typ::Interface::•(d.[](29)));
-  dec::init(d, 16, new typ::Interface::•(d.[](29)));
-  dec::init(d, 17, new typ::Interface::•(d.[](18)), <dynamic>[new typ::Interface::•(d.[](30), <dynamic>[new typ::Interface::•(d.[](17))]), new typ::Interface::•(d.[](31))]);
-  dec::init(d, 18, null);
-  dec::init(d, 19, new typ::Interface::•(d.[](18)));
-  dec::init(d, 20, new typ::Interface::•(d.[](27)));
-  dec::init(d, 21, new typ::Interface::•(d.[](27)));
-  dec::init(d, 22, new typ::Interface::•(d.[](18)), <dynamic>[new typ::Interface::•(d.[](32))]);
-  dec::init(d, 23, new typ::Interface::•(d.[](18)));
-  dec::init(d, 24, new typ::Interface::•(d.[](18)));
-  dec::init(d, 26, new typ::Interface::•(d.[](18)));
-  dec::init(d, 27, new typ::Interface::•(d.[](18)));
-  dec::init(d, 28, new typ::Interface::•(d.[](33), <dynamic>[d.[](28).variables.[](0)]));
-  dec::init(d, 29, new typ::Interface::•(d.[](18)), <dynamic>[new typ::Interface::•(d.[](30), <dynamic>[new typ::Interface::•(d.[](29))])]);
-  dec::init(d, 30, new typ::Interface::•(d.[](18)));
-  dec::init(d, 31, new typ::Interface::•(d.[](18)));
-  dec::init(d, 32, new typ::Interface::•(d.[](18)));
-  dec::init(d, 33, new typ::Interface::•(d.[](18)));
-  return d;
-}.call(dec::allocateDeclarations(<dynamic>["C", "D", "Closure#main#function", "AbstractClassInstantiationError", "Closure#main#function#1", "Closure#main#function#2", "Closure#main#function#3", "NoSuchMethodError", "Closure#main#function#4", "Closure#main#function#5", "CyclicInitializationError", "Closure#main#function#6", "List", "Closure#main#function#7", "RangeError", "int", "double", "String", "Object", "bool", "UnsupportedError", "ArgumentError", "IntegerDivisionByZeroException", "Null", "Type", "HasRuntimeTypeGetter", "Function", "Error", "EfficientLengthIterable", "num", "Comparable", "Pattern", "Exception", "Iterable"], <dynamic>[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1]));
-static method main() → dynamic {
-  tes::expectTrue(typ::isSubtypeOf(int::type(1), new typ::Interface::•(self::$declarations.[](15))));
-  tes::expectTrue(!typ::isSubtypeOf(int::type(1), new typ::Interface::•(self::$declarations.[](16))));
-  tes::expectTrue(typ::isSubtypeOf(int::type(int::attachType(core::List::_internal<core::int>(), new typ::Interface::•(self::$declarations.[](12), <dynamic>[new typ::Interface::•(self::$declarations.[](15))]))), new typ::Interface::•(self::$declarations.[](12), <dynamic>[new typ::Interface::•(self::$declarations.[](15))])));
-  tes::expectTrue(!typ::isSubtypeOf(int::type(int::attachType(core::List::_internal<core::int>(), new typ::Interface::•(self::$declarations.[](12), <dynamic>[new typ::Interface::•(self::$declarations.[](15))]))), new typ::Interface::•(self::$declarations.[](12), <dynamic>[new typ::Interface::•(self::$declarations.[](16))])));
-  tes::expectTrue(typ::isSubtypeOf(int::type("hest"), new typ::Interface::•(self::$declarations.[](17))));
-  tes::expectTrue(!typ::isSubtypeOf(int::type("hest"), new typ::Interface::•(self::$declarations.[](15))));
-  tes::expectTrue(!typ::isSubtypeOf(int::type(null), new typ::Interface::•(self::$declarations.[](17))));
-  tes::expectTrue(typ::isSubtypeOf(int::type(null), const typ::Dynamic::•()));
-  tes::expectTrue(typ::isSubtypeOf(int::type(null), new typ::Interface::•(self::$declarations.[](18))));
-  tes::expectTrue(typ::isSubtypeOf(int::type(true), new typ::Interface::•(self::$declarations.[](19))));
-  tes::expectTrue(!typ::isSubtypeOf(int::type(true), new typ::Interface::•(self::$declarations.[](15))));
-  tes::expectThrows(new self::Closure#main#function::•(null), new self::Closure#main#function#1::•(null));
-  tes::expectThrows(new self::Closure#main#function#2::•(null), new self::Closure#main#function#3::•(null));
-  tes::expectThrows(new self::Closure#main#function#4::•(null), new self::Closure#main#function#5::•(null));
-  tes::expectThrows(new self::Closure#main#function#6::•(null), new self::Closure#main#function#7::•(null));
-  tes::expectTrue(typ::isSubtypeOf(int::type(int::attachType(new core::UnsupportedError::•(""), new typ::Interface::•(self::$declarations.[](20)))), new typ::Interface::•(self::$declarations.[](20))));
-  tes::expectTrue(typ::isSubtypeOf(int::type(int::attachType(new core::ArgumentError::•(), new typ::Interface::•(self::$declarations.[](21)))), new typ::Interface::•(self::$declarations.[](21))));
-  tes::expectTrue(typ::isSubtypeOf(int::type(int::attachType(new core::IntegerDivisionByZeroException::•(), new typ::Interface::•(self::$declarations.[](22)))), new typ::Interface::•(self::$declarations.[](22))));
-}
diff --git a/pkg/kernel/testcases/reify/reuse_type_variables_test.dart b/pkg/kernel/testcases/reify/reuse_type_variables_test.dart
deleted file mode 100644
index 1e6cdc2..0000000
--- a/pkg/kernel/testcases/reify/reuse_type_variables_test.dart
+++ /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.
-
-library reuse_type_variables_test;
-
-import 'test_base.dart';
-
-class X {}
-
-class Y {}
-
-class Z {}
-
-class C<T, U, V> {
-  foo() => new D<T, U, V>();
-  bar() => new E<T, U>();
-  hest() => new D<T, V, U>();
-}
-
-class D<T, U, V> {
-  baz() => new C<T, U, V>();
-}
-
-class E<T, U> {
-  qux() => new C<T, U, U>();
-}
-
-main() {
-  var c = new C<X, Y, Z>();
-  var d = c.foo();
-  expectTrue(d is D<X, Y, Z>);
-  d = c.hest();
-  expectTrue(d is! D<X, Y, Z>);
-  expectTrue(d is D<X, Z, Y>);
-  c = d.baz();
-  expectTrue(c is C<X, Z, Y>);
-  var e = c.bar();
-  expectTrue(e is E<X, Z>);
-  c = e.qux();
-  expectTrue(c is C<X, Z, Z>);
-}
diff --git a/pkg/kernel/testcases/reify/reuse_type_variables_test.dart.expect b/pkg/kernel/testcases/reify/reuse_type_variables_test.dart.expect
deleted file mode 100644
index 473772b..0000000
--- a/pkg/kernel/testcases/reify/reuse_type_variables_test.dart.expect
+++ /dev/null
@@ -1,162 +0,0 @@
-library reuse_type_variables_test;
-import self as self;
-import "dart:core" as core;
-import "../../runtime/reify/interceptors.dart" as int;
-import "../../runtime/reify/types.dart" as typ;
-import "./test_base.dart" as tes;
-import "../../runtime/reify/declarations.dart" as dec;
-
-class X extends core::Object implements int::HasRuntimeTypeGetter {
-  constructor •() → void
-    : super core::Object::•()
-    ;
-  get $type() → typ::ReifiedType
-    return new typ::Interface::•(self::$declarations.[](0));
-  get $is$D() → core::bool
-    return false;
-  get $is$C() → core::bool
-    return false;
-  get $is$E() → core::bool
-    return false;
-}
-class Y extends core::Object implements int::HasRuntimeTypeGetter {
-  constructor •() → void
-    : super core::Object::•()
-    ;
-  get $type() → typ::ReifiedType
-    return new typ::Interface::•(self::$declarations.[](1));
-  get $is$D() → core::bool
-    return false;
-  get $is$C() → core::bool
-    return false;
-  get $is$E() → core::bool
-    return false;
-}
-class Z extends core::Object implements int::HasRuntimeTypeGetter {
-  constructor •() → void
-    : super core::Object::•()
-    ;
-  get $type() → typ::ReifiedType
-    return new typ::Interface::•(self::$declarations.[](2));
-  get $is$D() → core::bool
-    return false;
-  get $is$C() → core::bool
-    return false;
-  get $is$E() → core::bool
-    return false;
-}
-class C extends core::Object implements int::HasRuntimeTypeGetter {
-  final field typ::ReifiedType $type;
-  constructor •(typ::ReifiedType $type) → void
-    : self::C::$type = $type, super core::Object::•()
-    ;
-  method foo() → dynamic {
-    return new self::D::•(new typ::Interface::•(self::$declarations.[](4), typ::getTypeArguments(typ::asInstanceOf(this.$type, self::$declarations.[](3)))));
-  }
-  method bar() → dynamic {
-    return new self::E::•(new typ::Interface::•(self::$declarations.[](5), <dynamic>[this.$C$T, this.$C$U]));
-  }
-  method hest() → dynamic {
-    return new self::D::•(new typ::Interface::•(self::$declarations.[](4), <dynamic>[this.$C$T, this.$C$V, this.$C$U]));
-  }
-  get $C$T() → typ::ReifiedType
-    return typ::getTypeArguments(typ::asInstanceOf(this.$type, self::$declarations.[](3))).[](0);
-  get $C$U() → typ::ReifiedType
-    return typ::getTypeArguments(typ::asInstanceOf(this.$type, self::$declarations.[](3))).[](1);
-  get $C$V() → typ::ReifiedType
-    return typ::getTypeArguments(typ::asInstanceOf(this.$type, self::$declarations.[](3))).[](2);
-  get $is$D() → core::bool
-    return false;
-  get $is$C() → core::bool
-    return true;
-  get $is$E() → core::bool
-    return false;
-  get runtimeType() → core::Type
-    return this.{=self::C::$type};
-}
-class D extends core::Object implements int::HasRuntimeTypeGetter {
-  final field typ::ReifiedType $type;
-  constructor •(typ::ReifiedType $type) → void
-    : self::D::$type = $type, super core::Object::•()
-    ;
-  method baz() → dynamic {
-    return new self::C::•(new typ::Interface::•(self::$declarations.[](3), typ::getTypeArguments(typ::asInstanceOf(this.$type, self::$declarations.[](4)))));
-  }
-  get $D$T() → typ::ReifiedType
-    return typ::getTypeArguments(typ::asInstanceOf(this.$type, self::$declarations.[](4))).[](0);
-  get $D$U() → typ::ReifiedType
-    return typ::getTypeArguments(typ::asInstanceOf(this.$type, self::$declarations.[](4))).[](1);
-  get $D$V() → typ::ReifiedType
-    return typ::getTypeArguments(typ::asInstanceOf(this.$type, self::$declarations.[](4))).[](2);
-  get $is$D() → core::bool
-    return true;
-  get $is$C() → core::bool
-    return false;
-  get $is$E() → core::bool
-    return false;
-  get runtimeType() → core::Type
-    return this.{=self::D::$type};
-}
-class E extends core::Object implements int::HasRuntimeTypeGetter {
-  final field typ::ReifiedType $type;
-  constructor •(typ::ReifiedType $type) → void
-    : self::E::$type = $type, super core::Object::•()
-    ;
-  method qux() → dynamic {
-    return new self::C::•(new typ::Interface::•(self::$declarations.[](3), <dynamic>[this.$E$T, this.$E$U, this.$E$U]));
-  }
-  get $E$T() → typ::ReifiedType
-    return typ::getTypeArguments(typ::asInstanceOf(this.$type, self::$declarations.[](5))).[](0);
-  get $E$U() → typ::ReifiedType
-    return typ::getTypeArguments(typ::asInstanceOf(this.$type, self::$declarations.[](5))).[](1);
-  get $is$D() → core::bool
-    return false;
-  get $is$C() → core::bool
-    return false;
-  get $is$E() → core::bool
-    return true;
-  get runtimeType() → core::Type
-    return this.{=self::E::$type};
-}
-static final field core::List<dec::Class> $declarations = (core::List<dec::Class> d) → core::List<dec::Class> {
-  dec::init(d, 0, new typ::Interface::•(d.[](19)));
-  dec::init(d, 1, new typ::Interface::•(d.[](19)));
-  dec::init(d, 2, new typ::Interface::•(d.[](19)));
-  dec::init(d, 3, new typ::Interface::•(d.[](19)));
-  dec::init(d, 4, new typ::Interface::•(d.[](19)));
-  dec::init(d, 5, new typ::Interface::•(d.[](19)));
-  dec::init(d, 6, new typ::Interface::•(d.[](19)));
-  dec::init(d, 7, new typ::Interface::•(d.[](19)));
-  dec::init(d, 8, new typ::Interface::•(d.[](19)), <dynamic>[new typ::Interface::•(d.[](21), <dynamic>[new typ::Interface::•(d.[](8))]), new typ::Interface::•(d.[](22))]);
-  dec::init(d, 9, new typ::Interface::•(d.[](23)));
-  dec::init(d, 10, new typ::Interface::•(d.[](23)));
-  dec::init(d, 11, new typ::Interface::•(d.[](19)));
-  dec::init(d, 12, new typ::Interface::•(d.[](24)));
-  dec::init(d, 13, new typ::Interface::•(d.[](24)));
-  dec::init(d, 14, new typ::Interface::•(d.[](24)));
-  dec::init(d, 15, new typ::Interface::•(d.[](24)));
-  dec::init(d, 16, new typ::Interface::•(d.[](19)), <dynamic>[new typ::Interface::•(d.[](25))]);
-  dec::init(d, 17, new typ::Interface::•(d.[](18)));
-  dec::init(d, 18, new typ::Interface::•(d.[](24)));
-  dec::init(d, 19, null);
-  dec::init(d, 21, new typ::Interface::•(d.[](19)));
-  dec::init(d, 22, new typ::Interface::•(d.[](19)));
-  dec::init(d, 23, new typ::Interface::•(d.[](19)), <dynamic>[new typ::Interface::•(d.[](21), <dynamic>[new typ::Interface::•(d.[](23))])]);
-  dec::init(d, 24, new typ::Interface::•(d.[](19)));
-  dec::init(d, 25, new typ::Interface::•(d.[](19)));
-  return d;
-}.call(dec::allocateDeclarations(<dynamic>["X", "Y", "Z", "C", "D", "E", "Null", "bool", "String", "int", "double", "Type", "AbstractClassInstantiationError", "NoSuchMethodError", "CyclicInitializationError", "UnsupportedError", "IntegerDivisionByZeroException", "RangeError", "ArgumentError", "Object", "HasRuntimeTypeGetter", "Comparable", "Pattern", "num", "Error", "Exception"], <dynamic>[0, 0, 0, 3, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0]));
-static method main() → dynamic {
-  self::C c = new self::C::•(new typ::Interface::•(self::$declarations.[](3), <dynamic>[new typ::Interface::•(self::$declarations.[](0)), new typ::Interface::•(self::$declarations.[](1)), new typ::Interface::•(self::$declarations.[](2))]));
-  dynamic d = c.{self::C::foo}();
-  tes::expectTrue(let dynamic #t1 = d in #t1 is int::HasRuntimeTypeGetter && #t1.$is$D && (let dynamic #t2 = new typ::Interface::•(self::$declarations.[](4), <dynamic>[new typ::Interface::•(self::$declarations.[](0)), new typ::Interface::•(self::$declarations.[](1)), new typ::Interface::•(self::$declarations.[](2))]) in typ::isSubtypeOf(#t1.$type, #t2)));
-  d = c.{self::C::hest}();
-  tes::expectTrue(!(let dynamic #t3 = d in #t3 is int::HasRuntimeTypeGetter && #t3.$is$D && (let dynamic #t4 = new typ::Interface::•(self::$declarations.[](4), <dynamic>[new typ::Interface::•(self::$declarations.[](0)), new typ::Interface::•(self::$declarations.[](1)), new typ::Interface::•(self::$declarations.[](2))]) in typ::isSubtypeOf(#t3.$type, #t4))));
-  tes::expectTrue(let dynamic #t5 = d in #t5 is int::HasRuntimeTypeGetter && #t5.$is$D && (let dynamic #t6 = new typ::Interface::•(self::$declarations.[](4), <dynamic>[new typ::Interface::•(self::$declarations.[](0)), new typ::Interface::•(self::$declarations.[](2)), new typ::Interface::•(self::$declarations.[](1))]) in typ::isSubtypeOf(#t5.$type, #t6)));
-  c = d.baz();
-  tes::expectTrue(let dynamic #t7 = c in #t7 is int::HasRuntimeTypeGetter && #t7.$is$C && (let dynamic #t8 = new typ::Interface::•(self::$declarations.[](3), <dynamic>[new typ::Interface::•(self::$declarations.[](0)), new typ::Interface::•(self::$declarations.[](2)), new typ::Interface::•(self::$declarations.[](1))]) in typ::isSubtypeOf(#t7.$type, #t8)));
-  dynamic e = c.{self::C::bar}();
-  tes::expectTrue(let dynamic #t9 = e in #t9 is int::HasRuntimeTypeGetter && #t9.$is$E && (let dynamic #t10 = new typ::Interface::•(self::$declarations.[](5), <dynamic>[new typ::Interface::•(self::$declarations.[](0)), new typ::Interface::•(self::$declarations.[](2))]) in typ::isSubtypeOf(#t9.$type, #t10)));
-  c = e.qux();
-  tes::expectTrue(let dynamic #t11 = c in #t11 is int::HasRuntimeTypeGetter && #t11.$is$C && (let dynamic #t12 = new typ::Interface::•(self::$declarations.[](3), <dynamic>[new typ::Interface::•(self::$declarations.[](0)), new typ::Interface::•(self::$declarations.[](2)), new typ::Interface::•(self::$declarations.[](2))]) in typ::isSubtypeOf(#t11.$type, #t12)));
-}
diff --git a/pkg/kernel/testcases/reify/runtime_type_test.dart b/pkg/kernel/testcases/reify/runtime_type_test.dart
deleted file mode 100644
index 39b6b54..0000000
--- a/pkg/kernel/testcases/reify/runtime_type_test.dart
+++ /dev/null
@@ -1,22 +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 runtime_type_test;
-
-import 'test_base.dart';
-
-class A<T> {}
-
-class X {}
-
-class Y {}
-
-bool eqt(a, b) => a.runtimeType == b.runtimeType;
-
-main() {
-  expectTrue(eqt(new A(), new A<dynamic>()));
-  expectTrue(eqt(new A<X>(), new A<X>()));
-  expectFalse(eqt(new A<X>(), new A()));
-  expectFalse(eqt(new A<X>(), new A<Y>()));
-}
diff --git a/pkg/kernel/testcases/reify/runtime_type_test.dart.expect b/pkg/kernel/testcases/reify/runtime_type_test.dart.expect
deleted file mode 100644
index 360e853..0000000
--- a/pkg/kernel/testcases/reify/runtime_type_test.dart.expect
+++ /dev/null
@@ -1,66 +0,0 @@
-library runtime_type_test;
-import self as self;
-import "dart:core" as core;
-import "../../runtime/reify/interceptors.dart" as int;
-import "../../runtime/reify/types.dart" as typ;
-import "./test_base.dart" as tes;
-import "../../runtime/reify/declarations.dart" as dec;
-
-class A extends core::Object implements int::HasRuntimeTypeGetter {
-  final field typ::ReifiedType $type;
-  constructor •(typ::ReifiedType $type) → void
-    : self::A::$type = $type, super core::Object::•()
-    ;
-  get $A$T() → typ::ReifiedType
-    return typ::getTypeArguments(typ::asInstanceOf(this.$type, self::$declarations.[](0))).[](0);
-  get runtimeType() → core::Type
-    return this.{=self::A::$type};
-}
-class X extends core::Object implements int::HasRuntimeTypeGetter {
-  constructor •() → void
-    : super core::Object::•()
-    ;
-  get $type() → typ::ReifiedType
-    return new typ::Interface::•(self::$declarations.[](1));
-}
-class Y extends core::Object implements int::HasRuntimeTypeGetter {
-  constructor •() → void
-    : super core::Object::•()
-    ;
-  get $type() → typ::ReifiedType
-    return new typ::Interface::•(self::$declarations.[](2));
-}
-static final field core::List<dec::Class> $declarations = (core::List<dec::Class> d) → core::List<dec::Class> {
-  dec::init(d, 0, new typ::Interface::•(d.[](16)));
-  dec::init(d, 1, new typ::Interface::•(d.[](16)));
-  dec::init(d, 2, new typ::Interface::•(d.[](16)));
-  dec::init(d, 3, new typ::Interface::•(d.[](16)));
-  dec::init(d, 4, new typ::Interface::•(d.[](16)));
-  dec::init(d, 5, new typ::Interface::•(d.[](16)), <dynamic>[new typ::Interface::•(d.[](18), <dynamic>[new typ::Interface::•(d.[](5))]), new typ::Interface::•(d.[](19))]);
-  dec::init(d, 6, new typ::Interface::•(d.[](20)));
-  dec::init(d, 7, new typ::Interface::•(d.[](20)));
-  dec::init(d, 8, new typ::Interface::•(d.[](16)));
-  dec::init(d, 9, new typ::Interface::•(d.[](21)));
-  dec::init(d, 10, new typ::Interface::•(d.[](21)));
-  dec::init(d, 11, new typ::Interface::•(d.[](21)));
-  dec::init(d, 12, new typ::Interface::•(d.[](21)));
-  dec::init(d, 13, new typ::Interface::•(d.[](16)), <dynamic>[new typ::Interface::•(d.[](22))]);
-  dec::init(d, 14, new typ::Interface::•(d.[](15)));
-  dec::init(d, 15, new typ::Interface::•(d.[](21)));
-  dec::init(d, 16, null);
-  dec::init(d, 18, new typ::Interface::•(d.[](16)));
-  dec::init(d, 19, new typ::Interface::•(d.[](16)));
-  dec::init(d, 20, new typ::Interface::•(d.[](16)), <dynamic>[new typ::Interface::•(d.[](18), <dynamic>[new typ::Interface::•(d.[](20))])]);
-  dec::init(d, 21, new typ::Interface::•(d.[](16)));
-  dec::init(d, 22, new typ::Interface::•(d.[](16)));
-  return d;
-}.call(dec::allocateDeclarations(<dynamic>["A", "X", "Y", "Null", "bool", "String", "int", "double", "Type", "AbstractClassInstantiationError", "NoSuchMethodError", "CyclicInitializationError", "UnsupportedError", "IntegerDivisionByZeroException", "RangeError", "ArgumentError", "Object", "HasRuntimeTypeGetter", "Comparable", "Pattern", "num", "Error", "Exception"], <dynamic>[1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0]));
-static method eqt(dynamic a, dynamic b) → core::bool {
-  return a.runtimeType.==(b.runtimeType);
-}
-static method main() → dynamic {
-  tes::expectTrue(self::eqt(new self::A::•(new typ::Interface::•(self::$declarations.[](0), <dynamic>[const typ::Dynamic::•()])), new self::A::•(new typ::Interface::•(self::$declarations.[](0), <dynamic>[const typ::Dynamic::•()]))));
-  tes::expectTrue(self::eqt(new self::A::•(new typ::Interface::•(self::$declarations.[](0), <dynamic>[new typ::Interface::•(self::$declarations.[](1))])), new self::A::•(new typ::Interface::•(self::$declarations.[](0), <dynamic>[new typ::Interface::•(self::$declarations.[](1))]))));
-  tes::expectFalse(self::eqt(new self::A::•(new typ::Interface::•(self::$declarations.[](0), <dynamic>[new typ::Interface::•(self::$declarations.[](1))])), new self::A::•(new typ::Interface::•(self::$declarations.[](0), <dynamic>[const typ::Dynamic::•()]))));
-  tes::expectFalse(self::eqt(new self::A::•(new typ::Interface::•(self::$declarations.[](0), <dynamic>[new typ::Interface::•(self::$declarations.[](1))])), new self::A::•(new typ::Interface::•(self::$declarations.[](0), <dynamic>[new typ::Interface::•(self::$declarations.[](2))]))));
-}
diff --git a/pkg/kernel/testcases/reify/simple_test.dart b/pkg/kernel/testcases/reify/simple_test.dart
deleted file mode 100644
index 4a2d11f..0000000
--- a/pkg/kernel/testcases/reify/simple_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.
-
-library simple_test;
-
-import 'test_base.dart';
-
-class C {}
-
-class A implements C {}
-
-class B extends C {}
-
-class D extends B {}
-
-testIs(o) {
-  write(o is A);
-  write(o is B);
-  write(o is C);
-  write(o is D);
-}
-
-testIsNot(o) {
-  write(o is! A);
-  write(o is! B);
-  write(o is! C);
-  write(o is! D);
-}
-
-main() {
-  var objects = [new A(), new B(), new C(), new D()];
-  objects.forEach(testIs);
-  objects.forEach(testIsNot);
-
-  expectOutput("""
-true
-false
-true
-false
-false
-true
-true
-false
-false
-false
-true
-false
-false
-true
-true
-true
-false
-true
-false
-true
-true
-false
-false
-true
-true
-true
-false
-true
-true
-false
-false
-false""");
-}
diff --git a/pkg/kernel/testcases/reify/simple_test.dart.expect b/pkg/kernel/testcases/reify/simple_test.dart.expect
deleted file mode 100644
index 3b1c713..0000000
--- a/pkg/kernel/testcases/reify/simple_test.dart.expect
+++ /dev/null
@@ -1,152 +0,0 @@
-library simple_test;
-import self as self;
-import "dart:core" as core;
-import "../../runtime/reify/interceptors.dart" as int;
-import "../../runtime/reify/types.dart" as typ;
-import "./test_base.dart" as tes;
-import "../../runtime/reify/declarations.dart" as dec;
-
-class C extends core::Object implements int::HasRuntimeTypeGetter {
-  constructor •() → void
-    : super core::Object::•()
-    ;
-  get $type() → typ::ReifiedType
-    return new typ::Interface::•(self::$declarations.[](0));
-  get $is$A() → core::bool
-    return false;
-  get $is$B() → core::bool
-    return false;
-  get $is$C() → core::bool
-    return true;
-  get $is$D() → core::bool
-    return false;
-}
-class A extends core::Object implements self::C, int::HasRuntimeTypeGetter {
-  constructor •() → void
-    : super core::Object::•()
-    ;
-  get $type() → typ::ReifiedType
-    return new typ::Interface::•(self::$declarations.[](1));
-  get $is$A() → core::bool
-    return true;
-  get $is$B() → core::bool
-    return false;
-  get $is$C() → core::bool
-    return true;
-  get $is$D() → core::bool
-    return false;
-}
-class B extends self::C implements int::HasRuntimeTypeGetter {
-  constructor •() → void
-    : super self::C::•()
-    ;
-  get $type() → typ::ReifiedType
-    return new typ::Interface::•(self::$declarations.[](2));
-  get $is$A() → core::bool
-    return false;
-  get $is$B() → core::bool
-    return true;
-  get $is$C() → core::bool
-    return true;
-  get $is$D() → core::bool
-    return false;
-}
-class D extends self::B implements int::HasRuntimeTypeGetter {
-  constructor •() → void
-    : super self::B::•()
-    ;
-  get $type() → typ::ReifiedType
-    return new typ::Interface::•(self::$declarations.[](3));
-  get $is$A() → core::bool
-    return false;
-  get $is$B() → core::bool
-    return true;
-  get $is$C() → core::bool
-    return true;
-  get $is$D() → core::bool
-    return true;
-}
-class Closure#testIs extends core::Object implements core::Function, int::HasRuntimeTypeGetter {
-  field core::String note = "This is temporary. The VM doesn't need closure classes.";
-  constructor •() → dynamic
-    ;
-  method call(dynamic o) → dynamic
-    return self::testIs(o);
-  get $type() → typ::ReifiedType
-    return new typ::Interface::•(self::$declarations.[](4));
-  get $is$A() → core::bool
-    return false;
-  get $is$B() → core::bool
-    return false;
-  get $is$C() → core::bool
-    return false;
-  get $is$D() → core::bool
-    return false;
-}
-class Closure#testIsNot extends core::Object implements core::Function, int::HasRuntimeTypeGetter {
-  field core::String note = "This is temporary. The VM doesn't need closure classes.";
-  constructor •() → dynamic
-    ;
-  method call(dynamic o) → dynamic
-    return self::testIsNot(o);
-  get $type() → typ::ReifiedType
-    return new typ::Interface::•(self::$declarations.[](5));
-  get $is$A() → core::bool
-    return false;
-  get $is$B() → core::bool
-    return false;
-  get $is$C() → core::bool
-    return false;
-  get $is$D() → core::bool
-    return false;
-}
-static final field core::List<dec::Class> $declarations = (core::List<dec::Class> d) → core::List<dec::Class> {
-  dec::init(d, 0, new typ::Interface::•(d.[](20)));
-  dec::init(d, 1, new typ::Interface::•(d.[](20)), <dynamic>[new typ::Interface::•(d.[](0))]);
-  dec::init(d, 2, new typ::Interface::•(d.[](0)));
-  dec::init(d, 3, new typ::Interface::•(d.[](2)));
-  dec::init(d, 4, new typ::Interface::•(d.[](20)), <dynamic>[new typ::Interface::•(d.[](22))], new typ::FunctionType::•(new typ::Interface::•(d.[](22)), const typ::Dynamic::•(), 0, <dynamic>[const typ::Dynamic::•()]));
-  dec::init(d, 5, new typ::Interface::•(d.[](20)), <dynamic>[new typ::Interface::•(d.[](22))], new typ::FunctionType::•(new typ::Interface::•(d.[](22)), const typ::Dynamic::•(), 0, <dynamic>[const typ::Dynamic::•()]));
-  dec::init(d, 6, new typ::Interface::•(d.[](20)), <dynamic>[new typ::Interface::•(d.[](23), <dynamic>[d.[](6).variables.[](0)])]);
-  dec::init(d, 7, new typ::Interface::•(d.[](20)));
-  dec::init(d, 8, new typ::Interface::•(d.[](20)));
-  dec::init(d, 9, new typ::Interface::•(d.[](20)), <dynamic>[new typ::Interface::•(d.[](24), <dynamic>[new typ::Interface::•(d.[](9))]), new typ::Interface::•(d.[](25))]);
-  dec::init(d, 10, new typ::Interface::•(d.[](26)));
-  dec::init(d, 11, new typ::Interface::•(d.[](26)));
-  dec::init(d, 12, new typ::Interface::•(d.[](20)));
-  dec::init(d, 13, new typ::Interface::•(d.[](27)));
-  dec::init(d, 14, new typ::Interface::•(d.[](27)));
-  dec::init(d, 15, new typ::Interface::•(d.[](27)));
-  dec::init(d, 16, new typ::Interface::•(d.[](27)));
-  dec::init(d, 17, new typ::Interface::•(d.[](20)), <dynamic>[new typ::Interface::•(d.[](28))]);
-  dec::init(d, 18, new typ::Interface::•(d.[](19)));
-  dec::init(d, 19, new typ::Interface::•(d.[](27)));
-  dec::init(d, 20, null);
-  dec::init(d, 22, new typ::Interface::•(d.[](20)));
-  dec::init(d, 23, new typ::Interface::•(d.[](29), <dynamic>[d.[](23).variables.[](0)]));
-  dec::init(d, 24, new typ::Interface::•(d.[](20)));
-  dec::init(d, 25, new typ::Interface::•(d.[](20)));
-  dec::init(d, 26, new typ::Interface::•(d.[](20)), <dynamic>[new typ::Interface::•(d.[](24), <dynamic>[new typ::Interface::•(d.[](26))])]);
-  dec::init(d, 27, new typ::Interface::•(d.[](20)));
-  dec::init(d, 28, new typ::Interface::•(d.[](20)));
-  dec::init(d, 29, new typ::Interface::•(d.[](20)));
-  return d;
-}.call(dec::allocateDeclarations(<dynamic>["C", "A", "B", "D", "Closure#testIs", "Closure#testIsNot", "List", "Null", "bool", "String", "int", "double", "Type", "AbstractClassInstantiationError", "NoSuchMethodError", "CyclicInitializationError", "UnsupportedError", "IntegerDivisionByZeroException", "RangeError", "ArgumentError", "Object", "HasRuntimeTypeGetter", "Function", "EfficientLengthIterable", "Comparable", "Pattern", "num", "Error", "Exception", "Iterable"], <dynamic>[0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1]));
-static method testIs(dynamic o) → dynamic {
-  tes::write(let dynamic #t1 = o in #t1 is int::HasRuntimeTypeGetter && #t1.$is$A);
-  tes::write(let dynamic #t2 = o in #t2 is int::HasRuntimeTypeGetter && #t2.$is$B);
-  tes::write(let dynamic #t3 = o in #t3 is int::HasRuntimeTypeGetter && #t3.$is$C);
-  tes::write(let dynamic #t4 = o in #t4 is int::HasRuntimeTypeGetter && #t4.$is$D);
-}
-static method testIsNot(dynamic o) → dynamic {
-  tes::write(!(let dynamic #t5 = o in #t5 is int::HasRuntimeTypeGetter && #t5.$is$A));
-  tes::write(!(let dynamic #t6 = o in #t6 is int::HasRuntimeTypeGetter && #t6.$is$B));
-  tes::write(!(let dynamic #t7 = o in #t7 is int::HasRuntimeTypeGetter && #t7.$is$C));
-  tes::write(!(let dynamic #t8 = o in #t8 is int::HasRuntimeTypeGetter && #t8.$is$D));
-}
-static method main() → dynamic {
-  core::List<self::C> objects = int::attachType(<self::C>[new self::A::•(), new self::B::•(), new self::C::•(), new self::D::•()], new typ::Interface::•(self::$declarations.[](6), <dynamic>[new typ::Interface::•(self::$declarations.[](0))]));
-  objects.{core::Iterable::forEach}(new self::Closure#testIs::•());
-  objects.{core::Iterable::forEach}(new self::Closure#testIsNot::•());
-  tes::expectOutput("true\nfalse\ntrue\nfalse\nfalse\ntrue\ntrue\nfalse\nfalse\nfalse\ntrue\nfalse\nfalse\ntrue\ntrue\ntrue\nfalse\ntrue\nfalse\ntrue\ntrue\nfalse\nfalse\ntrue\ntrue\ntrue\nfalse\ntrue\ntrue\nfalse\nfalse\nfalse");
-}
diff --git a/pkg/kernel/testcases/reify/subclass_test.dart b/pkg/kernel/testcases/reify/subclass_test.dart
deleted file mode 100644
index 5b5b6bc..0000000
--- a/pkg/kernel/testcases/reify/subclass_test.dart
+++ /dev/null
@@ -1,35 +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.md file.
-
-library superclass_test;
-
-import 'test_base.dart';
-
-class X {}
-
-class Y {}
-
-class R<T> {}
-
-class A<T> {
-  foo() => new R<T>();
-}
-
-class B<T> extends A<T> {}
-
-class C<T> extends A<Y> {}
-
-class D<T> extends B<R<T>> {}
-
-main() {
-  expectTrue(new A<X>().foo() is R<X>);
-  expectTrue(new B<X>().foo() is R<X>);
-  expectTrue(new C<X>().foo() is R<Y>);
-  expectTrue(new D<X>().foo() is R<R<X>>);
-
-  expectTrue(new A<X>().foo() is! R<Y>);
-  expectTrue(new B<X>().foo() is! R<Y>);
-  expectTrue(new C<X>().foo() is! R<X>);
-  expectTrue(new D<X>().foo() is! R<R<Y>>);
-}
diff --git a/pkg/kernel/testcases/reify/subclass_test.dart.expect b/pkg/kernel/testcases/reify/subclass_test.dart.expect
deleted file mode 100644
index 2317bb7..0000000
--- a/pkg/kernel/testcases/reify/subclass_test.dart.expect
+++ /dev/null
@@ -1,119 +0,0 @@
-library superclass_test;
-import self as self;
-import "dart:core" as core;
-import "../../runtime/reify/interceptors.dart" as int;
-import "../../runtime/reify/types.dart" as typ;
-import "./test_base.dart" as tes;
-import "../../runtime/reify/declarations.dart" as dec;
-
-class X extends core::Object implements int::HasRuntimeTypeGetter {
-  constructor •() → void
-    : super core::Object::•()
-    ;
-  get $type() → typ::ReifiedType
-    return new typ::Interface::•(self::$declarations.[](0));
-  get $is$R() → core::bool
-    return false;
-}
-class Y extends core::Object implements int::HasRuntimeTypeGetter {
-  constructor •() → void
-    : super core::Object::•()
-    ;
-  get $type() → typ::ReifiedType
-    return new typ::Interface::•(self::$declarations.[](1));
-  get $is$R() → core::bool
-    return false;
-}
-class R extends core::Object implements int::HasRuntimeTypeGetter {
-  final field typ::ReifiedType $type;
-  constructor •(typ::ReifiedType $type) → void
-    : self::R::$type = $type, super core::Object::•()
-    ;
-  get $R$T() → typ::ReifiedType
-    return typ::getTypeArguments(typ::asInstanceOf(this.$type, self::$declarations.[](2))).[](0);
-  get $is$R() → core::bool
-    return true;
-  get runtimeType() → core::Type
-    return this.{=self::R::$type};
-}
-class A extends core::Object implements int::HasRuntimeTypeGetter {
-  final field typ::ReifiedType $type;
-  constructor •(typ::ReifiedType $type) → void
-    : self::A::$type = $type, super core::Object::•()
-    ;
-  method foo() → dynamic {
-    return new self::R::•(new typ::Interface::•(self::$declarations.[](2), typ::getTypeArguments(typ::asInstanceOf(this.$type, self::$declarations.[](3)))));
-  }
-  get $A$T() → typ::ReifiedType
-    return typ::getTypeArguments(typ::asInstanceOf(this.$type, self::$declarations.[](3))).[](0);
-  get $is$R() → core::bool
-    return false;
-  get runtimeType() → core::Type
-    return this.{=self::A::$type};
-}
-class B extends self::A implements int::HasRuntimeTypeGetter {
-  constructor •(typ::ReifiedType $type) → void
-    : super self::A::•($type)
-    ;
-  get $B$T() → typ::ReifiedType
-    return typ::getTypeArguments(typ::asInstanceOf(this.$type, self::$declarations.[](4))).[](0);
-  get $is$R() → core::bool
-    return false;
-}
-class C extends self::A implements int::HasRuntimeTypeGetter {
-  constructor •(typ::ReifiedType $type) → void
-    : super self::A::•($type)
-    ;
-  get $C$T() → typ::ReifiedType
-    return typ::getTypeArguments(typ::asInstanceOf(this.$type, self::$declarations.[](5))).[](0);
-  get $is$R() → core::bool
-    return false;
-}
-class D extends self::B implements int::HasRuntimeTypeGetter {
-  constructor •(typ::ReifiedType $type) → void
-    : super self::B::•($type)
-    ;
-  get $D$T() → typ::ReifiedType
-    return typ::getTypeArguments(typ::asInstanceOf(this.$type, self::$declarations.[](6))).[](0);
-  get $is$R() → core::bool
-    return false;
-}
-static final field core::List<dec::Class> $declarations = (core::List<dec::Class> d) → core::List<dec::Class> {
-  dec::init(d, 0, new typ::Interface::•(d.[](20)));
-  dec::init(d, 1, new typ::Interface::•(d.[](20)));
-  dec::init(d, 2, new typ::Interface::•(d.[](20)));
-  dec::init(d, 3, new typ::Interface::•(d.[](20)));
-  dec::init(d, 4, new typ::Interface::•(d.[](3), <dynamic>[d.[](4).variables.[](0)]));
-  dec::init(d, 5, new typ::Interface::•(d.[](3), <dynamic>[new typ::Interface::•(d.[](1))]));
-  dec::init(d, 6, new typ::Interface::•(d.[](4), <dynamic>[new typ::Interface::•(d.[](2), <dynamic>[d.[](6).variables.[](0)])]));
-  dec::init(d, 7, new typ::Interface::•(d.[](20)));
-  dec::init(d, 8, new typ::Interface::•(d.[](20)));
-  dec::init(d, 9, new typ::Interface::•(d.[](20)), <dynamic>[new typ::Interface::•(d.[](22), <dynamic>[new typ::Interface::•(d.[](9))]), new typ::Interface::•(d.[](23))]);
-  dec::init(d, 10, new typ::Interface::•(d.[](24)));
-  dec::init(d, 11, new typ::Interface::•(d.[](24)));
-  dec::init(d, 12, new typ::Interface::•(d.[](20)));
-  dec::init(d, 13, new typ::Interface::•(d.[](25)));
-  dec::init(d, 14, new typ::Interface::•(d.[](25)));
-  dec::init(d, 15, new typ::Interface::•(d.[](25)));
-  dec::init(d, 16, new typ::Interface::•(d.[](25)));
-  dec::init(d, 17, new typ::Interface::•(d.[](20)), <dynamic>[new typ::Interface::•(d.[](26))]);
-  dec::init(d, 18, new typ::Interface::•(d.[](19)));
-  dec::init(d, 19, new typ::Interface::•(d.[](25)));
-  dec::init(d, 20, null);
-  dec::init(d, 22, new typ::Interface::•(d.[](20)));
-  dec::init(d, 23, new typ::Interface::•(d.[](20)));
-  dec::init(d, 24, new typ::Interface::•(d.[](20)), <dynamic>[new typ::Interface::•(d.[](22), <dynamic>[new typ::Interface::•(d.[](24))])]);
-  dec::init(d, 25, new typ::Interface::•(d.[](20)));
-  dec::init(d, 26, new typ::Interface::•(d.[](20)));
-  return d;
-}.call(dec::allocateDeclarations(<dynamic>["X", "Y", "R", "A", "B", "C", "D", "Null", "bool", "String", "int", "double", "Type", "AbstractClassInstantiationError", "NoSuchMethodError", "CyclicInitializationError", "UnsupportedError", "IntegerDivisionByZeroException", "RangeError", "ArgumentError", "Object", "HasRuntimeTypeGetter", "Comparable", "Pattern", "num", "Error", "Exception"], <dynamic>[0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0]));
-static method main() → dynamic {
-  tes::expectTrue(let dynamic #t1 = new self::A::•(new typ::Interface::•(self::$declarations.[](3), <dynamic>[new typ::Interface::•(self::$declarations.[](0))])).{self::A::foo}() in #t1 is int::HasRuntimeTypeGetter && #t1.$is$R && (let dynamic #t2 = new typ::Interface::•(self::$declarations.[](2), <dynamic>[new typ::Interface::•(self::$declarations.[](0))]) in typ::isSubtypeOf(#t1.$type, #t2)));
-  tes::expectTrue(let dynamic #t3 = new self::B::•(new typ::Interface::•(self::$declarations.[](4), <dynamic>[new typ::Interface::•(self::$declarations.[](0))])).{self::A::foo}() in #t3 is int::HasRuntimeTypeGetter && #t3.$is$R && (let dynamic #t4 = new typ::Interface::•(self::$declarations.[](2), <dynamic>[new typ::Interface::•(self::$declarations.[](0))]) in typ::isSubtypeOf(#t3.$type, #t4)));
-  tes::expectTrue(let dynamic #t5 = new self::C::•(new typ::Interface::•(self::$declarations.[](5), <dynamic>[new typ::Interface::•(self::$declarations.[](0))])).{self::A::foo}() in #t5 is int::HasRuntimeTypeGetter && #t5.$is$R && (let dynamic #t6 = new typ::Interface::•(self::$declarations.[](2), <dynamic>[new typ::Interface::•(self::$declarations.[](1))]) in typ::isSubtypeOf(#t5.$type, #t6)));
-  tes::expectTrue(let dynamic #t7 = new self::D::•(new typ::Interface::•(self::$declarations.[](6), <dynamic>[new typ::Interface::•(self::$declarations.[](0))])).{self::A::foo}() in #t7 is int::HasRuntimeTypeGetter && #t7.$is$R && (let dynamic #t8 = new typ::Interface::•(self::$declarations.[](2), <dynamic>[new typ::Interface::•(self::$declarations.[](2), <dynamic>[new typ::Interface::•(self::$declarations.[](0))])]) in typ::isSubtypeOf(#t7.$type, #t8)));
-  tes::expectTrue(!(let dynamic #t9 = new self::A::•(new typ::Interface::•(self::$declarations.[](3), <dynamic>[new typ::Interface::•(self::$declarations.[](0))])).{self::A::foo}() in #t9 is int::HasRuntimeTypeGetter && #t9.$is$R && (let dynamic #t10 = new typ::Interface::•(self::$declarations.[](2), <dynamic>[new typ::Interface::•(self::$declarations.[](1))]) in typ::isSubtypeOf(#t9.$type, #t10))));
-  tes::expectTrue(!(let dynamic #t11 = new self::B::•(new typ::Interface::•(self::$declarations.[](4), <dynamic>[new typ::Interface::•(self::$declarations.[](0))])).{self::A::foo}() in #t11 is int::HasRuntimeTypeGetter && #t11.$is$R && (let dynamic #t12 = new typ::Interface::•(self::$declarations.[](2), <dynamic>[new typ::Interface::•(self::$declarations.[](1))]) in typ::isSubtypeOf(#t11.$type, #t12))));
-  tes::expectTrue(!(let dynamic #t13 = new self::C::•(new typ::Interface::•(self::$declarations.[](5), <dynamic>[new typ::Interface::•(self::$declarations.[](0))])).{self::A::foo}() in #t13 is int::HasRuntimeTypeGetter && #t13.$is$R && (let dynamic #t14 = new typ::Interface::•(self::$declarations.[](2), <dynamic>[new typ::Interface::•(self::$declarations.[](0))]) in typ::isSubtypeOf(#t13.$type, #t14))));
-  tes::expectTrue(!(let dynamic #t15 = new self::D::•(new typ::Interface::•(self::$declarations.[](6), <dynamic>[new typ::Interface::•(self::$declarations.[](0))])).{self::A::foo}() in #t15 is int::HasRuntimeTypeGetter && #t15.$is$R && (let dynamic #t16 = new typ::Interface::•(self::$declarations.[](2), <dynamic>[new typ::Interface::•(self::$declarations.[](2), <dynamic>[new typ::Interface::•(self::$declarations.[](1))])]) in typ::isSubtypeOf(#t15.$type, #t16))));
-}
diff --git a/pkg/kernel/testcases/reify/super1_test.dart b/pkg/kernel/testcases/reify/super1_test.dart
deleted file mode 100644
index bd007ff..0000000
--- a/pkg/kernel/testcases/reify/super1_test.dart
+++ /dev/null
@@ -1,18 +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 super1_test;
-
-import 'test_base.dart';
-
-class A<T> {}
-
-class B<T> extends A<T> {
-  int i;
-  B(this.i) : super();
-
-  B.redirect() : this(42);
-}
-
-main() {}
diff --git a/pkg/kernel/testcases/reify/super1_test.dart.expect b/pkg/kernel/testcases/reify/super1_test.dart.expect
deleted file mode 100644
index 3879cd4..0000000
--- a/pkg/kernel/testcases/reify/super1_test.dart.expect
+++ /dev/null
@@ -1,55 +0,0 @@
-library super1_test;
-import self as self;
-import "dart:core" as core;
-import "../../runtime/reify/interceptors.dart" as int;
-import "../../runtime/reify/types.dart" as typ;
-import "dart:mock" as mock;
-import "../../runtime/reify/declarations.dart" as dec;
-
-class A extends core::Object implements int::HasRuntimeTypeGetter {
-  final field typ::ReifiedType $type;
-  constructor •(typ::ReifiedType $type) → void
-    : self::A::$type = $type, super core::Object::•()
-    ;
-  get $A$T() → typ::ReifiedType
-    return typ::getTypeArguments(typ::asInstanceOf(this.$type, self::$declarations.[](0))).[](0);
-  get runtimeType() → core::Type
-    return this.{=self::A::$type};
-}
-class B extends self::A implements int::HasRuntimeTypeGetter {
-  field core::int i;
-  constructor •(typ::ReifiedType $type, core::int i) → void
-    : self::B::i = let final mock::Context #context = int::attachType(new mock::Context::•(1), new typ::Interface::•(self::$declarations.[](2))) in let dynamic #t1 = #context.[]=(0, i) in #context.[](0), super self::A::•($type)
-    ;
-  constructor redirect(typ::ReifiedType $type) → void
-    : this self::B::•($type, 42)
-    ;
-  get $B$T() → typ::ReifiedType
-    return typ::getTypeArguments(typ::asInstanceOf(this.$type, self::$declarations.[](1))).[](0);
-}
-static final field core::List<dec::Class> $declarations = (core::List<dec::Class> d) → core::List<dec::Class> {
-  dec::init(d, 0, new typ::Interface::•(d.[](16)));
-  dec::init(d, 1, new typ::Interface::•(d.[](0), <dynamic>[d.[](1).variables.[](0)]));
-  dec::init(d, 2, new typ::Interface::•(d.[](16)));
-  dec::init(d, 3, new typ::Interface::•(d.[](16)));
-  dec::init(d, 4, new typ::Interface::•(d.[](16)));
-  dec::init(d, 5, new typ::Interface::•(d.[](16)), <dynamic>[new typ::Interface::•(d.[](18), <dynamic>[new typ::Interface::•(d.[](5))]), new typ::Interface::•(d.[](19))]);
-  dec::init(d, 6, new typ::Interface::•(d.[](20)));
-  dec::init(d, 7, new typ::Interface::•(d.[](20)));
-  dec::init(d, 8, new typ::Interface::•(d.[](16)));
-  dec::init(d, 9, new typ::Interface::•(d.[](21)));
-  dec::init(d, 10, new typ::Interface::•(d.[](21)));
-  dec::init(d, 11, new typ::Interface::•(d.[](21)));
-  dec::init(d, 12, new typ::Interface::•(d.[](21)));
-  dec::init(d, 13, new typ::Interface::•(d.[](16)), <dynamic>[new typ::Interface::•(d.[](22))]);
-  dec::init(d, 14, new typ::Interface::•(d.[](15)));
-  dec::init(d, 15, new typ::Interface::•(d.[](21)));
-  dec::init(d, 16, null);
-  dec::init(d, 18, new typ::Interface::•(d.[](16)));
-  dec::init(d, 19, new typ::Interface::•(d.[](16)));
-  dec::init(d, 20, new typ::Interface::•(d.[](16)), <dynamic>[new typ::Interface::•(d.[](18), <dynamic>[new typ::Interface::•(d.[](20))])]);
-  dec::init(d, 21, new typ::Interface::•(d.[](16)));
-  dec::init(d, 22, new typ::Interface::•(d.[](16)));
-  return d;
-}.call(dec::allocateDeclarations(<dynamic>["A", "B", "Context", "Null", "bool", "String", "int", "double", "Type", "AbstractClassInstantiationError", "NoSuchMethodError", "CyclicInitializationError", "UnsupportedError", "IntegerDivisionByZeroException", "RangeError", "ArgumentError", "Object", "HasRuntimeTypeGetter", "Comparable", "Pattern", "num", "Error", "Exception"], <dynamic>[1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0]));
-static method main() → dynamic {}
diff --git a/pkg/kernel/testcases/reify/super2_test.dart b/pkg/kernel/testcases/reify/super2_test.dart
deleted file mode 100644
index 0707d4a..0000000
--- a/pkg/kernel/testcases/reify/super2_test.dart
+++ /dev/null
@@ -1,15 +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 super2_test;
-
-import 'test_base.dart';
-
-class X {}
-
-class A<T> {}
-
-class B extends A<X> {}
-
-main() {}
diff --git a/pkg/kernel/testcases/reify/super2_test.dart.expect b/pkg/kernel/testcases/reify/super2_test.dart.expect
deleted file mode 100644
index eb95978..0000000
--- a/pkg/kernel/testcases/reify/super2_test.dart.expect
+++ /dev/null
@@ -1,57 +0,0 @@
-library super2_test;
-import self as self;
-import "dart:core" as core;
-import "../../runtime/reify/interceptors.dart" as int;
-import "../../runtime/reify/types.dart" as typ;
-import "../../runtime/reify/declarations.dart" as dec;
-
-class X extends core::Object implements int::HasRuntimeTypeGetter {
-  constructor •() → void
-    : super core::Object::•()
-    ;
-  get $type() → typ::ReifiedType
-    return new typ::Interface::•(self::$declarations.[](0));
-}
-class A extends core::Object implements int::HasRuntimeTypeGetter {
-  final field typ::ReifiedType $type;
-  constructor •(typ::ReifiedType $type) → void
-    : self::A::$type = $type, super core::Object::•()
-    ;
-  get $A$T() → typ::ReifiedType
-    return typ::getTypeArguments(typ::asInstanceOf(this.$type, self::$declarations.[](1))).[](0);
-  get runtimeType() → core::Type
-    return this.{=self::A::$type};
-}
-class B extends self::A implements int::HasRuntimeTypeGetter {
-  constructor •() → void
-    : super self::A::•(null)
-    ;
-  get $type() → typ::ReifiedType
-    return new typ::Interface::•(self::$declarations.[](2));
-}
-static final field core::List<dec::Class> $declarations = (core::List<dec::Class> d) → core::List<dec::Class> {
-  dec::init(d, 0, new typ::Interface::•(d.[](16)));
-  dec::init(d, 1, new typ::Interface::•(d.[](16)));
-  dec::init(d, 2, new typ::Interface::•(d.[](1), <dynamic>[new typ::Interface::•(d.[](0))]));
-  dec::init(d, 3, new typ::Interface::•(d.[](16)));
-  dec::init(d, 4, new typ::Interface::•(d.[](16)));
-  dec::init(d, 5, new typ::Interface::•(d.[](16)), <dynamic>[new typ::Interface::•(d.[](18), <dynamic>[new typ::Interface::•(d.[](5))]), new typ::Interface::•(d.[](19))]);
-  dec::init(d, 6, new typ::Interface::•(d.[](20)));
-  dec::init(d, 7, new typ::Interface::•(d.[](20)));
-  dec::init(d, 8, new typ::Interface::•(d.[](16)));
-  dec::init(d, 9, new typ::Interface::•(d.[](21)));
-  dec::init(d, 10, new typ::Interface::•(d.[](21)));
-  dec::init(d, 11, new typ::Interface::•(d.[](21)));
-  dec::init(d, 12, new typ::Interface::•(d.[](21)));
-  dec::init(d, 13, new typ::Interface::•(d.[](16)), <dynamic>[new typ::Interface::•(d.[](22))]);
-  dec::init(d, 14, new typ::Interface::•(d.[](15)));
-  dec::init(d, 15, new typ::Interface::•(d.[](21)));
-  dec::init(d, 16, null);
-  dec::init(d, 18, new typ::Interface::•(d.[](16)));
-  dec::init(d, 19, new typ::Interface::•(d.[](16)));
-  dec::init(d, 20, new typ::Interface::•(d.[](16)), <dynamic>[new typ::Interface::•(d.[](18), <dynamic>[new typ::Interface::•(d.[](20))])]);
-  dec::init(d, 21, new typ::Interface::•(d.[](16)));
-  dec::init(d, 22, new typ::Interface::•(d.[](16)));
-  return d;
-}.call(dec::allocateDeclarations(<dynamic>["X", "A", "B", "Null", "bool", "String", "int", "double", "Type", "AbstractClassInstantiationError", "NoSuchMethodError", "CyclicInitializationError", "UnsupportedError", "IntegerDivisionByZeroException", "RangeError", "ArgumentError", "Object", "HasRuntimeTypeGetter", "Comparable", "Pattern", "num", "Error", "Exception"], <dynamic>[0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0]));
-static method main() → dynamic {}
diff --git a/pkg/kernel/testcases/reify/super3_test.dart b/pkg/kernel/testcases/reify/super3_test.dart
deleted file mode 100644
index 4de6a33..0000000
--- a/pkg/kernel/testcases/reify/super3_test.dart
+++ /dev/null
@@ -1,21 +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.md file.
-
-library super3_test;
-
-import 'test_base.dart';
-
-class A<T> {
-  get foo => T;
-}
-
-class B extends A<A> {
-  B();
-  B.redirect() : this();
-}
-
-main() {
-  new B().foo;
-  new B.redirect();
-}
diff --git a/pkg/kernel/testcases/reify/super3_test.dart.expect b/pkg/kernel/testcases/reify/super3_test.dart.expect
deleted file mode 100644
index 6ec46e7..0000000
--- a/pkg/kernel/testcases/reify/super3_test.dart.expect
+++ /dev/null
@@ -1,58 +0,0 @@
-library super3_test;
-import self as self;
-import "dart:core" as core;
-import "../../runtime/reify/interceptors.dart" as int;
-import "../../runtime/reify/types.dart" as typ;
-import "../../runtime/reify/declarations.dart" as dec;
-
-class A extends core::Object implements int::HasRuntimeTypeGetter {
-  final field typ::ReifiedType $type;
-  constructor •(typ::ReifiedType $type) → void
-    : self::A::$type = $type, super core::Object::•()
-    ;
-  get foo() → dynamic {
-    return dynamic;
-  }
-  get $A$T() → typ::ReifiedType
-    return typ::getTypeArguments(typ::asInstanceOf(this.$type, self::$declarations.[](0))).[](0);
-  get runtimeType() → core::Type
-    return this.{=self::A::$type};
-}
-class B extends self::A implements int::HasRuntimeTypeGetter {
-  constructor •() → void
-    : super self::A::•(null)
-    ;
-  constructor redirect() → void
-    : this self::B::•()
-    ;
-  get $type() → typ::ReifiedType
-    return new typ::Interface::•(self::$declarations.[](1));
-}
-static final field core::List<dec::Class> $declarations = (core::List<dec::Class> d) → core::List<dec::Class> {
-  dec::init(d, 0, new typ::Interface::•(d.[](15)));
-  dec::init(d, 1, new typ::Interface::•(d.[](0), <dynamic>[new typ::Interface::•(d.[](0), <dynamic>[const typ::Dynamic::•()])]));
-  dec::init(d, 2, new typ::Interface::•(d.[](15)));
-  dec::init(d, 3, new typ::Interface::•(d.[](15)));
-  dec::init(d, 4, new typ::Interface::•(d.[](15)), <dynamic>[new typ::Interface::•(d.[](17), <dynamic>[new typ::Interface::•(d.[](4))]), new typ::Interface::•(d.[](18))]);
-  dec::init(d, 5, new typ::Interface::•(d.[](19)));
-  dec::init(d, 6, new typ::Interface::•(d.[](19)));
-  dec::init(d, 7, new typ::Interface::•(d.[](15)));
-  dec::init(d, 8, new typ::Interface::•(d.[](20)));
-  dec::init(d, 9, new typ::Interface::•(d.[](20)));
-  dec::init(d, 10, new typ::Interface::•(d.[](20)));
-  dec::init(d, 11, new typ::Interface::•(d.[](20)));
-  dec::init(d, 12, new typ::Interface::•(d.[](15)), <dynamic>[new typ::Interface::•(d.[](21))]);
-  dec::init(d, 13, new typ::Interface::•(d.[](14)));
-  dec::init(d, 14, new typ::Interface::•(d.[](20)));
-  dec::init(d, 15, null);
-  dec::init(d, 17, new typ::Interface::•(d.[](15)));
-  dec::init(d, 18, new typ::Interface::•(d.[](15)));
-  dec::init(d, 19, new typ::Interface::•(d.[](15)), <dynamic>[new typ::Interface::•(d.[](17), <dynamic>[new typ::Interface::•(d.[](19))])]);
-  dec::init(d, 20, new typ::Interface::•(d.[](15)));
-  dec::init(d, 21, new typ::Interface::•(d.[](15)));
-  return d;
-}.call(dec::allocateDeclarations(<dynamic>["A", "B", "Null", "bool", "String", "int", "double", "Type", "AbstractClassInstantiationError", "NoSuchMethodError", "CyclicInitializationError", "UnsupportedError", "IntegerDivisionByZeroException", "RangeError", "ArgumentError", "Object", "HasRuntimeTypeGetter", "Comparable", "Pattern", "num", "Error", "Exception"], <dynamic>[1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0]));
-static method main() → dynamic {
-  new self::B::•().{self::A::foo};
-  new self::B::redirect();
-}
diff --git a/pkg/kernel/testcases/reify/test_base.dart b/pkg/kernel/testcases/reify/test_base.dart
deleted file mode 100644
index 696cb73..0000000
--- a/pkg/kernel/testcases/reify/test_base.dart
+++ /dev/null
@@ -1,40 +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 test_base;
-
-expectIs(expected, actual, [String note]) {
-  if (expected != actual) {
-    if (note != null) {
-      throw "Expected: '$expected': $note, actual: '$actual'";
-    }
-    throw "Expected: '$expected', actual: '$actual'";
-  }
-}
-
-expectTrue(actual) => expectIs(true, actual);
-
-expectFalse(actual) => expectIs(false, actual);
-
-expectThrows(f(), test(e)) {
-  var exception = false;
-  String note = null;
-  try {
-    f();
-  } catch (e) {
-    exception = test(e);
-    if (!exception) {
-      note = "$e [${e.runtimeType}]";
-    }
-  }
-  expectIs(true, exception, note);
-}
-
-expectOutput(String expected) => expectIs(expected, output);
-
-String output;
-
-write(o) {
-  output = output == null ? "$o" : "$output\n$o";
-}
diff --git a/pkg/kernel/testcases/reify/typevariable1_test.dart b/pkg/kernel/testcases/reify/typevariable1_test.dart
deleted file mode 100644
index 306a076..0000000
--- a/pkg/kernel/testcases/reify/typevariable1_test.dart
+++ /dev/null
@@ -1,21 +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 typevariable1_test;
-
-import 'test_base.dart';
-
-class Z {
-  get succ => new N<Z>();
-}
-
-class N<T> {
-  get succ => new N<N<T>>();
-  get pred => T;
-}
-
-main() {
-  var one = new Z().succ;
-  var two = one.succ;
-}
diff --git a/pkg/kernel/testcases/reify/typevariable1_test.dart.expect b/pkg/kernel/testcases/reify/typevariable1_test.dart.expect
deleted file mode 100644
index d6856ba..0000000
--- a/pkg/kernel/testcases/reify/typevariable1_test.dart.expect
+++ /dev/null
@@ -1,61 +0,0 @@
-library typevariable1_test;
-import self as self;
-import "dart:core" as core;
-import "../../runtime/reify/interceptors.dart" as int;
-import "../../runtime/reify/types.dart" as typ;
-import "../../runtime/reify/declarations.dart" as dec;
-
-class Z extends core::Object implements int::HasRuntimeTypeGetter {
-  constructor •() → void
-    : super core::Object::•()
-    ;
-  get succ() → dynamic {
-    return new self::N::•(new typ::Interface::•(self::$declarations.[](1), <dynamic>[new typ::Interface::•(self::$declarations.[](0))]));
-  }
-  get $type() → typ::ReifiedType
-    return new typ::Interface::•(self::$declarations.[](0));
-}
-class N extends core::Object implements int::HasRuntimeTypeGetter {
-  final field typ::ReifiedType $type;
-  constructor •(typ::ReifiedType $type) → void
-    : self::N::$type = $type, super core::Object::•()
-    ;
-  get succ() → dynamic {
-    return new self::N::•(new typ::Interface::•(self::$declarations.[](1), <dynamic>[new typ::Interface::•(self::$declarations.[](1), typ::getTypeArguments(typ::asInstanceOf(this.$type, self::$declarations.[](1))))]));
-  }
-  get pred() → dynamic {
-    return dynamic;
-  }
-  get $N$T() → typ::ReifiedType
-    return typ::getTypeArguments(typ::asInstanceOf(this.$type, self::$declarations.[](1))).[](0);
-  get runtimeType() → core::Type
-    return this.{=self::N::$type};
-}
-static final field core::List<dec::Class> $declarations = (core::List<dec::Class> d) → core::List<dec::Class> {
-  dec::init(d, 0, new typ::Interface::•(d.[](15)));
-  dec::init(d, 1, new typ::Interface::•(d.[](15)));
-  dec::init(d, 2, new typ::Interface::•(d.[](15)));
-  dec::init(d, 3, new typ::Interface::•(d.[](15)));
-  dec::init(d, 4, new typ::Interface::•(d.[](15)), <dynamic>[new typ::Interface::•(d.[](17), <dynamic>[new typ::Interface::•(d.[](4))]), new typ::Interface::•(d.[](18))]);
-  dec::init(d, 5, new typ::Interface::•(d.[](19)));
-  dec::init(d, 6, new typ::Interface::•(d.[](19)));
-  dec::init(d, 7, new typ::Interface::•(d.[](15)));
-  dec::init(d, 8, new typ::Interface::•(d.[](20)));
-  dec::init(d, 9, new typ::Interface::•(d.[](20)));
-  dec::init(d, 10, new typ::Interface::•(d.[](20)));
-  dec::init(d, 11, new typ::Interface::•(d.[](20)));
-  dec::init(d, 12, new typ::Interface::•(d.[](15)), <dynamic>[new typ::Interface::•(d.[](21))]);
-  dec::init(d, 13, new typ::Interface::•(d.[](14)));
-  dec::init(d, 14, new typ::Interface::•(d.[](20)));
-  dec::init(d, 15, null);
-  dec::init(d, 17, new typ::Interface::•(d.[](15)));
-  dec::init(d, 18, new typ::Interface::•(d.[](15)));
-  dec::init(d, 19, new typ::Interface::•(d.[](15)), <dynamic>[new typ::Interface::•(d.[](17), <dynamic>[new typ::Interface::•(d.[](19))])]);
-  dec::init(d, 20, new typ::Interface::•(d.[](15)));
-  dec::init(d, 21, new typ::Interface::•(d.[](15)));
-  return d;
-}.call(dec::allocateDeclarations(<dynamic>["Z", "N", "Null", "bool", "String", "int", "double", "Type", "AbstractClassInstantiationError", "NoSuchMethodError", "CyclicInitializationError", "UnsupportedError", "IntegerDivisionByZeroException", "RangeError", "ArgumentError", "Object", "HasRuntimeTypeGetter", "Comparable", "Pattern", "num", "Error", "Exception"], <dynamic>[0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0]));
-static method main() → dynamic {
-  dynamic one = new self::Z::•().{self::Z::succ};
-  dynamic two = one.succ;
-}
diff --git a/pkg/kernel/testcases/reify/typevariable2_test.dart b/pkg/kernel/testcases/reify/typevariable2_test.dart
deleted file mode 100644
index 1b4a0cd..0000000
--- a/pkg/kernel/testcases/reify/typevariable2_test.dart
+++ /dev/null
@@ -1,14 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library typevariable2_test;
-
-import 'test_base.dart';
-
-class C<T> {
-  bool test(o) => o is T;
-  Type get t => T;
-}
-
-main() {}
diff --git a/pkg/kernel/testcases/reify/typevariable2_test.dart.expect b/pkg/kernel/testcases/reify/typevariable2_test.dart.expect
deleted file mode 100644
index d6a878f..0000000
--- a/pkg/kernel/testcases/reify/typevariable2_test.dart.expect
+++ /dev/null
@@ -1,65 +0,0 @@
-library typevariable2_test;
-import self as self;
-import "dart:core" as core;
-import "../../runtime/reify/interceptors.dart" as int;
-import "../../runtime/reify/types.dart" as typ;
-import "../../runtime/reify/declarations.dart" as dec;
-
-class C extends core::Object implements int::HasRuntimeTypeGetter {
-  final field typ::ReifiedType $type;
-  constructor •(typ::ReifiedType $type) → void
-    : self::C::$type = $type, super core::Object::•()
-    ;
-  method test(dynamic o) → core::bool {
-    return typ::isSubtypeOf(int::type(o), this.$C$T);
-  }
-  get t() → core::Type {
-    return dynamic;
-  }
-  get test#get() → dynamic
-    return new self::Closure#C#test::•(new typ::Interface::•(self::$declarations.[](1), typ::getTypeArguments(typ::asInstanceOf(this.$type, self::$declarations.[](0)))), this);
-  get $C$T() → typ::ReifiedType
-    return typ::getTypeArguments(typ::asInstanceOf(this.$type, self::$declarations.[](0))).[](0);
-  get runtimeType() → core::Type
-    return this.{=self::C::$type};
-}
-class Closure#C#test extends core::Object implements core::Function, int::HasRuntimeTypeGetter {
-  field core::String note = "This is temporary. The VM doesn't need closure classes.";
-  field self::C self;
-  final field typ::ReifiedType $type;
-  constructor •(typ::ReifiedType $type, final self::C self) → dynamic
-    : self::Closure#C#test::$type = $type, self::Closure#C#test::self = self
-    ;
-  method call(dynamic o) → core::bool
-    return this.{self::Closure#C#test::self}.{self::C::test}(o);
-  get $Closure#C#test$T() → typ::ReifiedType
-    return typ::getTypeArguments(typ::asInstanceOf(this.$type, self::$declarations.[](1))).[](0);
-  get runtimeType() → core::Type
-    return this.{=self::Closure#C#test::$type};
-}
-static final field core::List<dec::Class> $declarations = (core::List<dec::Class> d) → core::List<dec::Class> {
-  dec::init(d, 0, new typ::Interface::•(d.[](15)));
-  dec::init(d, 1, new typ::Interface::•(d.[](15)), <dynamic>[new typ::Interface::•(d.[](17))], new typ::FunctionType::•(new typ::Interface::•(d.[](17)), new typ::Interface::•(d.[](3)), 0, <dynamic>[const typ::Dynamic::•()]));
-  dec::init(d, 2, new typ::Interface::•(d.[](15)));
-  dec::init(d, 3, new typ::Interface::•(d.[](15)));
-  dec::init(d, 4, new typ::Interface::•(d.[](15)), <dynamic>[new typ::Interface::•(d.[](18), <dynamic>[new typ::Interface::•(d.[](4))]), new typ::Interface::•(d.[](19))]);
-  dec::init(d, 5, new typ::Interface::•(d.[](20)));
-  dec::init(d, 6, new typ::Interface::•(d.[](20)));
-  dec::init(d, 7, new typ::Interface::•(d.[](15)));
-  dec::init(d, 8, new typ::Interface::•(d.[](21)));
-  dec::init(d, 9, new typ::Interface::•(d.[](21)));
-  dec::init(d, 10, new typ::Interface::•(d.[](21)));
-  dec::init(d, 11, new typ::Interface::•(d.[](21)));
-  dec::init(d, 12, new typ::Interface::•(d.[](15)), <dynamic>[new typ::Interface::•(d.[](22))]);
-  dec::init(d, 13, new typ::Interface::•(d.[](14)));
-  dec::init(d, 14, new typ::Interface::•(d.[](21)));
-  dec::init(d, 15, null);
-  dec::init(d, 17, new typ::Interface::•(d.[](15)));
-  dec::init(d, 18, new typ::Interface::•(d.[](15)));
-  dec::init(d, 19, new typ::Interface::•(d.[](15)));
-  dec::init(d, 20, new typ::Interface::•(d.[](15)), <dynamic>[new typ::Interface::•(d.[](18), <dynamic>[new typ::Interface::•(d.[](20))])]);
-  dec::init(d, 21, new typ::Interface::•(d.[](15)));
-  dec::init(d, 22, new typ::Interface::•(d.[](15)));
-  return d;
-}.call(dec::allocateDeclarations(<dynamic>["C", "Closure#C#test", "Null", "bool", "String", "int", "double", "Type", "AbstractClassInstantiationError", "NoSuchMethodError", "CyclicInitializationError", "UnsupportedError", "IntegerDivisionByZeroException", "RangeError", "ArgumentError", "Object", "HasRuntimeTypeGetter", "Function", "Comparable", "Pattern", "num", "Error", "Exception"], <dynamic>[1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0]));
-static method main() → dynamic {}
diff --git a/pkg/kernel/testcases/reify/typevariable3_test.dart b/pkg/kernel/testcases/reify/typevariable3_test.dart
deleted file mode 100644
index f7ecef8..0000000
--- a/pkg/kernel/testcases/reify/typevariable3_test.dart
+++ /dev/null
@@ -1,18 +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 typevariable3_test;
-
-import 'test_base.dart';
-
-class C<T> {
-  T foo(T t) {
-    T temp = t;
-    return temp;
-  }
-}
-
-main() {
-  C c = new C<C>().foo(new C());
-}
diff --git a/pkg/kernel/testcases/reify/typevariable3_test.dart.expect b/pkg/kernel/testcases/reify/typevariable3_test.dart.expect
deleted file mode 100644
index a6f8ff2..0000000
--- a/pkg/kernel/testcases/reify/typevariable3_test.dart.expect
+++ /dev/null
@@ -1,50 +0,0 @@
-library typevariable3_test;
-import self as self;
-import "dart:core" as core;
-import "../../runtime/reify/interceptors.dart" as int;
-import "../../runtime/reify/types.dart" as typ;
-import "../../runtime/reify/declarations.dart" as dec;
-
-class C extends core::Object implements int::HasRuntimeTypeGetter {
-  final field typ::ReifiedType $type;
-  constructor •(typ::ReifiedType $type) → void
-    : self::C::$type = $type, super core::Object::•()
-    ;
-  method foo(dynamic t) → dynamic {
-    dynamic temp = t;
-    return temp;
-  }
-  method foo$cc(core::Object t) → dynamic {
-    return this.{=self::C::foo}(t as dynamic);
-  }
-  get $C$T() → typ::ReifiedType
-    return typ::getTypeArguments(typ::asInstanceOf(this.$type, self::$declarations.[](0))).[](0);
-  get runtimeType() → core::Type
-    return this.{=self::C::$type};
-}
-static final field core::List<dec::Class> $declarations = (core::List<dec::Class> d) → core::List<dec::Class> {
-  dec::init(d, 0, new typ::Interface::•(d.[](14)));
-  dec::init(d, 1, new typ::Interface::•(d.[](14)));
-  dec::init(d, 2, new typ::Interface::•(d.[](14)));
-  dec::init(d, 3, new typ::Interface::•(d.[](14)), <dynamic>[new typ::Interface::•(d.[](16), <dynamic>[new typ::Interface::•(d.[](3))]), new typ::Interface::•(d.[](17))]);
-  dec::init(d, 4, new typ::Interface::•(d.[](18)));
-  dec::init(d, 5, new typ::Interface::•(d.[](18)));
-  dec::init(d, 6, new typ::Interface::•(d.[](14)));
-  dec::init(d, 7, new typ::Interface::•(d.[](19)));
-  dec::init(d, 8, new typ::Interface::•(d.[](19)));
-  dec::init(d, 9, new typ::Interface::•(d.[](19)));
-  dec::init(d, 10, new typ::Interface::•(d.[](19)));
-  dec::init(d, 11, new typ::Interface::•(d.[](14)), <dynamic>[new typ::Interface::•(d.[](20))]);
-  dec::init(d, 12, new typ::Interface::•(d.[](13)));
-  dec::init(d, 13, new typ::Interface::•(d.[](19)));
-  dec::init(d, 14, null);
-  dec::init(d, 16, new typ::Interface::•(d.[](14)));
-  dec::init(d, 17, new typ::Interface::•(d.[](14)));
-  dec::init(d, 18, new typ::Interface::•(d.[](14)), <dynamic>[new typ::Interface::•(d.[](16), <dynamic>[new typ::Interface::•(d.[](18))])]);
-  dec::init(d, 19, new typ::Interface::•(d.[](14)));
-  dec::init(d, 20, new typ::Interface::•(d.[](14)));
-  return d;
-}.call(dec::allocateDeclarations(<dynamic>["C", "Null", "bool", "String", "int", "double", "Type", "AbstractClassInstantiationError", "NoSuchMethodError", "CyclicInitializationError", "UnsupportedError", "IntegerDivisionByZeroException", "RangeError", "ArgumentError", "Object", "HasRuntimeTypeGetter", "Comparable", "Pattern", "num", "Error", "Exception"], <dynamic>[1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0]));
-static method main() → dynamic {
-  self::C c = new self::C::•(new typ::Interface::•(self::$declarations.[](0), <dynamic>[new typ::Interface::•(self::$declarations.[](0), <dynamic>[const typ::Dynamic::•()])])).{self::C::foo}(new self::C::•(new typ::Interface::•(self::$declarations.[](0), <dynamic>[const typ::Dynamic::•()])));
-}
diff --git a/pkg/pkg.status b/pkg/pkg.status
index 7b88bf2..a6d778d 100644
--- a/pkg/pkg.status
+++ b/pkg/pkg.status
@@ -169,10 +169,6 @@
 front_end/test/incremental_dart2js_load_from_dill_test: StaticWarning
 front_end/test/incremental_load_from_dill_test: StaticWarning
 
-# Don't analyze tests in strong mode yet
-[ $compiler == dart2analyzer && $strong ]
-*: Skip # Issue 28649
-
 # Analyze dev_compiler but only run its tests on the vm
 [ $compiler != dart2analyzer && $runtime != vm ]
 dev_compiler/test/*: Skip
diff --git a/pkg/sourcemap_testing/lib/src/stacktrace_helper.dart b/pkg/sourcemap_testing/lib/src/stacktrace_helper.dart
index e37478c..f7e3357 100644
--- a/pkg/sourcemap_testing/lib/src/stacktrace_helper.dart
+++ b/pkg/sourcemap_testing/lib/src/stacktrace_helper.dart
@@ -285,14 +285,12 @@
     String fileName;
     int lastColon = text.lastIndexOf(':');
     if (lastColon != -1) {
-      int lastValue =
-          int.parse(text.substring(lastColon + 1), onError: (_) => null);
+      int lastValue = int.tryParse(text.substring(lastColon + 1));
       if (lastValue != null) {
         int secondToLastColon = text.lastIndexOf(':', lastColon - 1);
         if (secondToLastColon != -1) {
-          int secondToLastValue = int.parse(
-              text.substring(secondToLastColon + 1, lastColon),
-              onError: (_) => null);
+          int secondToLastValue =
+              int.tryParse(text.substring(secondToLastColon + 1, lastColon));
           if (secondToLastValue != null) {
             lineNo = secondToLastValue;
             columnNo = lastValue;
diff --git a/pkg/status_file/test/data/vm.status b/pkg/status_file/test/data/vm.status
index e446356..726d64e 100644
--- a/pkg/status_file/test/data/vm.status
+++ b/pkg/status_file/test/data/vm.status
@@ -217,6 +217,7 @@
 cc/IsolateReload_KernelIncrementalCompile: Skip
 cc/IsolateReload_KernelIncrementalCompileAppAndLib: Skip
 cc/IsolateReload_KernelIncrementalCompileGenerics: Skip
+cc/IsolateReload_KernelIncrementalCompileExpression: Skip
 cc/Mixin_PrivateSuperResolution: Skip
 cc/Mixin_PrivateSuperResolutionCrossLibraryShouldFail: Skip
 
diff --git a/pkg/vm/bin/gen_kernel.dart b/pkg/vm/bin/gen_kernel.dart
index 0a2e4a2..16212bf 100644
--- a/pkg/vm/bin/gen_kernel.dart
+++ b/pkg/vm/bin/gen_kernel.dart
@@ -8,14 +8,14 @@
 import 'package:args/args.dart' show ArgParser, ArgResults;
 import 'package:front_end/src/api_prototype/front_end.dart';
 import 'package:kernel/binary/ast_to_binary.dart';
-import 'package:kernel/kernel.dart' show Component;
 import 'package:kernel/src/tool/batch_util.dart' as batch_util;
 import 'package:kernel/target/targets.dart' show TargetFlags;
 import 'package:kernel/target/vm.dart' show VmTarget;
 import 'package:kernel/text/ast_to_text.dart'
     show globalDebuggingNames, NameSystem;
 import 'package:vm/bytecode/gen_bytecode.dart' show isKernelBytecodeEnabled;
-import 'package:vm/kernel_front_end.dart' show compileToKernel, ErrorDetector;
+import 'package:vm/kernel_front_end.dart'
+    show compileToKernel, ErrorDetector, ErrorPrinter;
 
 final ArgParser _argParser = new ArgParser(allowTrailingOptions: true)
   ..addOption('platform',
@@ -36,10 +36,20 @@
       help:
           'Enable global type flow analysis and related transformations in AOT mode.',
       defaultsTo: true)
+  ..addMultiOption('define',
+      abbr: 'D',
+      help: 'The values for the environment constants (e.g. -Dkey=value).')
+  ..addFlag('enable-asserts',
+      help: 'Whether asserts will be enabled.', defaultsTo: false)
+  ..addFlag('enable-constant-evaluation',
+      help: 'Whether kernel constant evaluation will be enabled.',
+      defaultsTo: true)
   ..addMultiOption('entry-points',
       help: 'Path to JSON file with the list of entry points')
   ..addFlag('gen-bytecode',
-      help: 'Generate bytecode', defaultsTo: isKernelBytecodeEnabled);
+      help: 'Generate bytecode', defaultsTo: isKernelBytecodeEnabled)
+  ..addFlag('drop-ast',
+      help: 'Drop AST for members with bytecode', defaultsTo: false);
 
 final String _usage = '''
 Usage: dart pkg/vm/bin/gen_kernel.dart --platform vm_platform_strong.dill [options] input.dart
@@ -77,6 +87,14 @@
   final bool syncAsync = options['sync-async'];
   final bool tfa = options['tfa'];
   final bool genBytecode = options['gen-bytecode'];
+  final bool dropAST = options['drop-ast'];
+  final bool enableAsserts = options['enable-asserts'];
+  final bool enableConstantEvaluation = options['enable-constant-evaluation'];
+  final Map<String, String> environmentDefines = {};
+
+  if (!_parseDefines(options['define'], environmentDefines)) {
+    return _badUsageExitCode;
+  }
 
   final List<String> entryPoints = options['entry-points'] ?? <String>[];
   if (entryPoints.isEmpty) {
@@ -87,7 +105,8 @@
     ]);
   }
 
-  ErrorDetector errorDetector = new ErrorDetector();
+  final errorPrinter = new ErrorPrinter();
+  final errorDetector = new ErrorDetector(previousErrorHandler: errorPrinter);
 
   final CompilerOptions compilerOptions = new CompilerOptions()
     ..strongMode = strongMode
@@ -99,15 +118,22 @@
     ..packagesFileUri =
         packages != null ? Uri.base.resolveUri(new Uri.file(packages)) : null
     ..reportMessages = true
-    ..onError = errorDetector
+    ..onProblem = errorDetector
     ..embedSourceText = options['embed-sources'];
 
-  Component component = await compileToKernel(
-      Uri.base.resolveUri(new Uri.file(filename)), compilerOptions,
+  final inputUri = new Uri.file(filename);
+  final component = await compileToKernel(
+      Uri.base.resolveUri(inputUri), compilerOptions,
       aot: aot,
       useGlobalTypeFlowAnalysis: tfa,
       entryPoints: entryPoints,
-      genBytecode: genBytecode);
+      environmentDefines: environmentDefines,
+      genBytecode: genBytecode,
+      dropAST: dropAST,
+      enableAsserts: enableAsserts,
+      enableConstantEvaluation: enableConstantEvaluation);
+
+  errorPrinter.printCompilationMessages(inputUri);
 
   if (errorDetector.hasCompilationErrors || (component == null)) {
     return _compileTimeErrorExitCode;
@@ -152,3 +178,22 @@
     }
   });
 }
+
+bool _parseDefines(
+    List<String> dFlags, Map<String, String> environmentDefines) {
+  for (final String dflag in dFlags) {
+    final equalsSignIndex = dflag.indexOf('=');
+    if (equalsSignIndex < 0) {
+      environmentDefines[dflag] = '';
+    } else if (equalsSignIndex > 0) {
+      final key = dflag.substring(0, equalsSignIndex);
+      final value = dflag.substring(equalsSignIndex + 1);
+      environmentDefines[key] = value;
+    } else {
+      print('The environment constant options must have a key (was: "$dflag")');
+      print(_usage);
+      return false;
+    }
+  }
+  return true;
+}
diff --git a/pkg/vm/bin/kernel_service.dart b/pkg/vm/bin/kernel_service.dart
index 329b554..0590e39 100644
--- a/pkg/vm/bin/kernel_service.dart
+++ b/pkg/vm/bin/kernel_service.dart
@@ -33,7 +33,7 @@
     show computePlatformBinariesLocation;
 import 'package:front_end/src/fasta/kernel/utils.dart';
 import 'package:front_end/src/fasta/hybrid_file_system.dart';
-import 'package:kernel/kernel.dart' show Component;
+import 'package:kernel/kernel.dart' show Component, Procedure;
 import 'package:kernel/target/targets.dart' show TargetFlags;
 import 'package:kernel/target/vm.dart' show VmTarget;
 import 'package:vm/incremental_compiler.dart';
@@ -49,10 +49,15 @@
 //   1 - Update in-memory file system with in-memory sources (used by tests).
 //   2 - Accept last compilation result.
 //   3 - APP JIT snapshot training run for kernel_service.
+//   4 - Compile an individual expression in some context (for debugging
+//       purposes).
 const int kCompileTag = 0;
 const int kUpdateSourcesTag = 1;
 const int kAcceptTag = 2;
 const int kTrainTag = 3;
+const int kCompileExpressionTag = 4;
+
+bool allowDartInternalImport = false;
 
 abstract class Compiler {
   final FileSystem fileSystem;
@@ -177,9 +182,10 @@
   }
 }
 
-final Map<int, Compiler> isolateCompilers = new Map<int, Compiler>();
+final Map<int, IncrementalCompilerWrapper> isolateCompilers =
+    new Map<int, IncrementalCompilerWrapper>();
 
-Compiler lookupIncrementalCompiler(int isolateId) {
+IncrementalCompilerWrapper lookupIncrementalCompiler(int isolateId) {
   return isolateCompilers[isolateId];
 }
 
@@ -242,10 +248,60 @@
 
 // Process a request from the runtime. See KernelIsolate::CompileToKernel in
 // kernel_isolate.cc and Loader::SendKernelRequest in loader.cc.
+Future _processExpressionCompilationRequest(request) async {
+  final SendPort port = request[1];
+  final int isolateId = request[2];
+  final String expression = request[3];
+  final List definitions = request[4];
+  final List typeDefinitions = request[5];
+  final String libraryUri = request[6];
+  final String klass = request[7]; // might be null
+  final bool isStatic = request[8];
+
+  IncrementalCompilerWrapper compiler = isolateCompilers[isolateId];
+
+  if (compiler == null) {
+    port.send(new CompilationResult.errors(
+        ["No incremental compiler available for this isolate."]).toResponse());
+    return;
+  }
+
+  compiler.errors.clear();
+
+  CompilationResult result;
+  try {
+    Procedure procedure = await compiler.generator.compileExpression(
+        expression, definitions, typeDefinitions, libraryUri, klass, isStatic);
+
+    if (procedure == null) {
+      port.send(new CompilationResult.errors(["Invalid scope."]).toResponse());
+      return;
+    }
+
+    if (compiler.errors.isNotEmpty) {
+      // TODO(sigmund): the compiler prints errors to the console, so we
+      // shouldn't print those messages again here.
+      result = new CompilationResult.errors(compiler.errors);
+    } else {
+      result = new CompilationResult.ok(serializeProcedure(procedure));
+    }
+  } catch (error, stack) {
+    result = new CompilationResult.crash(error, stack);
+  }
+
+  port.send(result.toResponse());
+}
+
 Future _processLoadRequest(request) async {
   if (verbose) print("DFE: request: $request");
 
   int tag = request[0];
+
+  if (tag == kCompileExpressionTag) {
+    await _processExpressionCompilationRequest(request);
+    return;
+  }
+
   final SendPort port = request[1];
   final String inputFileUri = request[2];
   final Uri script =
diff --git a/pkg/vm/lib/bytecode/assembler.dart b/pkg/vm/lib/bytecode/assembler.dart
index ac3b157..fdf239e 100644
--- a/pkg/vm/lib/bytecode/assembler.dart
+++ b/pkg/vm/lib/bytecode/assembler.dart
@@ -7,6 +7,7 @@
 import 'dart:typed_data';
 
 import 'package:vm/bytecode/dbc.dart';
+import 'package:vm/bytecode/exceptions.dart' show ExceptionsTable;
 
 class Label {
   List<int> _jumps = <int>[];
@@ -42,6 +43,7 @@
   final List<int> bytecode = new List<int>();
   final Uint32List _encodeBufferIn;
   final Uint8List _encodeBufferOut;
+  final ExceptionsTable exceptionsTable = new ExceptionsTable();
 
   BytecodeAssembler._(this._encodeBufferIn, this._encodeBufferOut);
 
@@ -51,6 +53,7 @@
   }
 
   int get offset => bytecode.length;
+  int get offsetInWords => bytecode.length >> kLog2BytesPerBytecode;
 
   void bind(Label label) {
     final List<int> jumps = label.bind(offset);
@@ -819,8 +822,8 @@
     emitWord(_encode0(Opcode.kCloneContext));
   }
 
-  void emitMoveSpecial(int ra, int rd) {
-    emitWord(_encodeAD(Opcode.kMoveSpecial, ra, rd));
+  void emitMoveSpecial(int ra, SpecialIndex rd) {
+    emitWord(_encodeAD(Opcode.kMoveSpecial, ra, rd.index));
   }
 
   void emitInstantiateType(int rd) {
diff --git a/pkg/vm/lib/bytecode/constant_pool.dart b/pkg/vm/lib/bytecode/constant_pool.dart
index 958c7c6..0b3cb58 100644
--- a/pkg/vm/lib/bytecode/constant_pool.dart
+++ b/pkg/vm/lib/bytecode/constant_pool.dart
@@ -7,6 +7,7 @@
 import 'dart:typed_data';
 
 import 'package:kernel/ast.dart' hide MapEntry;
+import 'package:kernel/text/ast_to_text.dart' show Printer;
 
 /*
 
@@ -95,24 +96,24 @@
 
 type ConstantType extends ConstantPoolEntry {
   Byte tag = 14;
-  NodeReference type;
+  DartType type;
 }
 
 type ConstantTypeArguments extends ConstantPoolEntry {
   Byte tag = 15;
-  List<NodeReference> types;
+  List<DartType> types;
 }
 
 type ConstantList extends ConstantPoolEntry {
   Byte tag = 16;
-  NodeReference typeArg;
+  DartType typeArg;
   List<ConstantIndex> entries;
 }
 
 type ConstantInstance extends ConstantPoolEntry {
   Byte tag = 17;
   CanonicalNameReference class;
-  UInt typeArgumentsConstantIndex;
+  ConstantIndex typeArguments;
   List<Pair<CanonicalNameReference, ConstantIndex>> fieldValues;
 }
 
@@ -127,6 +128,23 @@
   ConstantIndex typeArguments;
 }
 
+type ConstantContextOffset extends ConstantPoolEntry {
+  Byte tag = 20;
+  // 0 = Offset of 'parent' field in Context object.
+  // 1 + i = Offset of i-th variable in Context object.
+  UInt index;
+}
+
+type ConstantClosureFunction extends ConstantPoolEntry {
+  Byte tag = 21;
+  StringReference name;
+  FunctionNode function; // Doesn't have a body.
+}
+
+type ConstantEndClosureFunctionScope extends ConstantPoolEntry {
+  Byte tag = 22;
+}
+
 */
 
 enum ConstantTag {
@@ -150,6 +168,9 @@
   kInstance,
   kSymbol,
   kTypeArgumentsForInstanceAllocation,
+  kContextOffset,
+  kClosureFunction,
+  kEndClosureFunctionScope,
 }
 
 abstract class ConstantPoolEntry {
@@ -208,6 +229,12 @@
       case ConstantTag.kTypeArgumentsForInstanceAllocation:
         return new ConstantTypeArgumentsForInstanceAllocation.readFromBinary(
             source);
+      case ConstantTag.kContextOffset:
+        return new ConstantContextOffset.readFromBinary(source);
+      case ConstantTag.kClosureFunction:
+        return new ConstantClosureFunction.readFromBinary(source);
+      case ConstantTag.kEndClosureFunctionScope:
+        return new ConstantEndClosureFunctionScope.readFromBinary(source);
     }
     throw 'Unexpected constant tag $tag';
   }
@@ -641,11 +668,11 @@
 
   @override
   void writeValueToBinary(BinarySink sink) {
-    sink.writeNodeReference(type);
+    sink.writeDartType(type);
   }
 
   ConstantType.readFromBinary(BinarySource source)
-      : type = source.readNodeReference() as DartType;
+      : type = source.readDartType();
 
   @override
   String toString() => 'Type $type';
@@ -668,12 +695,12 @@
   @override
   void writeValueToBinary(BinarySink sink) {
     sink.writeUInt30(typeArgs.length);
-    typeArgs.forEach(sink.writeNodeReference);
+    typeArgs.forEach(sink.writeDartType);
   }
 
   ConstantTypeArguments.readFromBinary(BinarySource source)
       : typeArgs = new List<DartType>.generate(
-            source.readUInt(), (_) => source.readNodeReference() as DartType);
+            source.readUInt(), (_) => source.readDartType());
 
   @override
   String toString() => 'TypeArgs $typeArgs';
@@ -698,13 +725,13 @@
 
   @override
   void writeValueToBinary(BinarySink sink) {
-    sink.writeNodeReference(typeArg);
+    sink.writeDartType(typeArg);
     sink.writeUInt30(entries.length);
     entries.forEach(sink.writeUInt30);
   }
 
   ConstantList.readFromBinary(BinarySource source)
-      : typeArg = source.readNodeReference() as DartType,
+      : typeArg = source.readDartType(),
         entries =
             new List<int>.generate(source.readUInt(), (_) => source.readUInt());
 
@@ -853,6 +880,90 @@
       this._typeArgumentsConstantIndex == other._typeArgumentsConstantIndex;
 }
 
+class ConstantContextOffset extends ConstantPoolEntry {
+  static const int kParent = 0;
+  static const int kVariableBase = 1;
+
+  final int _index;
+
+  ConstantContextOffset._(this._index);
+  ConstantContextOffset.parent() : this._(kParent);
+  ConstantContextOffset.variable(int index) : this._(index + kVariableBase);
+
+  @override
+  ConstantTag get tag => ConstantTag.kContextOffset;
+
+  @override
+  void writeValueToBinary(BinarySink sink) {
+    sink.writeUInt30(_index);
+  }
+
+  ConstantContextOffset.readFromBinary(BinarySource source)
+      : _index = source.readUInt();
+
+  @override
+  String toString() =>
+      'ContextOffset ${_index == kParent ? 'parent' : 'var [${_index - kVariableBase}]'}';
+
+  @override
+  int get hashCode => _index;
+
+  @override
+  bool operator ==(other) =>
+      other is ConstantContextOffset && this._index == other._index;
+}
+
+class ConstantClosureFunction extends ConstantPoolEntry {
+  final String name;
+  final FunctionNode function;
+
+  ConstantClosureFunction(this.name, this.function);
+
+  @override
+  ConstantTag get tag => ConstantTag.kClosureFunction;
+
+  @override
+  void writeValueToBinary(BinarySink sink) {
+    assert(function.body == null);
+    sink.writeStringReference(name);
+    sink.writeNode(function);
+  }
+
+  ConstantClosureFunction.readFromBinary(BinarySource source)
+      : name = source.readStringReference(),
+        function = source.readFunctionNode();
+
+  @override
+  String toString() {
+    StringBuffer buffer = new StringBuffer();
+    new Printer(buffer).writeFunction(function);
+    return 'ClosureFunction $name ${buffer.toString().trim()}';
+  }
+
+  // ConstantClosureFunction entries are created per closure and should not
+  // be merged, so ConstantClosureFunction class uses identity [hashCode] and
+  // [operator ==].
+}
+
+class ConstantEndClosureFunctionScope extends ConstantPoolEntry {
+  ConstantEndClosureFunctionScope();
+
+  @override
+  ConstantTag get tag => ConstantTag.kEndClosureFunctionScope;
+
+  @override
+  void writeValueToBinary(BinarySink sink) {}
+
+  ConstantEndClosureFunctionScope.readFromBinary(BinarySource source) {}
+
+  @override
+  String toString() => 'EndClosureFunctionScope';
+
+  // ConstantEndClosureFunctionScope entries are created per closure and should
+  // not be merged, so ConstantEndClosureFunctionScope class uses identity
+  // [hashCode] and [operator ==].
+}
+
 class ConstantPool {
   final List<ConstantPoolEntry> entries = <ConstantPoolEntry>[];
   final Map<ConstantPoolEntry, int> _canonicalizationCache =
@@ -868,17 +979,58 @@
     });
   }
 
-  void writeToBinary(BinarySink sink) {
+  void writeToBinary(Node node, BinarySink sink) {
+    final function = (node as Member).function;
+    sink.enterScope(
+        typeParameters: function?.typeParameters, memberScope: true);
+
+    final closureStack = <ConstantClosureFunction>[];
+
     sink.writeUInt30(entries.length);
     entries.forEach((e) {
       e.writeToBinary(sink);
+
+      if (e is ConstantClosureFunction) {
+        sink.enterScope(typeParameters: e.function.typeParameters);
+        closureStack.add(e);
+      } else if (e is ConstantEndClosureFunctionScope) {
+        sink.leaveScope(
+            typeParameters: closureStack.removeLast().function.typeParameters);
+      }
     });
+
+    assert(closureStack.isEmpty);
+
+    sink.leaveScope(
+        typeParameters: function?.typeParameters, memberScope: true);
   }
 
-  ConstantPool.readFromBinary(BinarySource source) {
+  ConstantPool.readFromBinary(Node node, BinarySource source) {
+    final function = (node as Member).function;
+    if (function != null) {
+      source.enterScope(typeParameters: function.typeParameters);
+    }
+
+    final closureStack = <ConstantClosureFunction>[];
+
     int len = source.readUInt();
     for (int i = 0; i < len; i++) {
-      entries.add(new ConstantPoolEntry.readFromBinary(source));
+      final e = new ConstantPoolEntry.readFromBinary(source);
+      entries.add(e);
+
+      if (e is ConstantClosureFunction) {
+        source.enterScope(typeParameters: e.function.typeParameters);
+        closureStack.add(e);
+      } else if (e is ConstantEndClosureFunctionScope) {
+        source.leaveScope(
+            typeParameters: closureStack.removeLast().function.typeParameters);
+      }
+    }
+
+    assert(closureStack.isEmpty);
+
+    if (function != null) {
+      source.leaveScope(typeParameters: function.typeParameters);
     }
   }
 
diff --git a/pkg/vm/lib/bytecode/dbc.dart b/pkg/vm/lib/bytecode/dbc.dart
index 17c68c3..6f48e18 100644
--- a/pkg/vm/lib/bytecode/dbc.dart
+++ b/pkg/vm/lib/bytecode/dbc.dart
@@ -7,8 +7,9 @@
 // List of changes from original DBC (described in runtime/vm/constants_dbc.h):
 //
 // 1. StoreFieldTOS, LoadFieldTOS instructions:
-//    D = index of constant pool entry with FieldOffset or
-//    TypeArgumentsFieldOffset tags (instead of field offset in words).
+//    D = index of constant pool entry with FieldOffset,
+//    TypeArgumentsFieldOffset or ConstantContextOffset tags
+//    (instead of field offset in words).
 //
 // 2. EntryOptional instruction is revived in order to re-shuffle optional
 //    parameters. This DBC instruction was removed at
@@ -182,6 +183,7 @@
   kBooleanNegate,
   kThrow,
   kEntry,
+  kEntryOptional,
   kEntryOptimized,
   kFrame,
   kSetFrame,
@@ -212,7 +214,6 @@
   kDebugBreak,
   kDeopt,
   kDeoptRewind,
-  kEntryOptional,
 }
 
 enum Encoding {
@@ -234,6 +235,7 @@
   reg, // register (unsigned FP relative local)
   xeg, // x-register (signed FP relative local)
   tgt, // jump target relative to the PC of the current instruction
+  spe, // SpecialIndex
 }
 
 class Format {
@@ -588,7 +590,7 @@
   Opcode.kCloneContext: const Format(
       Encoding.k0, const [Operand.none, Operand.none, Operand.none]),
   Opcode.kMoveSpecial: const Format(
-      Encoding.kAD, const [Operand.reg, Operand.imm, Operand.none]),
+      Encoding.kAD, const [Operand.reg, Operand.spe, Operand.none]),
   Opcode.kInstantiateType: const Format(
       Encoding.kD, const [Operand.lit, Operand.none, Operand.none]),
   Opcode.kInstantiateTypeArgumentsTOS: const Format(
@@ -649,3 +651,8 @@
 // Prefix used to distinguish setters in ICData target names.
 // Should match constant in runtime/vm/object.cc.
 const String kSetterPrefix = 'set:';
+
+enum SpecialIndex {
+  exception,
+  stackTrace,
+}
diff --git a/pkg/vm/lib/bytecode/disassembler.dart b/pkg/vm/lib/bytecode/disassembler.dart
index 9230268..279d492 100644
--- a/pkg/vm/lib/bytecode/disassembler.dart
+++ b/pkg/vm/lib/bytecode/disassembler.dart
@@ -7,6 +7,7 @@
 import 'dart:typed_data';
 
 import 'package:vm/bytecode/dbc.dart';
+import 'package:vm/bytecode/exceptions.dart';
 
 class _Instruction {
   final Opcode opcode;
@@ -20,11 +21,13 @@
 
   List<_Instruction> _instructions;
   int _labelCount;
-  Map<int, int> _labels;
+  Map<int, String> _labels;
+  Map<int, List<String>> _markers;
 
-  String disassemble(List<int> bytecode) {
+  String disassemble(List<int> bytecode, ExceptionsTable exceptionsTable) {
     _init(bytecode);
     _scanForJumpTargets();
+    _markTryBlocks(exceptionsTable);
     return _disasm();
   }
 
@@ -39,7 +42,8 @@
     }
 
     _labelCount = 0;
-    _labels = <int, int>{};
+    _labels = <int, String>{};
+    _markers = <int, List<String>>{};
   }
 
   _Instruction _decodeInstruction(int word) {
@@ -94,17 +98,35 @@
       if (instr.opcode == Opcode.kJump) {
         final target = i + instr.operands[0];
         assert(0 <= target && target < _instructions.length);
-        _labels[target] ??= (++_labelCount);
+        if (!_labels.containsKey(target)) {
+          final label = 'L${++_labelCount}';
+          _labels[target] = label;
+          _addMarker(target, '$label:');
+        }
       }
     }
   }
 
+  void _markTryBlocks(ExceptionsTable exceptionsTable) {
+    for (var tryBlock in exceptionsTable.blocks) {
+      final int tryIndex = tryBlock.tryIndex;
+      _addMarker(tryBlock.startPC, 'Try #$tryIndex start:');
+      _addMarker(tryBlock.endPC, 'Try #$tryIndex end:');
+      _addMarker(tryBlock.handlerPC, 'Try #$tryIndex handler:');
+    }
+  }
+
+  void _addMarker(int pc, String marker) {
+    final markers = (_markers[pc] ??= <String>[]);
+    markers.add(marker);
+  }
+
   String _disasm() {
     StringBuffer out = new StringBuffer();
     for (int i = 0; i < _instructions.length; i++) {
-      int label = _labels[i];
-      if (label != null) {
-        out.writeln('L$label:');
+      List<String> markers = _markers[i];
+      if (markers != null) {
+        markers.forEach(out.writeln);
       }
       _writeInstruction(out, i, _instructions[i]);
     }
@@ -158,7 +180,11 @@
       case Operand.xeg:
         return (value < 0) ? 'FP[$value]' : 'r$value';
       case Operand.tgt:
-        return 'L${_labels[bci + value] ?? (throw 'Label not found')}';
+        return _labels[bci + value] ?? (throw 'Label not found');
+      case Operand.spe:
+        return SpecialIndex.values[value]
+            .toString()
+            .substring('SpecialIndex.'.length);
     }
     throw 'Unexpected operand format $fmt';
   }
diff --git a/pkg/vm/lib/bytecode/exceptions.dart b/pkg/vm/lib/bytecode/exceptions.dart
new file mode 100644
index 0000000..7c955a3
--- /dev/null
+++ b/pkg/vm/lib/bytecode/exceptions.dart
@@ -0,0 +1,139 @@
+// 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.
+
+library vm.bytecode.exceptions;
+
+import 'package:kernel/ast.dart' show BinarySink, BinarySource;
+
+/*
+
+In kernel binary, try blocks are encoded in the following way
+(using notation from pkg/kernel/binary.md):
+
+// Offset of a bytecode instruction, in DBC words.
+type BytecodeOffset = UInt;
+
+type TryBlock {
+  UInt outerTryIndexPlus1;
+  BytecodeOffset startPC; // Inclusive.
+  BytecodeOffset endPC; // Exclusive.
+  BytecodeOffset handlerPC;
+  Byte flags (needsStackTrace, isSynthetic);
+  List<ConstantIndex> types;
+}
+
+type ExceptionsTable {
+  // Ordered by startPC, then by nesting (outer precedes inner).
+  // Try blocks are properly nested. It means there are no partially
+  // overlapping try blocks - each pair of try block regions either
+  // has no intersection or one try block region encloses another.
+  List<TryBlock> tryBlocks;
+}
+
+*/
+
+class TryBlock {
+  static const int flagNeedsStackTrace = 1 << 0;
+  static const int flagIsSynthetic = 1 << 1;
+
+  final int tryIndex;
+  final int outerTryIndex;
+  final int startPC;
+  int endPC;
+  int handlerPC;
+  int flags = 0;
+  List<int> types = <int>[];
+
+  TryBlock._(this.tryIndex, this.outerTryIndex, this.startPC);
+
+  bool get needsStackTrace => (flags & flagNeedsStackTrace) != 0;
+
+  void set needsStackTrace(bool value) {
+    flags = (flags & ~flagNeedsStackTrace) | (value ? flagNeedsStackTrace : 0);
+  }
+
+  bool get isSynthetic => (flags & flagIsSynthetic) != 0;
+
+  void set isSynthetic(bool value) {
+    flags = (flags & ~flagIsSynthetic) | (value ? flagIsSynthetic : 0);
+  }
+
+  void writeToBinary(BinarySink sink) {
+    sink.writeUInt30(outerTryIndex + 1);
+    sink.writeUInt30(startPC);
+    sink.writeUInt30(endPC);
+    sink.writeUInt30(handlerPC);
+    sink.writeByte(flags);
+    sink.writeUInt30(types.length);
+    types.forEach(sink.writeUInt30);
+  }
+
+  factory TryBlock.readFromBinary(BinarySource source, int tryIndex) {
+    final outerTryIndex = source.readUInt() - 1;
+    final startPC = source.readUInt();
+    final tryBlock = new TryBlock._(tryIndex, outerTryIndex, startPC);
+
+    tryBlock.endPC = source.readUInt();
+    tryBlock.handlerPC = source.readUInt();
+    tryBlock.flags = source.readByte();
+    tryBlock.types =
+        new List<int>.generate(source.readUInt(), (_) => source.readUInt());
+
+    return tryBlock;
+  }
+
+  @override
+  String toString() => 'try-index $tryIndex, outer $outerTryIndex, '
+      'start $startPC, end $endPC, handler $handlerPC, '
+      '${needsStackTrace ? 'needs-stack-trace, ' : ''}'
+      '${isSynthetic ? 'synthetic, ' : ''}'
+      'types ${types.map((t) => 'CP#$t').toList()}';
+}
+
+class ExceptionsTable {
+  List<TryBlock> blocks = <TryBlock>[];
+
+  ExceptionsTable();
+
+  TryBlock enterTryBlock(int startPC) {
+    assert(blocks.isEmpty || blocks.last.startPC <= startPC);
+    final tryBlock =
+        new TryBlock._(blocks.length, _outerTryBlockIndex(startPC), startPC);
+    blocks.add(tryBlock);
+    return tryBlock;
+  }
+
+  int _outerTryBlockIndex(int startPC) {
+    for (int i = blocks.length - 1; i >= 0; --i) {
+      final tryBlock = blocks[i];
+      if (tryBlock.endPC == null || tryBlock.endPC > startPC) {
+        return i;
+      }
+    }
+    return -1;
+  }
+
+  void writeToBinary(BinarySink sink) {
+    sink.writeUInt30(blocks.length);
+    blocks.forEach((b) => b.writeToBinary(sink));
+  }
+
+  ExceptionsTable.readFromBinary(BinarySource source)
+      : blocks = new List<TryBlock>.generate(source.readUInt(),
+            (int index) => new TryBlock.readFromBinary(source, index));
+
+  @override
+  String toString() {
+    if (blocks.isEmpty) {
+      return '';
+    }
+    StringBuffer sb = new StringBuffer();
+    sb.writeln('ExceptionsTable {');
+    for (var tryBlock in blocks) {
+      sb.writeln('  $tryBlock');
+    }
+    sb.writeln('}');
+    return sb.toString();
+  }
+}
diff --git a/pkg/vm/lib/bytecode/gen_bytecode.dart b/pkg/vm/lib/bytecode/gen_bytecode.dart
index 988a721..8d189b7 100644
--- a/pkg/vm/lib/bytecode/gen_bytecode.dart
+++ b/pkg/vm/lib/bytecode/gen_bytecode.dart
@@ -6,6 +6,7 @@
 
 import 'package:kernel/ast.dart' hide MapEntry;
 import 'package:kernel/class_hierarchy.dart' show ClassHierarchy;
+import 'package:kernel/clone.dart';
 import 'package:kernel/core_types.dart' show CoreTypes;
 import 'package:kernel/library_index.dart' show LibraryIndex;
 import 'package:kernel/transformations/constants.dart'
@@ -16,6 +17,7 @@
 import 'package:vm/bytecode/assembler.dart';
 import 'package:vm/bytecode/constant_pool.dart';
 import 'package:vm/bytecode/dbc.dart';
+import 'package:vm/bytecode/exceptions.dart';
 import 'package:vm/bytecode/local_vars.dart' show LocalVariables;
 import 'package:vm/metadata/bytecode.dart';
 
@@ -27,7 +29,8 @@
 
 const bool isTraceEnabled = false;
 
-void generateBytecode(Component component, {bool strongMode: true}) {
+void generateBytecode(Component component,
+    {bool strongMode: true, bool dropAST: false}) {
   final coreTypes = new CoreTypes(component);
   void ignoreAmbiguousSupertypes(Class cls, Supertype a, Supertype b) {}
   final hierarchy = new ClassHierarchy(component,
@@ -38,6 +41,9 @@
   new BytecodeGenerator(component, coreTypes, hierarchy, typeEnvironment,
           constantsBackend, strongMode)
       .visitComponent(component);
+  if (dropAST) {
+    new DropAST().visitComponent(component);
+  }
 }
 
 class BytecodeGenerator extends RecursiveVisitor<Null> {
@@ -51,13 +57,18 @@
 
   Class enclosingClass;
   Member enclosingMember;
-  BytecodeAssembler asm;
-  ConstantPool cp;
   LocalVariables locals;
-  ConstantEmitter constantEmitter;
   ConstantEvaluator constantEvaluator;
   Map<LabeledStatement, Label> labeledStatements;
   Map<SwitchCase, Label> switchCases;
+  Map<TryCatch, TryBlock> tryCatches;
+  Map<TryFinally, List<FinallyBlock>> finallyBlocks;
+  Map<TreeNode, int> contextLevels;
+  List<ClosureBytecode> closures;
+  ConstantPool cp;
+  ConstantEmitter constantEmitter;
+  BytecodeAssembler asm;
+  List<BytecodeAssembler> savedAssemblers;
 
   BytecodeGenerator(this.component, this.coreTypes, this.hierarchy,
       this.typeEnvironment, this.constantsBackend, this.strongMode) {
@@ -140,6 +151,32 @@
   Procedure get interpolate => _interpolate ??=
       libraryIndex.getMember('dart:core', '_StringBase', '_interpolate');
 
+  Class _closureClass;
+  Class get closureClass =>
+      _closureClass ??= libraryIndex.getClass('dart:core', '_Closure');
+
+  Field _closureInstantiatorTypeArguments;
+  Field get closureInstantiatorTypeArguments =>
+      _closureInstantiatorTypeArguments ??= libraryIndex.getMember(
+          'dart:core', '_Closure', '_instantiator_type_arguments');
+
+  Field _closureFunctionTypeArguments;
+  Field get closureFunctionTypeArguments =>
+      _closureFunctionTypeArguments ??= libraryIndex.getMember(
+          'dart:core', '_Closure', '_function_type_arguments');
+
+  Field _closureFunction;
+  Field get closureFunction => _closureFunction ??=
+      libraryIndex.getMember('dart:core', '_Closure', '_function');
+
+  Field _closureContext;
+  Field get closureContext => _closureContext ??=
+      libraryIndex.getMember('dart:core', '_Closure', '_context');
+
+  Procedure _prependTypeArguments;
+  Procedure get prependTypeArguments => _prependTypeArguments ??=
+      libraryIndex.getTopLevelMember('dart:_internal', '_prependTypeArguments');
+
   void _genConstructorInitializers(Constructor node) {
     bool isRedirecting =
         node.initializers.any((init) => init is RedirectingInitializer);
@@ -161,7 +198,7 @@
       return;
     }
 
-    asm.emitPush(locals.thisVarIndex);
+    _genPushReceiver();
     initializer.accept(this);
 
     // TODO(alexmarkov): assignability check
@@ -233,11 +270,6 @@
         (c.superclass != null && hasInstantiatorTypeArguments(c.superclass));
   }
 
-  bool isGenericFunction(Member member) {
-    final function = member.function;
-    return function != null && function.typeParameters.isNotEmpty;
-  }
-
   void _genTypeArguments(List<DartType> typeArgs, {Class instantiatingClass}) {
     int typeArgsCPIndex = cp.add(new ConstantTypeArguments(typeArgs));
     if (instantiatingClass != null) {
@@ -261,10 +293,10 @@
   }
 
   void _genPushInstantiatorTypeArguments() {
-    // TODO(alexmarkov): access from closures to up-level type arguments.
+    // TODO(alexmarkov): access to type arguments in factory constructors.
     if ((enclosingMember.isInstanceMember || enclosingMember is Constructor) &&
         hasInstantiatorTypeArguments(enclosingClass)) {
-      asm.emitPush(locals.thisVarIndex);
+      _genPushReceiver();
       final int cpIndex =
           cp.add(new ConstantTypeArgumentsFieldOffset(enclosingClass));
       asm.emitLoadFieldTOS(cpIndex);
@@ -274,14 +306,62 @@
   }
 
   void _genPushFunctionTypeArguments() {
-    // TODO(alexmarkov): closures
-    if (isGenericFunction(enclosingMember)) {
-      asm.emitPush(locals.functionTypeArgsVarIndex);
+    if (locals.hasTypeArgsVar) {
+      asm.emitPush(locals.typeArgsVarIndexInFrame);
     } else {
       _genPushNull();
     }
   }
 
+  void _genPushContextForVariable(VariableDeclaration variable) {
+    int depth =
+        locals.currentContextLevel - locals.getContextLevelOfVar(variable);
+    assert(depth >= 0);
+
+    asm.emitPush(locals.contextVarIndexInFrame);
+    if (depth > 0) {
+      int cpIndex = cp.add(new ConstantContextOffset.parent());
+      for (; depth > 0; --depth) {
+        asm.emitLoadFieldTOS(cpIndex);
+      }
+    }
+  }
+
+  void _genPushContextIfCaptured(VariableDeclaration variable) {
+    if (locals.isCaptured(variable)) {
+      _genPushContextForVariable(variable);
+    }
+  }
+
+  void _genLoadVar(VariableDeclaration v) {
+    if (locals.isCaptured(v)) {
+      _genPushContextForVariable(v);
+      final int cpIndex = cp.add(
+          new ConstantContextOffset.variable(locals.getVarIndexInContext(v)));
+      asm.emitLoadFieldTOS(cpIndex);
+    } else {
+      asm.emitPush(locals.getVarIndexInFrame(v));
+    }
+  }
+
+  void _genPushReceiver() {
+    // TODO(alexmarkov): generate more efficient access to receiver
+    // even if it is captured.
+    _genLoadVar(locals.receiverVar);
+  }
+
+  // Stores value into variable.
+  // If variable is captured, context should be pushed before value.
+  void _genStoreVar(VariableDeclaration variable) {
+    if (locals.isCaptured(variable)) {
+      final int cpIndex = cp.add(new ConstantContextOffset.variable(
+          locals.getVarIndexInContext(variable)));
+      asm.emitStoreFieldTOS(cpIndex);
+    } else {
+      asm.emitPopLocal(locals.getVarIndexInFrame(variable));
+    }
+  }
+
   /// Generates bool condition. Returns `true` if condition is negated.
   bool _genCondition(Node condition) {
     bool negated = false;
@@ -304,34 +384,116 @@
     asm.emitJump(dest); // ... then jump dest
   }
 
-  // Duplicates value on top of the stack using temporary variable
-  // corresponding to [node].
-  void _genDupTOS(TreeNode node) {
+  void _genJumpIfTrue(bool negated, Label dest) {
+    _genJumpIfFalse(!negated, dest);
+  }
+
+  int _getDefaultParamConstIndex(VariableDeclaration param) {
+    if (param.initializer == null) {
+      return cp.add(const ConstantNull());
+    }
+    final constant = constantEvaluator.evaluate(param.initializer);
+    return constant.accept(constantEmitter);
+  }
+
+  // Duplicates value on top of the stack using temporary variable with
+  // given index.
+  void _genDupTOS(int tempIndexInFrame) {
     // TODO(alexmarkov): Consider introducing Dup bytecode or keeping track of
     // expression stack depth.
-    final int temp = locals.tempIndex(node);
-    asm.emitStoreLocal(temp);
-    asm.emitPush(temp);
+    asm.emitStoreLocal(tempIndexInFrame);
+    asm.emitPush(tempIndexInFrame);
+  }
+
+  /// Generates is-test for the value at TOS.
+  void _genInstanceOf(DartType type) {
+    // TODO(alexmarkov): generate _simpleInstanceOf if possible
+
+    if (hasTypeParameters([type])) {
+      _genPushInstantiatorAndFunctionTypeArguments([type]);
+    } else {
+      _genPushNull(); // Instantiator type arguments.
+      _genPushNull(); // Function type arguments.
+    }
+    asm.emitPushConstant(cp.add(new ConstantType(type)));
+    final argDescIndex = cp.add(new ConstantArgDesc(4));
+    final icdataIndex = cp.add(new ConstantICData('_instanceOf', argDescIndex));
+    asm.emitInstanceCall1(4, icdataIndex);
   }
 
   void start(Member node) {
-    enclosingMember = node;
     enclosingClass = node.enclosingClass;
-    asm = new BytecodeAssembler();
-    cp = new ConstantPool();
-    locals = new LocalVariables();
-    constantEmitter = new ConstantEmitter(cp);
+    enclosingMember = node;
+    locals = new LocalVariables(node);
     // TODO(alexmarkov): improve caching in ConstantEvaluator and reuse it
     constantEvaluator = new ConstantEvaluator(constantsBackend, typeEnvironment,
         coreTypes, strongMode, /* enableAsserts = */ true)
       ..env = new EvaluationEnvironment();
     labeledStatements = <LabeledStatement, Label>{};
     switchCases = <SwitchCase, Label>{};
+    tryCatches = <TryCatch, TryBlock>{};
+    finallyBlocks = <TryFinally, List<FinallyBlock>>{};
+    contextLevels = <TreeNode, int>{};
+    closures = <ClosureBytecode>[];
+    cp = new ConstantPool();
+    constantEmitter = new ConstantEmitter(cp);
+    asm = new BytecodeAssembler();
+    savedAssemblers = <BytecodeAssembler>[];
 
-    node.accept(locals);
+    locals.enterScope(node);
 
+    _genPrologue(node, node.function);
+
+    _genEqualsOperatorNullHandling(node);
+  }
+
+  // Generate additional code for 'operator ==' to handle nulls.
+  void _genEqualsOperatorNullHandling(Member member) {
+    if (member.name.name != '==' ||
+        locals.numParameters != 2 ||
+        member.enclosingClass != coreTypes.objectClass) {
+      return;
+    }
+
+    Label done = new Label();
+
+    _genLoadVar(member.function.positionalParameters[0]);
+    _genPushNull();
+    asm.emitIfNeStrictTOS();
+    asm.emitJump(done);
+
+    asm.emitPushConstant(cp.add(new ConstantBool(false)));
+    _genReturnTOS();
+
+    asm.bind(done);
+  }
+
+  void end(Member node) {
+    metadata.mapping[node] =
+        new BytecodeMetadata(asm.bytecode, asm.exceptionsTable, cp, closures);
+
+    if (isTraceEnabled) {
+      print('Generated bytecode for $node');
+    }
+
+    enclosingClass = null;
+    enclosingMember = null;
+    locals = null;
+    constantEvaluator = null;
+    labeledStatements = null;
+    switchCases = null;
+    tryCatches = null;
+    finallyBlocks = null;
+    contextLevels = null;
+    closures = null;
+    cp = null;
+    constantEmitter = null;
+    asm = null;
+    savedAssemblers = null;
+  }
+
+  void _genPrologue(Node node, FunctionNode function) {
     if (locals.hasOptionalParameters) {
-      final function = node.function;
       final int numOptionalPositional = function.positionalParameters.length -
           function.requiredParameterCount;
       final int numOptionalNamed = function.namedParameters.length;
@@ -364,27 +526,219 @@
     asm.emitCheckStack();
 
     // TODO(alexmarkov): add type checks for parameters
-  }
 
-  int _getDefaultParamConstIndex(VariableDeclaration param) {
-    if (param.initializer == null) {
-      return cp.add(const ConstantNull());
+    final bool isClosure =
+        node is FunctionDeclaration || node is FunctionExpression;
+    if (isClosure) {
+      asm.emitPush(locals.closureVarIndexInFrame);
+      asm.emitLoadFieldTOS(cp.add(new ConstantFieldOffset(closureContext)));
+      asm.emitPopLocal(locals.contextVarIndexInFrame);
     }
-    final constant = constantEvaluator.evaluate(param.initializer);
-    return constant.accept(constantEmitter);
-  }
 
-  void _genJumpIfTrue(bool negated, Label dest) {
-    _genJumpIfFalse(!negated, dest);
-  }
+    _allocateContextIfNeeded();
 
-  void end(Member node) {
-    enclosingMember = null;
-    enclosingClass = null;
-    metadata.mapping[node] = new BytecodeMetadata(asm.bytecode, cp);
-    if (isTraceEnabled) {
-      print('Generated bytecode for $node');
+    if (locals.hasCapturedParameters) {
+      // Copy captured parameters to their respective locations in the context.
+      if (locals.hasReceiver) {
+        _copyParamIfCaptured(locals.receiverVar);
+      }
+      function.positionalParameters.forEach(_copyParamIfCaptured);
+      function.namedParameters.forEach(_copyParamIfCaptured);
     }
+
+    if (locals.hasTypeArgsVar && isClosure) {
+      if (function.typeParameters.isNotEmpty) {
+        final int numParentTypeArgs = locals.numParentTypeArguments;
+        asm.emitPush(locals.typeArgsVarIndexInFrame);
+        asm.emitPush(locals.closureVarIndexInFrame);
+        asm.emitLoadFieldTOS(
+            cp.add(new ConstantFieldOffset(closureFunctionTypeArguments)));
+        asm.emitPushConstant(cp.add(new ConstantInt(numParentTypeArgs)));
+        asm.emitPushConstant(cp.add(new ConstantInt(
+            numParentTypeArgs + function.typeParameters.length)));
+        _genStaticCall(prependTypeArguments, new ConstantArgDesc(4), 4);
+        asm.emitPopLocal(locals.typeArgsVarIndexInFrame);
+      } else {
+        asm.emitPush(locals.closureVarIndexInFrame);
+        asm.emitLoadFieldTOS(
+            cp.add(new ConstantFieldOffset(closureFunctionTypeArguments)));
+        asm.emitPopLocal(locals.typeArgsVarIndexInFrame);
+      }
+    }
+  }
+
+  void _copyParamIfCaptured(VariableDeclaration variable) {
+    if (locals.isCaptured(variable)) {
+      _genPushContextForVariable(variable);
+      asm.emitPush(locals.getOriginalParamSlotIndex(variable));
+      _genStoreVar(variable);
+      // TODO(alexmarkov): Do we need to store null at the original parameter
+      // location?
+    }
+  }
+
+  void _pushAssemblerState() {
+    savedAssemblers.add(asm);
+    asm = new BytecodeAssembler();
+  }
+
+  void _popAssemblerState() {
+    asm = savedAssemblers.removeLast();
+  }
+
+  int _genClosureBytecode(TreeNode node, String name, FunctionNode function) {
+    _pushAssemblerState();
+
+    locals.enterScope(node);
+
+    final int closureFunctionIndex = cp.add(new ConstantClosureFunction(
+        name, new CloneWithoutBody().visitFunctionNode(function)));
+
+    _genPrologue(node, function);
+    function.body.accept(this);
+
+    // TODO(alexmarkov): figure out when 'return null' should be generated.
+    _genPushNull();
+    _genReturnTOS();
+
+    cp.add(new ConstantEndClosureFunctionScope());
+
+    locals.leaveScope();
+
+    closures.add(new ClosureBytecode(
+        closureFunctionIndex, asm.bytecode, asm.exceptionsTable));
+    _popAssemblerState();
+
+    return closureFunctionIndex;
+  }
+
+  void _genAllocateClosureInstance(
+      TreeNode node, int closureFunctionIndex, FunctionNode function) {
+    // TODO(alexmarkov): Consider adding a bytecode to allocate closure.
+
+    assert(closureClass.typeParameters.isEmpty);
+    asm.emitAllocate(cp.add(new ConstantClass(closureClass)));
+
+    final int temp = locals.tempIndexInFrame(node);
+    asm.emitStoreLocal(temp);
+
+    // TODO(alexmarkov): We need to fill _instantiator_type_arguments field
+    // only if function signature uses instantiator type arguments.
+    asm.emitPush(temp);
+    _genPushInstantiatorTypeArguments();
+    asm.emitStoreFieldTOS(
+        cp.add(new ConstantFieldOffset(closureInstantiatorTypeArguments)));
+
+    asm.emitPush(temp);
+    _genPushFunctionTypeArguments();
+    asm.emitStoreFieldTOS(
+        cp.add(new ConstantFieldOffset(closureFunctionTypeArguments)));
+
+    // TODO(alexmarkov): How to put Object::empty_type_arguments()
+    // to _delayed_type_arguments?
+
+    asm.emitPush(temp);
+    asm.emitPushConstant(closureFunctionIndex);
+    asm.emitStoreFieldTOS(cp.add(new ConstantFieldOffset(closureFunction)));
+
+    asm.emitPush(temp);
+    asm.emitPush(locals.contextVarIndexInFrame);
+    asm.emitStoreFieldTOS(cp.add(new ConstantFieldOffset(closureContext)));
+  }
+
+  void _genClosure(TreeNode node, String name, FunctionNode function) {
+    final int closureFunctionIndex = _genClosureBytecode(node, name, function);
+    _genAllocateClosureInstance(node, closureFunctionIndex, function);
+  }
+
+  void _allocateContextIfNeeded() {
+    final int contextSize = locals.currentContextSize;
+    if (contextSize > 0) {
+      asm.emitAllocateContext(contextSize);
+
+      _genDupTOS(locals.scratchVarIndexInFrame);
+      asm.emitPush(locals.contextVarIndexInFrame);
+      asm.emitStoreFieldTOS(cp.add(new ConstantContextOffset.parent()));
+
+      asm.emitPopLocal(locals.contextVarIndexInFrame);
+    }
+  }
+
+  void _enterScope(TreeNode node) {
+    locals.enterScope(node);
+    _allocateContextIfNeeded();
+  }
+
+  void _leaveScope() {
+    if (locals.currentContextSize > 0) {
+      _genUnwindContext(locals.currentContextLevel - 1);
+    }
+    locals.leaveScope();
+  }
+
+  void _genUnwindContext(int targetContextLevel) {
+    int currentContextLevel = locals.currentContextLevel;
+    assert(currentContextLevel >= targetContextLevel);
+    while (currentContextLevel > targetContextLevel) {
+      asm.emitPush(locals.contextVarIndexInFrame);
+      asm.emitLoadFieldTOS(cp.add(new ConstantContextOffset.parent()));
+      asm.emitPopLocal(locals.contextVarIndexInFrame);
+      --currentContextLevel;
+    }
+  }
+
+  /// Returns the list of try-finally blocks between [from] and [to],
+  /// ordered from inner to outer. If [to] is null, returns all enclosing
+  /// try-finally blocks up to the function boundary.
+  List<TryFinally> _getEnclosingTryFinallyBlocks(TreeNode from, TreeNode to) {
+    List<TryFinally> blocks = <TryFinally>[];
+    TreeNode node = from;
+    for (;;) {
+      if (node == to) {
+        return blocks;
+      }
+      if (node == null || node is FunctionNode || node is Member) {
+        if (to == null) {
+          return blocks;
+        } else {
+          throw 'Unable to find node $to up from $from';
+        }
+      }
+      // Inspect parent as we only need try-finally blocks enclosing [node]
+      // in the body, and not in the finally-block.
+      final parent = node.parent;
+      if (parent is TryFinally && parent.body == node) {
+        blocks.add(parent);
+      }
+      node = parent;
+    }
+  }
+
+  /// Generates non-local transfer from inner node [from] into the outer
+  /// node, executing finally blocks on the way out. [to] can be null,
+  /// in such case all enclosing finally blocks are executed.
+  /// [continuation] is invoked to generate control transfer code following
+  /// the last finally block.
+  void _generateNonLocalControlTransfer(
+      TreeNode from, TreeNode to, GenerateContinuation continuation) {
+    List<TryFinally> tryFinallyBlocks = _getEnclosingTryFinallyBlocks(from, to);
+
+    // Add finally blocks to all try-finally from outer to inner.
+    // The outermost finally block should generate continuation, each inner
+    // finally block should proceed to a corresponding outer block.
+    for (var tryFinally in tryFinallyBlocks.reversed) {
+      final finallyBlock = new FinallyBlock(continuation);
+      finallyBlocks[tryFinally].add(finallyBlock);
+
+      final Label nextFinally = finallyBlock.entry;
+      continuation = () {
+        asm.emitJump(nextFinally);
+      };
+    }
+
+    // Generate jump to the innermost finally (or to the original
+    // continuation if there are no try-finally blocks).
+    continuation();
   }
 
   @override
@@ -437,7 +791,7 @@
   visitConditionalExpression(ConditionalExpression node) {
     final Label otherwisePart = new Label();
     final Label done = new Label();
-    final int temp = locals.tempIndex(node);
+    final int temp = locals.tempIndexInFrame(node);
 
     final bool negated = _genCondition(node.condition);
     _genJumpIfFalse(negated, otherwisePart);
@@ -474,7 +828,7 @@
       asm.emitAllocate(classIndex);
     }
 
-    _genDupTOS(node);
+    _genDupTOS(locals.tempIndexInFrame(node));
 
     // Remove type arguments as they are only passed to instance allocation,
     // and not passed to a constructor.
@@ -504,11 +858,12 @@
 //  @override
 //  visitDirectPropertySet(DirectPropertySet node) {
 //  }
-//
-//  @override
-//  visitFunctionExpression(FunctionExpression node) {
-//  }
-//
+
+  @override
+  visitFunctionExpression(FunctionExpression node) {
+    _genClosure(node, '<anonymous closure>', node.function);
+  }
+
 //  @override
 //  visitInstantiation(Instantiation node) {
 //  }
@@ -520,26 +875,15 @@
   @override
   visitIsExpression(IsExpression node) {
     node.operand.accept(this);
-
-    // TODO(alexmarkov): generate _simpleInstanceOf if possible
-
-    if (hasTypeParameters([node.type])) {
-      _genPushInstantiatorAndFunctionTypeArguments([node.type]);
-    } else {
-      _genPushNull(); // Instantiator type arguments.
-      _genPushNull(); // Function type arguments.
-    }
-    final typeIndex = cp.add(new ConstantType(node.type));
-    asm.emitPushConstant(typeIndex);
-    final argDescIndex = cp.add(new ConstantArgDesc(4));
-    final icdataIndex = cp.add(new ConstantICData('_instanceOf', argDescIndex));
-    asm.emitInstanceCall1(4, icdataIndex);
+    _genInstanceOf(node.type);
   }
 
   @override
   visitLet(Let node) {
+    _enterScope(node);
     node.variable.accept(this);
     node.body.accept(this);
+    _leaveScope();
   }
 
   @override
@@ -551,12 +895,12 @@
 
     _genTypeArguments([node.typeArgument]);
 
-    _genDupTOS(node);
+    _genDupTOS(locals.tempIndexInFrame(node));
 
     // TODO(alexmarkov): gen more efficient code for empty array
     _genPushInt(node.expressions.length);
     asm.emitCreateArrayTOS();
-    final int temp = locals.tempIndex(node);
+    final int temp = locals.tempIndexInFrame(node);
     asm.emitStoreLocal(temp);
 
     for (int i = 0; i < node.expressions.length; i++) {
@@ -576,7 +920,7 @@
 
     final Label shortCircuit = new Label();
     final Label done = new Label();
-    final int temp = locals.tempIndex(node);
+    final int temp = locals.tempIndexInFrame(node);
     final isOR = (node.operator == '||');
 
     bool negated = _genCondition(node.left);
@@ -624,7 +968,7 @@
       _genPushInt(node.entries.length * 2);
       asm.emitCreateArrayTOS();
 
-      final int temp = locals.tempIndex(node);
+      final int temp = locals.tempIndexInFrame(node);
       asm.emitStoreLocal(temp);
 
       for (int i = 0; i < node.entries.length; i++) {
@@ -669,7 +1013,7 @@
 
   @override
   visitPropertySet(PropertySet node) {
-    final int temp = locals.tempIndex(node);
+    final int temp = locals.tempIndexInFrame(node);
     node.receiver.accept(this);
     node.value.accept(this);
     asm.emitStoreLocal(temp);
@@ -701,7 +1045,7 @@
 
   @override
   visitSuperPropertyGet(SuperPropertyGet node) {
-    asm.emitPush(locals.thisVarIndex);
+    _genPushReceiver();
     Member target =
         hierarchy.getDispatchTarget(enclosingClass.superclass, node.name);
     if (target == null) {
@@ -734,9 +1078,21 @@
     asm.emitPushConstant(cpIndex);
   }
 
-//  @override
-//  visitRethrow(Rethrow node) {
-//  }
+  @override
+  visitRethrow(Rethrow node) {
+    TryCatch tryCatch;
+    for (var parent = node.parent;; parent = parent.parent) {
+      if (parent is Catch) {
+        tryCatch = parent.parent as TryCatch;
+        break;
+      }
+      if (parent == null || parent is FunctionNode) {
+        throw 'Unable to find enclosing catch for $node';
+      }
+    }
+    tryCatches[tryCatch].needsStackTrace = true;
+    _genRethrow(tryCatch);
+  }
 
   bool _hasTrivialInitializer(Field field) =>
       (field.initializer == null) ||
@@ -789,7 +1145,7 @@
   @override
   visitStaticSet(StaticSet node) {
     node.value.accept(this);
-    _genDupTOS(node);
+    _genDupTOS(locals.tempIndexInFrame(node));
     final target = node.target;
     if (target is Field) {
       // TODO(alexmarkov): assignable check
@@ -811,7 +1167,7 @@
       _genPushInt(node.expressions.length);
       asm.emitCreateArrayTOS();
 
-      final int temp = locals.tempIndex(node);
+      final int temp = locals.tempIndexInFrame(node);
       asm.emitStoreLocal(temp);
 
       for (int i = 0; i < node.expressions.length; i++) {
@@ -839,8 +1195,7 @@
 
   @override
   visitThisExpression(ThisExpression node) {
-    // TODO(alexmarkov): access to captured this from closures.
-    asm.emitPush(locals.thisVarIndex);
+    _genPushReceiver();
   }
 
   @override
@@ -863,19 +1218,33 @@
 
   @override
   visitVariableGet(VariableGet node) {
-    if (node.variable.isConst) {
-      _genPushConstExpr(node.variable.initializer);
+    final v = node.variable;
+    if (v.isConst) {
+      _genPushConstExpr(v.initializer);
     } else {
-      // TODO(alexmarkov): access to captured variables.
-      asm.emitPush(locals.varIndex(node.variable));
+      _genLoadVar(v);
     }
   }
 
   @override
   visitVariableSet(VariableSet node) {
-    node.value.accept(this);
-    // TODO(alexmarkov): access to captured variables.
-    asm.emitStoreLocal(locals.varIndex(node.variable));
+    final v = node.variable;
+    if (locals.isCaptured(v)) {
+      _genPushContextForVariable(v);
+
+      node.value.accept(this);
+
+      // Preserve value.
+      final int temp = locals.tempIndexInFrame(node);
+      asm.emitStoreLocal(temp);
+
+      _genStoreVar(v);
+
+      asm.emitPush(temp);
+    } else {
+      node.value.accept(this);
+      asm.emitStoreLocal(locals.getVarIndexInFrame(v));
+    }
   }
 
 //  @override
@@ -913,7 +1282,9 @@
 
   @override
   visitBlock(Block node) {
+    _enterScope(node);
     visitList(node.statements, this);
+    _leaveScope();
   }
 
   @override
@@ -923,18 +1294,26 @@
 
   @override
   visitBreakStatement(BreakStatement node) {
-    // TODO(alexmarkov): execute all finally blocks on the way out.
-    final label = labeledStatements[node.target] ??
+    final targetLabel = labeledStatements[node.target] ??
         (throw 'Target label ${node.target} was not registered for break $node');
-    asm.emitJump(label);
+    final targetContextLevel = contextLevels[node.target];
+
+    _generateNonLocalControlTransfer(node, node.target, () {
+      _genUnwindContext(targetContextLevel);
+      asm.emitJump(targetLabel);
+    });
   }
 
   @override
   visitContinueSwitchStatement(ContinueSwitchStatement node) {
-    // TODO(alexmarkov): execute all finally blocks on the way out.
-    final label = switchCases[node.target] ??
+    final targetLabel = switchCases[node.target] ??
         (throw 'Target label ${node.target} was not registered for continue-switch $node');
-    asm.emitJump(label);
+    final targetContextLevel = contextLevels[node.target.parent];
+
+    _generateNonLocalControlTransfer(node, node.target.parent, () {
+      _genUnwindContext(targetContextLevel);
+      asm.emitJump(targetLabel);
+    });
   }
 
   @override
@@ -975,13 +1354,13 @@
         cp.add(new ConstantICData(
             '$kGetterPrefix$kIterator', cp.add(new ConstantArgDesc(1)))));
 
-    final iteratorTemp = locals.tempIndex(node);
+    final iteratorTemp = locals.tempIndexInFrame(node);
     asm.emitPopLocal(iteratorTemp);
 
     final Label done = new Label();
     final Label join = new Label();
-    asm.bind(join);
 
+    asm.bind(join);
     asm.emitCheckStack();
 
     asm.emitPush(iteratorTemp);
@@ -989,13 +1368,21 @@
         cp.add(new ConstantICData(kMoveNext, cp.add(new ConstantArgDesc(1)))));
     _genJumpIfFalse(/* negated = */ false, done);
 
+    _enterScope(node);
+
+    _genPushContextIfCaptured(node.variable);
+
     asm.emitPush(iteratorTemp);
-    asm.emitInstanceCall1(1,
-        cp.add(new ConstantICData(kCurrent, cp.add(new ConstantArgDesc(1)))));
-    asm.emitPopLocal(locals.varIndex(node.variable));
+    asm.emitInstanceCall1(
+        1,
+        cp.add(new ConstantICData(
+            '$kGetterPrefix$kCurrent', cp.add(new ConstantArgDesc(1)))));
+
+    _genStoreVar(node.variable);
 
     node.body.accept(this);
 
+    _leaveScope();
     asm.emitJump(join);
 
     asm.bind(done);
@@ -1003,6 +1390,8 @@
 
   @override
   visitForStatement(ForStatement node) {
+    _enterScope(node);
+
     visitList(node.variables, this);
 
     final Label done = new Label();
@@ -1018,6 +1407,12 @@
 
     node.body.accept(this);
 
+    if (locals.currentContextSize > 0) {
+      asm.emitPush(locals.contextVarIndexInFrame);
+      asm.emitCloneContext();
+      asm.emitPopLocal(locals.contextVarIndexInFrame);
+    }
+
     for (var update in node.updates) {
       update.accept(this);
       asm.emitDrop1();
@@ -1026,11 +1421,15 @@
     asm.emitJump(join);
 
     asm.bind(done);
+    _leaveScope();
   }
 
-//  @override
-//  visitFunctionDeclaration(FunctionDeclaration node) {
-//  }
+  @override
+  visitFunctionDeclaration(FunctionDeclaration node) {
+    _genPushContextIfCaptured(node.variable);
+    _genClosure(node, node.variable.name, node.function);
+    _genStoreVar(node.variable);
+  }
 
   @override
   visitIfStatement(IfStatement node) {
@@ -1056,9 +1455,11 @@
   visitLabeledStatement(LabeledStatement node) {
     final label = new Label();
     labeledStatements[node] = label;
+    contextLevels[node] = locals.currentContextLevel;
     node.body.accept(this);
     asm.bind(label);
-    labeledStatements[node] = null;
+    labeledStatements.remove(node);
+    contextLevels.remove(node);
   }
 
   @override
@@ -1068,14 +1469,21 @@
     } else {
       _genPushNull();
     }
-    asm.emitReturnTOS();
+
+    // TODO(alexmarkov): Do we need to save return value
+    // to a variable?
+    _generateNonLocalControlTransfer(node, null, () {
+      asm.emitReturnTOS();
+    });
   }
 
   @override
   visitSwitchStatement(SwitchStatement node) {
+    contextLevels[node] = locals.currentContextLevel;
+
     node.expression.accept(this);
 
-    final int temp = locals.tempIndex(node);
+    final int temp = locals.tempIndexInFrame(node);
     asm.emitPopLocal(temp);
 
     final Label done = new Label();
@@ -1117,15 +1525,169 @@
 
     asm.bind(done);
     node.cases.forEach(switchCases.remove);
+    contextLevels.remove(node);
   }
 
-//  @override
-//  visitTryCatch(TryCatch node) {
-//  }
-//
-//  @override
-//  visitTryFinally(TryFinally node) {
-//  }
+  bool _isTryBlock(TreeNode node) => node is TryCatch || node is TryFinally;
+
+  int _savedContextVar(TreeNode node) {
+    assert(_isTryBlock(node));
+    return locals.tempIndexInFrame(node, tempIndex: 0);
+  }
+
+  // Exception var occupies the same slot as saved context, so context
+  // should be restored first, before loading exception.
+  int _exceptionVar(TreeNode node) {
+    assert(_isTryBlock(node));
+    return locals.tempIndexInFrame(node, tempIndex: 0);
+  }
+
+  int _stackTraceVar(TreeNode node) {
+    assert(_isTryBlock(node));
+    return locals.tempIndexInFrame(node, tempIndex: 1);
+  }
+
+  _saveContextForTryBlock(TreeNode node) {
+    if (locals.hasContextVar) {
+      asm.emitPush(locals.contextVarIndexInFrame);
+      asm.emitPopLocal(_savedContextVar(node));
+    }
+  }
+
+  _restoreContextForTryBlock(TreeNode node) {
+    if (locals.hasContextVar) {
+      asm.emitPush(_savedContextVar(node));
+      asm.emitPopLocal(locals.contextVarIndexInFrame);
+    }
+  }
+
+  /// Start try block
+  TryBlock _startTryBlock(TreeNode node) {
+    assert(_isTryBlock(node));
+
+    _saveContextForTryBlock(node);
+
+    return asm.exceptionsTable.enterTryBlock(asm.offsetInWords);
+  }
+
+  /// End try block and start its handler.
+  void _endTryBlock(TreeNode node, TryBlock tryBlock) {
+    tryBlock.endPC = asm.offsetInWords;
+    tryBlock.handlerPC = asm.offsetInWords;
+
+    // TODO(alexmarkov): Consider emitting SetFrame to cut expression stack.
+    // In such case, we need to save return value to a variable in visitReturn.
+
+    _restoreContextForTryBlock(node);
+
+    asm.emitMoveSpecial(_exceptionVar(node), SpecialIndex.exception);
+    asm.emitMoveSpecial(_stackTraceVar(node), SpecialIndex.stackTrace);
+  }
+
+  void _genRethrow(TreeNode node) {
+    asm.emitPush(_exceptionVar(node));
+    asm.emitPush(_stackTraceVar(node));
+    asm.emitThrow(1);
+  }
+
+  @override
+  visitTryCatch(TryCatch node) {
+    final Label done = new Label();
+
+    final TryBlock tryBlock = _startTryBlock(node);
+    tryBlock.isSynthetic = node.isSynthetic;
+    tryCatches[node] = tryBlock; // Used by rethrow.
+
+    node.body.accept(this);
+    asm.emitJump(done);
+
+    _endTryBlock(node, tryBlock);
+
+    final int exception = _exceptionVar(node);
+    final int stackTrace = _stackTraceVar(node);
+
+    bool hasCatchAll = false;
+
+    for (Catch catchClause in node.catches) {
+      tryBlock.types.add(cp.add(new ConstantType(catchClause.guard)));
+
+      Label skipCatch;
+      if (catchClause.guard == const DynamicType()) {
+        hasCatchAll = true;
+      } else {
+        asm.emitPush(exception);
+        _genInstanceOf(catchClause.guard);
+
+        skipCatch = new Label();
+        _genJumpIfFalse(/* negated = */ false, skipCatch);
+      }
+
+      _enterScope(catchClause);
+
+      if (catchClause.exception != null) {
+        _genPushContextIfCaptured(catchClause.exception);
+        asm.emitPush(exception);
+        _genStoreVar(catchClause.exception);
+      }
+
+      if (catchClause.stackTrace != null) {
+        tryBlock.needsStackTrace = true;
+        _genPushContextIfCaptured(catchClause.stackTrace);
+        asm.emitPush(stackTrace);
+        _genStoreVar(catchClause.stackTrace);
+      }
+
+      catchClause.body.accept(this);
+
+      _leaveScope();
+      asm.emitJump(done);
+
+      if (skipCatch != null) {
+        asm.bind(skipCatch);
+      }
+    }
+
+    if (!hasCatchAll) {
+      tryBlock.needsStackTrace = true;
+      _genRethrow(node);
+    }
+
+    asm.bind(done);
+    tryCatches.remove(node);
+  }
+
+  @override
+  visitTryFinally(TryFinally node) {
+    final TryBlock tryBlock = _startTryBlock(node);
+    finallyBlocks[node] = <FinallyBlock>[];
+
+    node.body.accept(this);
+
+    // TODO(alexmarkov): Do not generate normal continuation if control
+    // does not return from body.
+    final normalContinuation =
+        new FinallyBlock(() {/* do nothing (fall through) */});
+    finallyBlocks[node].add(normalContinuation);
+    asm.emitJump(normalContinuation.entry);
+
+    _endTryBlock(node, tryBlock);
+
+    tryBlock.types.add(cp.add(new ConstantType(const DynamicType())));
+
+    node.finalizer.accept(this);
+
+    tryBlock.needsStackTrace = true; // For rethrowing.
+    _genRethrow(node);
+
+    for (var finallyBlock in finallyBlocks[node]) {
+      asm.bind(finallyBlock.entry);
+      _restoreContextForTryBlock(node);
+      node.finalizer.accept(this);
+      finallyBlock.generateContinuation();
+    }
+
+    finallyBlocks.remove(node);
+  }
 
   @override
   visitVariableDeclaration(VariableDeclaration node) {
@@ -1133,12 +1695,22 @@
       final Constant constant = constantEvaluator.evaluate(node.initializer);
       constantEvaluator.env.addVariableValue(node, constant);
     } else {
+      final bool isCaptured = locals.isCaptured(node);
+      if (isCaptured) {
+        _genPushContextForVariable(node);
+      }
       if (node.initializer != null) {
         node.initializer.accept(this);
       } else {
         _genPushNull();
       }
-      asm.emitPopLocal(locals.varIndex(node));
+      if (isCaptured) {
+        final int cpIndex = cp.add(new ConstantContextOffset.variable(
+            locals.getVarIndexInContext(node)));
+        asm.emitStoreFieldTOS(cpIndex);
+      } else {
+        asm.emitPopLocal(locals.getVarIndexInFrame(node));
+      }
     }
   }
 
@@ -1310,3 +1882,55 @@
       node.positionalParameters.any((t) => t.accept(this)) ||
       node.namedParameters.any((p) => p.type.accept(this));
 }
+
+// Drop kernel AST for members with bytecode.
+class DropAST extends Transformer {
+  BytecodeMetadataRepository metadata;
+
+  @override
+  TreeNode visitComponent(Component node) {
+    metadata = node.metadata[new BytecodeMetadataRepository().tag];
+    if (metadata != null) {
+      return super.visitComponent(node);
+    }
+    return node;
+  }
+
+  @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.mapping.containsKey(node);
+}
+
+typedef void GenerateContinuation();
+
+class FinallyBlock {
+  final Label entry = new Label();
+  final GenerateContinuation generateContinuation;
+
+  FinallyBlock(this.generateContinuation);
+}
diff --git a/pkg/vm/lib/bytecode/local_vars.dart b/pkg/vm/lib/bytecode/local_vars.dart
index 93789ad..1bae25a 100644
--- a/pkg/vm/lib/bytecode/local_vars.dart
+++ b/pkg/vm/lib/bytecode/local_vars.dart
@@ -9,166 +9,690 @@
 import 'package:kernel/ast.dart';
 import 'package:vm/bytecode/dbc.dart';
 
-class LocalVariables extends RecursiveVisitor<Null> {
-  final Map<VariableDeclaration, int> _vars = <VariableDeclaration, int>{};
-  final Map<TreeNode, int> _temps = <TreeNode, int>{};
-  final List<int> _scopes = <int>[];
-  int _localVars = 0;
-  int _frameSize = 0;
-  int _numParameters = 0;
-  bool _hasOptionalParameters = false;
-  int _thisVarIndex;
-  int _functionTypeArgsVarIndex;
+class LocalVariables {
+  final Map<TreeNode, Scope> _scopes = <TreeNode, Scope>{};
+  final Map<VariableDeclaration, VarDesc> _vars =
+      <VariableDeclaration, VarDesc>{};
+  final Map<TreeNode, List<int>> _temps = <TreeNode, List<int>>{};
 
-  int get thisVarIndex =>
-      _thisVarIndex ?? (throw '\'this\' variable is not allocated');
+  Scope _currentScope;
+  Frame _currentFrame;
 
-  int get functionTypeArgsVarIndex =>
-      _functionTypeArgsVarIndex ??
-      (throw '\'functionTypeArgs\' variable is not allocated');
+  VarDesc _getVarDesc(VariableDeclaration variable) =>
+      _vars[variable] ??
+      (throw 'Variable descriptor is not created for $variable');
 
-  int get frameSize => _frameSize;
+  int _getVarIndex(VariableDeclaration variable, bool isCaptured) {
+    final v = _getVarDesc(variable);
+    if (v.isCaptured != isCaptured) {
+      throw 'Mismatch in captured state of $variable';
+    }
+    return v.index ?? (throw 'Variable $variable is not allocated');
+  }
 
-  int get numParameters => _numParameters;
+  bool isCaptured(VariableDeclaration variable) =>
+      _getVarDesc(variable).isCaptured;
 
-  bool get hasOptionalParameters => _hasOptionalParameters;
+  int getVarIndexInFrame(VariableDeclaration variable) =>
+      _getVarIndex(variable, false);
 
-  int varIndex(VariableDeclaration variable) =>
-      _vars[variable] ?? (throw '\'$variable\' variable is not allocated');
+  int getVarIndexInContext(VariableDeclaration variable) =>
+      _getVarIndex(variable, true);
 
-  int tempIndex(TreeNode node) =>
-      _temps[node] ??
-      (throw 'Temp is not allocated for node ${node.runtimeType} $node');
+  int getOriginalParamSlotIndex(VariableDeclaration variable) =>
+      _getVarDesc(variable).originalParamSlotIndex ??
+      (throw 'Variablie $variable does not have originalParamSlotIndex');
 
-  int _allocateVar(VariableDeclaration node, {int index}) {
-    if (index == null) {
-      index = _localVars++;
+  int tempIndexInFrame(TreeNode node, {int tempIndex: 0}) {
+    final temps = _temps[node];
+    if (temps == null) {
+      throw 'Temp is not allocated for node ${node.runtimeType} $node';
+    }
+    return temps[tempIndex];
+  }
+
+  int get currentContextSize => _currentScope.contextSize;
+  int get currentContextLevel => _currentScope.contextLevel;
+
+  int getContextLevelOfVar(VariableDeclaration variable) {
+    final v = _getVarDesc(variable);
+    assert(v.isCaptured);
+    return v.scope.contextLevel;
+  }
+
+  int get closureVarIndexInFrame => getVarIndexInFrame(_currentFrame
+          .closureVar ??
+      (throw 'Closure variable is not declared in ${_currentFrame.function}'));
+
+  int get contextVarIndexInFrame => getVarIndexInFrame(_currentFrame
+          .contextVar ??
+      (throw 'Context variable is not declared in ${_currentFrame.function}'));
+
+  bool get hasContextVar => _currentFrame.contextVar != null;
+
+  int get scratchVarIndexInFrame => getVarIndexInFrame(_currentFrame
+          .scratchVar ??
+      (throw 'Scratch variable is not declared in ${_currentFrame.function}'));
+
+  int get typeArgsVarIndexInFrame => getVarIndexInFrame(_currentFrame
+          .typeArgsVar ??
+      (throw 'TypeArgs variable is not declared in ${_currentFrame.function}'));
+
+  bool get hasTypeArgsVar => _currentFrame.typeArgsVar != null;
+
+  VariableDeclaration get receiverVar =>
+      _currentFrame.receiverVar ??
+      (throw 'Receiver variable is not declared in ${_currentFrame.function}');
+
+  bool get hasReceiver => _currentFrame.receiverVar != null;
+
+  int get frameSize => _currentFrame.frameSize;
+
+  int get numParameters => _currentFrame.numParameters;
+
+  int get numParentTypeArguments => _currentFrame.parent?.numTypeArguments ?? 0;
+
+  bool get hasOptionalParameters => _currentFrame.hasOptionalParameters;
+  bool get hasCapturedParameters => _currentFrame.hasCapturedParameters;
+
+  LocalVariables(Member node) {
+    final scopeBuilder = new _ScopeBuilder(this);
+    node.accept(scopeBuilder);
+
+    final allocator = new _Allocator(this);
+    node.accept(allocator);
+  }
+
+  void enterScope(TreeNode node) {
+    _currentScope = _scopes[node];
+    _currentFrame = _currentScope.frame;
+  }
+
+  void leaveScope() {
+    _currentScope = _currentScope.parent;
+    _currentFrame = _currentScope?.frame;
+  }
+}
+
+class VarDesc {
+  final VariableDeclaration declaration;
+  final Scope scope;
+  bool isCaptured = false;
+  int index;
+  int originalParamSlotIndex;
+
+  VarDesc(this.declaration, this.scope);
+
+  Frame get frame => scope.frame;
+
+  bool get isAllocated => index != null;
+
+  void capture() {
+    if (!isCaptured) {
+      assert(!isAllocated);
+      // TODO(alexmarkov): Consider sharing context between scopes.
+      index = scope.contextSize++;
+      isCaptured = true;
+    }
+  }
+}
+
+class Frame {
+  final TreeNode function;
+  final Frame parent;
+
+  int numParameters = 0;
+  int numTypeArguments = 0;
+  bool hasOptionalParameters = false;
+  bool hasCapturedParameters = false;
+  bool hasClosures = false;
+  VariableDeclaration receiverVar;
+  VariableDeclaration typeArgsVar;
+  VariableDeclaration closureVar;
+  VariableDeclaration contextVar;
+  VariableDeclaration scratchVar;
+  int frameSize = 0;
+  List<int> temporaries = <int>[];
+
+  Frame(this.function, this.parent);
+}
+
+class Scope {
+  final Scope parent;
+  final Frame frame;
+
+  int localsUsed;
+  int tempsUsed;
+  int contextSize = 0;
+  int contextLevel;
+
+  Scope(this.parent, this.frame);
+
+  bool get hasContext => contextSize > 0;
+}
+
+class _ScopeBuilder extends RecursiveVisitor<Null> {
+  final LocalVariables locals;
+
+  Scope _currentScope;
+  Frame _currentFrame;
+
+  _ScopeBuilder(this.locals);
+
+  void _sortNamedParameters(FunctionNode function) {
+    function.namedParameters.sort(
+        (VariableDeclaration a, VariableDeclaration b) =>
+            a.name.compareTo(b.name));
+  }
+
+  void _visitFunction(TreeNode node) {
+    _enterFrame(node);
+
+    if (node is Field) {
+      node.initializer.accept(this);
     } else {
-      // Should be a parameter.
-      assert(index < 0 || (_hasOptionalParameters && index < _numParameters));
+      assert(node is Procedure ||
+          node is Constructor ||
+          node is FunctionDeclaration ||
+          node is FunctionExpression);
+
+      FunctionNode function = (node as dynamic).function;
+      assert(function != null);
+
+      _currentFrame.numTypeArguments =
+          (_currentFrame.parent?.numTypeArguments ?? 0) +
+              function.typeParameters.length;
+
+      if (_currentFrame.numTypeArguments > 0) {
+        _currentFrame.typeArgsVar =
+            new VariableDeclaration(':function_type_arguments_var');
+        _declareVariable(_currentFrame.typeArgsVar);
+      }
+      if (node is Constructor || (node is Procedure && !node.isStatic)) {
+        _currentFrame.receiverVar = new VariableDeclaration('this');
+        _declareVariable(_currentFrame.receiverVar);
+      } else if (_currentFrame.parent?.receiverVar != null) {
+        _currentFrame.receiverVar = _currentFrame.parent.receiverVar;
+      }
+      if (node is FunctionDeclaration || node is FunctionExpression) {
+        _currentFrame.closureVar = new VariableDeclaration(':closure');
+        _declareVariable(_currentFrame.closureVar);
+      }
+
+      _sortNamedParameters(function);
+
+      visitList(function.positionalParameters, this);
+      visitList(function.namedParameters, this);
+
+      if (node is Constructor) {
+        for (var field in node.enclosingClass.fields) {
+          if (!field.isStatic && field.initializer != null) {
+            field.initializer.accept(this);
+          }
+        }
+        visitList(node.initializers, this);
+      }
+
+      function.body?.accept(this);
     }
-    _frameSize = max(_frameSize, _localVars);
-    if (node != null) {
-      assert(_vars[node] == null);
-      _vars[node] = index;
+
+    if (node is FunctionDeclaration ||
+        node is FunctionExpression ||
+        _currentFrame.hasClosures) {
+      _currentFrame.contextVar = new VariableDeclaration(':context');
+      _declareVariable(_currentFrame.contextVar);
+      _currentFrame.scratchVar = new VariableDeclaration(':scratch');
+      _declareVariable(_currentFrame.scratchVar);
     }
-    return index;
+
+    _leaveFrame();
   }
 
-  // TODO(alexmarkov): allocate temporaries more efficiently.
-  void _allocateTemp(TreeNode node) {
-    _temps[node] = _allocateVar(null);
+  _enterFrame(TreeNode node) {
+    _currentFrame = new Frame(node, _currentFrame);
+    _enterScope(node);
   }
 
-  int _allocateParameter(VariableDeclaration node, int i) {
-    assert(0 <= i && i < _numParameters);
-    int paramSlotIndex =
-        _hasOptionalParameters ? i : -kParamEndSlotFromFp - _numParameters + i;
-    return _allocateVar(node, index: paramSlotIndex);
+  _leaveFrame() {
+    _leaveScope();
+    _currentFrame = _currentFrame.parent;
   }
 
-  void _enterScope() {
-    _scopes.add(_localVars);
+  void _enterScope(TreeNode node) {
+    _currentScope = new Scope(_currentScope, _currentFrame);
+    assert(locals._scopes[node] == null);
+    locals._scopes[node] = _currentScope;
   }
 
   void _leaveScope() {
-    final int enclosingScopeLocalVars = _scopes.removeLast();
-    assert(_localVars >= enclosingScopeLocalVars);
-    _localVars = enclosingScopeLocalVars;
+    _currentScope = _currentScope.parent;
+  }
+
+  void _declareVariable(VariableDeclaration variable) {
+    final VarDesc v = new VarDesc(variable, _currentScope);
+    assert(locals._vars[variable] == null);
+    locals._vars[variable] = v;
+  }
+
+  void _useVariable(VariableDeclaration variable) {
+    assert(variable != null);
+    final VarDesc v = locals._vars[variable];
+    if (v == null) {
+      throw 'Variable $variable is used before declared';
+    }
+    if (v.frame != _currentFrame) {
+      v.capture();
+    }
+  }
+
+  void _useThis() {
+    assert(_currentFrame.receiverVar != null);
+    _useVariable(_currentFrame.receiverVar);
+  }
+
+  void _visitWithScope(TreeNode node) {
+    _enterScope(node);
+    node.visitChildren(this);
+    _leaveScope();
   }
 
   @override
-  visitField(Field node) {
-    if (node.initializer != null) {
-      assert(_vars.isEmpty);
-      assert(_localVars == 0);
+  defaultMember(Member node) {
+    _visitFunction(node);
+  }
 
-      _enterScope();
+  @override
+  visitFunctionDeclaration(FunctionDeclaration node) {
+    _currentFrame.hasClosures = true;
+    node.variable.accept(this);
+    _visitFunction(node);
+  }
+
+  @override
+  visitFunctionExpression(FunctionExpression node) {
+    _currentFrame.hasClosures = true;
+    _visitFunction(node);
+  }
+
+  @override
+  visitVariableDeclaration(VariableDeclaration node) {
+    _declareVariable(node);
+    node.visitChildren(this);
+  }
+
+  @override
+  visitVariableGet(VariableGet node) {
+    _useVariable(node.variable);
+  }
+
+  @override
+  visitVariableSet(VariableSet node) {
+    _useVariable(node.variable);
+    node.visitChildren(this);
+  }
+
+  @override
+  visitThisExpression(ThisExpression node) {
+    _useThis();
+  }
+
+  @override
+  visitSuperMethodInvocation(SuperMethodInvocation node) {
+    _useThis();
+    node.visitChildren(this);
+  }
+
+  @override
+  visitSuperPropertyGet(SuperPropertyGet node) {
+    _useThis();
+    node.visitChildren(this);
+  }
+
+  @override
+  visitSuperPropertySet(SuperPropertySet node) {
+    _useThis();
+    node.visitChildren(this);
+  }
+
+  @override
+  visitTypeParameterType(TypeParameterType node) {
+    if (node.parameter.parent is Class) {
+      _useThis();
+    }
+    node.visitChildren(this);
+  }
+
+  @override
+  visitBlock(Block node) {
+    _visitWithScope(node);
+  }
+
+  @override
+  visitAssertBlock(AssertBlock node) {
+    _visitWithScope(node);
+  }
+
+  @override
+  visitForStatement(ForStatement node) {
+    _visitWithScope(node);
+  }
+
+  @override
+  visitForInStatement(ForInStatement node) {
+    node.iterable.accept(this);
+
+    _enterScope(node);
+    node.variable.accept(this);
+    node.body.accept(this);
+    _leaveScope();
+  }
+
+  @override
+  visitCatch(Catch node) {
+    _visitWithScope(node);
+  }
+
+  @override
+  visitLet(Let node) {
+    _visitWithScope(node);
+  }
+}
+
+class _Allocator extends RecursiveVisitor<Null> {
+  final LocalVariables locals;
+
+  Scope _currentScope;
+  Frame _currentFrame;
+  int _contextLevel = 0;
+
+  _Allocator(this.locals);
+
+  void _enterScope(TreeNode node) {
+    final scope = locals._scopes[node];
+    assert(scope != null);
+    assert(scope.parent == _currentScope);
+    _currentScope = scope;
+
+    if (_currentScope.frame != _currentFrame) {
+      _currentFrame = _currentScope.frame;
+
+      _currentScope.localsUsed = 0;
+      _currentScope.tempsUsed = 0;
+    } else {
+      _currentScope.localsUsed = _currentScope.parent.localsUsed;
+      _currentScope.tempsUsed = _currentScope.parent.tempsUsed;
+    }
+
+    if (_currentScope.parent == null || _currentScope.hasContext) {
+      _currentScope.contextLevel = _contextLevel++;
+    } else {
+      _currentScope.contextLevel = _currentScope.parent.contextLevel;
+    }
+  }
+
+  void _leaveScope() {
+    if (_currentScope.hasContext) {
+      --_contextLevel;
+    }
+
+    _currentScope = _currentScope.parent;
+    _currentFrame = _currentScope?.frame;
+
+    // Remove temporary variables which are out of scope.
+    if (_currentScope != null) {
+      int tempsToRetain = _currentFrame.temporaries.length;
+      while (tempsToRetain > 0 &&
+          _currentFrame.temporaries[tempsToRetain - 1] >=
+              _currentScope.localsUsed) {
+        --tempsToRetain;
+      }
+      assert(tempsToRetain >= _currentScope.tempsUsed);
+      _currentFrame.temporaries.length = tempsToRetain;
+      assert(_currentFrame.temporaries
+          .every((index) => index < _currentScope.localsUsed));
+    }
+  }
+
+  void _updateFrameSize() {
+    _currentFrame.frameSize =
+        max(_currentFrame.frameSize, _currentScope.localsUsed);
+  }
+
+  void _allocateTemp(TreeNode node, {int count: 1}) {
+    assert(locals._temps[node] == null);
+    if (_currentScope.tempsUsed + count > _currentFrame.temporaries.length) {
+      // Allocate new local slots for temporary variables.
+      final int newSlots =
+          (_currentScope.tempsUsed + count) - _currentFrame.temporaries.length;
+      int local = _currentScope.localsUsed;
+      _currentScope.localsUsed += newSlots;
+      _updateFrameSize();
+      for (int i = 0; i < newSlots; i++) {
+        _currentFrame.temporaries.add(local + i);
+      }
+    }
+    locals._temps[node] = _currentFrame.temporaries
+        .sublist(_currentScope.tempsUsed, _currentScope.tempsUsed + count);
+    _currentScope.tempsUsed += count;
+  }
+
+  void _freeTemp(TreeNode node, {int count: 1}) {
+    assert(_currentScope.tempsUsed >= count);
+    _currentScope.tempsUsed -= count;
+    assert(listEquals(
+        locals._temps[node],
+        _currentFrame.temporaries.sublist(
+            _currentScope.tempsUsed, _currentScope.tempsUsed + count)));
+  }
+
+  void _allocateVariable(VariableDeclaration variable, {int paramSlotIndex}) {
+    final VarDesc v = locals._getVarDesc(variable);
+    if (v.isCaptured) {
+      assert(v.isAllocated);
+      v.originalParamSlotIndex = paramSlotIndex;
+      return;
+    }
+
+    assert(!v.isAllocated);
+    assert(v.scope == _currentScope);
+
+    if (paramSlotIndex != null) {
+      assert(paramSlotIndex < 0 ||
+          (_currentFrame.hasOptionalParameters &&
+              paramSlotIndex < _currentFrame.numParameters));
+      v.index = paramSlotIndex;
+    } else {
+      v.index = _currentScope.localsUsed++;
+    }
+    _updateFrameSize();
+  }
+
+  void _ensureVariableAllocated(VariableDeclaration variable) {
+    if (variable != null) {
+      final VarDesc v = locals._getVarDesc(variable);
+      if (!v.isAllocated) {
+        _allocateVariable(variable);
+      }
+    }
+  }
+
+  void _allocateParameter(VariableDeclaration node, int i) {
+    final numParameters = _currentFrame.numParameters;
+    assert(0 <= i && i < numParameters);
+    int paramSlotIndex = _currentFrame.hasOptionalParameters
+        ? i
+        : -kParamEndSlotFromFp - numParameters + i;
+    _allocateVariable(node, paramSlotIndex: paramSlotIndex);
+  }
+
+  void _allocateParameters(TreeNode node, FunctionNode function) {
+    final bool hasTypeArgs = function.typeParameters.isNotEmpty;
+    final bool hasReceiver =
+        node is Constructor || (node is Procedure && !node.isStatic);
+    final bool hasClosureArg =
+        node is FunctionDeclaration || node is FunctionExpression;
+
+    _currentFrame.numParameters = function.positionalParameters.length +
+        function.namedParameters.length +
+        (hasTypeArgs ? 1 : 0) +
+        (hasReceiver ? 1 : 0) +
+        (hasClosureArg ? 1 : 0);
+
+    _currentFrame.hasOptionalParameters = function.requiredParameterCount <
+            function.positionalParameters.length ||
+        function.namedParameters.isNotEmpty;
+
+    _currentFrame.hasCapturedParameters =
+        (hasReceiver && locals.isCaptured(_currentFrame.receiverVar)) ||
+            function.positionalParameters.any(locals.isCaptured) ||
+            function.namedParameters.any(locals.isCaptured);
+
+    int count = 0;
+    if (hasTypeArgs) {
+      assert(!locals.isCaptured(_currentFrame.typeArgsVar));
+      _allocateParameter(_currentFrame.typeArgsVar, count++);
+    }
+    if (hasReceiver) {
+      _allocateParameter(_currentFrame.receiverVar, count++);
+    }
+    if (hasClosureArg) {
+      assert(!locals.isCaptured(_currentFrame.closureVar));
+      _allocateParameter(_currentFrame.closureVar, count++);
+    }
+    for (var param in function.positionalParameters) {
+      _allocateParameter(param, count++);
+    }
+    for (var param in function.namedParameters) {
+      _allocateParameter(param, count++);
+    }
+    assert(count == _currentFrame.numParameters);
+
+    if (_currentFrame.hasOptionalParameters) {
+      _currentScope.localsUsed = _currentFrame.numParameters;
+      _updateFrameSize();
+    }
+  }
+
+  void _allocateSpecialVariables() {
+    _ensureVariableAllocated(_currentFrame.typeArgsVar);
+    _ensureVariableAllocated(_currentFrame.contextVar);
+    _ensureVariableAllocated(_currentFrame.scratchVar);
+  }
+
+  void _visitFunction(TreeNode node) {
+    _enterScope(node);
+
+    if (node is Field) {
+      _allocateSpecialVariables();
       node.initializer.accept(this);
-      _leaveScope();
+    } else {
+      assert(node is Procedure ||
+          node is Constructor ||
+          node is FunctionDeclaration ||
+          node is FunctionExpression);
 
-      assert(_scopes.isEmpty);
+      final FunctionNode function = (node as dynamic).function;
+      assert(function != null);
+
+      _allocateParameters(node, function);
+      _allocateSpecialVariables();
+
+      if (node is Constructor) {
+        for (var field in node.enclosingClass.fields) {
+          if (!field.isStatic && field.initializer != null) {
+            field.initializer.accept(this);
+          }
+        }
+        visitList(node.initializers, this);
+      }
+
+      function.body?.accept(this);
+    }
+
+    _leaveScope();
+  }
+
+  void _visit(TreeNode node, {bool scope: false, int temps: 0}) {
+    if (scope) {
+      _enterScope(node);
+    }
+    if (temps > 0) {
+      _allocateTemp(node, count: temps);
+    }
+
+    node.visitChildren(this);
+
+    if (temps > 0) {
+      _freeTemp(node, count: temps);
+    }
+    if (scope) {
+      _leaveScope();
     }
   }
 
   @override
   defaultMember(Member node) {
-    assert(_vars.isEmpty);
-    assert(_localVars == 0);
-
-    final function = node.function;
-    final bool hasTypeArgs = function.typeParameters.isNotEmpty;
-    final bool hasReceiver =
-        node is Constructor || ((node is Procedure) && !node.isStatic);
-    _numParameters = function.positionalParameters.length +
-        function.namedParameters.length +
-        (hasTypeArgs ? 1 : 0) +
-        (hasReceiver ? 1 : 0);
-    _hasOptionalParameters = function.requiredParameterCount <
-            function.positionalParameters.length ||
-        function.namedParameters.isNotEmpty;
-    int count = 0;
-
-    if (hasTypeArgs) {
-      _functionTypeArgsVarIndex = _allocateParameter(null, count++);
-    }
-
-    if (hasReceiver) {
-      _thisVarIndex = _allocateParameter(null, count++);
-    }
-
-    for (var param in function.positionalParameters) {
-      _allocateParameter(param, count++);
-    }
-
-    List<VariableDeclaration> namedParams = function.namedParameters;
-    namedParams.sort((VariableDeclaration a, VariableDeclaration b) =>
-        a.name.compareTo(b.name));
-    for (var param in namedParams) {
-      _allocateParameter(param, count++);
-    }
-
-    if (_hasOptionalParameters) {
-      _localVars = _numParameters;
-      _frameSize = _numParameters;
-    }
-
-    _enterScope();
-    if (node is Constructor) {
-      _enterScope();
-      for (var field in node.enclosingClass.fields) {
-        if (!field.isStatic && field.initializer != null) {
-          field.initializer.accept(this);
-        }
-      }
-      visitList(node.initializers, this);
-      _leaveScope();
-    }
-    function.body?.accept(this);
-    _leaveScope();
-
-    assert(_scopes.isEmpty);
+    _visitFunction(node);
   }
 
   @override
-  visitBlock(Block node) {
-    _enterScope();
-    node.visitChildren(this);
-    _leaveScope();
+  visitFunctionDeclaration(FunctionDeclaration node) {
+    _allocateVariable(node.variable);
+    _allocateTemp(node);
+    _visitFunction(node);
+    _freeTemp(node);
+  }
+
+  @override
+  visitFunctionExpression(FunctionExpression node) {
+    _allocateTemp(node);
+    _visitFunction(node);
+    _freeTemp(node);
   }
 
   @override
   visitVariableDeclaration(VariableDeclaration node) {
-    _allocateVar(node);
+    _allocateVariable(node);
     node.visitChildren(this);
   }
 
   @override
-  visitLet(Let node) {
-    _enterScope();
+  visitBlock(Block node) {
+    _visit(node, scope: true);
+  }
+
+  @override
+  visitAssertBlock(AssertBlock node) {
+    _visit(node, scope: true);
+  }
+
+  @override
+  visitForStatement(ForStatement node) {
+    _visit(node, scope: true);
+  }
+
+  @override
+  visitForInStatement(ForInStatement node) {
+    _allocateTemp(node);
+
+    node.iterable.accept(this);
+
+    _enterScope(node);
     node.variable.accept(this);
     node.body.accept(this);
     _leaveScope();
+
+    _freeTemp(node);
+  }
+
+  @override
+  visitCatch(Catch node) {
+    _visit(node, scope: true);
+  }
+
+  @override
+  visitLet(Let node) {
+    _visit(node, scope: true);
   }
 
   // -------------- Allocation of temporaries --------------
@@ -178,8 +702,7 @@
     if (node.isConst) {
       return;
     }
-    _allocateTemp(node);
-    super.visitConstructorInvocation(node);
+    _visit(node, temps: 1);
   }
 
   @override
@@ -187,8 +710,7 @@
     if (node.isConst) {
       return;
     }
-    _allocateTemp(node);
-    super.visitListLiteral(node);
+    _visit(node, temps: 1);
   }
 
   @override
@@ -196,44 +718,37 @@
     if (node.isConst) {
       return;
     }
-    _allocateTemp(node);
-    super.visitMapLiteral(node);
+    _visit(node, temps: 1);
   }
 
   @override
   visitStringConcatenation(StringConcatenation node) {
-    _allocateTemp(node);
-    super.visitStringConcatenation(node);
+    _visit(node, temps: 1);
   }
 
   @override
   visitConditionalExpression(ConditionalExpression node) {
-    _allocateTemp(node);
-    super.visitConditionalExpression(node);
+    _visit(node, temps: 1);
   }
 
   @override
   visitLogicalExpression(LogicalExpression node) {
-    _allocateTemp(node);
-    super.visitLogicalExpression(node);
+    _visit(node, temps: 1);
   }
 
   @override
   visitPropertySet(PropertySet node) {
-    _allocateTemp(node);
-    super.visitPropertySet(node);
-  }
-
-  @override
-  visitForInStatement(ForInStatement node) {
-    _allocateTemp(node);
-    super.visitForInStatement(node);
+    _visit(node, temps: 1);
   }
 
   @override
   visitSwitchStatement(SwitchStatement node) {
-    _allocateTemp(node);
-    super.visitSwitchStatement(node);
+    _visit(node, temps: 1);
+  }
+
+  @override
+  visitVariableSet(VariableSet node) {
+    _visit(node, temps: locals.isCaptured(node.variable) ? 1 : 0);
   }
 
   @override
@@ -241,4 +756,14 @@
     _allocateTemp(node);
     super.visitStaticSet(node);
   }
+
+  @override
+  visitTryCatch(TryCatch node) {
+    _visit(node, temps: 2);
+  }
+
+  @override
+  visitTryFinally(TryFinally node) {
+    _visit(node, temps: 2);
+  }
 }
diff --git a/pkg/vm/lib/frontend_server.dart b/pkg/vm/lib/frontend_server.dart
index d950c1e..c38213d 100644
--- a/pkg/vm/lib/frontend_server.dart
+++ b/pkg/vm/lib/frontend_server.dart
@@ -25,7 +25,8 @@
 import 'package:kernel/ast.dart';
 import 'package:kernel/binary/ast_to_binary.dart';
 import 'package:kernel/binary/limited_ast_to_binary.dart';
-import 'package:kernel/kernel.dart' show Component, loadComponentFromBytes;
+import 'package:kernel/kernel.dart'
+    show Component, loadComponentSourceFromBytes;
 import 'package:kernel/target/targets.dart';
 import 'package:path/path.dart' as path;
 import 'package:usage/uuid/uuid.dart';
@@ -88,7 +89,12 @@
           ' option',
       defaultsTo: 'org-dartlang-root',
       hide: true)
-  ..addFlag('verbose', help: 'Enables verbose output from the compiler.');
+  ..addFlag('verbose', help: 'Enables verbose output from the compiler.')
+  ..addOption('initialize-from-dill',
+      help: 'Normally the output dill is used to specify which dill to '
+          'initialize from, but it can be overwritten here.',
+      defaultsTo: null,
+      hide: true);
 
 String usage = '''
 Usage: server [options] [input.dart]
@@ -179,6 +185,7 @@
   String _kernelBinaryFilename;
   String _kernelBinaryFilenameIncremental;
   String _kernelBinaryFilenameFull;
+  String _initializeFromDill;
 
   final ProgramTransformer transformer;
 
@@ -203,6 +210,8 @@
             ? '${_options["output-dill"]}.incremental.dill'
             : '$filename.incremental.dill');
     _kernelBinaryFilename = _kernelBinaryFilenameFull;
+    _initializeFromDill =
+        _options['initialize-from-dill'] ?? _kernelBinaryFilenameFull;
     final String boundaryKey = new Uuid().generateV4();
     _outputStream.writeln('result $boundaryKey');
     final Uri sdkRoot = _ensureFolderPath(options['sdk-root']);
@@ -270,9 +279,9 @@
     Component component;
     if (options['incremental']) {
       _compilerOptions = compilerOptions;
-      _generator = generator ??
-          _createGenerator(new Uri.file(_kernelBinaryFilenameFull));
-      await invalidateIfBootstrapping();
+      _generator =
+          generator ?? _createGenerator(new Uri.file(_initializeFromDill));
+      await invalidateIfInitializingFromDill();
       component = await _runWithPrintRedirection(() => _generator.compile());
     } else {
       if (options['link-platform']) {
@@ -321,18 +330,19 @@
     await sink.close();
   }
 
-  Future<Null> invalidateIfBootstrapping() async {
+  Future<Null> invalidateIfInitializingFromDill() async {
     if (_kernelBinaryFilename != _kernelBinaryFilenameFull) return null;
-    // If the generator is initialized bootstrapping is not in effect anyway,
-    // so there's no reason to spend time invalidating what should be
-    // invalidated by the normal approach anyway.
+    // If the generator is initialized, it's not going to initialize from dill
+    // again anyway, so there's no reason to spend time invalidating what should
+    // be invalidated by the normal approach anyway.
     if (_generator.initialized) return null;
 
     try {
-      final File f = new File(_kernelBinaryFilenameFull);
+      final File f = new File(_initializeFromDill);
       if (!f.existsSync()) return null;
 
-      final Component component = loadComponentFromBytes(f.readAsBytesSync());
+      final Component component =
+          loadComponentSourceFromBytes(f.readAsBytesSync());
       for (Uri uri in component.uriToSource.keys) {
         if ('$uri' == '') continue;
 
@@ -357,8 +367,8 @@
       }
     } catch (e) {
       // If there's a failure in the above block we might not have invalidated
-      // correctly. Create a new generator that doesn't bootstrap to avoid missing
-      // any changes.
+      // correctly. Create a new generator that doesn't initialize from dill to
+      // avoid missing any changes.
       _generator = _createGenerator(null);
     }
   }
@@ -367,7 +377,7 @@
   Future<Null> recompileDelta({String filename}) async {
     final String boundaryKey = new Uuid().generateV4();
     _outputStream.writeln('result $boundaryKey');
-    await invalidateIfBootstrapping();
+    await invalidateIfInitializingFromDill();
     if (filename != null) {
       setMainSourceFilename(filename);
     }
@@ -421,9 +431,9 @@
     return Uri.base.resolveUri(new Uri.file(fileOrUri));
   }
 
-  IncrementalCompiler _createGenerator(Uri bootstrapDill) {
+  IncrementalCompiler _createGenerator(Uri initializeFromDillUri) {
     return new IncrementalCompiler(_compilerOptions, _mainSource,
-        bootstrapDill: bootstrapDill);
+        initializeFromDillUri: initializeFromDillUri);
   }
 
   Uri _ensureFolderPath(String path) {
@@ -454,6 +464,7 @@
   file.write(_escapePath(output));
   file.write(':');
   for (Uri dep in component.uriToSource.keys) {
+    if (dep == null) continue;
     file.write(' ');
     file.write(_escapePath(dep.toFilePath()));
   }
diff --git a/pkg/vm/lib/incremental_compiler.dart b/pkg/vm/lib/incremental_compiler.dart
index 91d9426..f52a72a 100644
--- a/pkg/vm/lib/incremental_compiler.dart
+++ b/pkg/vm/lib/incremental_compiler.dart
@@ -10,6 +10,8 @@
 import 'package:front_end/src/api_prototype/incremental_kernel_generator.dart';
 import 'package:kernel/kernel.dart';
 
+const String kDebugProcedureName = ":Eval";
+
 /// Wrapper around [IncrementalKernelGenerator] that keeps track of rejected
 /// deltas and combines them together into resultant program until it is
 /// accepted.
@@ -19,11 +21,12 @@
   CompilerOptions _compilerOptions;
   bool initialized = false;
   bool fullComponent = false;
+  Uri initializeFromDillUri;
 
   IncrementalCompiler(this._compilerOptions, Uri entryPoint,
-      {Uri bootstrapDill}) {
+      {this.initializeFromDillUri}) {
     _generator = new IncrementalKernelGenerator(
-        _compilerOptions, entryPoint, bootstrapDill);
+        _compilerOptions, entryPoint, initializeFromDillUri);
     _pendingDeltas = <Component>[];
   }
 
@@ -74,4 +77,30 @@
     _pendingDeltas.clear();
     fullComponent = true;
   }
+
+  Future<Procedure> compileExpression(
+      String expression,
+      List<String> definitions,
+      List<String> typeDefinitions,
+      String libraryUri,
+      String klass,
+      bool isStatic) {
+    Map<String, DartType> completeDefinitions = {};
+    for (String name in definitions) {
+      if (!isLegalIdentifier(name)) continue;
+      completeDefinitions[name] = new DynamicType();
+    }
+
+    List<TypeParameter> typeParameters = [];
+    for (String name in typeDefinitions) {
+      if (!isLegalIdentifier(name)) continue;
+      typeParameters.add(new TypeParameter(name, new DynamicType()));
+    }
+
+    Uri library = Uri.parse(libraryUri);
+    if (library == null) return null;
+
+    return _generator.compileExpression(expression, completeDefinitions,
+        typeParameters, kDebugProcedureName, library, klass, isStatic);
+  }
 }
diff --git a/pkg/vm/lib/kernel_front_end.dart b/pkg/vm/lib/kernel_front_end.dart
index 8bf56e0..7d3cec8 100644
--- a/pkg/vm/lib/kernel_front_end.dart
+++ b/pkg/vm/lib/kernel_front_end.dart
@@ -7,16 +7,34 @@
 
 import 'dart:async';
 
+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/fasta_codes.dart' as codes;
+
 import 'package:front_end/src/api_prototype/compiler_options.dart'
-    show CompilerOptions, ErrorHandler;
+    show CompilerOptions, ProblemHandler;
 import 'package:front_end/src/api_prototype/kernel_generator.dart'
     show kernelForProgram;
 import 'package:front_end/src/api_prototype/compilation_message.dart'
-    show CompilationMessage, Severity;
-import 'package:front_end/src/fasta/severity.dart' show Severity;
-import 'package:kernel/ast.dart' show Component, StaticGet, Field;
+    show Severity;
+import 'package:kernel/type_environment.dart' show TypeEnvironment;
+import 'package:kernel/class_hierarchy.dart' show ClassHierarchy;
+import 'package:kernel/ast.dart'
+    show
+        Component,
+        Constant,
+        DartType,
+        Field,
+        FileUriNode,
+        Procedure,
+        StaticGet,
+        TreeNode;
 import 'package:kernel/core_types.dart' show CoreTypes;
-import 'package:vm/bytecode/gen_bytecode.dart' show generateBytecode;
+import 'package:kernel/transformations/constants.dart' as constants;
+import 'package:kernel/vm/constants_native_effects.dart' as vm_constants;
+
+import 'bytecode/gen_bytecode.dart' show generateBytecode;
 
 import 'transformations/devirtualization.dart' as devirtualization
     show transformComponent;
@@ -36,35 +54,59 @@
     {bool aot: false,
     bool useGlobalTypeFlowAnalysis: false,
     List<String> entryPoints,
-    bool genBytecode: false}) async {
+    Map<String, String> environmentDefines,
+    bool genBytecode: false,
+    bool dropAST: false,
+    bool enableAsserts: false,
+    bool enableConstantEvaluation: true}) async {
   // Replace error handler to detect if there are compilation errors.
   final errorDetector =
-      new ErrorDetector(previousErrorHandler: options.onError);
-  options.onError = errorDetector;
+      new ErrorDetector(previousErrorHandler: options.onProblem);
+  options.onProblem = errorDetector;
 
   final component = await kernelForProgram(source, options);
 
-  // Restore error handler (in case 'options' are reused).
-  options.onError = errorDetector.previousErrorHandler;
-
   // Run global transformations only if component is correct.
-  if (aot && (component != null) && !errorDetector.hasCompilationErrors) {
-    _runGlobalTransformations(
-        component, options.strongMode, useGlobalTypeFlowAnalysis, entryPoints);
+  if (aot && component != null) {
+    await _runGlobalTransformations(
+        source,
+        options,
+        component,
+        options.strongMode,
+        useGlobalTypeFlowAnalysis,
+        entryPoints,
+        environmentDefines,
+        enableAsserts,
+        enableConstantEvaluation,
+        errorDetector);
   }
 
+  // Restore error handler (in case 'options' are reused).
+  options.onProblem = errorDetector.previousErrorHandler;
+
   if (genBytecode && component != null) {
-    generateBytecode(component, strongMode: options.strongMode);
+    generateBytecode(component,
+        strongMode: options.strongMode, dropAST: dropAST);
   }
 
   return component;
 }
 
-_runGlobalTransformations(Component component, bool strongMode,
-    bool useGlobalTypeFlowAnalysis, List<String> entryPoints) {
+Future _runGlobalTransformations(
+    Uri source,
+    CompilerOptions compilerOptions,
+    Component component,
+    bool strongMode,
+    bool useGlobalTypeFlowAnalysis,
+    List<String> entryPoints,
+    Map<String, String> environmentDefines,
+    bool enableAsserts,
+    bool enableConstantEvaluation,
+    ErrorDetector errorDetector) async {
   if (strongMode) {
-    final coreTypes = new CoreTypes(component);
+    if (errorDetector.hasCompilationErrors) return;
 
+    final coreTypes = new CoreTypes(component);
     _patchVmConstants(coreTypes);
 
     // TODO(alexmarkov, dmitryas): Consider doing canonicalization of identical
@@ -81,10 +123,56 @@
       devirtualization.transformComponent(coreTypes, component);
     }
 
+    if (enableConstantEvaluation) {
+      await _performConstantEvaluation(source, compilerOptions, component,
+          coreTypes, environmentDefines, strongMode, enableAsserts);
+
+      if (errorDetector.hasCompilationErrors) return;
+    }
+
     no_dynamic_invocations_annotator.transformComponent(component);
   }
 }
 
+Future _performConstantEvaluation(
+    Uri source,
+    CompilerOptions compilerOptions,
+    Component component,
+    CoreTypes coreTypes,
+    Map<String, String> environmentDefines,
+    bool strongMode,
+    bool enableAsserts) async {
+  final vmConstants =
+      new vm_constants.VmConstantsBackend(environmentDefines, coreTypes);
+
+  final processedOptions =
+      new ProcessedOptions(compilerOptions, false, [source]);
+
+  // Run within the context, so we have uri source tokens...
+  await CompilerContext.runWithOptions(processedOptions,
+      (CompilerContext context) async {
+    // To make the fileUri/fileOffset -> line/column mapping, we need to
+    // pre-fill the map.
+    context.uriToSource.addAll(component.uriToSource);
+
+    final hierarchy = new ClassHierarchy(component);
+    final typeEnvironment =
+        new TypeEnvironment(coreTypes, hierarchy, strongMode: strongMode);
+
+    // NOTE: Currently we keep fields, because there are certain constant
+    // fields which the VM accesses (e.g. `_Random._A` needs to be preserved).
+    // TODO(kustermann): We should use the entrypoints manifest to find out
+    // which fields need to be preserved and remove the rest.
+    constants.transformComponent(component, vmConstants,
+        keepFields: true,
+        strongMode: true,
+        evaluateAnnotations: false,
+        enableAsserts: enableAsserts,
+        errorReporter:
+            new ForwardConstantEvaluationErrors(context, typeEnvironment));
+  });
+}
+
 void _patchVmConstants(CoreTypes coreTypes) {
   // Fix Endian.host to be a const field equal to Endial.little instead of
   // a final field. VM does not support big-endian architectures at the
@@ -101,16 +189,147 @@
 }
 
 class ErrorDetector {
-  final ErrorHandler previousErrorHandler;
+  final ProblemHandler previousErrorHandler;
   bool hasCompilationErrors = false;
 
   ErrorDetector({this.previousErrorHandler});
 
-  void call(CompilationMessage message) {
-    if (message.severity == Severity.error) {
+  void call(codes.FormattedMessage problem, Severity severity,
+      List<codes.FormattedMessage> context) {
+    if (severity == Severity.error) {
       hasCompilationErrors = true;
     }
 
-    previousErrorHandler?.call(message);
+    previousErrorHandler?.call(problem, severity, context);
+  }
+}
+
+class ErrorPrinter {
+  final ProblemHandler previousErrorHandler;
+  final compilationMessages = <Uri, List<List>>{};
+
+  ErrorPrinter({this.previousErrorHandler});
+
+  void call(codes.FormattedMessage problem, Severity severity,
+      List<codes.FormattedMessage> context) {
+    final sourceUri = problem.locatedMessage.uri;
+    compilationMessages.putIfAbsent(sourceUri, () => [])
+      ..add([problem, context]);
+    previousErrorHandler?.call(problem, severity, context);
+  }
+
+  void printCompilationMessages(Uri baseUri) {
+    final sortedUris = compilationMessages.keys.toList()
+      ..sort((a, b) => '$a'.compareTo('$b'));
+    for (final Uri sourceUri in sortedUris) {
+      for (final List errorTuple in compilationMessages[sourceUri]) {
+        final codes.FormattedMessage message = errorTuple.first;
+        print(message.formatted);
+
+        final List context = errorTuple.last;
+        for (final codes.FormattedMessage message in context?.reversed) {
+          print(message.formatted);
+        }
+      }
+    }
+  }
+}
+
+class ForwardConstantEvaluationErrors implements constants.ErrorReporter {
+  final CompilerContext compilerContext;
+  final TypeEnvironment typeEnvironment;
+
+  ForwardConstantEvaluationErrors(this.compilerContext, this.typeEnvironment);
+
+  duplicateKey(List<TreeNode> context, TreeNode node, Constant key) {
+    final message = codes.templateConstEvalDuplicateKey.withArguments(key);
+    reportIt(context, message, node);
+  }
+
+  invalidDartType(List<TreeNode> context, TreeNode node, Constant receiver,
+      DartType expectedType) {
+    final message = codes.templateConstEvalInvalidType.withArguments(
+        receiver, expectedType, receiver.getType(typeEnvironment));
+    reportIt(context, message, node);
+  }
+
+  invalidBinaryOperandType(
+      List<TreeNode> context,
+      TreeNode node,
+      Constant receiver,
+      String op,
+      DartType expectedType,
+      DartType actualType) {
+    final message = codes.templateConstEvalInvalidBinaryOperandType
+        .withArguments(op, receiver, expectedType, actualType);
+    reportIt(context, message, node);
+  }
+
+  invalidMethodInvocation(
+      List<TreeNode> context, TreeNode node, Constant receiver, String op) {
+    final message = codes.templateConstEvalInvalidMethodInvocation
+        .withArguments(op, receiver);
+    reportIt(context, message, node);
+  }
+
+  invalidStaticInvocation(
+      List<TreeNode> context, TreeNode node, Procedure target) {
+    final message = codes.templateConstEvalInvalidStaticInvocation
+        .withArguments(target.name.toString());
+    reportIt(context, message, node);
+  }
+
+  invalidStringInterpolationOperand(
+      List<TreeNode> context, TreeNode node, Constant constant) {
+    final message = codes.templateConstEvalInvalidStringInterpolationOperand
+        .withArguments(constant);
+    reportIt(context, message, node);
+  }
+
+  nonConstLiteral(List<TreeNode> context, TreeNode node, String klass) {
+    final message =
+        codes.templateConstEvalNonConstantLiteral.withArguments(klass);
+    reportIt(context, message, node);
+  }
+
+  failedAssertion(List<TreeNode> context, TreeNode node, String string) {
+    final message = string == null
+        ? codes.messageConstEvalFailedAssertion
+        : codes.templateConstEvalFailedAssertionWithMessage
+            .withArguments(string);
+    reportIt(context, message, node);
+  }
+
+  reportIt(List<TreeNode> context, codes.Message message, TreeNode node) {
+    final Uri uri = getFileUri(node);
+    final int fileOffset = getFileOffset(node);
+
+    final contextMessages = <codes.LocatedMessage>[];
+    for (final TreeNode node in context) {
+      final Uri uri = getFileUri(node);
+      final int fileOffset = getFileOffset(node);
+      contextMessages.add(codes.messageConstEvalContext
+          .withLocation(uri, fileOffset, codes.noLength));
+    }
+
+    final locatedMessage =
+        message.withLocation(uri, fileOffset, codes.noLength);
+
+    compilerContext.options
+        .report(locatedMessage, Severity.error, context: contextMessages);
+  }
+
+  getFileUri(TreeNode node) {
+    while (node is! FileUriNode) {
+      node = node.parent;
+    }
+    return (node as FileUriNode).fileUri;
+  }
+
+  getFileOffset(TreeNode node) {
+    while (node.fileOffset == TreeNode.noOffset) {
+      node = node.parent;
+    }
+    return node == null ? TreeNode.noOffset : node.fileOffset;
   }
 }
diff --git a/pkg/vm/lib/metadata/bytecode.dart b/pkg/vm/lib/metadata/bytecode.dart
index 1c28c0e..3d5261f 100644
--- a/pkg/vm/lib/metadata/bytecode.dart
+++ b/pkg/vm/lib/metadata/bytecode.dart
@@ -7,17 +7,82 @@
 import 'package:kernel/ast.dart';
 import 'package:vm/bytecode/constant_pool.dart' show ConstantPool;
 import 'package:vm/bytecode/disassembler.dart' show BytecodeDisassembler;
+import 'package:vm/bytecode/exceptions.dart' show ExceptionsTable;
 
 /// Metadata containing bytecode.
+///
+/// In kernel binary, bytecode metadata is encoded as following:
+///
+/// type BytecodeMetadata {
+///   List<Byte> bytecodes
+///   ExceptionsTable exceptionsTable
+///   ConstantPool constantPool
+///   List<ClosureBytecode> closures
+/// }
+///
+/// type ClosureBytecode {
+///   ConstantIndex closureFunction
+///   List<Byte> bytecodes
+///   ExceptionsTable exceptionsTable
+/// }
+///
+/// Encoding of ExceptionsTable is described in
+/// pkg/vm/lib/bytecode/exceptions.dart.
+///
+/// Encoding of ConstantPool is described in
+/// pkg/vm/lib/bytecode/constant_pool.dart.
+///
 class BytecodeMetadata {
   final List<int> bytecodes;
+  final ExceptionsTable exceptionsTable;
   final ConstantPool constantPool;
+  final List<ClosureBytecode> closures;
 
-  BytecodeMetadata(this.bytecodes, this.constantPool);
+  BytecodeMetadata(
+      this.bytecodes, this.exceptionsTable, this.constantPool, this.closures);
 
   @override
-  String toString() =>
-      "\nBytecode {\n${new BytecodeDisassembler().disassemble(bytecodes)}}\n$constantPool";
+  String toString() => "\n"
+      "Bytecode {\n"
+      "${new BytecodeDisassembler().disassemble(bytecodes, exceptionsTable)}}\n"
+      "$exceptionsTable"
+      "$constantPool"
+      "${closures.join('\n')}";
+}
+
+/// Bytecode of a nested function (closure).
+/// Closures share the constant pool of a top-level member.
+class ClosureBytecode {
+  final int closureFunctionConstantIndex;
+  final List<int> bytecodes;
+  final ExceptionsTable exceptionsTable;
+
+  ClosureBytecode(
+      this.closureFunctionConstantIndex, this.bytecodes, this.exceptionsTable);
+
+  void writeToBinary(BinarySink sink) {
+    sink.writeUInt30(closureFunctionConstantIndex);
+    sink.writeByteList(bytecodes);
+    exceptionsTable.writeToBinary(sink);
+  }
+
+  factory ClosureBytecode.readFromBinary(BinarySource source) {
+    final closureFunctionConstantIndex = source.readUInt();
+    final List<int> bytecodes = source.readByteList();
+    final exceptionsTable = new ExceptionsTable.readFromBinary(source);
+    return new ClosureBytecode(
+        closureFunctionConstantIndex, bytecodes, exceptionsTable);
+  }
+
+  @override
+  String toString() {
+    StringBuffer sb = new StringBuffer();
+    sb.writeln('Closure CP#$closureFunctionConstantIndex {');
+    sb.writeln(
+        new BytecodeDisassembler().disassemble(bytecodes, exceptionsTable));
+    sb.writeln('}');
+    return sb.toString();
+  }
 }
 
 /// Repository for [BytecodeMetadata].
@@ -30,15 +95,23 @@
       <TreeNode, BytecodeMetadata>{};
 
   @override
-  void writeToBinary(BytecodeMetadata metadata, BinarySink sink) {
+  void writeToBinary(BytecodeMetadata metadata, Node node, BinarySink sink) {
     sink.writeByteList(metadata.bytecodes);
-    metadata.constantPool.writeToBinary(sink);
+    metadata.exceptionsTable.writeToBinary(sink);
+    metadata.constantPool.writeToBinary(node, sink);
+    sink.writeUInt30(metadata.closures.length);
+    metadata.closures.forEach((c) => c.writeToBinary(sink));
   }
 
   @override
-  BytecodeMetadata readFromBinary(BinarySource source) {
+  BytecodeMetadata readFromBinary(Node node, BinarySource source) {
     final List<int> bytecodes = source.readByteList();
-    final ConstantPool constantPool = new ConstantPool.readFromBinary(source);
-    return new BytecodeMetadata(bytecodes, constantPool);
+    final exceptionsTable = new ExceptionsTable.readFromBinary(source);
+    final ConstantPool constantPool =
+        new ConstantPool.readFromBinary(node, source);
+    final List<ClosureBytecode> closures = new List<ClosureBytecode>.generate(
+        source.readUInt(), (_) => new ClosureBytecode.readFromBinary(source));
+    return new BytecodeMetadata(
+        bytecodes, exceptionsTable, constantPool, closures);
   }
 }
diff --git a/pkg/vm/lib/metadata/direct_call.dart b/pkg/vm/lib/metadata/direct_call.dart
index 570e303..dd9348c 100644
--- a/pkg/vm/lib/metadata/direct_call.dart
+++ b/pkg/vm/lib/metadata/direct_call.dart
@@ -34,13 +34,13 @@
       <TreeNode, DirectCallMetadata>{};
 
   @override
-  void writeToBinary(DirectCallMetadata metadata, BinarySink sink) {
+  void writeToBinary(DirectCallMetadata metadata, Node node, BinarySink sink) {
     sink.writeCanonicalNameReference(getCanonicalNameOfMember(metadata.target));
     sink.writeByte(metadata.checkReceiverForNull ? 1 : 0);
   }
 
   @override
-  DirectCallMetadata readFromBinary(BinarySource source) {
+  DirectCallMetadata readFromBinary(Node node, BinarySource source) {
     final targetReference = source.readCanonicalNameReference()?.getReference();
     if (targetReference == null) {
       throw 'DirectCallMetadata should have a non-null target';
diff --git a/pkg/vm/lib/metadata/inferred_type.dart b/pkg/vm/lib/metadata/inferred_type.dart
index dafb370..17daf11 100644
--- a/pkg/vm/lib/metadata/inferred_type.dart
+++ b/pkg/vm/lib/metadata/inferred_type.dart
@@ -32,14 +32,14 @@
   final Map<TreeNode, InferredType> mapping = <TreeNode, InferredType>{};
 
   @override
-  void writeToBinary(InferredType metadata, BinarySink sink) {
+  void writeToBinary(InferredType metadata, Node node, BinarySink sink) {
     sink.writeCanonicalNameReference(
         getCanonicalNameOfClass(metadata.concreteClass));
     sink.writeByte(metadata.nullable ? 1 : 0);
   }
 
   @override
-  InferredType readFromBinary(BinarySource source) {
+  InferredType readFromBinary(Node node, BinarySource source) {
     final concreteClassReference =
         source.readCanonicalNameReference()?.getReference();
     final nullable = (source.readByte() != 0);
diff --git a/pkg/vm/lib/metadata/procedure_attributes.dart b/pkg/vm/lib/metadata/procedure_attributes.dart
index 5581074..531f7d2 100644
--- a/pkg/vm/lib/metadata/procedure_attributes.dart
+++ b/pkg/vm/lib/metadata/procedure_attributes.dart
@@ -39,7 +39,8 @@
       <TreeNode, ProcedureAttributesMetadata>{};
 
   @override
-  void writeToBinary(ProcedureAttributesMetadata metadata, BinarySink sink) {
+  void writeToBinary(
+      ProcedureAttributesMetadata metadata, Node node, BinarySink sink) {
     int flags = 0;
     if (metadata.hasDynamicUses) {
       flags |= kDynamicUsesBit;
@@ -54,7 +55,7 @@
   }
 
   @override
-  ProcedureAttributesMetadata readFromBinary(BinarySource source) {
+  ProcedureAttributesMetadata readFromBinary(Node node, BinarySource source) {
     final int flags = source.readByte();
 
     final bool hasDynamicUses = (flags & kDynamicUsesBit) == kDynamicUsesBit;
diff --git a/pkg/vm/lib/metadata/unreachable.dart b/pkg/vm/lib/metadata/unreachable.dart
index aff77e2..a4c44e0 100644
--- a/pkg/vm/lib/metadata/unreachable.dart
+++ b/pkg/vm/lib/metadata/unreachable.dart
@@ -26,10 +26,10 @@
   final Map<TreeNode, UnreachableNode> mapping = <TreeNode, UnreachableNode>{};
 
   @override
-  void writeToBinary(UnreachableNode metadata, BinarySink sink) {}
+  void writeToBinary(UnreachableNode metadata, Node node, BinarySink sink) {}
 
   @override
-  UnreachableNode readFromBinary(BinarySource source) {
+  UnreachableNode readFromBinary(Node node, BinarySource source) {
     return const UnreachableNode();
   }
 }
diff --git a/pkg/vm/lib/transformations/devirtualization.dart b/pkg/vm/lib/transformations/devirtualization.dart
index 479755d..b83c1cf 100644
--- a/pkg/vm/lib/transformations/devirtualization.dart
+++ b/pkg/vm/lib/transformations/devirtualization.dart
@@ -7,7 +7,7 @@
 import 'package:kernel/ast.dart';
 import 'package:kernel/core_types.dart' show CoreTypes;
 import 'package:kernel/class_hierarchy.dart'
-    show ClassHierarchy, ClosedWorldClassHierarchy;
+    show ClassHierarchy, ClassHierarchySubtypes, ClosedWorldClassHierarchy;
 
 import '../metadata/direct_call.dart';
 
@@ -15,9 +15,10 @@
 /// analysis. Assumes strong mode and closed world.
 Component transformComponent(CoreTypes coreTypes, Component component) {
   void ignoreAmbiguousSupertypes(Class cls, Supertype a, Supertype b) {}
-  final hierarchy = new ClassHierarchy(component,
+  ClosedWorldClassHierarchy hierarchy = new ClassHierarchy(component,
       onAmbiguousSupertypes: ignoreAmbiguousSupertypes);
-  new CHADevirtualization(coreTypes, component, hierarchy)
+  final hierarchySubtypes = hierarchy.computeSubtypesInformation();
+  new CHADevirtualization(coreTypes, component, hierarchy, hierarchySubtypes)
       .visitComponent(component);
   return component;
 }
@@ -140,15 +141,16 @@
 
 /// Devirtualization based on the closed-world class hierarchy analysis.
 class CHADevirtualization extends Devirtualization {
-  final ClosedWorldClassHierarchy _hierarchy;
+  final ClassHierarchySubtypes _hierarchySubtype;
 
-  CHADevirtualization(CoreTypes coreTypes, Component component, this._hierarchy)
-      : super(coreTypes, component, _hierarchy);
+  CHADevirtualization(CoreTypes coreTypes, Component component,
+      ClosedWorldClassHierarchy hierarchy, this._hierarchySubtype)
+      : super(coreTypes, component, hierarchy);
 
   @override
   DirectCallMetadata getDirectCall(TreeNode node, Member target,
       {bool setter = false}) {
-    Member singleTarget = _hierarchy
+    Member singleTarget = _hierarchySubtype
         .getSingleTargetForInterfaceInvocation(target, setter: setter);
     if (singleTarget == null) {
       return null;
diff --git a/pkg/vm/lib/transformations/no_dynamic_invocations_annotator.dart b/pkg/vm/lib/transformations/no_dynamic_invocations_annotator.dart
index aff93fa..9806c89 100644
--- a/pkg/vm/lib/transformations/no_dynamic_invocations_annotator.dart
+++ b/pkg/vm/lib/transformations/no_dynamic_invocations_annotator.dart
@@ -164,13 +164,6 @@
   }
 
   @override
-  visitConstantExpression(ConstantExpression node) {
-    // We run the kernel2kernel "constants" transformation before running the
-    // this transformation, so we will encounter constant expressions.
-    // We don't need to do anything here, because there are no invocations.
-  }
-
-  @override
   visitMethodInvocation(MethodInvocation node) {
     super.visitMethodInvocation(node);
 
diff --git a/pkg/vm/lib/transformations/type_flow/entry_points.json b/pkg/vm/lib/transformations/type_flow/entry_points.json
index 95d1f01..5465003 100644
--- a/pkg/vm/lib/transformations/type_flow/entry_points.json
+++ b/pkg/vm/lib/transformations/type_flow/entry_points.json
@@ -619,6 +619,12 @@
     },
     {
       "library": "dart:core",
+      "class": "_InvocationMirror",
+      "name": "_allocateInvocationMirrorForClosure",
+      "action": "call"
+    },
+    {
+      "library": "dart:core",
       "class": "_TypeError",
       "name": "_TypeError._create",
       "action": "call"
diff --git a/pkg/vm/lib/transformations/type_flow/transformer.dart b/pkg/vm/lib/transformations/type_flow/transformer.dart
index 73e1194..ce9998f 100644
--- a/pkg/vm/lib/transformations/type_flow/transformer.dart
+++ b/pkg/vm/lib/transformations/type_flow/transformer.dart
@@ -379,7 +379,9 @@
 
   void addUsedTypedef(Typedef typedef) {
     if (_usedTypedefs.add(typedef)) {
-      typedef.visitChildren(typeVisitor);
+      transformList(typedef.annotations, _pass1, typedef);
+      visitList(typedef.typeParameters, typeVisitor);
+      typedef.type?.accept(typeVisitor);
     }
   }
 }
@@ -417,6 +419,14 @@
       shaker.addUsedTypedef(typedef);
     }
   }
+
+  @override
+  visitTypeParameterType(TypeParameterType node) {
+    final parent = node.parameter.parent;
+    if (parent is Class) {
+      shaker.addClassUsedInType(parent);
+    }
+  }
 }
 
 /// The first pass of [TreeShaker].
diff --git a/pkg/vm/test/common_test_utils.dart b/pkg/vm/test/common_test_utils.dart
index 20b0126..f31cb60 100644
--- a/pkg/vm/test/common_test_utils.dart
+++ b/pkg/vm/test/common_test_utils.dart
@@ -10,6 +10,7 @@
     show computePlatformBinariesLocation;
 import 'package:kernel/ast.dart';
 import 'package:kernel/text/ast_to_text.dart' show Printer;
+import 'package:kernel/binary/ast_to_binary.dart' show BinaryPrinter;
 import 'package:kernel/target/targets.dart';
 import 'package:kernel/target/vm.dart';
 import 'package:test/test.dart';
@@ -44,6 +45,18 @@
   return buffer.toString();
 }
 
+class DevNullSink<T> extends Sink<T> {
+  @override
+  void add(T data) {}
+
+  @override
+  void close() {}
+}
+
+void ensureKernelCanBeSerializedToBinary(Component component) {
+  new BinaryPrinter(new DevNullSink<List<int>>()).writeComponentFile(component);
+}
+
 void compareResultWithExpectationsFile(Uri source, String actual) {
   final expectFile = new File(source.toFilePath() + '.expect');
   final expected = expectFile.existsSync() ? expectFile.readAsStringSync() : '';
diff --git a/pkg/vm/test/transformations/type_flow/transformer_test.dart b/pkg/vm/test/transformations/type_flow/transformer_test.dart
index 07dcb37..009110a 100644
--- a/pkg/vm/test/transformations/type_flow/transformer_test.dart
+++ b/pkg/vm/test/transformations/type_flow/transformer_test.dart
@@ -30,6 +30,8 @@
   final actual = kernelLibraryToString(component.mainMethod.enclosingLibrary);
 
   compareResultWithExpectationsFile(source, actual);
+
+  ensureKernelCanBeSerializedToBinary(component);
 }
 
 main() {
diff --git a/pkg/vm/testcases/bytecode/boostrapping.dart.expect b/pkg/vm/testcases/bytecode/boostrapping.dart.expect
index 264ed59..ba4d29e 100644
--- a/pkg/vm/testcases/bytecode/boostrapping.dart.expect
+++ b/pkg/vm/testcases/bytecode/boostrapping.dart.expect
@@ -451,7 +451,7 @@
   }
 [@vm.bytecode=
 Bytecode {
-  Entry                2
+  Entry                1
   CheckStack
   PushConstant         CP#0
   PushStatic           CP#0
@@ -478,8 +478,8 @@
   PushConstant         CP#5
   PushStatic           CP#5
   InstanceCall1        1, CP#9
-  StoreLocal           r1
-  Push                 r1
+  StoreLocal           r0
+  Push                 r0
   StoreStaticTOS       CP#0
   Drop1
 L3:
diff --git a/pkg/vm/testcases/bytecode/closures.dart b/pkg/vm/testcases/bytecode/closures.dart
new file mode 100644
index 0000000..102cb0f
--- /dev/null
+++ b/pkg/vm/testcases/bytecode/closures.dart
@@ -0,0 +1,134 @@
+// 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.
+
+int simpleClosure() {
+  int x = 5;
+  var inc = (int y) {
+    x = x + y;
+  };
+  inc(3);
+  return x;
+}
+
+class C1 {}
+
+class C2 {}
+
+class C3 {}
+
+class C4 {}
+
+class C5 {}
+
+class C6 {}
+
+class C7 {}
+
+class C8 {}
+
+class A<T1, T2> {
+  void foo<T3, T4>() {
+    void nested1<T5, T6>() {
+      void nested2<T7, T8>() {
+        var nested3 = () {
+          print([T1, T2, T3, T4, T5, T6, T7, T8]);
+          callWithArgs<T1, T2, T3, T4, T5, T6, T7, T8>();
+        };
+        nested3();
+      }
+
+      nested2<C7, C8>();
+      nested2<List<C7>, List<C8>>();
+    }
+
+    nested1<C5, C6>();
+    nested1<List<C5>, List<C6>>();
+  }
+}
+
+void callWithArgs<T1, T2, T3, T4, T5, T6, T7, T8>() {
+  print([T1, T2, T3, T4, T5, T6, T7, T8]);
+}
+
+void callA() {
+  new A<C1, C2>().foo<C3, C4>();
+  new A<C1, C2>().foo<List<C3>, List<C4>>();
+  new A<List<C1>, List<C2>>().foo<List<C3>, List<C4>>();
+}
+
+class B {
+  int foo;
+
+  void topLevel() {
+    {
+      int x = 1;
+
+      {
+        int y = 2;
+        int z = 3;
+
+        var closure1 = (int y) {
+          x = y + 1;
+
+          if (x > 5) {
+            int w = 4;
+
+            void closure2() {
+              z = x + 2;
+              w = foo + y;
+            }
+
+            closure2();
+
+            print(w);
+          }
+        };
+
+        closure1(10);
+        closure1(11);
+
+        print(y);
+        print(z);
+      }
+
+      print(x);
+    }
+
+    {
+      int x = 42;
+
+      var closure3 = () {
+        foo = x;
+      };
+
+      closure3();
+    }
+  }
+}
+
+class C {
+  void testForLoop() {
+    int delta = 0;
+    List<Function> getI = <Function>[];
+    List<Function> setI = <Function>[];
+    for (int i = 0; i < 10; i++) {
+      getI.add(() => i + delta);
+      setI.add((int ii) {
+        i = ii + delta;
+      });
+    }
+  }
+
+  void testForInLoop(List<int> list) {
+    for (var i in list) {
+      var inc = () {
+        i = i + 1;
+      };
+      inc();
+      print(i);
+    }
+  }
+}
+
+main() {}
diff --git a/pkg/vm/testcases/bytecode/closures.dart.expect b/pkg/vm/testcases/bytecode/closures.dart.expect
new file mode 100644
index 0000000..2f1906c
--- /dev/null
+++ b/pkg/vm/testcases/bytecode/closures.dart.expect
@@ -0,0 +1,1394 @@
+library #lib;
+import self as self;
+import "dart:core" as core;
+
+class C1 extends core::Object {
+[@vm.bytecode=
+Bytecode {
+  Entry                0
+  CheckStack
+  Push                 FP[-5]
+  PushConstant         CP#1
+  IndirectStaticCall   1, CP#0
+  Drop1
+  PushConstant         CP#2
+  ReturnTOS
+}
+ConstantPool {
+  [0] = ArgDesc num-args 1, num-type-args 0, names []
+  [1] = StaticICData target 'dart.core::Object::', arg-desc CP#0
+  [2] = Null
+}
+]  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class C2 extends core::Object {
+[@vm.bytecode=
+Bytecode {
+  Entry                0
+  CheckStack
+  Push                 FP[-5]
+  PushConstant         CP#1
+  IndirectStaticCall   1, CP#0
+  Drop1
+  PushConstant         CP#2
+  ReturnTOS
+}
+ConstantPool {
+  [0] = ArgDesc num-args 1, num-type-args 0, names []
+  [1] = StaticICData target 'dart.core::Object::', arg-desc CP#0
+  [2] = Null
+}
+]  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class C3 extends core::Object {
+[@vm.bytecode=
+Bytecode {
+  Entry                0
+  CheckStack
+  Push                 FP[-5]
+  PushConstant         CP#1
+  IndirectStaticCall   1, CP#0
+  Drop1
+  PushConstant         CP#2
+  ReturnTOS
+}
+ConstantPool {
+  [0] = ArgDesc num-args 1, num-type-args 0, names []
+  [1] = StaticICData target 'dart.core::Object::', arg-desc CP#0
+  [2] = Null
+}
+]  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class C4 extends core::Object {
+[@vm.bytecode=
+Bytecode {
+  Entry                0
+  CheckStack
+  Push                 FP[-5]
+  PushConstant         CP#1
+  IndirectStaticCall   1, CP#0
+  Drop1
+  PushConstant         CP#2
+  ReturnTOS
+}
+ConstantPool {
+  [0] = ArgDesc num-args 1, num-type-args 0, names []
+  [1] = StaticICData target 'dart.core::Object::', arg-desc CP#0
+  [2] = Null
+}
+]  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class C5 extends core::Object {
+[@vm.bytecode=
+Bytecode {
+  Entry                0
+  CheckStack
+  Push                 FP[-5]
+  PushConstant         CP#1
+  IndirectStaticCall   1, CP#0
+  Drop1
+  PushConstant         CP#2
+  ReturnTOS
+}
+ConstantPool {
+  [0] = ArgDesc num-args 1, num-type-args 0, names []
+  [1] = StaticICData target 'dart.core::Object::', arg-desc CP#0
+  [2] = Null
+}
+]  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class C6 extends core::Object {
+[@vm.bytecode=
+Bytecode {
+  Entry                0
+  CheckStack
+  Push                 FP[-5]
+  PushConstant         CP#1
+  IndirectStaticCall   1, CP#0
+  Drop1
+  PushConstant         CP#2
+  ReturnTOS
+}
+ConstantPool {
+  [0] = ArgDesc num-args 1, num-type-args 0, names []
+  [1] = StaticICData target 'dart.core::Object::', arg-desc CP#0
+  [2] = Null
+}
+]  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class C7 extends core::Object {
+[@vm.bytecode=
+Bytecode {
+  Entry                0
+  CheckStack
+  Push                 FP[-5]
+  PushConstant         CP#1
+  IndirectStaticCall   1, CP#0
+  Drop1
+  PushConstant         CP#2
+  ReturnTOS
+}
+ConstantPool {
+  [0] = ArgDesc num-args 1, num-type-args 0, names []
+  [1] = StaticICData target 'dart.core::Object::', arg-desc CP#0
+  [2] = Null
+}
+]  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class C8 extends core::Object {
+[@vm.bytecode=
+Bytecode {
+  Entry                0
+  CheckStack
+  Push                 FP[-5]
+  PushConstant         CP#1
+  IndirectStaticCall   1, CP#0
+  Drop1
+  PushConstant         CP#2
+  ReturnTOS
+}
+ConstantPool {
+  [0] = ArgDesc num-args 1, num-type-args 0, names []
+  [1] = StaticICData target 'dart.core::Object::', arg-desc CP#0
+  [2] = Null
+}
+]  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class A<T1 extends core::Object = dynamic, T2 extends core::Object = dynamic> extends core::Object {
+[@vm.bytecode=
+Bytecode {
+  Entry                0
+  CheckStack
+  Push                 FP[-5]
+  PushConstant         CP#1
+  IndirectStaticCall   1, CP#0
+  Drop1
+  PushConstant         CP#2
+  ReturnTOS
+}
+ConstantPool {
+  [0] = ArgDesc num-args 1, num-type-args 0, names []
+  [1] = StaticICData target 'dart.core::Object::', arg-desc CP#0
+  [2] = Null
+}
+]  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+[@vm.bytecode=
+Bytecode {
+  Entry                4
+  CheckStack
+  AllocateContext      1
+  StoreLocal           r1
+  Push                 r1
+  Push                 r0
+  StoreFieldTOS        CP#0
+  PopLocal             r0
+  Push                 r0
+  Push                 FP[-5]
+  StoreFieldTOS        CP#1
+  Allocate             CP#38
+  StoreLocal           r3
+  Push                 r3
+  Push                 r0
+  LoadFieldTOS         CP#1
+  LoadFieldTOS         CP#17
+  StoreFieldTOS        CP#39
+  Push                 r3
+  Push                 FP[-6]
+  StoreFieldTOS        CP#4
+  Push                 r3
+  PushConstant         CP#2
+  StoreFieldTOS        CP#40
+  Push                 r3
+  Push                 r0
+  StoreFieldTOS        CP#3
+  PopLocal             r2
+  PushConstant         CP#49
+  Push                 r2
+  InstanceCall1        1, CP#50
+  Drop1
+  PushConstant         CP#51
+  Push                 r2
+  InstanceCall1        1, CP#52
+  Drop1
+  PushConstant         CP#36
+  ReturnTOS
+}
+ConstantPool {
+  [0] = ContextOffset parent
+  [1] = ContextOffset var [0]
+  [2] = ClosureFunction nested1 <T5 extends dart.core::Object = dynamic, T6 extends dart.core::Object = dynamic>() → void;
+  [3] = FieldOffset dart.core::_Closure::_context
+  [4] = FieldOffset dart.core::_Closure::_function_type_arguments
+  [5] = Int 2
+  [6] = Int 4
+  [7] = ArgDesc num-args 4, num-type-args 0, names []
+  [8] = StaticICData target 'dart._internal::_prependTypeArguments', arg-desc CP#7
+  [9] = ClosureFunction nested2 <T7 extends dart.core::Object = dynamic, T8 extends dart.core::Object = dynamic>() → void;
+  [10] = Int 6
+  [11] = StaticICData target 'dart._internal::_prependTypeArguments', arg-desc CP#7
+  [12] = ClosureFunction <anonymous closure> () → dart.core::Null;
+  [13] = TypeArgs [dart.core::Type]
+  [14] = Int 8
+  [15] = Int 0
+  [16] = Type #lib::A::T1
+  [17] = TypeArgumentsFieldOffset #lib::A
+  [18] = Int 1
+  [19] = Type #lib::A::T2
+  [20] = Type #lib::A::foo::T3
+  [21] = Int 3
+  [22] = Type #lib::A::foo::T4
+  [23] = Type T5
+  [24] = Int 5
+  [25] = Type T6
+  [26] = Type T7
+  [27] = Int 7
+  [28] = Type T8
+  [29] = ArgDesc num-args 1, num-type-args 1, names []
+  [30] = StaticICData target 'dart.core::List::_fromLiteral', arg-desc CP#29
+  [31] = ArgDesc num-args 1, num-type-args 0, names []
+  [32] = StaticICData target 'dart.core::print', arg-desc CP#31
+  [33] = TypeArgs [#lib::A::T1, #lib::A::T2, #lib::A::foo::T3, #lib::A::foo::T4, T5, T6, T7, T8]
+  [34] = ArgDesc num-args 0, num-type-args 8, names []
+  [35] = StaticICData target '#lib::callWithArgs', arg-desc CP#34
+  [36] = Null
+  [37] = EndClosureFunctionScope
+  [38] = Class dart.core::_Closure
+  [39] = FieldOffset dart.core::_Closure::_instantiator_type_arguments
+  [40] = FieldOffset dart.core::_Closure::_function
+  [41] = ICData target-name 'call', arg-desc CP#31
+  [42] = EndClosureFunctionScope
+  [43] = TypeArgs [#lib::C7, #lib::C8]
+  [44] = ArgDesc num-args 1, num-type-args 2, names []
+  [45] = ICData target-name 'call', arg-desc CP#44
+  [46] = TypeArgs [dart.core::List<#lib::C7>, dart.core::List<#lib::C8>]
+  [47] = ICData target-name 'call', arg-desc CP#44
+  [48] = EndClosureFunctionScope
+  [49] = TypeArgs [#lib::C5, #lib::C6]
+  [50] = ICData target-name 'call', arg-desc CP#44
+  [51] = TypeArgs [dart.core::List<#lib::C5>, dart.core::List<#lib::C6>]
+  [52] = ICData target-name 'call', arg-desc CP#44
+}
+Closure CP#12 {
+  Entry                4
+  CheckStack
+  Push                 FP[-5]
+  LoadFieldTOS         CP#3
+  PopLocal             r1
+  Push                 FP[-5]
+  LoadFieldTOS         CP#4
+  PopLocal             r0
+  PushConstant         CP#13
+  StoreLocal           r3
+  Push                 r3
+  PushConstant         CP#14
+  CreateArrayTOS
+  StoreLocal           r3
+  Push                 r3
+  PushConstant         CP#15
+  Push                 r1
+  LoadFieldTOS         CP#1
+  LoadFieldTOS         CP#17
+  Push                 r0
+  InstantiateType      CP#16
+  StoreIndexedTOS
+  Push                 r3
+  PushConstant         CP#18
+  Push                 r1
+  LoadFieldTOS         CP#1
+  LoadFieldTOS         CP#17
+  Push                 r0
+  InstantiateType      CP#19
+  StoreIndexedTOS
+  Push                 r3
+  PushConstant         CP#5
+  Push                 r1
+  LoadFieldTOS         CP#1
+  LoadFieldTOS         CP#17
+  Push                 r0
+  InstantiateType      CP#20
+  StoreIndexedTOS
+  Push                 r3
+  PushConstant         CP#21
+  Push                 r1
+  LoadFieldTOS         CP#1
+  LoadFieldTOS         CP#17
+  Push                 r0
+  InstantiateType      CP#22
+  StoreIndexedTOS
+  Push                 r3
+  PushConstant         CP#6
+  Push                 r1
+  LoadFieldTOS         CP#1
+  LoadFieldTOS         CP#17
+  Push                 r0
+  InstantiateType      CP#23
+  StoreIndexedTOS
+  Push                 r3
+  PushConstant         CP#24
+  Push                 r1
+  LoadFieldTOS         CP#1
+  LoadFieldTOS         CP#17
+  Push                 r0
+  InstantiateType      CP#25
+  StoreIndexedTOS
+  Push                 r3
+  PushConstant         CP#10
+  Push                 r1
+  LoadFieldTOS         CP#1
+  LoadFieldTOS         CP#17
+  Push                 r0
+  InstantiateType      CP#26
+  StoreIndexedTOS
+  Push                 r3
+  PushConstant         CP#27
+  Push                 r1
+  LoadFieldTOS         CP#1
+  LoadFieldTOS         CP#17
+  Push                 r0
+  InstantiateType      CP#28
+  StoreIndexedTOS
+  PushConstant         CP#30
+  IndirectStaticCall   2, CP#29
+  PushConstant         CP#32
+  IndirectStaticCall   1, CP#31
+  Drop1
+  Push                 r1
+  LoadFieldTOS         CP#1
+  LoadFieldTOS         CP#17
+  Push                 r0
+  InstantiateTypeArgumentsTOS 1, CP#33
+  PushConstant         CP#35
+  IndirectStaticCall   1, CP#34
+  Drop1
+  PushConstant         CP#36
+  ReturnTOS
+
+}
+
+Closure CP#9 {
+  Entry                4
+  CheckStack
+  Push                 FP[-5]
+  LoadFieldTOS         CP#3
+  PopLocal             r0
+  Push                 FP[-6]
+  Push                 FP[-5]
+  LoadFieldTOS         CP#4
+  PushConstant         CP#6
+  PushConstant         CP#10
+  PushConstant         CP#11
+  IndirectStaticCall   4, CP#7
+  PopLocal             FP[-6]
+  Allocate             CP#38
+  StoreLocal           r3
+  Push                 r3
+  Push                 r0
+  LoadFieldTOS         CP#1
+  LoadFieldTOS         CP#17
+  StoreFieldTOS        CP#39
+  Push                 r3
+  Push                 FP[-6]
+  StoreFieldTOS        CP#4
+  Push                 r3
+  PushConstant         CP#12
+  StoreFieldTOS        CP#40
+  Push                 r3
+  Push                 r0
+  StoreFieldTOS        CP#3
+  PopLocal             r2
+  Push                 r2
+  InstanceCall1        1, CP#41
+  Drop1
+  PushConstant         CP#36
+  ReturnTOS
+
+}
+
+Closure CP#2 {
+  Entry                4
+  CheckStack
+  Push                 FP[-5]
+  LoadFieldTOS         CP#3
+  PopLocal             r0
+  Push                 FP[-6]
+  Push                 FP[-5]
+  LoadFieldTOS         CP#4
+  PushConstant         CP#5
+  PushConstant         CP#6
+  PushConstant         CP#8
+  IndirectStaticCall   4, CP#7
+  PopLocal             FP[-6]
+  Allocate             CP#38
+  StoreLocal           r3
+  Push                 r3
+  Push                 r0
+  LoadFieldTOS         CP#1
+  LoadFieldTOS         CP#17
+  StoreFieldTOS        CP#39
+  Push                 r3
+  Push                 FP[-6]
+  StoreFieldTOS        CP#4
+  Push                 r3
+  PushConstant         CP#9
+  StoreFieldTOS        CP#40
+  Push                 r3
+  Push                 r0
+  StoreFieldTOS        CP#3
+  PopLocal             r2
+  PushConstant         CP#43
+  Push                 r2
+  InstanceCall1        1, CP#45
+  Drop1
+  PushConstant         CP#46
+  Push                 r2
+  InstanceCall1        1, CP#47
+  Drop1
+  PushConstant         CP#36
+  ReturnTOS
+
+}
+]  method foo<T3 extends core::Object = dynamic, T4 extends core::Object = dynamic>() → void {
+    function nested1<T5 extends core::Object = dynamic, T6 extends core::Object = dynamic>() → void {
+      function nested2<T7 extends core::Object = dynamic, T8 extends core::Object = dynamic>() → void {
+        () → core::Null nested3 = () → core::Null {
+          core::print(<core::Type>[self::A::T1, self::A::T2, self::A::foo::T3, self::A::foo::T4, T5, T6, T7, T8]);
+          self::callWithArgs<self::A::T1, self::A::T2, self::A::foo::T3, self::A::foo::T4, T5, T6, T7, T8>();
+        };
+        nested3.call();
+      }
+      nested2.call<self::C7, self::C8>();
+      nested2.call<core::List<self::C7>, core::List<self::C8>>();
+    }
+    nested1.call<self::C5, self::C6>();
+    nested1.call<core::List<self::C5>, core::List<self::C6>>();
+  }
+}
+class B extends core::Object {
+  field core::int foo = null;
+[@vm.bytecode=
+Bytecode {
+  Entry                0
+  CheckStack
+  Push                 FP[-5]
+  PushConstant         CP#1
+  IndirectStaticCall   1, CP#0
+  Drop1
+  PushConstant         CP#2
+  ReturnTOS
+}
+ConstantPool {
+  [0] = ArgDesc num-args 1, num-type-args 0, names []
+  [1] = StaticICData target 'dart.core::Object::', arg-desc CP#0
+  [2] = Null
+}
+]  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+[@vm.bytecode=
+Bytecode {
+  Entry                5
+  CheckStack
+  AllocateContext      1
+  StoreLocal           r1
+  Push                 r1
+  Push                 r0
+  StoreFieldTOS        CP#0
+  PopLocal             r0
+  Push                 r0
+  Push                 FP[-5]
+  StoreFieldTOS        CP#1
+  AllocateContext      1
+  StoreLocal           r1
+  Push                 r1
+  Push                 r0
+  StoreFieldTOS        CP#0
+  PopLocal             r0
+  Push                 r0
+  PushConstant         CP#2
+  StoreFieldTOS        CP#1
+  AllocateContext      1
+  StoreLocal           r1
+  Push                 r1
+  Push                 r0
+  StoreFieldTOS        CP#0
+  PopLocal             r0
+  PushConstant         CP#3
+  PopLocal             r2
+  Push                 r0
+  PushConstant         CP#4
+  StoreFieldTOS        CP#1
+  Allocate             CP#20
+  StoreLocal           r4
+  Push                 r4
+  PushConstant         CP#18
+  StoreFieldTOS        CP#21
+  Push                 r4
+  PushConstant         CP#18
+  StoreFieldTOS        CP#22
+  Push                 r4
+  PushConstant         CP#5
+  StoreFieldTOS        CP#23
+  Push                 r4
+  Push                 r0
+  StoreFieldTOS        CP#6
+  PopLocal             r3
+  Push                 r3
+  PushConstant         CP#27
+  InstanceCall1        2, CP#28
+  Drop1
+  Push                 r3
+  PushConstant         CP#29
+  InstanceCall1        2, CP#30
+  Drop1
+  Push                 r2
+  PushConstant         CP#31
+  IndirectStaticCall   1, CP#15
+  Drop1
+  Push                 r0
+  LoadFieldTOS         CP#1
+  PushConstant         CP#32
+  IndirectStaticCall   1, CP#15
+  Drop1
+  Push                 r0
+  LoadFieldTOS         CP#0
+  PopLocal             r0
+  Push                 r0
+  LoadFieldTOS         CP#1
+  PushConstant         CP#33
+  IndirectStaticCall   1, CP#15
+  Drop1
+  Push                 r0
+  LoadFieldTOS         CP#0
+  PopLocal             r0
+  AllocateContext      1
+  StoreLocal           r1
+  Push                 r1
+  Push                 r0
+  StoreFieldTOS        CP#0
+  PopLocal             r0
+  Push                 r0
+  PushConstant         CP#34
+  StoreFieldTOS        CP#1
+  Allocate             CP#20
+  StoreLocal           r3
+  Push                 r3
+  PushConstant         CP#18
+  StoreFieldTOS        CP#21
+  Push                 r3
+  PushConstant         CP#18
+  StoreFieldTOS        CP#22
+  Push                 r3
+  PushConstant         CP#35
+  StoreFieldTOS        CP#23
+  Push                 r3
+  Push                 r0
+  StoreFieldTOS        CP#6
+  PopLocal             r2
+  Push                 r2
+  InstanceCall1        1, CP#38
+  Drop1
+  Push                 r0
+  LoadFieldTOS         CP#0
+  PopLocal             r0
+  PushConstant         CP#18
+  ReturnTOS
+}
+ConstantPool {
+  [0] = ContextOffset parent
+  [1] = ContextOffset var [0]
+  [2] = Int 1
+  [3] = Int 2
+  [4] = Int 3
+  [5] = ClosureFunction <anonymous closure> (dart.core::int y) → dart.core::Null;
+  [6] = FieldOffset dart.core::_Closure::_context
+  [7] = ArgDesc num-args 2, num-type-args 0, names []
+  [8] = ICData target-name '+', arg-desc CP#7
+  [9] = Int 5
+  [10] = ICData target-name '>', arg-desc CP#7
+  [11] = Bool true
+  [12] = Int 4
+  [13] = ClosureFunction closure2 () → void;
+  [14] = ICData target-name '+', arg-desc CP#7
+  [15] = ArgDesc num-args 1, num-type-args 0, names []
+  [16] = ICData target-name 'get:foo', arg-desc CP#15
+  [17] = ICData target-name '+', arg-desc CP#7
+  [18] = Null
+  [19] = EndClosureFunctionScope
+  [20] = Class dart.core::_Closure
+  [21] = FieldOffset dart.core::_Closure::_instantiator_type_arguments
+  [22] = FieldOffset dart.core::_Closure::_function_type_arguments
+  [23] = FieldOffset dart.core::_Closure::_function
+  [24] = ICData target-name 'call', arg-desc CP#15
+  [25] = StaticICData target 'dart.core::print', arg-desc CP#15
+  [26] = EndClosureFunctionScope
+  [27] = Int 10
+  [28] = ICData target-name 'call', arg-desc CP#7
+  [29] = Int 11
+  [30] = ICData target-name 'call', arg-desc CP#7
+  [31] = StaticICData target 'dart.core::print', arg-desc CP#15
+  [32] = StaticICData target 'dart.core::print', arg-desc CP#15
+  [33] = StaticICData target 'dart.core::print', arg-desc CP#15
+  [34] = Int 42
+  [35] = ClosureFunction <anonymous closure> () → dart.core::Null;
+  [36] = ICData target-name 'set:foo', arg-desc CP#7
+  [37] = EndClosureFunctionScope
+  [38] = ICData target-name 'call', arg-desc CP#15
+}
+Closure CP#13 {
+  Entry                3
+  CheckStack
+  Push                 FP[-5]
+  LoadFieldTOS         CP#6
+  PopLocal             r0
+  Push                 r0
+  LoadFieldTOS         CP#0
+  LoadFieldTOS         CP#0
+  Push                 r0
+  LoadFieldTOS         CP#0
+  LoadFieldTOS         CP#0
+  LoadFieldTOS         CP#0
+  LoadFieldTOS         CP#1
+  PushConstant         CP#3
+  InstanceCall1        2, CP#14
+  StoreLocal           r2
+  StoreFieldTOS        CP#1
+  Push                 r2
+  Drop1
+  Push                 r0
+  Push                 r0
+  LoadFieldTOS         CP#0
+  LoadFieldTOS         CP#0
+  LoadFieldTOS         CP#0
+  LoadFieldTOS         CP#0
+  LoadFieldTOS         CP#1
+  InstanceCall1        1, CP#16
+  Push                 r0
+  LoadFieldTOS         CP#0
+  LoadFieldTOS         CP#1
+  InstanceCall1        2, CP#17
+  StoreLocal           r2
+  StoreFieldTOS        CP#1
+  Push                 r2
+  Drop1
+  PushConstant         CP#18
+  ReturnTOS
+
+}
+
+Closure CP#5 {
+  Entry                4
+  CheckStack
+  Push                 FP[-6]
+  LoadFieldTOS         CP#6
+  PopLocal             r0
+  AllocateContext      1
+  StoreLocal           r1
+  Push                 r1
+  Push                 r0
+  StoreFieldTOS        CP#0
+  PopLocal             r0
+  Push                 r0
+  LoadFieldTOS         CP#0
+  LoadFieldTOS         CP#0
+  LoadFieldTOS         CP#0
+  Push                 FP[-5]
+  StoreFieldTOS        CP#1
+  Push                 r0
+  Push                 FP[-5]
+  StoreFieldTOS        CP#1
+  Push                 r0
+  LoadFieldTOS         CP#0
+  LoadFieldTOS         CP#0
+  Push                 r0
+  LoadFieldTOS         CP#1
+  PushConstant         CP#2
+  InstanceCall1        2, CP#8
+  StoreLocal           r2
+  StoreFieldTOS        CP#1
+  Push                 r2
+  Drop1
+  Push                 r0
+  LoadFieldTOS         CP#0
+  LoadFieldTOS         CP#0
+  LoadFieldTOS         CP#1
+  PushConstant         CP#9
+  InstanceCall1        2, CP#10
+  PushConstant         CP#11
+  IfNeStrictTOS
+  Jump                 L1
+  AllocateContext      1
+  StoreLocal           r1
+  Push                 r1
+  Push                 r0
+  StoreFieldTOS        CP#0
+  PopLocal             r0
+  Push                 r0
+  PushConstant         CP#12
+  StoreFieldTOS        CP#1
+  Allocate             CP#20
+  StoreLocal           r2
+  Push                 r2
+  PushConstant         CP#18
+  StoreFieldTOS        CP#21
+  Push                 r2
+  PushConstant         CP#18
+  StoreFieldTOS        CP#22
+  Push                 r2
+  PushConstant         CP#13
+  StoreFieldTOS        CP#23
+  Push                 r2
+  Push                 r0
+  StoreFieldTOS        CP#6
+  PopLocal             r3
+  Push                 r3
+  InstanceCall1        1, CP#24
+  Drop1
+  Push                 r0
+  LoadFieldTOS         CP#1
+  PushConstant         CP#25
+  IndirectStaticCall   1, CP#15
+  Drop1
+  Push                 r0
+  LoadFieldTOS         CP#0
+  PopLocal             r0
+L1:
+  PushConstant         CP#18
+  ReturnTOS
+
+}
+
+Closure CP#35 {
+  Entry                3
+  CheckStack
+  Push                 FP[-5]
+  LoadFieldTOS         CP#6
+  PopLocal             r0
+  Push                 r0
+  LoadFieldTOS         CP#0
+  LoadFieldTOS         CP#1
+  Push                 r0
+  LoadFieldTOS         CP#1
+  StoreLocal           r2
+  InstanceCall1        2, CP#36
+  Drop1
+  Push                 r2
+  Drop1
+  PushConstant         CP#18
+  ReturnTOS
+
+}
+]  method topLevel() → void {
+    {
+      core::int x = 1;
+      {
+        core::int y = 2;
+        core::int z = 3;
+        (core::int) → core::Null closure1 = (core::int y) → core::Null {
+          x = y.{core::num::+}(1);
+          if(x.{core::num::>}(5)) {
+            core::int w = 4;
+            function closure2() → void {
+              z = x.{core::num::+}(2);
+              w = this.{self::B::foo}.{core::num::+}(y);
+            }
+            closure2.call();
+            core::print(w);
+          }
+        };
+        closure1.call(10);
+        closure1.call(11);
+        core::print(y);
+        core::print(z);
+      }
+      core::print(x);
+    }
+    {
+      core::int x = 42;
+      () → core::Null closure3 = () → core::Null {
+        this.{self::B::foo} = x;
+      };
+      closure3.call();
+    }
+  }
+}
+class C extends core::Object {
+[@vm.bytecode=
+Bytecode {
+  Entry                0
+  CheckStack
+  Push                 FP[-5]
+  PushConstant         CP#1
+  IndirectStaticCall   1, CP#0
+  Drop1
+  PushConstant         CP#2
+  ReturnTOS
+}
+ConstantPool {
+  [0] = ArgDesc num-args 1, num-type-args 0, names []
+  [1] = StaticICData target 'dart.core::Object::', arg-desc CP#0
+  [2] = Null
+}
+]  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+[@vm.bytecode=
+Bytecode {
+  Entry                5
+  CheckStack
+  AllocateContext      1
+  StoreLocal           r1
+  Push                 r1
+  Push                 r0
+  StoreFieldTOS        CP#0
+  PopLocal             r0
+  Push                 r0
+  PushConstant         CP#1
+  StoreFieldTOS        CP#2
+  PushConstant         CP#3
+  StoreLocal           r3
+  Push                 r3
+  PushConstant         CP#1
+  CreateArrayTOS
+  StoreLocal           r3
+  PushConstant         CP#5
+  IndirectStaticCall   2, CP#4
+  PopLocal             r2
+  PushConstant         CP#3
+  StoreLocal           r3
+  Push                 r3
+  PushConstant         CP#1
+  CreateArrayTOS
+  StoreLocal           r3
+  PushConstant         CP#6
+  IndirectStaticCall   2, CP#4
+  PopLocal             r4
+  AllocateContext      1
+  StoreLocal           r1
+  Push                 r1
+  Push                 r0
+  StoreFieldTOS        CP#0
+  PopLocal             r0
+  Push                 r0
+  PushConstant         CP#1
+  StoreFieldTOS        CP#2
+L2:
+  CheckStack
+  Push                 r0
+  LoadFieldTOS         CP#2
+  PushConstant         CP#7
+  InstanceCall1        2, CP#9
+  PushConstant         CP#10
+  IfNeStrictTOS
+  Jump                 L1
+  Push                 r2
+  Allocate             CP#16
+  StoreLocal           r3
+  Push                 r3
+  PushConstant         CP#14
+  StoreFieldTOS        CP#17
+  Push                 r3
+  PushConstant         CP#14
+  StoreFieldTOS        CP#18
+  Push                 r3
+  PushConstant         CP#11
+  StoreFieldTOS        CP#19
+  Push                 r3
+  Push                 r0
+  StoreFieldTOS        CP#12
+  InstanceCall1        2, CP#20
+  Drop1
+  Push                 r4
+  Allocate             CP#16
+  StoreLocal           r3
+  Push                 r3
+  PushConstant         CP#14
+  StoreFieldTOS        CP#17
+  Push                 r3
+  PushConstant         CP#14
+  StoreFieldTOS        CP#18
+  Push                 r3
+  PushConstant         CP#21
+  StoreFieldTOS        CP#19
+  Push                 r3
+  Push                 r0
+  StoreFieldTOS        CP#12
+  InstanceCall1        2, CP#24
+  Drop1
+  Push                 r0
+  CloneContext
+  PopLocal             r0
+  Push                 r0
+  Push                 r0
+  LoadFieldTOS         CP#2
+  PushConstant         CP#25
+  InstanceCall1        2, CP#26
+  StoreLocal           r3
+  StoreFieldTOS        CP#2
+  Push                 r3
+  Drop1
+  Jump                 L2
+L1:
+  Push                 r0
+  LoadFieldTOS         CP#0
+  PopLocal             r0
+  Push                 r0
+  LoadFieldTOS         CP#0
+  PopLocal             r0
+  PushConstant         CP#14
+  ReturnTOS
+}
+ConstantPool {
+  [0] = ContextOffset parent
+  [1] = Int 0
+  [2] = ContextOffset var [0]
+  [3] = TypeArgs [dart.core::Function]
+  [4] = ArgDesc num-args 1, num-type-args 1, names []
+  [5] = StaticICData target 'dart.core::List::_fromLiteral', arg-desc CP#4
+  [6] = StaticICData target 'dart.core::List::_fromLiteral', arg-desc CP#4
+  [7] = Int 10
+  [8] = ArgDesc num-args 2, num-type-args 0, names []
+  [9] = ICData target-name '<', arg-desc CP#8
+  [10] = Bool true
+  [11] = ClosureFunction <anonymous closure> () → dart.core::int;
+  [12] = FieldOffset dart.core::_Closure::_context
+  [13] = ICData target-name '+', arg-desc CP#8
+  [14] = Null
+  [15] = EndClosureFunctionScope
+  [16] = Class dart.core::_Closure
+  [17] = FieldOffset dart.core::_Closure::_instantiator_type_arguments
+  [18] = FieldOffset dart.core::_Closure::_function_type_arguments
+  [19] = FieldOffset dart.core::_Closure::_function
+  [20] = ICData target-name 'add', arg-desc CP#8
+  [21] = ClosureFunction <anonymous closure> (dart.core::int ii) → dart.core::Null;
+  [22] = ICData target-name '+', arg-desc CP#8
+  [23] = EndClosureFunctionScope
+  [24] = ICData target-name 'add', arg-desc CP#8
+  [25] = Int 1
+  [26] = ICData target-name '+', arg-desc CP#8
+}
+Closure CP#11 {
+  Entry                2
+  CheckStack
+  Push                 FP[-5]
+  LoadFieldTOS         CP#12
+  PopLocal             r0
+  Push                 r0
+  LoadFieldTOS         CP#2
+  Push                 r0
+  LoadFieldTOS         CP#0
+  LoadFieldTOS         CP#2
+  InstanceCall1        2, CP#13
+  ReturnTOS
+  PushConstant         CP#14
+  ReturnTOS
+
+}
+
+Closure CP#21 {
+  Entry                3
+  CheckStack
+  Push                 FP[-6]
+  LoadFieldTOS         CP#12
+  PopLocal             r0
+  Push                 r0
+  Push                 FP[-5]
+  Push                 r0
+  LoadFieldTOS         CP#0
+  LoadFieldTOS         CP#2
+  InstanceCall1        2, CP#22
+  StoreLocal           r2
+  StoreFieldTOS        CP#2
+  Push                 r2
+  Drop1
+  PushConstant         CP#14
+  ReturnTOS
+
+}
+]  method testForLoop() → void {
+    core::int delta = 0;
+    core::List<core::Function> getI = <core::Function>[];
+    core::List<core::Function> setI = <core::Function>[];
+    for (core::int i = 0; i.{core::num::<}(10); i = i.{core::num::+}(1)) {
+      getI.{core::List::add}(() → core::int => i.{core::num::+}(delta));
+      setI.{core::List::add}((core::int ii) → core::Null {
+        i = ii.{core::num::+}(delta);
+      });
+    }
+  }
+[@vm.bytecode=
+Bytecode {
+  Entry                5
+  CheckStack
+  Push                 FP[-5]
+  InstanceCall1        1, CP#1
+  PopLocal             r2
+L2:
+  CheckStack
+  Push                 r2
+  InstanceCall1        1, CP#2
+  PushConstant         CP#3
+  IfNeStrictTOS
+  Jump                 L1
+  AllocateContext      1
+  StoreLocal           r1
+  Push                 r1
+  Push                 r0
+  StoreFieldTOS        CP#4
+  PopLocal             r0
+  Push                 r0
+  Push                 r2
+  InstanceCall1        1, CP#5
+  StoreFieldTOS        CP#6
+  Allocate             CP#14
+  StoreLocal           r4
+  Push                 r4
+  PushConstant         CP#12
+  StoreFieldTOS        CP#15
+  Push                 r4
+  PushConstant         CP#12
+  StoreFieldTOS        CP#16
+  Push                 r4
+  PushConstant         CP#7
+  StoreFieldTOS        CP#17
+  Push                 r4
+  Push                 r0
+  StoreFieldTOS        CP#8
+  PopLocal             r3
+  Push                 r3
+  InstanceCall1        1, CP#18
+  Drop1
+  Push                 r0
+  LoadFieldTOS         CP#6
+  PushConstant         CP#19
+  IndirectStaticCall   1, CP#0
+  Drop1
+  Push                 r0
+  LoadFieldTOS         CP#4
+  PopLocal             r0
+  Jump                 L2
+L1:
+  PushConstant         CP#12
+  ReturnTOS
+}
+ConstantPool {
+  [0] = ArgDesc num-args 1, num-type-args 0, names []
+  [1] = ICData target-name 'get:iterator', arg-desc CP#0
+  [2] = ICData target-name 'moveNext', arg-desc CP#0
+  [3] = Bool true
+  [4] = ContextOffset parent
+  [5] = ICData target-name 'get:current', arg-desc CP#0
+  [6] = ContextOffset var [0]
+  [7] = ClosureFunction <anonymous closure> () → dart.core::Null;
+  [8] = FieldOffset dart.core::_Closure::_context
+  [9] = Int 1
+  [10] = ArgDesc num-args 2, num-type-args 0, names []
+  [11] = ICData target-name '+', arg-desc CP#10
+  [12] = Null
+  [13] = EndClosureFunctionScope
+  [14] = Class dart.core::_Closure
+  [15] = FieldOffset dart.core::_Closure::_instantiator_type_arguments
+  [16] = FieldOffset dart.core::_Closure::_function_type_arguments
+  [17] = FieldOffset dart.core::_Closure::_function
+  [18] = ICData target-name 'call', arg-desc CP#0
+  [19] = StaticICData target 'dart.core::print', arg-desc CP#0
+}
+Closure CP#7 {
+  Entry                3
+  CheckStack
+  Push                 FP[-5]
+  LoadFieldTOS         CP#8
+  PopLocal             r0
+  Push                 r0
+  Push                 r0
+  LoadFieldTOS         CP#6
+  PushConstant         CP#9
+  InstanceCall1        2, CP#11
+  StoreLocal           r2
+  StoreFieldTOS        CP#6
+  Push                 r2
+  Drop1
+  PushConstant         CP#12
+  ReturnTOS
+
+}
+]  method testForInLoop(core::List<core::int> list) → void {
+    for (core::int i in list) {
+      () → core::Null inc = () → core::Null {
+        i = i.{core::num::+}(1);
+      };
+      inc.call();
+      core::print(i);
+    }
+  }
+}
+[@vm.bytecode=
+Bytecode {
+  Entry                4
+  CheckStack
+  AllocateContext      1
+  StoreLocal           r1
+  Push                 r1
+  Push                 r0
+  StoreFieldTOS        CP#0
+  PopLocal             r0
+  Push                 r0
+  PushConstant         CP#1
+  StoreFieldTOS        CP#2
+  Allocate             CP#9
+  StoreLocal           r3
+  Push                 r3
+  PushConstant         CP#7
+  StoreFieldTOS        CP#10
+  Push                 r3
+  PushConstant         CP#7
+  StoreFieldTOS        CP#11
+  Push                 r3
+  PushConstant         CP#3
+  StoreFieldTOS        CP#12
+  Push                 r3
+  Push                 r0
+  StoreFieldTOS        CP#4
+  PopLocal             r2
+  Push                 r2
+  PushConstant         CP#13
+  InstanceCall1        2, CP#14
+  Drop1
+  Push                 r0
+  LoadFieldTOS         CP#2
+  ReturnTOS
+  Push                 r0
+  LoadFieldTOS         CP#0
+  PopLocal             r0
+  PushConstant         CP#7
+  ReturnTOS
+}
+ConstantPool {
+  [0] = ContextOffset parent
+  [1] = Int 5
+  [2] = ContextOffset var [0]
+  [3] = ClosureFunction <anonymous closure> (dart.core::int y) → dart.core::Null;
+  [4] = FieldOffset dart.core::_Closure::_context
+  [5] = ArgDesc num-args 2, num-type-args 0, names []
+  [6] = ICData target-name '+', arg-desc CP#5
+  [7] = Null
+  [8] = EndClosureFunctionScope
+  [9] = Class dart.core::_Closure
+  [10] = FieldOffset dart.core::_Closure::_instantiator_type_arguments
+  [11] = FieldOffset dart.core::_Closure::_function_type_arguments
+  [12] = FieldOffset dart.core::_Closure::_function
+  [13] = Int 3
+  [14] = ICData target-name 'call', arg-desc CP#5
+}
+Closure CP#3 {
+  Entry                3
+  CheckStack
+  Push                 FP[-6]
+  LoadFieldTOS         CP#4
+  PopLocal             r0
+  Push                 r0
+  Push                 r0
+  LoadFieldTOS         CP#2
+  Push                 FP[-5]
+  InstanceCall1        2, CP#6
+  StoreLocal           r2
+  StoreFieldTOS        CP#2
+  Push                 r2
+  Drop1
+  PushConstant         CP#7
+  ReturnTOS
+
+}
+]static method simpleClosure() → core::int {
+  core::int x = 5;
+  (core::int) → core::Null inc = (core::int y) → core::Null {
+    x = x.{core::num::+}(y);
+  };
+  inc.call(3);
+  return x;
+}
+[@vm.bytecode=
+Bytecode {
+  Entry                1
+  CheckStack
+  PushConstant         CP#0
+  StoreLocal           r0
+  Push                 r0
+  PushConstant         CP#1
+  CreateArrayTOS
+  StoreLocal           r0
+  Push                 r0
+  PushConstant         CP#2
+  PushConstant         CP#4
+  Push                 FP[-5]
+  InstantiateType      CP#3
+  StoreIndexedTOS
+  Push                 r0
+  PushConstant         CP#5
+  PushConstant         CP#4
+  Push                 FP[-5]
+  InstantiateType      CP#6
+  StoreIndexedTOS
+  Push                 r0
+  PushConstant         CP#7
+  PushConstant         CP#4
+  Push                 FP[-5]
+  InstantiateType      CP#8
+  StoreIndexedTOS
+  Push                 r0
+  PushConstant         CP#9
+  PushConstant         CP#4
+  Push                 FP[-5]
+  InstantiateType      CP#10
+  StoreIndexedTOS
+  Push                 r0
+  PushConstant         CP#11
+  PushConstant         CP#4
+  Push                 FP[-5]
+  InstantiateType      CP#12
+  StoreIndexedTOS
+  Push                 r0
+  PushConstant         CP#13
+  PushConstant         CP#4
+  Push                 FP[-5]
+  InstantiateType      CP#14
+  StoreIndexedTOS
+  Push                 r0
+  PushConstant         CP#15
+  PushConstant         CP#4
+  Push                 FP[-5]
+  InstantiateType      CP#16
+  StoreIndexedTOS
+  Push                 r0
+  PushConstant         CP#17
+  PushConstant         CP#4
+  Push                 FP[-5]
+  InstantiateType      CP#18
+  StoreIndexedTOS
+  PushConstant         CP#20
+  IndirectStaticCall   2, CP#19
+  PushConstant         CP#22
+  IndirectStaticCall   1, CP#21
+  Drop1
+  PushConstant         CP#4
+  ReturnTOS
+}
+ConstantPool {
+  [0] = TypeArgs [dart.core::Type]
+  [1] = Int 8
+  [2] = Int 0
+  [3] = Type #lib::callWithArgs::T1
+  [4] = Null
+  [5] = Int 1
+  [6] = Type #lib::callWithArgs::T2
+  [7] = Int 2
+  [8] = Type #lib::callWithArgs::T3
+  [9] = Int 3
+  [10] = Type #lib::callWithArgs::T4
+  [11] = Int 4
+  [12] = Type #lib::callWithArgs::T5
+  [13] = Int 5
+  [14] = Type #lib::callWithArgs::T6
+  [15] = Int 6
+  [16] = Type #lib::callWithArgs::T7
+  [17] = Int 7
+  [18] = Type #lib::callWithArgs::T8
+  [19] = ArgDesc num-args 1, num-type-args 1, names []
+  [20] = StaticICData target 'dart.core::List::_fromLiteral', arg-desc CP#19
+  [21] = ArgDesc num-args 1, num-type-args 0, names []
+  [22] = StaticICData target 'dart.core::print', arg-desc CP#21
+}
+]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]);
+}
+[@vm.bytecode=
+Bytecode {
+  Entry                1
+  CheckStack
+  PushConstant         CP#0
+  PushConstant         CP#3
+  PushConstant         CP#1
+  AllocateT
+  StoreLocal           r0
+  Push                 r0
+  PushConstant         CP#5
+  IndirectStaticCall   1, CP#4
+  Drop1
+  InstanceCall1        1, CP#7
+  Drop1
+  PushConstant         CP#8
+  PushConstant         CP#3
+  PushConstant         CP#1
+  AllocateT
+  StoreLocal           r0
+  Push                 r0
+  PushConstant         CP#9
+  IndirectStaticCall   1, CP#4
+  Drop1
+  InstanceCall1        1, CP#10
+  Drop1
+  PushConstant         CP#8
+  PushConstant         CP#12
+  PushConstant         CP#1
+  AllocateT
+  StoreLocal           r0
+  Push                 r0
+  PushConstant         CP#13
+  IndirectStaticCall   1, CP#4
+  Drop1
+  InstanceCall1        1, CP#14
+  Drop1
+  PushConstant         CP#15
+  ReturnTOS
+}
+ConstantPool {
+  [0] = TypeArgs [#lib::C3, #lib::C4]
+  [1] = Class #lib::A
+  [2] = TypeArgs [#lib::C1, #lib::C2]
+  [3] = TypeArgumentsForInstanceAllocation #lib::A type-args CP#2
+  [4] = ArgDesc num-args 1, num-type-args 0, names []
+  [5] = StaticICData target '#lib::A::', arg-desc CP#4
+  [6] = ArgDesc num-args 1, num-type-args 2, names []
+  [7] = ICData target-name 'foo', arg-desc CP#6
+  [8] = TypeArgs [dart.core::List<#lib::C3>, dart.core::List<#lib::C4>]
+  [9] = StaticICData target '#lib::A::', arg-desc CP#4
+  [10] = ICData target-name 'foo', arg-desc CP#6
+  [11] = TypeArgs [dart.core::List<#lib::C1>, dart.core::List<#lib::C2>]
+  [12] = TypeArgumentsForInstanceAllocation #lib::A type-args CP#11
+  [13] = StaticICData target '#lib::A::', arg-desc CP#4
+  [14] = ICData target-name 'foo', arg-desc CP#6
+  [15] = Null
+}
+]static method callA() → void {
+  new self::A::•<self::C1, self::C2>().{self::A::foo}<self::C3, self::C4>();
+  new self::A::•<self::C1, self::C2>().{self::A::foo}<core::List<self::C3>, core::List<self::C4>>();
+  new self::A::•<core::List<self::C1>, core::List<self::C2>>().{self::A::foo}<core::List<self::C3>, core::List<self::C4>>();
+}
+[@vm.bytecode=
+Bytecode {
+  Entry                0
+  CheckStack
+  PushConstant         CP#0
+  ReturnTOS
+}
+ConstantPool {
+  [0] = Null
+}
+]static method main() → dynamic {}
diff --git a/pkg/vm/testcases/bytecode/instance_creation.dart.expect b/pkg/vm/testcases/bytecode/instance_creation.dart.expect
index ec7540c..239c9ac 100644
--- a/pkg/vm/testcases/bytecode/instance_creation.dart.expect
+++ b/pkg/vm/testcases/bytecode/instance_creation.dart.expect
@@ -211,7 +211,7 @@
   return new self::C::•("hello");
 [@vm.bytecode=
 Bytecode {
-  Entry                2
+  Entry                1
   CheckStack
   PushConstant         CP#2
   PushConstant         CP#0
@@ -226,8 +226,8 @@
   PushConstant         CP#8
   PushConstant         CP#6
   AllocateT
-  StoreLocal           r1
-  Push                 r1
+  StoreLocal           r0
+  Push                 r0
   PushConstant         CP#10
   IndirectStaticCall   1, CP#9
   Drop1
diff --git a/pkg/vm/testcases/bytecode/literals.dart.expect b/pkg/vm/testcases/bytecode/literals.dart.expect
index df1fe96..07727bf 100644
--- a/pkg/vm/testcases/bytecode/literals.dart.expect
+++ b/pkg/vm/testcases/bytecode/literals.dart.expect
@@ -420,7 +420,7 @@
 }
 [@vm.bytecode=
 Bytecode {
-  Entry                2
+  Entry                1
   CheckStack
   PushConstant         CP#0
   StoreLocal           r0
@@ -446,21 +446,21 @@
   IndirectStaticCall   1, CP#7
   Drop1
   PushConstant         CP#9
-  StoreLocal           r1
-  Push                 r1
+  StoreLocal           r0
+  Push                 r0
   PushConstant         CP#1
   CreateArrayTOS
-  StoreLocal           r1
-  Push                 r1
+  StoreLocal           r0
+  Push                 r0
   PushConstant         CP#2
   PushConstant         CP#10
   StoreIndexedTOS
-  Push                 r1
+  Push                 r0
   PushConstant         CP#3
   Push                 FP[-5]
   InstanceCall1        1, CP#11
   StoreIndexedTOS
-  Push                 r1
+  Push                 r0
   PushConstant         CP#4
   PushConstant         CP#12
   StoreIndexedTOS
@@ -496,7 +496,7 @@
 }
 [@vm.bytecode=
 Bytecode {
-  Entry                4
+  Entry                1
   CheckStack
   PushConstant         CP#0
   PushConstant         CP#1
@@ -528,21 +528,21 @@
   PushConstant         CP#1
   PushConstant         CP#2
   CreateArrayTOS
-  StoreLocal           r1
-  Push                 r1
+  StoreLocal           r0
+  Push                 r0
   PushConstant         CP#3
   PushConstant         CP#12
   StoreIndexedTOS
-  Push                 r1
+  Push                 r0
   PushConstant         CP#4
   Push                 FP[-7]
   StoreIndexedTOS
-  Push                 r1
+  Push                 r0
   PushConstant         CP#5
   Push                 FP[-6]
   InstanceCall1        1, CP#13
   StoreIndexedTOS
-  Push                 r1
+  Push                 r0
   PushConstant         CP#6
   PushConstant         CP#6
   StoreIndexedTOS
@@ -566,12 +566,12 @@
   PushConstant         CP#1
   PushConstant         CP#5
   CreateArrayTOS
-  StoreLocal           r3
-  Push                 r3
+  StoreLocal           r0
+  Push                 r0
   PushConstant         CP#3
   Push                 FP[-5]
   StoreIndexedTOS
-  Push                 r3
+  Push                 r0
   PushConstant         CP#4
   PushConstant         CP#2
   StoreIndexedTOS
diff --git a/pkg/vm/testcases/bytecode/loops.dart b/pkg/vm/testcases/bytecode/loops.dart
index a2d2d10..4d9dd1b 100644
--- a/pkg/vm/testcases/bytecode/loops.dart
+++ b/pkg/vm/testcases/bytecode/loops.dart
@@ -59,4 +59,13 @@
   return sum;
 }
 
+int test_for_in_with_outer_var(List<int> list) {
+  int sum = 0;
+  int e = 42;
+  for (e in list) {
+    sum = sum + e;
+  }
+  return sum;
+}
+
 main() {}
diff --git a/pkg/vm/testcases/bytecode/loops.dart.expect b/pkg/vm/testcases/bytecode/loops.dart.expect
index a23aa00..635bc5b 100644
--- a/pkg/vm/testcases/bytecode/loops.dart.expect
+++ b/pkg/vm/testcases/bytecode/loops.dart.expect
@@ -354,7 +354,7 @@
   [2] = ICData target-name 'get:iterator', arg-desc CP#1
   [3] = ICData target-name 'moveNext', arg-desc CP#1
   [4] = Bool true
-  [5] = ICData target-name 'current', arg-desc CP#1
+  [5] = ICData target-name 'get:current', arg-desc CP#1
   [6] = ArgDesc num-args 2, num-type-args 0, names []
   [7] = ICData target-name '+', arg-desc CP#6
   [8] = Null
@@ -368,6 +368,63 @@
 }
 [@vm.bytecode=
 Bytecode {
+  Entry                4
+  CheckStack
+  PushConstant         CP#0
+  PopLocal             r0
+  PushConstant         CP#1
+  PopLocal             r1
+  Push                 FP[-5]
+  InstanceCall1        1, CP#3
+  PopLocal             r2
+L2:
+  CheckStack
+  Push                 r2
+  InstanceCall1        1, CP#4
+  PushConstant         CP#5
+  IfNeStrictTOS
+  Jump                 L1
+  Push                 r2
+  InstanceCall1        1, CP#6
+  PopLocal             r3
+  Push                 r3
+  StoreLocal           r1
+  Drop1
+  Push                 r0
+  Push                 r1
+  InstanceCall1        2, CP#8
+  StoreLocal           r0
+  Drop1
+  Jump                 L2
+L1:
+  Push                 r0
+  ReturnTOS
+  PushConstant         CP#9
+  ReturnTOS
+}
+ConstantPool {
+  [0] = Int 0
+  [1] = Int 42
+  [2] = ArgDesc num-args 1, num-type-args 0, names []
+  [3] = ICData target-name 'get:iterator', arg-desc CP#2
+  [4] = ICData target-name 'moveNext', arg-desc CP#2
+  [5] = Bool true
+  [6] = ICData target-name 'get:current', arg-desc CP#2
+  [7] = ArgDesc num-args 2, num-type-args 0, names []
+  [8] = ICData target-name '+', arg-desc CP#7
+  [9] = Null
+}
+]static method test_for_in_with_outer_var(core::List<core::int> list) → core::int {
+  core::int sum = 0;
+  core::int e = 42;
+  for (final core::int #t3 in list) {
+    e = #t3;
+    sum = sum.{core::num::+}(e);
+  }
+  return sum;
+}
+[@vm.bytecode=
+Bytecode {
   Entry                0
   CheckStack
   PushConstant         CP#0
diff --git a/pkg/vm/testcases/bytecode/optional_params.dart.expect b/pkg/vm/testcases/bytecode/optional_params.dart.expect
index 36b3b1a..c85a618 100644
--- a/pkg/vm/testcases/bytecode/optional_params.dart.expect
+++ b/pkg/vm/testcases/bytecode/optional_params.dart.expect
@@ -7,7 +7,7 @@
   EntryOptional        1, 2, 0
   LoadConstant         r1, CP#0
   LoadConstant         r2, CP#1
-  Frame                3
+  Frame                1
   CheckStack
   PushConstant         CP#2
   PushConstant         CP#3
@@ -29,12 +29,12 @@
   PushConstant         CP#2
   PushConstant         CP#3
   CreateArrayTOS
-  StoreLocal           r4
-  Push                 r4
+  StoreLocal           r3
+  Push                 r3
   PushConstant         CP#4
   PushConstant         CP#10
   StoreIndexedTOS
-  Push                 r4
+  Push                 r3
   PushConstant         CP#6
   Push                 r1
   StoreIndexedTOS
@@ -46,12 +46,12 @@
   PushConstant         CP#2
   PushConstant         CP#3
   CreateArrayTOS
-  StoreLocal           r5
-  Push                 r5
+  StoreLocal           r3
+  Push                 r3
   PushConstant         CP#4
   PushConstant         CP#13
   StoreIndexedTOS
-  Push                 r5
+  Push                 r3
   PushConstant         CP#6
   Push                 r2
   StoreIndexedTOS
@@ -95,7 +95,7 @@
   LoadConstant         r3, CP#4
   LoadConstant         r4, CP#5
   LoadConstant         r4, CP#6
-  Frame                5
+  Frame                1
   CheckStack
   PushConstant         CP#7
   PushConstant         CP#8
@@ -117,12 +117,12 @@
   PushConstant         CP#7
   PushConstant         CP#8
   CreateArrayTOS
-  StoreLocal           r6
-  Push                 r6
+  StoreLocal           r5
+  Push                 r5
   PushConstant         CP#9
   PushConstant         CP#15
   StoreIndexedTOS
-  Push                 r6
+  Push                 r5
   PushConstant         CP#11
   Push                 r1
   StoreIndexedTOS
@@ -134,12 +134,12 @@
   PushConstant         CP#7
   PushConstant         CP#8
   CreateArrayTOS
-  StoreLocal           r7
-  Push                 r7
+  StoreLocal           r5
+  Push                 r5
   PushConstant         CP#9
   PushConstant         CP#18
   StoreIndexedTOS
-  Push                 r7
+  Push                 r5
   PushConstant         CP#11
   Push                 r2
   StoreIndexedTOS
@@ -151,12 +151,12 @@
   PushConstant         CP#7
   PushConstant         CP#8
   CreateArrayTOS
-  StoreLocal           r8
-  Push                 r8
+  StoreLocal           r5
+  Push                 r5
   PushConstant         CP#9
   PushConstant         CP#21
   StoreIndexedTOS
-  Push                 r8
+  Push                 r5
   PushConstant         CP#11
   Push                 r3
   StoreIndexedTOS
@@ -168,12 +168,12 @@
   PushConstant         CP#7
   PushConstant         CP#8
   CreateArrayTOS
-  StoreLocal           r9
-  Push                 r9
+  StoreLocal           r5
+  Push                 r5
   PushConstant         CP#9
   PushConstant         CP#24
   StoreIndexedTOS
-  Push                 r9
+  Push                 r5
   PushConstant         CP#11
   Push                 r4
   StoreIndexedTOS
diff --git a/pkg/vm/testcases/bytecode/try_blocks.dart b/pkg/vm/testcases/bytecode/try_blocks.dart
new file mode 100644
index 0000000..d07c18f
--- /dev/null
+++ b/pkg/vm/testcases/bytecode/try_blocks.dart
@@ -0,0 +1,153 @@
+// 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.
+
+testTryCatch1() {
+  try {
+    print('danger!');
+  } catch (e) {
+    print('caught $e');
+  }
+}
+
+testTryCatch2() {
+  try {
+    print('danger!');
+  } on TypeError {
+    print('caught type error');
+  } on AssertionError catch (e) {
+    print('caught assertion error $e');
+  } on Error catch (e, st) {
+    print('caught error $e $st');
+  } catch (e, st) {
+    print('caught something $e $st');
+  }
+}
+
+testTryCatch3() {
+  int x = 1;
+  try {
+    int y = 2;
+    void foo() {
+      try {
+        print('danger foo');
+      } catch (e) {
+        print(x);
+        y = 3;
+      }
+    }
+
+    foo();
+    print(y);
+  } catch (e, st) {
+    print('caught $e $st');
+
+    void bar() {
+      try {
+        print('danger bar');
+      } on Error catch (e) {
+        print('error $e, captured stack trace: $st');
+      }
+    }
+
+    return bar;
+  }
+}
+
+testRethrow(bool cond) {
+  try {
+    try {
+      print('try 1 > try 2');
+    } catch (e) {
+      try {
+        print('try 1 > catch 2 > try 3');
+        if (cond) {
+          rethrow;
+        }
+      } catch (e) {
+        print('try 1 > catch 2 > catch 3');
+      }
+    }
+  } catch (e, st) {
+    print('catch 1');
+    print(st);
+  }
+}
+
+testTryFinally1() {
+  for (int i = 0; i < 10; i++) {
+    try {
+      if (i > 5) {
+        break;
+      }
+    } finally {
+      print(i);
+    }
+  }
+}
+
+testTryFinally2(int x) {
+  switch (x) {
+    case 1:
+      try {
+        print('before try 1');
+        int y = 3;
+        try {
+          print('try');
+          void foo() {
+            print(x);
+            print(y);
+          }
+
+          foo();
+          continue L;
+        } finally {
+          print('finally 1');
+        }
+        print('after try 1');
+      } finally {
+        print('finally 2');
+      }
+      break;
+    L:
+    case 2:
+      print('case 2');
+      break;
+  }
+}
+
+testTryFinally3() {
+  int x = 11;
+  var y;
+  try {
+    y = () {
+      print(x);
+      try {
+        print('try 1');
+        return 42;
+      } finally {
+        try {
+          print('try 2');
+          return 43;
+        } finally {
+          print(x);
+        }
+      }
+    };
+  } finally {
+    print(x);
+    y();
+  }
+}
+
+testTryCatchFinally() {
+  try {
+    print('try');
+  } catch (e) {
+    print('catch');
+  } finally {
+    print('finally');
+  }
+}
+
+main() {}
diff --git a/pkg/vm/testcases/bytecode/try_blocks.dart.expect b/pkg/vm/testcases/bytecode/try_blocks.dart.expect
new file mode 100644
index 0000000..0dbaad8
--- /dev/null
+++ b/pkg/vm/testcases/bytecode/try_blocks.dart.expect
@@ -0,0 +1,1379 @@
+library #lib;
+import self as self;
+import "dart:core" as core;
+
+[@vm.bytecode=
+Bytecode {
+  Entry                4
+  CheckStack
+Try #0 start:
+  PushConstant         CP#0
+  PushConstant         CP#2
+  IndirectStaticCall   1, CP#1
+  Drop1
+  Jump                 L1
+Try #0 end:
+Try #0 handler:
+  MoveSpecial          r0, exception
+  MoveSpecial          r1, stackTrace
+  Push                 r0
+  PopLocal             r2
+  PushConstant         CP#4
+  PushConstant         CP#5
+  CreateArrayTOS
+  StoreLocal           r3
+  Push                 r3
+  PushConstant         CP#6
+  PushConstant         CP#7
+  StoreIndexedTOS
+  Push                 r3
+  PushConstant         CP#8
+  Push                 r2
+  StoreIndexedTOS
+  PushConstant         CP#9
+  IndirectStaticCall   1, CP#1
+  PushConstant         CP#10
+  IndirectStaticCall   1, CP#1
+  Drop1
+  Jump                 L1
+L1:
+  PushConstant         CP#4
+  ReturnTOS
+}
+ExceptionsTable {
+  try-index 0, outer -1, start 2, end 7, handler 7, 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
+  [3] = Type dynamic
+  [4] = Null
+  [5] = Int 2
+  [6] = Int 0
+  [7] = String 'caught '
+  [8] = Int 1
+  [9] = StaticICData target 'dart.core::_StringBase::_interpolate', arg-desc CP#1
+  [10] = StaticICData target 'dart.core::print', arg-desc CP#1
+}
+]static method testTryCatch1() → dynamic {
+  try {
+    core::print("danger!");
+  }
+  on dynamic catch(final dynamic e) {
+    core::print("caught ${e}");
+  }
+}
+[@vm.bytecode=
+Bytecode {
+  Entry                5
+  CheckStack
+Try #0 start:
+  PushConstant         CP#0
+  PushConstant         CP#2
+  IndirectStaticCall   1, CP#1
+  Drop1
+  Jump                 L1
+Try #0 end:
+Try #0 handler:
+  MoveSpecial          r0, exception
+  MoveSpecial          r1, stackTrace
+  Push                 r0
+  PushConstant         CP#4
+  PushConstant         CP#4
+  PushConstant         CP#3
+  InstanceCall1        4, CP#6
+  PushConstant         CP#7
+  IfNeStrictTOS
+  Jump                 L2
+  PushConstant         CP#8
+  PushConstant         CP#9
+  IndirectStaticCall   1, CP#1
+  Drop1
+  Jump                 L1
+L2:
+  Push                 r0
+  PushConstant         CP#4
+  PushConstant         CP#4
+  PushConstant         CP#10
+  InstanceCall1        4, CP#11
+  PushConstant         CP#7
+  IfNeStrictTOS
+  Jump                 L3
+  Push                 r0
+  PopLocal             r2
+  PushConstant         CP#4
+  PushConstant         CP#12
+  CreateArrayTOS
+  StoreLocal           r3
+  Push                 r3
+  PushConstant         CP#13
+  PushConstant         CP#14
+  StoreIndexedTOS
+  Push                 r3
+  PushConstant         CP#15
+  Push                 r2
+  StoreIndexedTOS
+  PushConstant         CP#16
+  IndirectStaticCall   1, CP#1
+  PushConstant         CP#17
+  IndirectStaticCall   1, CP#1
+  Drop1
+  Jump                 L1
+L3:
+  Push                 r0
+  PushConstant         CP#4
+  PushConstant         CP#4
+  PushConstant         CP#18
+  InstanceCall1        4, CP#19
+  PushConstant         CP#7
+  IfNeStrictTOS
+  Jump                 L4
+  Push                 r0
+  PopLocal             r2
+  Push                 r1
+  PopLocal             r3
+  PushConstant         CP#4
+  PushConstant         CP#20
+  CreateArrayTOS
+  StoreLocal           r4
+  Push                 r4
+  PushConstant         CP#13
+  PushConstant         CP#21
+  StoreIndexedTOS
+  Push                 r4
+  PushConstant         CP#15
+  Push                 r2
+  StoreIndexedTOS
+  Push                 r4
+  PushConstant         CP#12
+  PushConstant         CP#22
+  StoreIndexedTOS
+  Push                 r4
+  PushConstant         CP#23
+  Push                 r3
+  StoreIndexedTOS
+  PushConstant         CP#24
+  IndirectStaticCall   1, CP#1
+  PushConstant         CP#25
+  IndirectStaticCall   1, CP#1
+  Drop1
+  Jump                 L1
+L4:
+  Push                 r0
+  PopLocal             r2
+  Push                 r1
+  PopLocal             r3
+  PushConstant         CP#4
+  PushConstant         CP#20
+  CreateArrayTOS
+  StoreLocal           r4
+  Push                 r4
+  PushConstant         CP#13
+  PushConstant         CP#27
+  StoreIndexedTOS
+  Push                 r4
+  PushConstant         CP#15
+  Push                 r2
+  StoreIndexedTOS
+  Push                 r4
+  PushConstant         CP#12
+  PushConstant         CP#22
+  StoreIndexedTOS
+  Push                 r4
+  PushConstant         CP#23
+  Push                 r3
+  StoreIndexedTOS
+  PushConstant         CP#28
+  IndirectStaticCall   1, CP#1
+  PushConstant         CP#29
+  IndirectStaticCall   1, CP#1
+  Drop1
+  Jump                 L1
+L1:
+  PushConstant         CP#4
+  ReturnTOS
+}
+ExceptionsTable {
+  try-index 0, outer -1, start 2, end 7, handler 7, needs-stack-trace, types [CP#3, CP#10, CP#18, CP#26]
+}
+ConstantPool {
+  [0] = String 'danger!'
+  [1] = ArgDesc num-args 1, num-type-args 0, names []
+  [2] = StaticICData target 'dart.core::print', arg-desc CP#1
+  [3] = Type dart.core::TypeError
+  [4] = Null
+  [5] = ArgDesc num-args 4, num-type-args 0, names []
+  [6] = ICData target-name '_instanceOf', arg-desc CP#5
+  [7] = Bool true
+  [8] = String 'caught type error'
+  [9] = StaticICData target 'dart.core::print', arg-desc CP#1
+  [10] = Type dart.core::AssertionError
+  [11] = ICData target-name '_instanceOf', arg-desc CP#5
+  [12] = Int 2
+  [13] = Int 0
+  [14] = String 'caught assertion error '
+  [15] = Int 1
+  [16] = StaticICData target 'dart.core::_StringBase::_interpolate', arg-desc CP#1
+  [17] = StaticICData target 'dart.core::print', arg-desc CP#1
+  [18] = Type dart.core::Error
+  [19] = ICData target-name '_instanceOf', arg-desc CP#5
+  [20] = Int 4
+  [21] = String 'caught error '
+  [22] = String ' '
+  [23] = Int 3
+  [24] = StaticICData target 'dart.core::_StringBase::_interpolate', arg-desc CP#1
+  [25] = StaticICData target 'dart.core::print', arg-desc CP#1
+  [26] = Type dynamic
+  [27] = String 'caught something '
+  [28] = StaticICData target 'dart.core::_StringBase::_interpolate', arg-desc CP#1
+  [29] = StaticICData target 'dart.core::print', arg-desc CP#1
+}
+]static method testTryCatch2() → dynamic {
+  try {
+    core::print("danger!");
+  }
+  on core::TypeError catch(no-exception-var) {
+    core::print("caught type error");
+  }
+  on core::AssertionError catch(final core::AssertionError e) {
+    core::print("caught assertion error ${e}");
+  }
+  on core::Error catch(final core::Error e, final core::StackTrace st) {
+    core::print("caught error ${e} ${st}");
+  }
+  on dynamic catch(final dynamic e, final core::StackTrace st) {
+    core::print("caught something ${e} ${st}");
+  }
+}
+[@vm.bytecode=
+Bytecode {
+  Entry                7
+  CheckStack
+  AllocateContext      1
+  StoreLocal           r1
+  Push                 r1
+  Push                 r0
+  StoreFieldTOS        CP#0
+  PopLocal             r0
+  Push                 r0
+  PushConstant         CP#1
+  StoreFieldTOS        CP#2
+  Push                 r0
+  PopLocal             r2
+Try #0 start:
+  AllocateContext      1
+  StoreLocal           r1
+  Push                 r1
+  Push                 r0
+  StoreFieldTOS        CP#0
+  PopLocal             r0
+  Push                 r0
+  PushConstant         CP#3
+  StoreFieldTOS        CP#2
+  Allocate             CP#14
+  StoreLocal           r5
+  Push                 r5
+  PushConstant         CP#12
+  StoreFieldTOS        CP#15
+  Push                 r5
+  PushConstant         CP#12
+  StoreFieldTOS        CP#16
+  Push                 r5
+  PushConstant         CP#4
+  StoreFieldTOS        CP#17
+  Push                 r5
+  Push                 r0
+  StoreFieldTOS        CP#5
+  PopLocal             r4
+  Push                 r4
+  InstanceCall1        1, CP#18
+  Drop1
+  Push                 r0
+  LoadFieldTOS         CP#2
+  PushConstant         CP#19
+  IndirectStaticCall   1, CP#7
+  Drop1
+  Push                 r0
+  LoadFieldTOS         CP#0
+  PopLocal             r0
+  Jump                 L1
+Try #0 end:
+Try #0 handler:
+  Push                 r2
+  PopLocal             r0
+  MoveSpecial          r2, exception
+  MoveSpecial          r3, stackTrace
+  AllocateContext      1
+  StoreLocal           r1
+  Push                 r1
+  Push                 r0
+  StoreFieldTOS        CP#0
+  PopLocal             r0
+  Push                 r2
+  PopLocal             r4
+  Push                 r0
+  Push                 r3
+  StoreFieldTOS        CP#2
+  PushConstant         CP#12
+  PushConstant         CP#20
+  CreateArrayTOS
+  StoreLocal           r5
+  Push                 r5
+  PushConstant         CP#21
+  PushConstant         CP#22
+  StoreIndexedTOS
+  Push                 r5
+  PushConstant         CP#1
+  Push                 r4
+  StoreIndexedTOS
+  Push                 r5
+  PushConstant         CP#3
+  PushConstant         CP#23
+  StoreIndexedTOS
+  Push                 r5
+  PushConstant         CP#11
+  Push                 r0
+  LoadFieldTOS         CP#2
+  StoreIndexedTOS
+  PushConstant         CP#24
+  IndirectStaticCall   1, CP#7
+  PushConstant         CP#25
+  IndirectStaticCall   1, CP#7
+  Drop1
+  Allocate             CP#14
+  StoreLocal           r5
+  Push                 r5
+  PushConstant         CP#12
+  StoreFieldTOS        CP#15
+  Push                 r5
+  PushConstant         CP#12
+  StoreFieldTOS        CP#16
+  Push                 r5
+  PushConstant         CP#26
+  StoreFieldTOS        CP#17
+  Push                 r5
+  Push                 r0
+  StoreFieldTOS        CP#5
+  PopLocal             r6
+  Push                 r6
+  ReturnTOS
+  Push                 r0
+  LoadFieldTOS         CP#0
+  PopLocal             r0
+  Jump                 L1
+L1:
+  Push                 r0
+  LoadFieldTOS         CP#0
+  PopLocal             r0
+  PushConstant         CP#12
+  ReturnTOS
+}
+ExceptionsTable {
+  try-index 0, outer -1, start 13, end 49, handler 49, needs-stack-trace, types [CP#9]
+}
+ConstantPool {
+  [0] = ContextOffset parent
+  [1] = Int 1
+  [2] = ContextOffset var [0]
+  [3] = Int 2
+  [4] = ClosureFunction foo () → void;
+  [5] = FieldOffset dart.core::_Closure::_context
+  [6] = String 'danger foo'
+  [7] = ArgDesc num-args 1, num-type-args 0, names []
+  [8] = StaticICData target 'dart.core::print', arg-desc CP#7
+  [9] = Type dynamic
+  [10] = StaticICData target 'dart.core::print', arg-desc CP#7
+  [11] = Int 3
+  [12] = Null
+  [13] = EndClosureFunctionScope
+  [14] = Class dart.core::_Closure
+  [15] = FieldOffset dart.core::_Closure::_instantiator_type_arguments
+  [16] = FieldOffset dart.core::_Closure::_function_type_arguments
+  [17] = FieldOffset dart.core::_Closure::_function
+  [18] = ICData target-name 'call', arg-desc CP#7
+  [19] = StaticICData target 'dart.core::print', arg-desc CP#7
+  [20] = Int 4
+  [21] = Int 0
+  [22] = String 'caught '
+  [23] = String ' '
+  [24] = StaticICData target 'dart.core::_StringBase::_interpolate', arg-desc CP#7
+  [25] = StaticICData target 'dart.core::print', arg-desc CP#7
+  [26] = ClosureFunction bar () → void;
+  [27] = String 'danger bar'
+  [28] = StaticICData target 'dart.core::print', arg-desc CP#7
+  [29] = Type dart.core::Error
+  [30] = ArgDesc num-args 4, num-type-args 0, names []
+  [31] = ICData target-name '_instanceOf', arg-desc CP#30
+  [32] = Bool true
+  [33] = String 'error '
+  [34] = String ', captured stack trace: '
+  [35] = StaticICData target 'dart.core::_StringBase::_interpolate', arg-desc CP#7
+  [36] = StaticICData target 'dart.core::print', arg-desc CP#7
+  [37] = EndClosureFunctionScope
+}
+Closure CP#4 {
+  Entry                6
+  CheckStack
+  Push                 FP[-5]
+  LoadFieldTOS         CP#5
+  PopLocal             r0
+  Push                 r0
+  PopLocal             r2
+Try #0 start:
+  PushConstant         CP#6
+  PushConstant         CP#8
+  IndirectStaticCall   1, CP#7
+  Drop1
+  Jump                 L1
+Try #0 end:
+Try #0 handler:
+  Push                 r2
+  PopLocal             r0
+  MoveSpecial          r2, exception
+  MoveSpecial          r3, stackTrace
+  Push                 r2
+  PopLocal             r4
+  Push                 r0
+  LoadFieldTOS         CP#0
+  LoadFieldTOS         CP#2
+  PushConstant         CP#10
+  IndirectStaticCall   1, CP#7
+  Drop1
+  Push                 r0
+  PushConstant         CP#11
+  StoreLocal           r5
+  StoreFieldTOS        CP#2
+  Push                 r5
+  Drop1
+  Jump                 L1
+L1:
+  PushConstant         CP#12
+  ReturnTOS
+
+}
+
+Closure CP#26 {
+  Entry                6
+  CheckStack
+  Push                 FP[-5]
+  LoadFieldTOS         CP#5
+  PopLocal             r0
+  Push                 r0
+  PopLocal             r2
+Try #0 start:
+  PushConstant         CP#27
+  PushConstant         CP#28
+  IndirectStaticCall   1, CP#7
+  Drop1
+  Jump                 L1
+Try #0 end:
+Try #0 handler:
+  Push                 r2
+  PopLocal             r0
+  MoveSpecial          r2, exception
+  MoveSpecial          r3, stackTrace
+  Push                 r2
+  PushConstant         CP#12
+  PushConstant         CP#12
+  PushConstant         CP#29
+  InstanceCall1        4, CP#31
+  PushConstant         CP#32
+  IfNeStrictTOS
+  Jump                 L2
+  Push                 r2
+  PopLocal             r4
+  PushConstant         CP#12
+  PushConstant         CP#20
+  CreateArrayTOS
+  StoreLocal           r5
+  Push                 r5
+  PushConstant         CP#21
+  PushConstant         CP#33
+  StoreIndexedTOS
+  Push                 r5
+  PushConstant         CP#1
+  Push                 r4
+  StoreIndexedTOS
+  Push                 r5
+  PushConstant         CP#3
+  PushConstant         CP#34
+  StoreIndexedTOS
+  Push                 r5
+  PushConstant         CP#11
+  Push                 r0
+  LoadFieldTOS         CP#2
+  StoreIndexedTOS
+  PushConstant         CP#35
+  IndirectStaticCall   1, CP#7
+  PushConstant         CP#36
+  IndirectStaticCall   1, CP#7
+  Drop1
+  Jump                 L1
+L2:
+  Push                 r2
+  Push                 r3
+  Throw                1
+L1:
+  PushConstant         CP#12
+  ReturnTOS
+
+}
+]static method testTryCatch3() → dynamic {
+  core::int x = 1;
+  try {
+    core::int y = 2;
+    function foo() → void {
+      try {
+        core::print("danger foo");
+      }
+      on dynamic catch(final dynamic e) {
+        core::print(x);
+        y = 3;
+      }
+    }
+    foo.call();
+    core::print(y);
+  }
+  on dynamic catch(final dynamic e, final core::StackTrace st) {
+    core::print("caught ${e} ${st}");
+    function bar() → void {
+      try {
+        core::print("danger bar");
+      }
+      on core::Error catch(final core::Error e) {
+        core::print("error ${e}, captured stack trace: ${st}");
+      }
+    }
+    return bar;
+  }
+}
+[@vm.bytecode=
+Bytecode {
+  Entry                8
+  CheckStack
+Try #0 start:
+Try #1 start:
+  PushConstant         CP#0
+  PushConstant         CP#2
+  IndirectStaticCall   1, CP#1
+  Drop1
+  Jump                 L1
+Try #1 end:
+Try #1 handler:
+  MoveSpecial          r2, exception
+  MoveSpecial          r3, stackTrace
+  Push                 r2
+  PopLocal             r4
+Try #2 start:
+  PushConstant         CP#4
+  PushConstant         CP#5
+  IndirectStaticCall   1, CP#1
+  Drop1
+  Push                 FP[-5]
+  PushConstant         CP#6
+  IfNeStrictTOS
+  Jump                 L2
+  Push                 r2
+  Push                 r3
+  Throw                1
+  Drop1
+L2:
+  Jump                 L3
+Try #2 end:
+Try #2 handler:
+  MoveSpecial          r5, exception
+  MoveSpecial          r6, stackTrace
+  Push                 r5
+  PopLocal             r7
+  PushConstant         CP#7
+  PushConstant         CP#8
+  IndirectStaticCall   1, CP#1
+  Drop1
+  Jump                 L3
+L3:
+  Jump                 L1
+L1:
+  Jump                 L4
+Try #0 end:
+Try #0 handler:
+  MoveSpecial          r0, exception
+  MoveSpecial          r1, stackTrace
+  Push                 r0
+  PopLocal             r2
+  Push                 r1
+  PopLocal             r3
+  PushConstant         CP#9
+  PushConstant         CP#10
+  IndirectStaticCall   1, CP#1
+  Drop1
+  Push                 r3
+  PushConstant         CP#11
+  IndirectStaticCall   1, CP#1
+  Drop1
+  Jump                 L4
+L4:
+  PushConstant         CP#12
+  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 11, end 24, handler 24, 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
+  [3] = Type dynamic
+  [4] = String 'try 1 > catch 2 > try 3'
+  [5] = StaticICData target 'dart.core::print', arg-desc CP#1
+  [6] = Bool true
+  [7] = String 'try 1 > catch 2 > catch 3'
+  [8] = StaticICData target 'dart.core::print', arg-desc CP#1
+  [9] = String 'catch 1'
+  [10] = StaticICData target 'dart.core::print', arg-desc CP#1
+  [11] = StaticICData target 'dart.core::print', arg-desc CP#1
+  [12] = Null
+}
+]static method testRethrow(core::bool cond) → dynamic {
+  try {
+    try {
+      core::print("try 1 > try 2");
+    }
+    on dynamic catch(final dynamic e) {
+      try {
+        core::print("try 1 > catch 2 > try 3");
+        if(cond) {
+          rethrow;
+        }
+      }
+      on dynamic catch(final dynamic e) {
+        core::print("try 1 > catch 2 > catch 3");
+      }
+    }
+  }
+  on dynamic catch(final dynamic e, final core::StackTrace st) {
+    core::print("catch 1");
+    core::print(st);
+  }
+}
+[@vm.bytecode=
+Bytecode {
+  Entry                3
+  CheckStack
+  PushConstant         CP#0
+  PopLocal             r0
+L5:
+  CheckStack
+  Push                 r0
+  PushConstant         CP#1
+  InstanceCall1        2, CP#3
+  PushConstant         CP#4
+  IfNeStrictTOS
+  Jump                 L1
+Try #0 start:
+  Push                 r0
+  PushConstant         CP#5
+  InstanceCall1        2, CP#6
+  PushConstant         CP#4
+  IfNeStrictTOS
+  Jump                 L2
+  Jump                 L3
+L2:
+  Jump                 L4
+Try #0 end:
+Try #0 handler:
+  MoveSpecial          r1, exception
+  MoveSpecial          r2, stackTrace
+  Push                 r0
+  PushConstant         CP#9
+  IndirectStaticCall   1, CP#8
+  Drop1
+  Push                 r1
+  Push                 r2
+  Throw                1
+L3:
+  Push                 r0
+  PushConstant         CP#10
+  IndirectStaticCall   1, CP#8
+  Drop1
+  Jump                 L1
+L4:
+  Push                 r0
+  PushConstant         CP#11
+  IndirectStaticCall   1, CP#8
+  Drop1
+  Push                 r0
+  PushConstant         CP#12
+  InstanceCall1        2, CP#13
+  StoreLocal           r0
+  Drop1
+  Jump                 L5
+L1:
+  PushConstant         CP#14
+  ReturnTOS
+}
+ExceptionsTable {
+  try-index 0, outer -1, start 11, end 19, handler 19, needs-stack-trace, types [CP#7]
+}
+ConstantPool {
+  [0] = Int 0
+  [1] = Int 10
+  [2] = ArgDesc num-args 2, num-type-args 0, names []
+  [3] = ICData target-name '<', arg-desc CP#2
+  [4] = Bool true
+  [5] = Int 5
+  [6] = ICData target-name '>', arg-desc CP#2
+  [7] = Type dynamic
+  [8] = ArgDesc num-args 1, num-type-args 0, names []
+  [9] = StaticICData target 'dart.core::print', arg-desc CP#8
+  [10] = StaticICData target 'dart.core::print', arg-desc CP#8
+  [11] = StaticICData target 'dart.core::print', arg-desc CP#8
+  [12] = Int 1
+  [13] = ICData target-name '+', arg-desc CP#2
+  [14] = Null
+}
+]static method testTryFinally1() → dynamic {
+  #L1:
+  for (core::int i = 0; i.{core::num::<}(10); i = i.{core::num::+}(1)) {
+    try {
+      if(i.{core::num::>}(5)) {
+        break #L1;
+      }
+    }
+    finally {
+      core::print(i);
+    }
+  }
+}
+[@vm.bytecode=
+Bytecode {
+  Entry                9
+  CheckStack
+  AllocateContext      1
+  StoreLocal           r1
+  Push                 r1
+  Push                 r0
+  StoreFieldTOS        CP#0
+  PopLocal             r0
+  Push                 r0
+  Push                 FP[-5]
+  StoreFieldTOS        CP#1
+  Push                 r0
+  LoadFieldTOS         CP#1
+  PopLocal             r2
+  Push                 r2
+  PushConstant         CP#3
+  InstanceCall2        2, CP#4
+  PushConstant         CP#5
+  IfEqStrictTOS
+  Jump                 L1
+  Push                 r2
+  PushConstant         CP#6
+  InstanceCall2        2, CP#7
+  PushConstant         CP#5
+  IfEqStrictTOS
+  Jump                 L2
+  Jump                 L3
+L1:
+  Push                 r0
+  PopLocal             r3
+Try #0 start:
+  AllocateContext      1
+  StoreLocal           r1
+  Push                 r1
+  Push                 r0
+  StoreFieldTOS        CP#0
+  PopLocal             r0
+  PushConstant         CP#8
+  PushConstant         CP#10
+  IndirectStaticCall   1, CP#9
+  Drop1
+  Push                 r0
+  PushConstant         CP#11
+  StoreFieldTOS        CP#1
+  Push                 r0
+  PopLocal             r5
+Try #1 start:
+  PushConstant         CP#12
+  PushConstant         CP#13
+  IndirectStaticCall   1, CP#9
+  Drop1
+  Allocate             CP#20
+  StoreLocal           r8
+  Push                 r8
+  PushConstant         CP#18
+  StoreFieldTOS        CP#21
+  Push                 r8
+  PushConstant         CP#18
+  StoreFieldTOS        CP#22
+  Push                 r8
+  PushConstant         CP#14
+  StoreFieldTOS        CP#23
+  Push                 r8
+  Push                 r0
+  StoreFieldTOS        CP#15
+  PopLocal             r7
+  Push                 r7
+  InstanceCall1        1, CP#24
+  Drop1
+  Jump                 L4
+  Jump                 L5
+Try #1 end:
+Try #1 handler:
+  Push                 r5
+  PopLocal             r0
+  MoveSpecial          r5, exception
+  MoveSpecial          r6, stackTrace
+  PushConstant         CP#26
+  PushConstant         CP#27
+  IndirectStaticCall   1, CP#9
+  Drop1
+  Push                 r5
+  Push                 r6
+  Throw                1
+L4:
+  Push                 r5
+  PopLocal             r0
+  PushConstant         CP#26
+  PushConstant         CP#28
+  IndirectStaticCall   1, CP#9
+  Drop1
+  Jump                 L6
+L5:
+  Push                 r5
+  PopLocal             r0
+  PushConstant         CP#26
+  PushConstant         CP#29
+  IndirectStaticCall   1, CP#9
+  Drop1
+  PushConstant         CP#30
+  PushConstant         CP#31
+  IndirectStaticCall   1, CP#9
+  Drop1
+  Push                 r0
+  LoadFieldTOS         CP#0
+  PopLocal             r0
+  Jump                 L7
+Try #0 end:
+Try #0 handler:
+  Push                 r3
+  PopLocal             r0
+  MoveSpecial          r3, exception
+  MoveSpecial          r4, stackTrace
+  PushConstant         CP#32
+  PushConstant         CP#33
+  IndirectStaticCall   1, CP#9
+  Drop1
+  Push                 r3
+  Push                 r4
+  Throw                1
+L6:
+  Push                 r3
+  PopLocal             r0
+  PushConstant         CP#32
+  PushConstant         CP#34
+  IndirectStaticCall   1, CP#9
+  Drop1
+  Jump                 L2
+L7:
+  Push                 r3
+  PopLocal             r0
+  PushConstant         CP#32
+  PushConstant         CP#35
+  IndirectStaticCall   1, CP#9
+  Drop1
+  Jump                 L3
+L2:
+  PushConstant         CP#36
+  PushConstant         CP#37
+  IndirectStaticCall   1, CP#9
+  Drop1
+  Jump                 L3
+L3:
+  PushConstant         CP#18
+  ReturnTOS
+}
+ExceptionsTable {
+  try-index 0, outer -1, start 29, end 100, handler 100, needs-stack-trace, types [CP#25]
+  try-index 1, outer 0, start 44, end 68, handler 68, needs-stack-trace, types [CP#25]
+}
+ConstantPool {
+  [0] = ContextOffset parent
+  [1] = ContextOffset var [0]
+  [2] = ArgDesc num-args 2, num-type-args 0, names []
+  [3] = Int 1
+  [4] = ICData target-name '==', arg-desc CP#2
+  [5] = Bool true
+  [6] = Int 2
+  [7] = ICData target-name '==', arg-desc CP#2
+  [8] = String 'before try 1'
+  [9] = ArgDesc num-args 1, num-type-args 0, names []
+  [10] = StaticICData target 'dart.core::print', arg-desc CP#9
+  [11] = Int 3
+  [12] = String 'try'
+  [13] = StaticICData target 'dart.core::print', arg-desc CP#9
+  [14] = ClosureFunction foo () → void;
+  [15] = FieldOffset dart.core::_Closure::_context
+  [16] = StaticICData target 'dart.core::print', arg-desc CP#9
+  [17] = StaticICData target 'dart.core::print', arg-desc CP#9
+  [18] = Null
+  [19] = EndClosureFunctionScope
+  [20] = Class dart.core::_Closure
+  [21] = FieldOffset dart.core::_Closure::_instantiator_type_arguments
+  [22] = FieldOffset dart.core::_Closure::_function_type_arguments
+  [23] = FieldOffset dart.core::_Closure::_function
+  [24] = ICData target-name 'call', arg-desc CP#9
+  [25] = Type dynamic
+  [26] = String 'finally 1'
+  [27] = StaticICData target 'dart.core::print', arg-desc CP#9
+  [28] = StaticICData target 'dart.core::print', arg-desc CP#9
+  [29] = StaticICData target 'dart.core::print', arg-desc CP#9
+  [30] = String 'after try 1'
+  [31] = StaticICData target 'dart.core::print', arg-desc CP#9
+  [32] = String 'finally 2'
+  [33] = StaticICData target 'dart.core::print', arg-desc CP#9
+  [34] = StaticICData target 'dart.core::print', arg-desc CP#9
+  [35] = StaticICData target 'dart.core::print', arg-desc CP#9
+  [36] = String 'case 2'
+  [37] = StaticICData target 'dart.core::print', arg-desc CP#9
+}
+Closure CP#14 {
+  Entry                2
+  CheckStack
+  Push                 FP[-5]
+  LoadFieldTOS         CP#15
+  PopLocal             r0
+  Push                 r0
+  LoadFieldTOS         CP#0
+  LoadFieldTOS         CP#1
+  PushConstant         CP#16
+  IndirectStaticCall   1, CP#9
+  Drop1
+  Push                 r0
+  LoadFieldTOS         CP#1
+  PushConstant         CP#17
+  IndirectStaticCall   1, CP#9
+  Drop1
+  PushConstant         CP#18
+  ReturnTOS
+
+}
+]static method testTryFinally2(core::int x) → dynamic {
+  #L2:
+  switch(x) {
+    #L3:
+    case 1:
+      {
+        try {
+          core::print("before try 1");
+          core::int y = 3;
+          try {
+            core::print("try");
+            function foo() → void {
+              core::print(x);
+              core::print(y);
+            }
+            foo.call();
+            continue #L4;
+          }
+          finally {
+            core::print("finally 1");
+          }
+          core::print("after try 1");
+        }
+        finally {
+          core::print("finally 2");
+        }
+        break #L2;
+      }
+    #L4:
+    case 2:
+      {
+        core::print("case 2");
+        break #L2;
+      }
+  }
+}
+[@vm.bytecode=
+Bytecode {
+  Entry                6
+  CheckStack
+  AllocateContext      1
+  StoreLocal           r1
+  Push                 r1
+  Push                 r0
+  StoreFieldTOS        CP#0
+  PopLocal             r0
+  Push                 r0
+  PushConstant         CP#1
+  StoreFieldTOS        CP#2
+  PushConstant         CP#3
+  PopLocal             r2
+  Push                 r0
+  PopLocal             r3
+Try #0 start:
+  Allocate             CP#27
+  StoreLocal           r5
+  Push                 r5
+  PushConstant         CP#3
+  StoreFieldTOS        CP#28
+  Push                 r5
+  PushConstant         CP#3
+  StoreFieldTOS        CP#29
+  Push                 r5
+  PushConstant         CP#4
+  StoreFieldTOS        CP#30
+  Push                 r5
+  Push                 r0
+  StoreFieldTOS        CP#5
+  StoreLocal           r2
+  Drop1
+  Jump                 L1
+Try #0 end:
+Try #0 handler:
+  Push                 r3
+  PopLocal             r0
+  MoveSpecial          r3, exception
+  MoveSpecial          r4, stackTrace
+  Push                 r0
+  LoadFieldTOS         CP#2
+  PushConstant         CP#31
+  IndirectStaticCall   1, CP#6
+  Drop1
+  Push                 r2
+  InstanceCall1        1, CP#32
+  Drop1
+  Push                 r3
+  Push                 r4
+  Throw                1
+L1:
+  Push                 r3
+  PopLocal             r0
+  Push                 r0
+  LoadFieldTOS         CP#2
+  PushConstant         CP#33
+  IndirectStaticCall   1, CP#6
+  Drop1
+  Push                 r2
+  InstanceCall1        1, CP#34
+  Drop1
+  Push                 r0
+  LoadFieldTOS         CP#0
+  PopLocal             r0
+  PushConstant         CP#3
+  ReturnTOS
+}
+ExceptionsTable {
+  try-index 0, outer -1, start 15, end 32, handler 32, needs-stack-trace, types [CP#11]
+}
+ConstantPool {
+  [0] = ContextOffset parent
+  [1] = Int 11
+  [2] = ContextOffset var [0]
+  [3] = Null
+  [4] = ClosureFunction <anonymous closure> () → dart.core::int;
+  [5] = FieldOffset dart.core::_Closure::_context
+  [6] = ArgDesc num-args 1, num-type-args 0, names []
+  [7] = StaticICData target 'dart.core::print', arg-desc CP#6
+  [8] = String 'try 1'
+  [9] = StaticICData target 'dart.core::print', arg-desc CP#6
+  [10] = Int 42
+  [11] = Type dynamic
+  [12] = String 'try 2'
+  [13] = StaticICData target 'dart.core::print', arg-desc CP#6
+  [14] = Int 43
+  [15] = StaticICData target 'dart.core::print', arg-desc CP#6
+  [16] = StaticICData target 'dart.core::print', arg-desc CP#6
+  [17] = StaticICData target 'dart.core::print', arg-desc CP#6
+  [18] = StaticICData target 'dart.core::print', arg-desc CP#6
+  [19] = StaticICData target 'dart.core::print', arg-desc CP#6
+  [20] = StaticICData target 'dart.core::print', arg-desc CP#6
+  [21] = StaticICData target 'dart.core::print', arg-desc CP#6
+  [22] = StaticICData target 'dart.core::print', arg-desc CP#6
+  [23] = StaticICData target 'dart.core::print', arg-desc CP#6
+  [24] = StaticICData target 'dart.core::print', arg-desc CP#6
+  [25] = StaticICData target 'dart.core::print', arg-desc CP#6
+  [26] = EndClosureFunctionScope
+  [27] = Class dart.core::_Closure
+  [28] = FieldOffset dart.core::_Closure::_instantiator_type_arguments
+  [29] = FieldOffset dart.core::_Closure::_function_type_arguments
+  [30] = FieldOffset dart.core::_Closure::_function
+  [31] = StaticICData target 'dart.core::print', arg-desc CP#6
+  [32] = ICData target-name 'call', arg-desc CP#6
+  [33] = StaticICData target 'dart.core::print', arg-desc CP#6
+  [34] = ICData target-name 'call', arg-desc CP#6
+}
+Closure CP#4 {
+  Entry                6
+  CheckStack
+  Push                 FP[-5]
+  LoadFieldTOS         CP#5
+  PopLocal             r0
+  Push                 r0
+  LoadFieldTOS         CP#2
+  PushConstant         CP#7
+  IndirectStaticCall   1, CP#6
+  Drop1
+  Push                 r0
+  PopLocal             r2
+Try #0 start:
+  PushConstant         CP#8
+  PushConstant         CP#9
+  IndirectStaticCall   1, CP#6
+  Drop1
+  PushConstant         CP#10
+  Jump                 L1
+  Jump                 L2
+Try #0 end:
+Try #0 handler:
+  Push                 r2
+  PopLocal             r0
+  MoveSpecial          r2, exception
+  MoveSpecial          r3, stackTrace
+  Push                 r0
+  PopLocal             r4
+Try #1 start:
+  PushConstant         CP#12
+  PushConstant         CP#13
+  IndirectStaticCall   1, CP#6
+  Drop1
+  PushConstant         CP#14
+  Jump                 L3
+  Jump                 L4
+Try #1 end:
+Try #1 handler:
+  Push                 r4
+  PopLocal             r0
+  MoveSpecial          r4, exception
+  MoveSpecial          r5, stackTrace
+  Push                 r0
+  LoadFieldTOS         CP#2
+  PushConstant         CP#15
+  IndirectStaticCall   1, CP#6
+  Drop1
+  Push                 r4
+  Push                 r5
+  Throw                1
+L3:
+  Push                 r4
+  PopLocal             r0
+  Push                 r0
+  LoadFieldTOS         CP#2
+  PushConstant         CP#16
+  IndirectStaticCall   1, CP#6
+  Drop1
+  ReturnTOS
+L4:
+  Push                 r4
+  PopLocal             r0
+  Push                 r0
+  LoadFieldTOS         CP#2
+  PushConstant         CP#17
+  IndirectStaticCall   1, CP#6
+  Drop1
+  Push                 r2
+  Push                 r3
+  Throw                1
+L1:
+  Push                 r2
+  PopLocal             r0
+  Push                 r0
+  PopLocal             r4
+Try #2 start:
+  PushConstant         CP#12
+  PushConstant         CP#18
+  IndirectStaticCall   1, CP#6
+  Drop1
+  PushConstant         CP#14
+  Jump                 L5
+  Jump                 L6
+Try #2 end:
+Try #2 handler:
+  Push                 r4
+  PopLocal             r0
+  MoveSpecial          r4, exception
+  MoveSpecial          r5, stackTrace
+  Push                 r0
+  LoadFieldTOS         CP#2
+  PushConstant         CP#19
+  IndirectStaticCall   1, CP#6
+  Drop1
+  Push                 r4
+  Push                 r5
+  Throw                1
+L5:
+  Push                 r4
+  PopLocal             r0
+  Push                 r0
+  LoadFieldTOS         CP#2
+  PushConstant         CP#20
+  IndirectStaticCall   1, CP#6
+  Drop1
+  ReturnTOS
+L6:
+  Push                 r4
+  PopLocal             r0
+  Push                 r0
+  LoadFieldTOS         CP#2
+  PushConstant         CP#21
+  IndirectStaticCall   1, CP#6
+  Drop1
+  ReturnTOS
+L2:
+  Push                 r2
+  PopLocal             r0
+  Push                 r0
+  PopLocal             r4
+Try #3 start:
+  PushConstant         CP#12
+  PushConstant         CP#22
+  IndirectStaticCall   1, CP#6
+  Drop1
+  PushConstant         CP#14
+  Jump                 L7
+  Jump                 L8
+Try #3 end:
+Try #3 handler:
+  Push                 r4
+  PopLocal             r0
+  MoveSpecial          r4, exception
+  MoveSpecial          r5, stackTrace
+  Push                 r0
+  LoadFieldTOS         CP#2
+  PushConstant         CP#23
+  IndirectStaticCall   1, CP#6
+  Drop1
+  Push                 r4
+  Push                 r5
+  Throw                1
+L7:
+  Push                 r4
+  PopLocal             r0
+  Push                 r0
+  LoadFieldTOS         CP#2
+  PushConstant         CP#24
+  IndirectStaticCall   1, CP#6
+  Drop1
+  ReturnTOS
+L8:
+  Push                 r4
+  PopLocal             r0
+  Push                 r0
+  LoadFieldTOS         CP#2
+  PushConstant         CP#25
+  IndirectStaticCall   1, CP#6
+  Drop1
+  PushConstant         CP#3
+  ReturnTOS
+
+}
+]static method testTryFinally3() → dynamic {
+  core::int x = 11;
+  dynamic y;
+  try {
+    y = () → core::int {
+      core::print(x);
+      try {
+        core::print("try 1");
+        return 42;
+      }
+      finally {
+        try {
+          core::print("try 2");
+          return 43;
+        }
+        finally {
+          core::print(x);
+        }
+      }
+    };
+  }
+  finally {
+    core::print(x);
+    y.call();
+  }
+}
+[@vm.bytecode=
+Bytecode {
+  Entry                5
+  CheckStack
+Try #0 start:
+Try #1 start:
+  PushConstant         CP#0
+  PushConstant         CP#2
+  IndirectStaticCall   1, CP#1
+  Drop1
+  Jump                 L1
+Try #1 end:
+Try #1 handler:
+  MoveSpecial          r2, exception
+  MoveSpecial          r3, stackTrace
+  Push                 r2
+  PopLocal             r4
+  PushConstant         CP#4
+  PushConstant         CP#5
+  IndirectStaticCall   1, CP#1
+  Drop1
+  Jump                 L1
+L1:
+  Jump                 L2
+Try #0 end:
+Try #0 handler:
+  MoveSpecial          r0, exception
+  MoveSpecial          r1, stackTrace
+  PushConstant         CP#6
+  PushConstant         CP#7
+  IndirectStaticCall   1, CP#1
+  Drop1
+  Push                 r0
+  Push                 r1
+  Throw                1
+L2:
+  PushConstant         CP#6
+  PushConstant         CP#8
+  IndirectStaticCall   1, CP#1
+  Drop1
+  PushConstant         CP#9
+  ReturnTOS
+}
+ExceptionsTable {
+  try-index 0, outer -1, start 2, end 17, handler 17, needs-stack-trace, types [CP#3]
+  try-index 1, outer 0, start 2, end 7, handler 7, 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
+  [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
+  [9] = Null
+}
+]static method testTryCatchFinally() → dynamic {
+  try
+    try {
+      core::print("try");
+    }
+    on dynamic catch(final dynamic e) {
+      core::print("catch");
+    }
+  finally {
+    core::print("finally");
+  }
+}
+[@vm.bytecode=
+Bytecode {
+  Entry                0
+  CheckStack
+  PushConstant         CP#0
+  ReturnTOS
+}
+ConstantPool {
+  [0] = Null
+}
+]static method main() → dynamic {}
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/annotation.dart b/pkg/vm/testcases/transformations/type_flow/transformer/annotation.dart
new file mode 100644
index 0000000..b5b68eb
--- /dev/null
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/annotation.dart
@@ -0,0 +1,59 @@
+// 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 ClassAnnotation {
+  const ClassAnnotation();
+}
+
+const classAnnotation = const ClassAnnotation();
+
+class ClassAnnotation2 {
+  const ClassAnnotation2();
+}
+
+class MethodAnnotation {
+  final int x;
+  const MethodAnnotation(this.x);
+}
+
+class TypedefAnnotation {
+  final List<int> list;
+  const TypedefAnnotation(this.list);
+}
+
+class VarAnnotation {
+  const VarAnnotation();
+}
+
+class ParametrizedAnnotation<T> {
+  final T foo;
+  const ParametrizedAnnotation(this.foo);
+}
+
+@classAnnotation
+class A {
+  static void staticMethod() {}
+}
+
+@ClassAnnotation2()
+class B {
+  @MethodAnnotation(42)
+  void instanceMethod() {}
+}
+
+@TypedefAnnotation([1, 2, 3])
+typedef void SomeType<T>(List<T> arg);
+
+int foo(SomeType<int> a) {
+  @VarAnnotation()
+  int x = 2;
+  return x + 2;
+}
+
+@ParametrizedAnnotation(null)
+main(List<String> args) {
+  A.staticMethod();
+  new B().instanceMethod();
+  foo(null);
+}
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/annotation.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/annotation.dart.expect
new file mode 100644
index 0000000..34dfa36
--- /dev/null
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/annotation.dart.expect
@@ -0,0 +1,47 @@
+library #lib;
+import self as self;
+import "dart:core" as core;
+
+@self::TypedefAnnotation::•(const <core::int>[1, 2, 3])
+typedef SomeType<T extends core::Object = dynamic> = (core::List<T>) → void;
+abstract class ClassAnnotation2 extends core::Object {
+[@vm.unreachable.metadata=]  const constructor •() → void
+    throw "Attempt to execute method removed by Dart AOT compiler (TFA)";
+}
+abstract class MethodAnnotation extends core::Object {
+[@vm.unreachable.metadata=]  const constructor •(core::int x) → void
+    throw "Attempt to execute method removed by Dart AOT compiler (TFA)";
+}
+abstract class TypedefAnnotation extends core::Object {
+[@vm.unreachable.metadata=]  const constructor •(core::List<core::int> list) → void
+    throw "Attempt to execute method removed by Dart AOT compiler (TFA)";
+}
+abstract class VarAnnotation extends core::Object {
+[@vm.unreachable.metadata=]  const constructor •() → void
+    throw "Attempt to execute method removed by Dart AOT compiler (TFA)";
+}
+abstract class ParametrizedAnnotation<T extends core::Object = dynamic> extends core::Object {
+[@vm.unreachable.metadata=]  const constructor •(self::ParametrizedAnnotation::T foo) → void
+    throw "Attempt to execute method removed by Dart AOT compiler (TFA)";
+}
+abstract class A extends core::Object {
+  static method staticMethod() → void {}
+}
+@self::ClassAnnotation2::•()
+class B extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  @self::MethodAnnotation::•(42)
+  method instanceMethod() → void {}
+}
+static method foo([@vm.inferred-type.metadata=dart.core::Null?] (core::List<core::int>) → void a) → core::int {
+  @self::VarAnnotation::•() core::int x = 2;
+  return x.{core::num::+}(2);
+}
+@self::ParametrizedAnnotation::•<core::Null>(null)
+static method main(core::List<core::String> args) → dynamic {
+  self::A::staticMethod();
+  [@vm.direct-call.metadata=#lib::B::instanceMethod] new self::B::•().{self::B::instanceMethod}();
+  self::foo(null);
+}
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/no_such_method.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/no_such_method.dart.expect
index aef2831..79d7fdc 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/no_such_method.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/no_such_method.dart.expect
@@ -47,9 +47,12 @@
   method noSuchMethod(core::Invocation invocation) → dynamic {
     return new self::T1::•();
   }
-  abstract no-such-method-forwarder get bar() → dynamic;
-  abstract no-such-method-forwarder method foo() → dynamic;
-  abstract no-such-method-forwarder method bazz(dynamic a1, dynamic a2, dynamic a3, [dynamic a4, dynamic a5]) → dynamic;
+  no-such-method-forwarder get bar() → dynamic
+    return [@vm.direct-call.metadata=#lib::B::noSuchMethod] [@vm.inferred-type.metadata=#lib::T1] this.{self::B::noSuchMethod}(new core::_InvocationMirror::_withoutType("get:bar", const <core::Type>[], const <dynamic>[], [@vm.inferred-type.metadata=dart.collection::UnmodifiableMapView] core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} dynamic;
+  no-such-method-forwarder method foo() → dynamic
+    return [@vm.direct-call.metadata=#lib::B::noSuchMethod] [@vm.inferred-type.metadata=#lib::T1] this.{self::B::noSuchMethod}(new core::_InvocationMirror::_withoutType("foo", const <core::Type>[], const <dynamic>[], [@vm.inferred-type.metadata=dart.collection::UnmodifiableMapView] core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} dynamic;
+  no-such-method-forwarder method bazz([@vm.inferred-type.metadata=!] dynamic a1, [@vm.inferred-type.metadata=!] dynamic a2, [@vm.inferred-type.metadata=!] dynamic a3, [[@vm.inferred-type.metadata=!] dynamic a4, [@vm.inferred-type.metadata=dart.core::Null?] dynamic a5]) → dynamic
+    return [@vm.direct-call.metadata=#lib::B::noSuchMethod] [@vm.inferred-type.metadata=#lib::T1] this.{self::B::noSuchMethod}(new core::_InvocationMirror::_withoutType("bazz", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[a1, a2, a3, a4, a5]), [@vm.inferred-type.metadata=dart.collection::UnmodifiableMapView] core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} dynamic;
 }
 abstract class C extends core::Object {
   synthetic constructor •() → void
@@ -63,9 +66,12 @@
   synthetic constructor •() → void
     : super self::C::•()
     ;
-  abstract no-such-method-forwarder get bar() → dynamic;
-  abstract no-such-method-forwarder method foo() → dynamic;
-  abstract no-such-method-forwarder method bazz(dynamic a1, dynamic a2, dynamic a3, [dynamic a4, dynamic a5]) → dynamic;
+  no-such-method-forwarder get bar() → dynamic
+    return [@vm.direct-call.metadata=#lib::C::noSuchMethod] [@vm.inferred-type.metadata=#lib::T2] this.{self::C::noSuchMethod}(new core::_InvocationMirror::_withoutType("get:bar", const <core::Type>[], const <dynamic>[], [@vm.inferred-type.metadata=dart.collection::UnmodifiableMapView] core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} dynamic;
+  no-such-method-forwarder method foo() → dynamic
+    return [@vm.direct-call.metadata=#lib::C::noSuchMethod] [@vm.inferred-type.metadata=#lib::T2] this.{self::C::noSuchMethod}(new core::_InvocationMirror::_withoutType("foo", const <core::Type>[], const <dynamic>[], [@vm.inferred-type.metadata=dart.collection::UnmodifiableMapView] core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} dynamic;
+  no-such-method-forwarder method bazz([@vm.inferred-type.metadata=!] dynamic a1, [@vm.inferred-type.metadata=!] dynamic a2, [@vm.inferred-type.metadata=!] dynamic a3, [[@vm.inferred-type.metadata=!] dynamic a4, [@vm.inferred-type.metadata=dart.core::Null?] dynamic a5]) → dynamic
+    return [@vm.direct-call.metadata=#lib::C::noSuchMethod] [@vm.inferred-type.metadata=#lib::T2] this.{self::C::noSuchMethod}(new core::_InvocationMirror::_withoutType("bazz", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[a1, a2, a3, a4, a5]), [@vm.inferred-type.metadata=dart.collection::UnmodifiableMapView] core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} dynamic;
 }
 class E extends core::Object implements self::A {
   synthetic constructor •() → void
@@ -74,8 +80,8 @@
   method noSuchMethod(core::Invocation invocation) → dynamic {
     return new self::T4::•();
   }
-  abstract no-such-method-forwarder get bar() → dynamic;
-  abstract no-such-method-forwarder method bazz(dynamic a1, dynamic a2, dynamic a3, [dynamic a4, dynamic a5]) → dynamic;
+  no-such-method-forwarder get bar() → dynamic
+    return [@vm.direct-call.metadata=#lib::E::noSuchMethod] [@vm.inferred-type.metadata=#lib::T4] this.{self::E::noSuchMethod}(new core::_InvocationMirror::_withoutType("get:bar", const <core::Type>[], const <dynamic>[], [@vm.inferred-type.metadata=dart.collection::UnmodifiableMapView] core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} dynamic;
 }
 class F extends core::Object {
   synthetic constructor •() → void
@@ -109,12 +115,12 @@
 static method getDynamic() → dynamic
   return self::unknown.call();
 static method main(core::List<core::String> args) → dynamic {
-  core::print([@vm.inferred-type.metadata=#lib::T1] [@vm.inferred-type.metadata=#lib::B?] self::bb.{self::A::foo}());
-  core::print([@vm.inferred-type.metadata=#lib::T1] [@vm.inferred-type.metadata=#lib::B?] self::bb.{self::A::bar});
-  core::print([@vm.inferred-type.metadata=#lib::T1] [@vm.inferred-type.metadata=#lib::B?] self::bb.{self::A::bazz}(1, 2, 3, 4));
-  core::print([@vm.inferred-type.metadata=#lib::T2] [@vm.inferred-type.metadata=#lib::D?] self::dd.{self::A::foo}());
-  core::print([@vm.inferred-type.metadata=#lib::T2] [@vm.inferred-type.metadata=#lib::D?] self::dd.{self::A::bar});
-  core::print([@vm.inferred-type.metadata=#lib::T2] [@vm.inferred-type.metadata=#lib::D?] self::dd.{self::A::bazz}(1, 2, 3, 4));
+  core::print([@vm.direct-call.metadata=#lib::B::foo??] [@vm.inferred-type.metadata=#lib::T1] [@vm.inferred-type.metadata=#lib::B?] self::bb.{self::A::foo}());
+  core::print([@vm.direct-call.metadata=#lib::B::bar??] [@vm.inferred-type.metadata=#lib::T1] [@vm.inferred-type.metadata=#lib::B?] self::bb.{self::A::bar});
+  core::print([@vm.direct-call.metadata=#lib::B::bazz??] [@vm.inferred-type.metadata=#lib::T1] [@vm.inferred-type.metadata=#lib::B?] self::bb.{self::A::bazz}(1, 2, 3, 4));
+  core::print([@vm.direct-call.metadata=#lib::D::foo??] [@vm.inferred-type.metadata=#lib::T2] [@vm.inferred-type.metadata=#lib::D?] self::dd.{self::A::foo}());
+  core::print([@vm.direct-call.metadata=#lib::D::bar??] [@vm.inferred-type.metadata=#lib::T2] [@vm.inferred-type.metadata=#lib::D?] self::dd.{self::A::bar});
+  core::print([@vm.direct-call.metadata=#lib::D::bazz??] [@vm.inferred-type.metadata=#lib::T2] [@vm.inferred-type.metadata=#lib::D?] self::dd.{self::A::bazz}(1, 2, 3, 4));
   new self::E::•();
   self::A xx = self::getDynamic() as{TypeError} self::A;
   core::print([@vm.inferred-type.metadata=!] xx.{self::A::bar});
diff --git a/pkg/vm/tool/precompiler2 b/pkg/vm/tool/precompiler2
index cd965fe..64908b5 100755
--- a/pkg/vm/tool/precompiler2
+++ b/pkg/vm/tool/precompiler2
@@ -24,10 +24,15 @@
     --packages=*)
     PACKAGES="$arg"
     ;;
+    --enable-asserts)
+    GEN_KERNEL_OPTIONS+=("$arg")
+    OPTIONS+=("$arg")
+    ;;
     --sync-async | \
     --no-sync-async | \
     --tfa | \
-    --no-tfa )
+    --no-tfa | \
+    -D* )
     GEN_KERNEL_OPTIONS+=("$arg")
     ;;
     --*)
diff --git a/pkg/vm/tool/test_bytecode b/pkg/vm/tool/test_bytecode
index f1c4893..7b05997 100755
--- a/pkg/vm/tool/test_bytecode
+++ b/pkg/vm/tool/test_bytecode
@@ -9,6 +9,10 @@
 # Usage
 # pkg/vm/tool/test_bytecode ~/foo.dart
 
+# Note: To generate bytecode in the platform dill file as well, change the value
+#       of the constant 'isKernelBytecodeEnabled' in file
+#       pkg/vm/lib/bytecode/gen_bytecode.dart from 'false' to 'true'.
+
 set -e
 
 # Pick the architecture and mode to build and test.
@@ -55,11 +59,21 @@
 $CUR_DIR/gen_kernel --platform $BUILD_DIR/vm_platform_strong.dill \
   --gen-bytecode $@ -o $BUILD_DIR/test_bytecode.dill
 
+# Dump bytecode in generated vm_platform_strong.dill file to platform.txt.
+# $BUILD_DIR/dart $SDK_DIR/pkg/vm/bin/dump_kernel.dart \
+#   $BUILD_DIR/vm_platform_strong.dill $BUILD_DIR/platform.txt
+
+# Dump bytecode in generated test_bytecode.dill file to test_bytecode.txt.
+# $BUILD_DIR/dart $SDK_DIR/pkg/vm/bin/dump_kernel.dart \
+#   $BUILD_DIR/test_bytecode.dill $BUILD_DIR/test_bytecode.txt
+
 # Required flags.
 DART_VM_FLAGS="--preview-dart-2 --optimization-counter-threshold=-1 $DART_VM_FLAGS"
 
-# Optional flags.
-# DART_VM_FLAGS="--force-log-flush --dump-kernel-bytecode --trace-interpreter-after=0 $DART_VM_FLAGS"
+# Optional flags examples. Uncomment as needed.
+# DART_VM_FLAGS="--force-log-flush --isolate-log-filter=\"\" $DART_VM_FLAGS"
+# DART_VM_FLAGS="--dump-kernel-bytecode $DART_VM_FLAGS"
+# DART_VM_FLAGS="--trace-interpreter-after=0 $DART_VM_FLAGS"
 
 # Execute dill file.
 exec $BUILD_DIR/dart $DART_VM_FLAGS $BUILD_DIR/test_bytecode.dill
diff --git a/runtime/BUILD.gn b/runtime/BUILD.gn
index 1a7fc12..2062431 100644
--- a/runtime/BUILD.gn
+++ b/runtime/BUILD.gn
@@ -3,6 +3,7 @@
 # BSD-style license that can be found in the LICENSE file.
 
 import("../build/dart/dart_host_sdk_toolchain.gni")
+import("configs.gni")
 import("runtime_args.gni")
 
 config("dart_public_config") {
@@ -48,7 +49,7 @@
   defines += [ "DART_PRECOMPILER" ]
 }
 
-config("dart_no_snapshot_config") {
+config("dart_nosnapshot_config") {
   defines = []
   defines += [ "DART_NO_SNAPSHOT" ]
 }
@@ -120,6 +121,17 @@
   }
 }
 
+config("dart_interpreter_config") {
+  defines = [ "DART_USE_INTERPRETER" ]
+}
+
+config("dart_maybe_interpreter_config") {
+  defines = []
+  if (dart_use_interpreter) {
+    defines += [ "DART_USE_INTERPRETER" ]
+  }
+}
+
 config("dart_config") {
   defines = []
 
@@ -136,15 +148,14 @@
   }
 
   if (is_fuchsia) {
-    defines += [ "DART_USE_JEMALLOC" ]
+    import("//build/config/scudo/scudo.gni")
     include_dirs += [
       "//zircon/system/ulib/zx/include",
-      "//zircon/third_party/ulib/jemalloc/include",
     ]
-  }
-
-  if (dart_use_interpreter) {
-    defines += [ "DART_USE_INTERPRETER" ]
+    if (!use_scudo) {
+      defines += [ "DART_USE_JEMALLOC" ]
+      include_dirs += [ "//zircon/third_party/ulib/jemalloc/include" ]
+    }
   }
 
   if (!is_win) {
@@ -191,172 +202,29 @@
   ]
 }
 
-template("libdart_library") {
-  extra_configs = []
-  if (defined(invoker.extra_configs)) {
-    extra_configs += invoker.extra_configs
-  }
-  extra_deps = []
-  if (defined(invoker.extra_deps)) {
-    extra_deps += invoker.extra_deps
-  }
-  target(dart_component_kind, target_name) {
-    configs += [
-                 ":dart_arch_config",
-                 ":dart_config",
-               ] + extra_configs
-    if (is_fuchsia) {
-      configs -= [ "//build/config:symbol_visibility_hidden" ]
-    }
-    deps = [
-             "third_party/double-conversion/src:libdouble_conversion",
-             ":generate_version_cc_file",
-           ] + extra_deps
-    include_dirs = [ "." ]
-    public_configs = [ ":dart_public_config" ]
-    sources = [
-      "$target_gen_dir/version.cc",
-      "include/dart_api.h",
-      "include/dart_native_api.h",
-      "include/dart_tools_api.h",
-      "vm/dart_api_impl.cc",
-      "vm/native_api_impl.cc",
-      "vm/version.h",
-    ]
-    defines = [ "DART_SHARED_LIB" ]
-  }
-}
-
-libdart_library("libdart_jit") {
-  extra_configs = [
-    ":dart_maybe_product_config",
-    ":dart_os_config",
-  ]
+library_for_all_configs("libdart") {
+  target_type = dart_component_kind
   extra_deps = [
+    "third_party/double-conversion/src:libdouble_conversion",
+    ":generate_version_cc_file",
+  ]
+  configurable_deps = [
     "platform:libdart_platform",
-    "vm:libdart_lib_jit",
-    "vm:libdart_vm_jit",
+    "vm:libdart_lib",
+    "vm:libdart_vm",
   ]
-}
-
-libdart_library("libdart_jit_product") {
-  extra_configs = [
-    ":dart_product_config",
-    ":dart_os_config",
+  include_dirs = [ "." ]
+  public_configs = [ ":dart_public_config" ]
+  sources = [
+    "$target_gen_dir/version.cc",
+    "include/dart_api.h",
+    "include/dart_native_api.h",
+    "include/dart_tools_api.h",
+    "vm/dart_api_impl.cc",
+    "vm/native_api_impl.cc",
+    "vm/version.h",
   ]
-  extra_deps = [
-    "platform:libdart_platform_product",
-    "vm:libdart_lib_jit_product",
-    "vm:libdart_vm_jit_product",
-  ]
-}
-
-libdart_library("libdart_precompiled_runtime") {
-  extra_configs = [
-    ":dart_maybe_product_config",
-    ":dart_precompiled_runtime_config",
-    ":dart_os_config",
-  ]
-  extra_deps = [
-    "platform:libdart_platform",
-    "vm:libdart_lib_precompiled_runtime",
-    "vm:libdart_vm_precompiled_runtime",
-  ]
-}
-
-libdart_library("libdart_precompiled_runtime_product") {
-  extra_configs = [
-    ":dart_product_config",
-    ":dart_precompiled_runtime_config",
-    ":dart_os_config",
-  ]
-  extra_deps = [
-    "platform:libdart_platform_product",
-    "vm:libdart_lib_precompiled_runtime_product",
-    "vm:libdart_vm_precompiled_runtime_product",
-  ]
-}
-
-libdart_library("libdart_nosnapshot_with_precompiler") {
-  extra_configs = [
-    ":dart_maybe_product_config",
-    ":dart_no_snapshot_config",
-    ":dart_precompiler_config",
-    ":dart_os_config",
-  ]
-  extra_deps = [
-    "platform:libdart_platform",
-    "vm:libdart_lib_nosnapshot_with_precompiler",
-    "vm:libdart_vm_nosnapshot_with_precompiler",
-  ]
-}
-
-libdart_library("libdart_nosnapshot_with_precompiler_product") {
-  extra_configs = [
-    ":dart_product_config",
-    ":dart_no_snapshot_config",
-    ":dart_precompiler_config",
-    ":dart_os_config",
-  ]
-  extra_deps = [
-    "platform:libdart_platform_product",
-    "vm:libdart_lib_nosnapshot_with_precompiler_product",
-    "vm:libdart_vm_nosnapshot_with_precompiler_product",
-  ]
-}
-
-libdart_library("libdart_nosnapshot_with_precompiler_fuchsia") {
-  extra_configs = [
-    ":dart_maybe_product_config",
-    ":dart_no_snapshot_config",
-    ":dart_precompiler_config",
-    ":dart_os_fuchsia_config",
-  ]
-  extra_deps = [
-    "platform:libdart_platform_fuchsia",
-    "vm:libdart_lib_nosnapshot_with_precompiler_fuchsia",
-    "vm:libdart_vm_nosnapshot_with_precompiler_fuchsia",
-  ]
-}
-
-libdart_library("libdart_nosnapshot_with_precompiler_product_fuchsia") {
-  extra_configs = [
-    ":dart_product_config",
-    ":dart_no_snapshot_config",
-    ":dart_precompiler_config",
-    ":dart_os_fuchsia_config",
-  ]
-  extra_deps = [
-    "platform:libdart_platform_product_fuchsia",
-    "vm:libdart_lib_nosnapshot_with_precompiler_product_fuchsia",
-    "vm:libdart_vm_nosnapshot_with_precompiler_product_fuchsia",
-  ]
-}
-
-libdart_library("libdart_with_precompiler") {
-  extra_configs = [
-    ":dart_maybe_product_config",
-    ":dart_precompiler_config",
-    ":dart_os_config",
-  ]
-  extra_deps = [
-    "platform:libdart_platform",
-    "vm:libdart_lib_with_precompiler",
-    "vm:libdart_vm_with_precompiler",
-  ]
-}
-
-libdart_library("libdart_with_precompiler_product") {
-  extra_configs = [
-    ":dart_product_config",
-    ":dart_precompiler_config",
-    ":dart_os_config",
-  ]
-  extra_deps = [
-    "platform:libdart_platform_product",
-    "vm:libdart_lib_with_precompiler_product",
-    "vm:libdart_vm_with_precompiler_product",
-  ]
+  defines = [ "DART_SHARED_LIB" ]
 }
 
 action("generate_version_cc_file") {
diff --git a/runtime/bin/BUILD.gn b/runtime/bin/BUILD.gn
index 71d98d4..970dad7 100644
--- a/runtime/bin/BUILD.gn
+++ b/runtime/bin/BUILD.gn
@@ -246,6 +246,7 @@
   static_library(target_name) {
     configs += [
                  "..:dart_arch_config",
+                 "..:dart_maybe_interpreter_config",
                  "..:dart_config",
                ] + extra_configs
     if (is_fuchsia) {
@@ -332,6 +333,7 @@
     configs += [
                  "..:dart_arch_config",
                  "..:dart_config",
+                 "..:dart_maybe_interpreter_config",
                  "..:dart_precompiler_config",
                ] + extra_configs
     if (is_fuchsia) {
@@ -467,6 +469,7 @@
     configs += [
                  "..:dart_arch_config",
                  "..:dart_config",
+                 "..:dart_maybe_interpreter_config",
                  "..:dart_precompiler_config",
                ] + extra_configs
     deps = []
@@ -554,6 +557,7 @@
     configs += [
                  "..:dart_arch_config",
                  "..:dart_config",
+                 "..:dart_maybe_interpreter_config",
                  "..:dart_os_config",
                ] + extra_configs
     if (is_fuchsia) {
@@ -868,6 +872,7 @@
                  "..:dart_arch_config",
                  "..:dart_config",
                  "..:dart_os_config",
+                 "..:dart_maybe_interpreter_config",
                  "..:dart_maybe_product_config",
                ] + extra_configs
     if (is_fuchsia) {
@@ -1011,7 +1016,7 @@
 dart_executable("dart_bootstrap") {
   extra_configs = [
     "..:dart_precompiler_config",
-    "..:dart_no_snapshot_config",
+    "..:dart_nosnapshot_config",
   ]
   extra_deps = [
     ":gen_resources_cc",
@@ -1113,6 +1118,7 @@
     "..:dart_arch_config",
     "..:dart_config",
     "..:dart_os_config",
+    "..:dart_maybe_interpreter_config",
     "..:dart_maybe_product_config",
   ]
   if (is_fuchsia) {
diff --git a/runtime/bin/dartutils.cc b/runtime/bin/dartutils.cc
index bb4661e..a5d1d83 100644
--- a/runtime/bin/dartutils.cc
+++ b/runtime/bin/dartutils.cc
@@ -213,7 +213,7 @@
   return reinterpret_cast<void*>(file);
 }
 
-void DartUtils::ReadFile(const uint8_t** data, intptr_t* len, void* stream) {
+void DartUtils::ReadFile(uint8_t** data, intptr_t* len, void* stream) {
   ASSERT(data != NULL);
   ASSERT(len != NULL);
   ASSERT(stream != NULL);
@@ -225,14 +225,16 @@
     return;
   }
   *len = static_cast<intptr_t>(file_len);
-  uint8_t* text_buffer = reinterpret_cast<uint8_t*>(malloc(*len));
-  ASSERT(text_buffer != NULL);
-  if (!file_stream->ReadFully(text_buffer, *len)) {
+  *data = reinterpret_cast<uint8_t*>(malloc(*len));
+  if (*data == NULL) {
+    OUT_OF_MEMORY();
+  }
+  if (!file_stream->ReadFully(*data, *len)) {
+    free(*data);
     *data = NULL;
     *len = -1;  // Indicates read was not successful.
     return;
   }
-  *data = text_buffer;
 }
 
 void DartUtils::WriteFile(const void* buffer,
@@ -270,16 +272,16 @@
   snprintf(msg, len + 1, format, __VA_ARGS__);                                 \
   *error_msg = msg
 
-static const uint8_t* ReadFileFully(const char* filename,
-                                    intptr_t* file_len,
-                                    const char** error_msg) {
+static uint8_t* ReadFileFully(const char* filename,
+                              intptr_t* file_len,
+                              const char** error_msg) {
   *file_len = -1;
   void* stream = DartUtils::OpenFile(filename, false);
   if (stream == NULL) {
     SET_ERROR_MSG(error_msg, "Unable to open file: %s", filename);
     return NULL;
   }
-  const uint8_t* text_buffer = NULL;
+  uint8_t* text_buffer = NULL;
   DartUtils::ReadFile(&text_buffer, file_len, stream);
   if (text_buffer == NULL || *file_len == -1) {
     *error_msg = "Unable to read file contents";
@@ -292,12 +294,12 @@
 Dart_Handle DartUtils::ReadStringFromFile(const char* filename) {
   const char* error_msg = NULL;
   intptr_t len;
-  const uint8_t* text_buffer = ReadFileFully(filename, &len, &error_msg);
+  uint8_t* text_buffer = ReadFileFully(filename, &len, &error_msg);
   if (text_buffer == NULL) {
     return Dart_NewApiError(error_msg);
   }
   Dart_Handle str = Dart_NewStringFromUTF8(text_buffer, len);
-  free(const_cast<uint8_t*>(text_buffer));
+  free(text_buffer);
   return str;
 }
 
diff --git a/runtime/bin/dartutils.h b/runtime/bin/dartutils.h
index 5c14911..2ae7ca6 100644
--- a/runtime/bin/dartutils.h
+++ b/runtime/bin/dartutils.h
@@ -122,7 +122,7 @@
   static void* MapExecutable(const char* name, intptr_t* file_len);
   static void* OpenFile(const char* name, bool write);
   static void* OpenFileUri(const char* uri, bool write);
-  static void ReadFile(const uint8_t** data, intptr_t* file_len, void* stream);
+  static void ReadFile(uint8_t** data, intptr_t* file_len, void* stream);
   static void WriteFile(const void* buffer, intptr_t num_bytes, void* stream);
   static void CloseFile(void* stream);
   static bool EntropySource(uint8_t* buffer, intptr_t length);
diff --git a/runtime/bin/dfe.cc b/runtime/bin/dfe.cc
index 11167d4..c53b8d1 100644
--- a/runtime/bin/dfe.cc
+++ b/runtime/bin/dfe.cc
@@ -3,14 +3,16 @@
 // BSD-style license that can be found in the LICENSE file.
 
 #include "bin/dfe.h"
+
 #include "bin/dartutils.h"
 #include "bin/directory.h"
 #include "bin/error_exit.h"
 #include "bin/file.h"
 #include "bin/platform.h"
 #include "bin/utils.h"
-
-#include "vm/kernel.h"
+#include "include/dart_tools_api.h"
+#include "platform/utils.h"
+#include "vm/os.h"
 
 extern "C" {
 #if !defined(EXCLUDE_CFE_AND_KERNEL_PLATFORM)
@@ -75,15 +77,11 @@
   return Utils::StrNDup(name, i + 1);
 }
 
-static void NoopRelease(uint8_t* buffer) {}
-
 DFE::DFE()
     : use_dfe_(false),
       frontend_filename_(NULL),
-      kernel_service_program_(NULL),
-      platform_program_(NULL),
-      platform_strong_program_(NULL),
-      application_kernel_binary_(NULL) {}
+      application_kernel_buffer_(NULL),
+      application_kernel_buffer_size_(0) {}
 
 DFE::~DFE() {
   if (frontend_filename_ != NULL) {
@@ -91,38 +89,15 @@
   }
   frontend_filename_ = NULL;
 
-  // Do NOT delete kernel_service_program_ in the destructor.
-  // It is always a full a dill file, hence it is used as
-  // argument to Dart_CreateIsolateFromKernel as well as loaded
-  // as the kernel program for the isolate. Hence, deleting here
-  // would lead to double deletion.
-
-  delete reinterpret_cast<kernel::Program*>(platform_program_);
-  platform_program_ = NULL;
-
-  delete reinterpret_cast<kernel::Program*>(platform_strong_program_);
-  platform_strong_program_ = NULL;
-
-  delete reinterpret_cast<kernel::Program*>(application_kernel_binary_);
-  application_kernel_binary_ = NULL;
+  free(application_kernel_buffer_);
+  application_kernel_buffer_ = NULL;
+  application_kernel_buffer_size_ = 0;
 }
 
 void DFE::Init() {
   if (platform_dill == NULL) {
     return;
   }
-  // platform_dill is not NULL implies that platform_strong_dill is also
-  // not NULL.
-  if (platform_program_ == NULL) {
-    ASSERT(Dart_IsKernel(platform_dill, platform_dill_size));
-    platform_program_ =
-        Dart_ReadKernelBinary(platform_dill, platform_dill_size, NoopRelease);
-  }
-  if (platform_strong_program_ == NULL) {
-    ASSERT(Dart_IsKernel(platform_strong_dill, platform_strong_dill_size));
-    platform_strong_program_ = Dart_ReadKernelBinary(
-        platform_strong_dill, platform_strong_dill_size, NoopRelease);
-  }
 
   if (frontend_filename_ == NULL) {
     // Look for the frontend snapshot next to the executable.
@@ -153,34 +128,29 @@
   return kernel_service_dill != NULL;
 }
 
-void* DFE::LoadKernelServiceProgram() {
-  if (kernel_service_dill == NULL) {
-    return NULL;
-  }
-  if (kernel_service_program_ == NULL) {
-    kernel_service_program_ = Dart_ReadKernelBinary(
-        kernel_service_dill, kernel_service_dill_size, NoopRelease);
-  }
-  return kernel_service_program_;
+void DFE::LoadKernelService(const uint8_t** kernel_service_buffer,
+                            intptr_t* kernel_service_buffer_size) {
+  *kernel_service_buffer = kernel_service_dill;
+  *kernel_service_buffer_size = kernel_service_dill_size;
 }
 
-void* DFE::platform_program(bool strong) const {
+void DFE::LoadPlatform(const uint8_t** kernel_buffer,
+                       intptr_t* kernel_buffer_size,
+                       bool strong) {
   if (strong) {
-    return platform_strong_program_;
+    *kernel_buffer = platform_strong_dill;
+    *kernel_buffer_size = platform_strong_dill_size;
   } else {
-    return platform_program_;
+    *kernel_buffer = platform_dill;
+    *kernel_buffer_size = platform_dill_size;
   }
 }
 
 bool DFE::CanUseDartFrontend() const {
-  return (platform_program() != NULL) &&
+  return (platform_dill != NULL) &&
          (KernelServiceDillAvailable() || (frontend_filename() != NULL));
 }
 
-static void ReleaseFetchedBytes(uint8_t* buffer) {
-  free(buffer);
-}
-
 class WindowsPathSanitizer {
  public:
   explicit WindowsPathSanitizer(const char* path) {
@@ -239,17 +209,22 @@
                               package_config);
 }
 
-void* DFE::CompileAndReadScript(const char* script_uri,
-                                char** error,
-                                int* exit_code,
-                                bool strong,
-                                const char* package_config) {
+void DFE::CompileAndReadScript(const char* script_uri,
+                               uint8_t** kernel_buffer,
+                               intptr_t* kernel_buffer_size,
+                               char** error,
+                               int* exit_code,
+                               bool strong,
+                               const char* package_config) {
   Dart_KernelCompilationResult result =
       CompileScript(script_uri, strong, true, package_config);
   switch (result.status) {
     case Dart_KernelCompilationStatus_Ok:
-      return Dart_ReadKernelBinary(result.kernel, result.kernel_size,
-                                   ReleaseFetchedBytes);
+      *kernel_buffer = result.kernel;
+      *kernel_buffer_size = result.kernel_size;
+      *error = NULL;
+      *exit_code = 0;
+      break;
     case Dart_KernelCompilationStatus_Error:
       *error = result.error;  // Copy error message.
       *exit_code = kCompilationErrorExitCode;
@@ -263,25 +238,27 @@
       *exit_code = kErrorExitCode;
       break;
   }
-  return NULL;
 }
 
-void* DFE::ReadScript(const char* script_uri) const {
+void DFE::ReadScript(const char* script_uri,
+                     uint8_t** kernel_buffer,
+                     intptr_t* kernel_buffer_size) const {
   int64_t start = Dart_TimelineGetMicros();
-  const uint8_t* buffer = NULL;
-  intptr_t buffer_length = -1;
-  bool result = TryReadKernelFile(script_uri, &buffer, &buffer_length);
-  void* read_binary =
-      result ? Dart_ReadKernelBinary(buffer, buffer_length, ReleaseFetchedBytes)
-             : NULL;
+  if (!TryReadKernelFile(script_uri, kernel_buffer, kernel_buffer_size)) {
+    return;
+  }
+  if (!Dart_IsKernel(*kernel_buffer, *kernel_buffer_size)) {
+    free(*kernel_buffer);
+    *kernel_buffer = NULL;
+    *kernel_buffer_size = -1;
+  }
   int64_t end = Dart_TimelineGetMicros();
   Dart_TimelineEvent("DFE::ReadScript", start, end,
                      Dart_Timeline_Event_Duration, 0, NULL, NULL);
-  return read_binary;
 }
 
 bool DFE::TryReadKernelFile(const char* script_uri,
-                            const uint8_t** kernel_ir,
+                            uint8_t** kernel_ir,
                             intptr_t* kernel_ir_size) {
   *kernel_ir = NULL;
   *kernel_ir_size = -1;
@@ -289,7 +266,7 @@
   if (script_file == NULL) {
     return false;
   }
-  const uint8_t* buffer = NULL;
+  uint8_t* buffer = NULL;
   DartUtils::ReadFile(&buffer, kernel_ir_size, script_file);
   DartUtils::CloseFile(script_file);
   if (*kernel_ir_size == 0 || buffer == NULL) {
@@ -297,7 +274,7 @@
   }
   if (DartUtils::SniffForMagicNumber(buffer, *kernel_ir_size) !=
       DartUtils::kKernelMagicNumber) {
-    free(const_cast<uint8_t*>(buffer));
+    free(buffer);
     *kernel_ir = NULL;
     *kernel_ir_size = -1;
     return false;
diff --git a/runtime/bin/dfe.h b/runtime/bin/dfe.h
index d770bb0..6efb45c 100644
--- a/runtime/bin/dfe.h
+++ b/runtime/bin/dfe.h
@@ -40,10 +40,14 @@
 
   // Set the kernel program for the main application if it was specified
   // as a dill file.
-  void set_application_kernel_binary(void* application_kernel_binary) {
-    application_kernel_binary_ = application_kernel_binary;
+  void set_application_kernel_buffer(uint8_t* buffer, intptr_t size) {
+    application_kernel_buffer_ = buffer;
+    application_kernel_buffer_size_ = size;
   }
-  void* application_kernel_binary() const { return application_kernel_binary_; }
+  void application_kernel_buffer(const uint8_t** buffer, intptr_t* size) const {
+    *buffer = application_kernel_buffer_;
+    *size = application_kernel_buffer_size_;
+  }
 
   // Compiles specified script.
   // Returns result from compiling the script.
@@ -56,16 +60,20 @@
   // If the compilation is successful, returns a valid in memory kernel
   // representation of the script, NULL otherwise
   // 'error' and 'exit_code' have the error values in case of errors.
-  void* CompileAndReadScript(const char* script_uri,
-                             char** error,
-                             int* exit_code,
-                             bool strong,
-                             const char* package_config);
+  void CompileAndReadScript(const char* script_uri,
+                            uint8_t** kernel_buffer,
+                            intptr_t* kernel_buffer_size,
+                            char** error,
+                            int* exit_code,
+                            bool strong,
+                            const char* package_config);
 
   // Reads the script kernel file if specified 'script_uri' is a kernel file.
   // Returns an in memory kernel representation of the specified script is a
   // valid kernel file, false otherwise.
-  void* ReadScript(const char* script_uri) const;
+  void ReadScript(const char* script_uri,
+                  uint8_t** kernel_buffer,
+                  intptr_t* kernel_buffer_size) const;
 
   static bool KernelServiceDillAvailable();
 
@@ -75,8 +83,8 @@
   // The caller is responsible for free()ing [kernel_file] if `true`
   // was returned.
   static bool TryReadKernelFile(const char* script_uri,
-                                const uint8_t** kernel_ir,
-                                intptr_t* kernel_ir_size);
+                                uint8_t** kernel_buffer,
+                                intptr_t* kernel_buffer_size);
 
   // We distinguish between "intent to use Dart frontend" vs "can actually
   // use Dart frontend". The method UseDartFrontend tells us about the
@@ -84,20 +92,19 @@
   // be used.
   bool CanUseDartFrontend() const;
 
-  void* platform_program(bool strong = false) const;
-
-  void* LoadKernelServiceProgram();
+  void LoadPlatform(const uint8_t** kernel_buffer,
+                    intptr_t* kernel_buffer_size,
+                    bool strong = false);
+  void LoadKernelService(const uint8_t** kernel_service_buffer,
+                         intptr_t* kernel_service_buffer_size);
 
  private:
   bool use_dfe_;
   char* frontend_filename_;
 
-  void* kernel_service_program_;
-  void* platform_program_;
-  void* platform_strong_program_;
-
   // Kernel binary specified on the cmd line.
-  void* application_kernel_binary_;
+  uint8_t* application_kernel_buffer_;
+  intptr_t application_kernel_buffer_size_;
 
   DISALLOW_COPY_AND_ASSIGN(DFE);
 };
diff --git a/runtime/bin/gen_snapshot.cc b/runtime/bin/gen_snapshot.cc
index 6de85ad..76e73d7 100644
--- a/runtime/bin/gen_snapshot.cc
+++ b/runtime/bin/gen_snapshot.cc
@@ -1416,7 +1416,8 @@
   return isolate;
 }
 
-static int GenerateSnapshotFromKernelProgram(void* kernel_program) {
+static int GenerateSnapshotFromKernel(const uint8_t* kernel_buffer,
+                                      intptr_t kernel_buffer_size) {
   ASSERT(SnapshotKindAllowedFromKernel());
 
   char* error = NULL;
@@ -1440,7 +1441,8 @@
   // in the main isolate as well.
   isolate_flags.load_vmservice_library = true;
   Dart_Isolate isolate = Dart_CreateIsolateFromKernel(
-      NULL, NULL, kernel_program, &isolate_flags, isolate_data, &error);
+      NULL, NULL, kernel_buffer, kernel_buffer_size, &isolate_flags,
+      isolate_data, &error);
   if (isolate == NULL) {
     delete isolate_data;
     Log::PrintErr("%s\n", error);
@@ -1462,11 +1464,8 @@
     //
     // If the input dill file does not have a root library, then
     // Dart_LoadScript will error.
-    Dart_Handle dummy_uri =
-        DartUtils::NewString("____dummy_gen_snapshot_root_library_uri____");
     Dart_Handle library =
-        Dart_LoadScript(dummy_uri, Dart_Null(),
-                        reinterpret_cast<Dart_Handle>(kernel_program), 0, 0);
+        Dart_LoadScriptFromKernel(kernel_buffer, kernel_buffer_size);
     if (Dart_IsError(library)) {
       Log::PrintErr("Unable to load root library from the input dill file.\n");
       return kErrorExitCode;
@@ -1511,11 +1510,12 @@
   }
 
   // Sniff the script to check if it is actually a dill file.
-  void* kernel_program = NULL;
+  uint8_t* kernel_buffer = NULL;
+  intptr_t kernel_buffer_size = NULL;
   if (app_script_name != NULL) {
-    kernel_program = dfe.ReadScript(app_script_name);
+    dfe.ReadScript(app_script_name, &kernel_buffer, &kernel_buffer_size);
   }
-  if (kernel_program != NULL && !SnapshotKindAllowedFromKernel()) {
+  if (kernel_buffer != NULL && !SnapshotKindAllowedFromKernel()) {
     // TODO(sivachandra): Add check for the kernel program format (incremental
     // vs batch).
     Log::PrintErr(
@@ -1567,7 +1567,7 @@
   Dart_InitializeParams init_params;
   memset(&init_params, 0, sizeof(init_params));
   init_params.version = DART_INITIALIZE_PARAMS_CURRENT_VERSION;
-  if (app_script_name != NULL && kernel_program == NULL) {
+  if (app_script_name != NULL && kernel_buffer == NULL) {
     // We need the service isolate to load script files.
     // When generating snapshots from a kernel program, we do not need to load
     // any script files.
@@ -1613,8 +1613,8 @@
     return kErrorExitCode;
   }
 
-  if (kernel_program != NULL) {
-    return GenerateSnapshotFromKernelProgram(kernel_program);
+  if (kernel_buffer != NULL) {
+    return GenerateSnapshotFromKernel(kernel_buffer, kernel_buffer_size);
   }
 
   Dart_IsolateFlags flags;
@@ -1714,7 +1714,7 @@
       AddDependency(commandline_packages_file);
     }
 
-    ASSERT(kernel_program == NULL);
+    ASSERT(kernel_buffer == NULL);
 
     // Load any libraries named in the entry points. Do this before loading the
     // user's script to ensure conditional imports see the embedder-specific
diff --git a/runtime/bin/io_natives.cc b/runtime/bin/io_natives.cc
index 72368ca..324eb1a 100644
--- a/runtime/bin/io_natives.cc
+++ b/runtime/bin/io_natives.cc
@@ -169,6 +169,9 @@
   V(SynchronousSocket_ReadList, 4)                                             \
   V(SynchronousSocket_WriteList, 4)                                            \
   V(SystemEncodingToString, 1)                                                 \
+  V(X509_Der, 1)                                                               \
+  V(X509_Pem, 1)                                                               \
+  V(X509_Sha1, 1)                                                              \
   V(X509_Subject, 1)                                                           \
   V(X509_Issuer, 1)                                                            \
   V(X509_StartValidity, 1)                                                     \
diff --git a/runtime/bin/isolate_data.cc b/runtime/bin/isolate_data.cc
index 796509a..c7f1779 100644
--- a/runtime/bin/isolate_data.cc
+++ b/runtime/bin/isolate_data.cc
@@ -5,8 +5,6 @@
 #include "bin/isolate_data.h"
 #include "bin/snapshot_utils.h"
 
-#include "vm/kernel.h"
-
 namespace dart {
 namespace bin {
 
@@ -17,12 +15,14 @@
     : script_url((url != NULL) ? strdup(url) : NULL),
       package_root(NULL),
       packages_file(NULL),
-      kernel_program(NULL),
       builtin_lib_(NULL),
       loader_(NULL),
       app_snapshot_(app_snapshot),
       dependencies_(NULL),
-      create_isolate_from_kernel_(false) {
+      resolved_packages_config_(NULL),
+      kernel_buffer_(NULL),
+      kernel_buffer_size_(0),
+      owns_kernel_buffer_(false) {
   if (package_root != NULL) {
     ASSERT(packages_file == NULL);
     this->package_root = strdup(package_root);
@@ -45,10 +45,14 @@
   package_root = NULL;
   free(packages_file);
   packages_file = NULL;
-  if (kernel_program != NULL) {
-    delete reinterpret_cast<kernel::Program*>(kernel_program);
-    kernel_program = NULL;
+  free(resolved_packages_config_);
+  resolved_packages_config_ = NULL;
+  if (owns_kernel_buffer_) {
+    ASSERT(kernel_buffer_ != NULL);
+    free(kernel_buffer_);
   }
+  kernel_buffer_ = NULL;
+  kernel_buffer_size_ = 0;
   delete app_snapshot_;
   app_snapshot_ = NULL;
 }
diff --git a/runtime/bin/isolate_data.h b/runtime/bin/isolate_data.h
index ed78806..575d1b0 100644
--- a/runtime/bin/isolate_data.h
+++ b/runtime/bin/isolate_data.h
@@ -51,7 +51,15 @@
   char* script_url;
   char* package_root;
   char* packages_file;
-  void* kernel_program;
+
+  const uint8_t* kernel_buffer() const { return kernel_buffer_; }
+  intptr_t kernel_buffer_size() const { return kernel_buffer_size_; }
+  void set_kernel_buffer(uint8_t* buffer, intptr_t size, bool take_ownership) {
+    ASSERT(kernel_buffer_ == NULL);
+    kernel_buffer_ = buffer;
+    kernel_buffer_size_ = size;
+    owns_kernel_buffer_ = take_ownership;
+  }
 
   void UpdatePackagesFile(const char* packages_file_) {
     if (packages_file != NULL) {
@@ -61,6 +69,18 @@
     packages_file = strdup(packages_file_);
   }
 
+  const char* resolved_packages_config() const {
+    return resolved_packages_config_;
+  }
+
+  void set_resolved_packages_config(const char* packages_config) {
+    if (resolved_packages_config_ != NULL) {
+      free(resolved_packages_config_);
+      resolved_packages_config_ = NULL;
+    }
+    resolved_packages_config_ = strdup(packages_config);
+  }
+
   // While loading a loader is associated with the isolate.
   bool HasLoader() const { return loader_ != NULL; }
   Loader* loader() const {
@@ -78,19 +98,15 @@
 
   void OnIsolateShutdown();
 
-  void set_create_isolate_from_kernel(bool value) {
-    create_isolate_from_kernel_ = value;
-  }
-  bool create_isolate_from_kernel() const {
-    return create_isolate_from_kernel_;
-  }
-
  private:
   Dart_Handle builtin_lib_;
   Loader* loader_;
   AppSnapshot* app_snapshot_;
   MallocGrowableArray<char*>* dependencies_;
-  bool create_isolate_from_kernel_;
+  char* resolved_packages_config_;
+  uint8_t* kernel_buffer_;
+  intptr_t kernel_buffer_size_;
+  bool owns_kernel_buffer_;
 
   DISALLOW_COPY_AND_ASSIGN(IsolateData);
 };
diff --git a/runtime/bin/loader.cc b/runtime/bin/loader.cc
index 70c34e3..64b76f5 100644
--- a/runtime/bin/loader.cc
+++ b/runtime/bin/loader.cc
@@ -336,10 +336,6 @@
   uint8_t* decompressed_;
 };
 
-static void ReleaseFetchedBytes(uint8_t* buffer) {
-  free(buffer);
-}
-
 bool Loader::ProcessResultLocked(Loader* loader, Loader::IOResult* result) {
   // We have to copy everything we care about out of |result| because after
   // dropping the lock below |result| may no longer valid.
@@ -457,10 +453,7 @@
         // isolates. We currently do not have support for neither
         // `Isolate.spawn()` nor `Isolate.spawnUri()` with kernel-based
         // frontend.
-        Dart_Handle kernel_binary =
-            reinterpret_cast<Dart_Handle>(Dart_ReadKernelBinary(
-                payload, payload_length, ReleaseFetchedBytes));
-        dart_result = Dart_LoadScript(uri, resolved_uri, kernel_binary, 0, 0);
+        dart_result = Dart_LoadScriptFromKernel(payload, payload_length);
       } else {
         dart_result = Dart_LoadScript(uri, resolved_uri, source, 0, 0);
       }
@@ -646,6 +639,12 @@
   return Dart_Null();
 }
 #else
+static void MallocFinalizer(void* isolate_callback_data,
+                            Dart_WeakPersistentHandle handle,
+                            void* peer) {
+  free(peer);
+}
+
 Dart_Handle Loader::LibraryTagHandler(Dart_LibraryTag tag,
                                       Dart_Handle library,
                                       Dart_Handle url) {
@@ -663,17 +662,17 @@
   }
   Dart_Isolate current = Dart_CurrentIsolate();
   if (tag == Dart_kKernelTag) {
-    const uint8_t* kernel_ir = NULL;
-    intptr_t kernel_ir_size = 0;
-
-    // Check to see if url_string points to a valid dill file. If so, return the
-    // loaded kernel::Program.
-    if (!DFE::TryReadKernelFile(url_string, &kernel_ir, &kernel_ir_size)) {
+    uint8_t* kernel_buffer = NULL;
+    intptr_t kernel_buffer_size = 0;
+    if (!DFE::TryReadKernelFile(url_string, &kernel_buffer,
+                                &kernel_buffer_size)) {
       return DartUtils::NewError("'%s' is not a kernel file", url_string);
     }
-    void* kernel_program =
-        Dart_ReadKernelBinary(kernel_ir, kernel_ir_size, ReleaseFetchedBytes);
-    return Dart_NewExternalTypedData(Dart_TypedData_kUint64, kernel_program, 1);
+    result = Dart_NewExternalTypedData(Dart_TypedData_kUint8, kernel_buffer,
+                                       kernel_buffer_size);
+    Dart_NewWeakPersistentHandle(result, kernel_buffer, kernel_buffer_size,
+                                 MallocFinalizer);
+    return result;
   }
   if (tag == Dart_kImportResolvedExtensionTag) {
     if (strncmp(url_string, "file://", 7)) {
diff --git a/runtime/bin/main.cc b/runtime/bin/main.cc
index 9e2a352..5a495e8 100644
--- a/runtime/bin/main.cc
+++ b/runtime/bin/main.cc
@@ -224,9 +224,12 @@
                                        char** error,
                                        int* exit_code) {
   Dart_EnterScope();
+#if !defined(DART_PRECOMPILED_RUNTIME)
   IsolateData* isolate_data =
       reinterpret_cast<IsolateData*>(Dart_IsolateData(isolate));
-  void* kernel_program = isolate_data->kernel_program;
+  const uint8_t* kernel_buffer = isolate_data->kernel_buffer();
+  intptr_t kernel_buffer_size = isolate_data->kernel_buffer_size();
+#endif
 
   // Set up the library tag handler for this isolate.
   Dart_Handle result = Dart_SetLibraryTagHandler(Loader::LibraryTagHandler);
@@ -251,6 +254,9 @@
     result = Dart_StringToCString(result, &resolved_packages_config);
     CHECK_RESULT(result);
     ASSERT(resolved_packages_config != NULL);
+#if !defined(DART_PRECOMPILED_RUNTIME)
+    isolate_data->set_resolved_packages_config(resolved_packages_config);
+#endif
   }
 
   result = Dart_SetEnvironmentCallback(EnvironmentCallback);
@@ -258,7 +264,7 @@
 
 #if !defined(DART_PRECOMPILED_RUNTIME)
   if (Options::preview_dart_2() && !isolate_run_app_snapshot &&
-      kernel_program == NULL && !Dart_IsKernelIsolate(isolate)) {
+      kernel_buffer == NULL && !Dart_IsKernelIsolate(isolate)) {
     if (!dfe.CanUseDartFrontend()) {
       const char* format = "Dart frontend unavailable to compile script %s.";
       intptr_t len = snprintf(NULL, 0, format, script_uri) + 1;
@@ -270,24 +276,28 @@
       Dart_ShutdownIsolate();
       return NULL;
     }
-    kernel_program = dfe.CompileAndReadScript(
-        script_uri, error, exit_code, flags->strong, resolved_packages_config);
-    if (kernel_program == NULL) {
+    uint8_t* application_kernel_buffer = NULL;
+    intptr_t application_kernel_buffer_size = 0;
+    dfe.CompileAndReadScript(script_uri, &application_kernel_buffer,
+                             &application_kernel_buffer_size, error, exit_code,
+                             flags->strong, resolved_packages_config);
+    if (application_kernel_buffer == NULL) {
       Dart_ExitScope();
       Dart_ShutdownIsolate();
       return NULL;
     }
-    isolate_data->kernel_program = kernel_program;
+    isolate_data->set_kernel_buffer(application_kernel_buffer,
+                                    application_kernel_buffer_size,
+                                    true /*take ownership*/);
+    kernel_buffer = application_kernel_buffer;
+    kernel_buffer_size = application_kernel_buffer_size;
   }
-  if (kernel_program != NULL) {
+  if (kernel_buffer != NULL) {
     Dart_Handle uri = Dart_NewStringFromCString(script_uri);
     CHECK_RESULT(uri);
     Dart_Handle resolved_script_uri = DartUtils::ResolveScript(uri);
     CHECK_RESULT(resolved_script_uri);
-    result =
-        Dart_LoadScript(uri, resolved_script_uri,
-                        reinterpret_cast<Dart_Handle>(kernel_program), 0, 0);
-    isolate_data->kernel_program = NULL;  // Dart_LoadScript takes ownership.
+    result = Dart_LoadScriptFromKernel(kernel_buffer, kernel_buffer_size);
     CHECK_RESULT(result);
   }
 #endif  // !defined(DART_PRECOMPILED_RUNTIME)
@@ -322,11 +332,12 @@
     }
 #endif  // !defined(DART_PRECOMPILED_RUNTIME)
   } else {
+#if !defined(DART_PRECOMPILED_RUNTIME)
     // Load the specified application script into the newly created isolate.
     Dart_Handle uri =
         DartUtils::ResolveScript(Dart_NewStringFromCString(script_uri));
     CHECK_RESULT(uri);
-    if (kernel_program == NULL) {
+    if (kernel_buffer == NULL) {
       result = Loader::LibraryTagHandler(Dart_kScriptTag, Dart_Null(), uri);
       CHECK_RESULT(result);
     } else {
@@ -344,6 +355,9 @@
     result = DartUtils::SetupIOLibrary(Options::namespc(), script_uri,
                                        Options::exit_disabled());
     CHECK_RESULT(result);
+#else
+    UNREACHABLE();
+#endif  // !defined(DART_PRECOMPILED_RUNTIME)
   }
 
   // Make the isolate runnable so that it is ready to handle messages.
@@ -402,13 +416,18 @@
         isolate_snapshot_instructions, app_isolate_shared_data,
         app_isolate_shared_instructions, flags, isolate_data, error);
   } else {
-    void* kernel_service_program = dfe.LoadKernelServiceProgram();
-    ASSERT(kernel_service_program != NULL);
+    const uint8_t* kernel_service_buffer = NULL;
+    intptr_t kernel_service_buffer_size = 0;
+    dfe.LoadKernelService(&kernel_service_buffer, &kernel_service_buffer_size);
+    ASSERT(kernel_service_buffer != NULL);
     IsolateData* isolate_data =
         new IsolateData(uri, package_root, packages_config, NULL);
-    isolate_data->kernel_program = kernel_service_program;
-    isolate = Dart_CreateIsolateFromKernel(uri, main, kernel_service_program,
-                                           flags, isolate_data, error);
+    isolate_data->set_kernel_buffer(const_cast<uint8_t*>(kernel_service_buffer),
+                                    kernel_service_buffer_size,
+                                    false /* take_ownership */);
+    isolate = Dart_CreateIsolateFromKernel(uri, main, kernel_service_buffer,
+                                           kernel_service_buffer_size, flags,
+                                           isolate_data, error);
   }
 
   if (isolate == NULL) {
@@ -466,15 +485,20 @@
   if (Options::preview_dart_2()) {
     // If there is intention to use DFE, then we create the isolate
     // from kernel only if we can.
-    void* platform_program = dfe.platform_program(flags->strong) != NULL
-                                 ? dfe.platform_program(flags->strong)
-                                 : dfe.application_kernel_binary();
+    const uint8_t* kernel_buffer = NULL;
+    intptr_t kernel_buffer_size = 0;
+    dfe.LoadPlatform(&kernel_buffer, &kernel_buffer_size, flags->strong);
+    if (kernel_buffer == NULL) {
+      dfe.application_kernel_buffer(&kernel_buffer, &kernel_buffer_size);
+    }
+
     // TODO(sivachandra): When the platform program is unavailable, check if
     // application kernel binary is self contained or an incremental binary.
     // Isolate should be created only if it is a self contained kernel binary.
-    if (platform_program != NULL) {
-      isolate = Dart_CreateIsolateFromKernel(script_uri, NULL, platform_program,
-                                             flags, isolate_data, error);
+    if (kernel_buffer != NULL) {
+      isolate = Dart_CreateIsolateFromKernel(script_uri, NULL, kernel_buffer,
+                                             kernel_buffer_size, flags,
+                                             isolate_data, error);
     } else {
       *error =
           strdup("Platform kernel not available to create service isolate.");
@@ -529,7 +553,8 @@
                                                 int* exit_code) {
   int64_t start = Dart_TimelineGetMicros();
   ASSERT(script_uri != NULL);
-  void* kernel_program = NULL;
+  uint8_t* kernel_buffer = NULL;
+  intptr_t kernel_buffer_size = 0;
   AppSnapshot* app_snapshot = NULL;
 
 #if defined(DART_PRECOMPILED_RUNTIME)
@@ -563,12 +588,16 @@
     }
   }
   if (!isolate_run_app_snapshot) {
-    kernel_program = dfe.ReadScript(script_uri);
+    dfe.ReadScript(script_uri, &kernel_buffer, &kernel_buffer_size);
   }
 #endif  // !defined(DART_PRECOMPILED_RUNTIME)
 
   IsolateData* isolate_data =
       new IsolateData(script_uri, package_root, packages_config, app_snapshot);
+  if (kernel_buffer != NULL) {
+    isolate_data->set_kernel_buffer(kernel_buffer, kernel_buffer_size,
+                                    true /*take ownership*/);
+  }
   if (is_main_isolate && (Options::snapshot_deps_filename() != NULL)) {
     isolate_data->set_dependencies(new MallocGrowableArray<char*>());
   }
@@ -576,20 +605,24 @@
   Dart_Isolate isolate = NULL;
 
 #if !defined(DART_PRECOMPILED_RUNTIME)
-  if (Options::preview_dart_2()) {
-    void* platform_program = dfe.platform_program(flags->strong) != NULL
-                                 ? dfe.platform_program(flags->strong)
-                                 : kernel_program;
-
-    if (platform_program == NULL) {
+  if (Options::preview_dart_2() && !isolate_run_app_snapshot) {
+    const uint8_t* platform_kernel_buffer = NULL;
+    intptr_t platform_kernel_buffer_size = 0;
+    dfe.LoadPlatform(&platform_kernel_buffer, &platform_kernel_buffer_size,
+                     flags->strong);
+    if (platform_kernel_buffer == NULL) {
+      platform_kernel_buffer = kernel_buffer;
+      platform_kernel_buffer_size = kernel_buffer_size;
+    }
+    if (platform_kernel_buffer == NULL) {
       FATAL("platform_program cannot be NULL.");
     }
     // TODO(sivachandra): When the platform program is unavailable, check if
     // application kernel binary is self contained or an incremental binary.
     // Isolate should be created only if it is a self contained kernel binary.
-    isolate = Dart_CreateIsolateFromKernel(script_uri, main, platform_program,
-                                           flags, isolate_data, error);
-    isolate_data->kernel_program = kernel_program;
+    isolate = Dart_CreateIsolateFromKernel(
+        script_uri, main, platform_kernel_buffer, platform_kernel_buffer_size,
+        flags, isolate_data, error);
   } else {
     isolate = Dart_CreateIsolate(
         script_uri, main, isolate_snapshot_data, isolate_snapshot_instructions,
@@ -607,7 +640,12 @@
   if (isolate == NULL) {
     delete isolate_data;
   } else {
-    bool set_native_resolvers = (kernel_program || isolate_snapshot_data);
+#if !defined(DART_PRECOMPILED_RUNTIME)
+    bool set_native_resolvers =
+        (kernel_buffer != NULL) || (isolate_snapshot_data != NULL);
+#else
+    bool set_native_resolvers = isolate_snapshot_data != NULL;
+#endif  // !defined(DART_PRECOMPILED_RUNTIME)
     created_isolate =
         IsolateSetupHelper(isolate, is_main_isolate, script_uri, package_root,
                            packages_config, set_native_resolvers,
@@ -616,7 +654,6 @@
   int64_t end = Dart_TimelineGetMicros();
   Dart_TimelineEvent("CreateIsolateAndSetupHelper", start, end,
                      Dart_Timeline_Event_Duration, 0, NULL, NULL);
-
   return created_isolate;
 }
 
@@ -871,6 +908,8 @@
 
   Dart_EnterScope();
 
+  IsolateData* isolate_data =
+      reinterpret_cast<IsolateData*>(Dart_IsolateData(isolate));
   if (Options::gen_snapshot_kind() == kScript) {
     if (vm_run_app_snapshot) {
       Log::PrintErr("Cannot create a script snapshot from an app snapshot.\n");
@@ -880,7 +919,8 @@
     }
     if (Options::preview_dart_2()) {
       Snapshot::GenerateKernel(Options::snapshot_filename(), script_name,
-                               flags.strong, Options::packages_file());
+                               flags.strong,
+                               isolate_data->resolved_packages_config());
     } else {
       Snapshot::GenerateScript(Options::snapshot_filename());
     }
@@ -889,8 +929,6 @@
     Dart_Handle root_lib = Dart_RootLibrary();
     // Import the root library into the builtin library so that we can easily
     // lookup the main entry point exported from the root library.
-    IsolateData* isolate_data =
-        reinterpret_cast<IsolateData*>(Dart_IsolateData(isolate));
     result = Dart_LibraryImportLibrary(isolate_data->builtin_lib(), root_lib,
                                        Dart_Null());
 #if !defined(DART_PRECOMPILED_RUNTIME)
@@ -1158,10 +1196,14 @@
 // they might affect how the platform is loaded.
 #if !defined(DART_PRECOMPILED_RUNTIME)
   dfe.Init();
-  void* application_kernel_binary = dfe.ReadScript(script_name);
-  if (application_kernel_binary != NULL) {
+  uint8_t* application_kernel_buffer = NULL;
+  intptr_t application_kernel_buffer_size = 0;
+  dfe.ReadScript(script_name, &application_kernel_buffer,
+                 &application_kernel_buffer_size);
+  if (application_kernel_buffer != NULL) {
     // Since we loaded the script anyway, save it.
-    dfe.set_application_kernel_binary(application_kernel_binary);
+    dfe.set_application_kernel_buffer(application_kernel_buffer,
+                                      application_kernel_buffer_size);
     // Since we saw a dill file, it means we have to turn on all the
     // preview_dart_2 options.
     Options::SetPreviewDart2Options(&vm_options);
diff --git a/runtime/bin/main_options.cc b/runtime/bin/main_options.cc
index c5ce7a6..3dfe66c 100644
--- a/runtime/bin/main_options.cc
+++ b/runtime/bin/main_options.cc
@@ -71,6 +71,7 @@
   vm_options->AddArgument("--strong");
   vm_options->AddArgument("--reify-generic-functions");
   vm_options->AddArgument("--limit-ints-to-64-bits");
+  vm_options->AddArgument("--sync-async");
 }
 
 bool OPTION_FIELD(preview_dart_2) = false;
diff --git a/runtime/bin/namespace_fuchsia.cc b/runtime/bin/namespace_fuchsia.cc
index 384aa9d..b84ccb4 100644
--- a/runtime/bin/namespace_fuchsia.cc
+++ b/runtime/bin/namespace_fuchsia.cc
@@ -41,15 +41,15 @@
   }
 
   ~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));
       }
     }
-    NO_RETRY_EXPECTED(close(rootfd_));
-    free(cwd_);
-    NO_RETRY_EXPECTED(close(cwdfd_));
   }
 
   intptr_t rootfd() const { return rootfd_; }
diff --git a/runtime/bin/run_vm_tests.cc b/runtime/bin/run_vm_tests.cc
index 9d08b5d..b255370 100644
--- a/runtime/bin/run_vm_tests.cc
+++ b/runtime/bin/run_vm_tests.cc
@@ -172,7 +172,7 @@
   Dart_EnterScope();
 
   if (isolate_run_script_snapshot) {
-    const uint8_t* payload;
+    uint8_t* payload;
     intptr_t payload_length;
     void* file = bin::DartUtils::OpenFile(script_uri, false);
     bin::DartUtils::ReadFile(&payload, &payload_length, file);
diff --git a/runtime/bin/secure_socket_patch.dart b/runtime/bin/secure_socket_patch.dart
index 74c8bf4..3bb9e53 100644
--- a/runtime/bin/secure_socket_patch.dart
+++ b/runtime/bin/secure_socket_patch.dart
@@ -202,6 +202,33 @@
   // This is done by WrappedX509 in secure_socket.cc.
   _X509CertificateImpl();
 
+  Uint8List _cachedDer;
+  Uint8List get _der native "X509_Der";
+  Uint8List get der {
+    if (_cachedDer == null) {
+      _cachedDer = _der;
+    }
+    return _cachedDer;
+  }
+
+  String _cachedPem;
+  String get _pem native "X509_Pem";
+  String get pem {
+    if (_cachedPem == null) {
+      _cachedPem = _pem;
+    }
+    return _cachedPem;
+  }
+
+  Uint8List _cachedSha1;
+  Uint8List get _sha1 native "X509_Sha1";
+  Uint8List get sha1 {
+    if (_cachedSha1 == null) {
+      _cachedSha1 = _sha1;
+    }
+    return _cachedSha1;
+  }
+
   String get subject native "X509_Subject";
   String get issuer native "X509_Issuer";
   DateTime get startValidity {
diff --git a/runtime/bin/secure_socket_unsupported.cc b/runtime/bin/secure_socket_unsupported.cc
index 7cd46d4..6a72909 100644
--- a/runtime/bin/secure_socket_unsupported.cc
+++ b/runtime/bin/secure_socket_unsupported.cc
@@ -125,6 +125,16 @@
       "Secure Sockets unsupported on this platform"));
 }
 
+void FUNCTION_NAME(X509_Der)(Dart_NativeArguments args) {
+  Dart_ThrowException(DartUtils::NewDartArgumentError(
+      "Secure Sockets unsupported on this platform"));
+}
+
+void FUNCTION_NAME(X509_Sha1)(Dart_NativeArguments args) {
+  Dart_ThrowException(DartUtils::NewDartArgumentError(
+      "Secure Sockets unsupported on this platform"));
+}
+
 void FUNCTION_NAME(X509_Subject)(Dart_NativeArguments args) {
   Dart_ThrowException(DartUtils::NewDartArgumentError(
       "Secure Sockets unsupported on this platform"));
@@ -145,6 +155,11 @@
       "Secure Sockets unsupported on this platform"));
 }
 
+void FUNCTION_NAME(X509_Pem)(Dart_NativeArguments args) {
+  Dart_ThrowException(DartUtils::NewDartArgumentError(
+      "Secure Sockets unsupported on this platform"));
+}
+
 class SSLFilter {
  public:
   static CObject* ProcessFilterRequest(const CObjectArray& request);
diff --git a/runtime/bin/security_context.cc b/runtime/bin/security_context.cc
index 56d99e4..dd92a40 100644
--- a/runtime/bin/security_context.cc
+++ b/runtime/bin/security_context.cc
@@ -647,6 +647,102 @@
   return certificate;
 }
 
+Dart_Handle X509Helper::GetDer(Dart_NativeArguments args) {
+  X509* certificate = GetX509Certificate(args);
+  // When the second argument is NULL, i2d_X509() returns the length of the
+  // DER encoded cert in bytes.
+  intptr_t length = i2d_X509(certificate, NULL);
+  Dart_Handle cert_handle = Dart_NewTypedData(Dart_TypedData_kUint8, length);
+  if (Dart_IsError(cert_handle)) {
+    Dart_PropagateError(cert_handle);
+  }
+  Dart_TypedData_Type typ;
+  void* dart_cert_bytes = NULL;
+  Dart_Handle status =
+      Dart_TypedDataAcquireData(cert_handle, &typ, &dart_cert_bytes, &length);
+  if (Dart_IsError(status)) {
+    Dart_PropagateError(status);
+  }
+
+  // When the the second argument points to a non-NULL buffer address,
+  // i2d_X509 fills that buffer with the DER encoded cert data and increments
+  // the buffer pointer.
+  unsigned char* tmp = static_cast<unsigned char*>(dart_cert_bytes);
+  const intptr_t written_length = i2d_X509(certificate, &tmp);
+  ASSERT(written_length <= length);
+  if (written_length < 0) {
+    Dart_TypedDataReleaseData(cert_handle);
+    SecureSocketUtils::ThrowIOException(
+        -1, "TlsException", "Failed to get certificate bytes", NULL);
+    // SecureSocketUtils::ThrowIOException() does not return.
+  }
+
+  status = Dart_TypedDataReleaseData(cert_handle);
+  if (Dart_IsError(status)) {
+    Dart_PropagateError(status);
+  }
+  return cert_handle;
+}
+
+Dart_Handle X509Helper::GetPem(Dart_NativeArguments args) {
+  X509* certificate = GetX509Certificate(args);
+  BIO* cert_bio = BIO_new(BIO_s_mem());
+  intptr_t status = PEM_write_bio_X509(cert_bio, certificate);
+  if (status == 0) {
+    BIO_free(cert_bio);
+    SecureSocketUtils::ThrowIOException(
+        -1, "TlsException", "Failed to write certificate to PEM", NULL);
+    // SecureSocketUtils::ThrowIOException() does not return.
+  }
+
+  BUF_MEM* mem = NULL;
+  BIO_get_mem_ptr(cert_bio, &mem);
+  Dart_Handle pem_string = Dart_NewStringFromUTF8(
+      reinterpret_cast<const uint8_t*>(mem->data), mem->length);
+  BIO_free(cert_bio);
+  if (Dart_IsError(pem_string)) {
+    Dart_PropagateError(pem_string);
+  }
+
+  return pem_string;
+}
+
+Dart_Handle X509Helper::GetSha1(Dart_NativeArguments args) {
+  unsigned char sha1_bytes[EVP_MAX_MD_SIZE];
+  X509* certificate = GetX509Certificate(args);
+  const EVP_MD* hash_type = EVP_sha1();
+
+  unsigned int sha1_size;
+  intptr_t status = X509_digest(certificate, hash_type, sha1_bytes, &sha1_size);
+  if (status == 0) {
+    SecureSocketUtils::ThrowIOException(
+        -1, "TlsException", "Failed to compute certificate's sha1", NULL);
+    // SecureSocketUtils::ThrowIOException() does not return.
+  }
+
+  Dart_Handle sha1_handle = Dart_NewTypedData(Dart_TypedData_kUint8, sha1_size);
+  if (Dart_IsError(sha1_handle)) {
+    Dart_PropagateError(sha1_handle);
+  }
+
+  Dart_TypedData_Type typ;
+  void* dart_sha1_bytes;
+  intptr_t length;
+  Dart_Handle result =
+      Dart_TypedDataAcquireData(sha1_handle, &typ, &dart_sha1_bytes, &length);
+  if (Dart_IsError(result)) {
+    Dart_PropagateError(result);
+  }
+
+  memmove(dart_sha1_bytes, sha1_bytes, length);
+
+  result = Dart_TypedDataReleaseData(sha1_handle);
+  if (Dart_IsError(result)) {
+    Dart_PropagateError(result);
+  }
+  return sha1_handle;
+}
+
 Dart_Handle X509Helper::GetSubject(Dart_NativeArguments args) {
   X509* certificate = GetX509Certificate(args);
   X509_NAME* subject = X509_get_subject_name(certificate);
@@ -784,6 +880,18 @@
   context->TrustBuiltinRoots();
 }
 
+void FUNCTION_NAME(X509_Der)(Dart_NativeArguments args) {
+  Dart_SetReturnValue(args, X509Helper::GetDer(args));
+}
+
+void FUNCTION_NAME(X509_Pem)(Dart_NativeArguments args) {
+  Dart_SetReturnValue(args, X509Helper::GetPem(args));
+}
+
+void FUNCTION_NAME(X509_Sha1)(Dart_NativeArguments args) {
+  Dart_SetReturnValue(args, X509Helper::GetSha1(args));
+}
+
 void FUNCTION_NAME(X509_Subject)(Dart_NativeArguments args) {
   Dart_SetReturnValue(args, X509Helper::GetSubject(args));
 }
diff --git a/runtime/bin/security_context.h b/runtime/bin/security_context.h
index 968c550..8c37365 100644
--- a/runtime/bin/security_context.h
+++ b/runtime/bin/security_context.h
@@ -102,6 +102,9 @@
 
 class X509Helper : public AllStatic {
  public:
+  static Dart_Handle GetDer(Dart_NativeArguments args);
+  static Dart_Handle GetPem(Dart_NativeArguments args);
+  static Dart_Handle GetSha1(Dart_NativeArguments args);
   static Dart_Handle GetSubject(Dart_NativeArguments args);
   static Dart_Handle GetIssuer(Dart_NativeArguments args);
   static Dart_Handle GetStartValidity(Dart_NativeArguments args);
diff --git a/runtime/bin/security_context_macos.cc b/runtime/bin/security_context_macos.cc
index 8dbb43e..73f0fa8 100644
--- a/runtime/bin/security_context_macos.cc
+++ b/runtime/bin/security_context_macos.cc
@@ -58,14 +58,20 @@
   if (cert == NULL) {
     return NULL;
   }
-  unsigned char* deb_cert = NULL;
-  int length = i2d_X509(cert, &deb_cert);
+  int length = i2d_X509(cert, NULL);
   if (length < 0) {
     return 0;
   }
-  ASSERT(deb_cert != NULL);
-  ScopedCFDataRef cert_buf(
-      CFDataCreateWithBytesNoCopy(NULL, deb_cert, length, kCFAllocatorNull));
+  auto deb_cert = std::make_unique<unsigned char[]>(length);
+  unsigned char* temp = deb_cert.get();
+  if (i2d_X509(cert, &temp) != length) {
+    return NULL;
+  }
+  // TODO(bkonyi): we create a copy of the deb_cert here since it's unclear
+  // whether or not SecCertificateCreateWithData takes ownership of the CFData.
+  // Implementation here:
+  // https://opensource.apple.com/source/libsecurity_keychain/libsecurity_keychain-55050.2/lib/SecCertificate.cpp.auto.html
+  ScopedCFDataRef cert_buf(CFDataCreate(NULL, deb_cert.get(), length));
   SecCertificateRef auth_cert =
       SecCertificateCreateWithData(NULL, cert_buf.get());
   if (auth_cert == NULL) {
diff --git a/runtime/configs.gni b/runtime/configs.gni
new file mode 100644
index 0000000..648083d
--- /dev/null
+++ b/runtime/configs.gni
@@ -0,0 +1,247 @@
+# Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+# for details. All rights reserved. Use of this source code is governed by a
+# BSD-style license that can be found in the LICENSE file.
+
+_dart_runtime = get_path_info("../runtime", "abspath")
+
+_base_config = [
+  "$_dart_runtime:dart_arch_config",
+  "$_dart_runtime:dart_config",
+  "$_dart_runtime:dart_os_config",
+]
+
+_base_fuchsia_config = [
+  "$_dart_runtime:dart_arch_config",
+  "$_dart_runtime:dart_config",
+  "$_dart_runtime:dart_os_fuchsia_config",
+]
+
+_jit_config = _base_config + [
+                "$_dart_runtime:dart_maybe_interpreter_config",
+                "$_dart_runtime:dart_maybe_product_config",
+              ]
+
+_jit_product_config = _base_config + [
+                        "$_dart_runtime:dart_maybe_interpreter_config",
+                        "$_dart_runtime:dart_product_config",
+                      ]
+
+_jit_interpreter_config = _base_config + [
+                            "$_dart_runtime:dart_interpreter_config",
+                            "$_dart_runtime:dart_maybe_product_config",
+                          ]
+
+_jit_product_interpreter_config = _base_config + [
+                                    "$_dart_runtime:dart_interpreter_config",
+                                    "$_dart_runtime:dart_product_config",
+                                  ]
+
+_precompiled_runtime_config =
+    _base_config + [
+      "$_dart_runtime:dart_maybe_product_config",
+      "$_dart_runtime:dart_precompiled_runtime_config",
+    ]
+
+_precompiled_runtime_product_config =
+    _base_config + [
+      "$_dart_runtime:dart_precompiled_runtime_config",
+      "$_dart_runtime:dart_product_config",
+    ]
+
+_precompiler_config = _base_config + [
+                        "$_dart_runtime:dart_maybe_product_config",
+                        "$_dart_runtime:dart_precompiler_config",
+                      ]
+
+_precompiler_product_config = _base_config + [
+                                "$_dart_runtime:dart_product_config",
+                                "$_dart_runtime:dart_precompiler_config",
+                              ]
+
+_nosnapshot_with_precompiler_config =
+    _base_config + [
+      "$_dart_runtime:dart_maybe_product_config",
+      "$_dart_runtime:dart_nosnapshot_config",
+      "$_dart_runtime:dart_precompiler_config",
+    ]
+
+_nosnapshot_with_precompiler_product_config =
+    _base_config + [
+      "$_dart_runtime:dart_product_config",
+      "$_dart_runtime:dart_nosnapshot_config",
+      "$_dart_runtime:dart_precompiler_config",
+    ]
+
+_nosnapshot_with_precompiler_fuchsia_config =
+    _base_fuchsia_config + [
+      "$_dart_runtime:dart_maybe_product_config",
+      "$_dart_runtime:dart_nosnapshot_config",
+      "$_dart_runtime:dart_precompiler_config",
+    ]
+
+_nosnapshot_with_precompiler_product_fuchsia_config =
+    _base_fuchsia_config + [
+      "$_dart_runtime:dart_product_config",
+      "$_dart_runtime:dart_nosnapshot_config",
+      "$_dart_runtime:dart_precompiler_config",
+    ]
+
+_all_configs = [
+  {
+    suffix = "_jit"
+    configs = _jit_config
+    snapshot = true
+  },
+  {
+    suffix = "_jit_product"
+    configs = _jit_product_config
+    snapshot = true
+  },
+  {
+    suffix = "_precompiled_runtime"
+    configs = _precompiled_runtime_config
+    snapshot = true
+  },
+  {
+    suffix = "_precompiled_runtime_product"
+    configs = _precompiled_runtime_product_config
+    snapshot = true
+  },
+  {
+    suffix = "_with_precompiler"
+    configs = _precompiler_config
+    snapshot = true
+  },
+  {
+    suffix = "_with_precompiler_product"
+    configs = _precompiler_product_config
+    snapshot = true
+  },
+  {
+    suffix = "_nosnapshot_with_precompiler"
+    configs = _nosnapshot_with_precompiler_config
+    snapshot = false
+  },
+  {
+    suffix = "_nosnapshot_with_precompiler_product"
+    configs = _nosnapshot_with_precompiler_product_config
+    snapshot = false
+  },
+  {
+    suffix = "_nosnapshot_with_precompiler_fuchsia"
+    configs = _nosnapshot_with_precompiler_fuchsia_config
+    snapshot = false
+  },
+  {
+    suffix = "_nosnapshot_with_precompiler_product_fuchsia"
+    configs = _nosnapshot_with_precompiler_product_fuchsia_config
+    snapshot = false
+  },
+]
+
+# The interpreter is not currently needed on Windows.
+if (!is_win) {
+  _all_configs += [
+    {
+      suffix = "_jit_interpreter"
+      configs = _jit_interpreter_config
+      snapshot = true
+    },
+    {
+      suffix = "_jit_product_interpreter"
+      configs = _jit_product_interpreter_config
+      snapshot = true
+    },
+  ]
+}
+
+# This template creates a target for each of the configurations listed above.
+# For example:
+#
+#  library_for_all_configs("libfoo") {
+#    target_type = "source_set"
+#    sources = [ "foo.c" ]
+#    configurable_deps [ ":libbar" ]
+#  }
+#
+# will make a source_set target for libfoo_jit, libfoo_jit_product, etc. that
+# depends on libbar_jit, libbar_jit_product etc. respectively.
+#
+# Parameters
+#
+#  target_type (required):
+#    The target declaration or template to repeat for each configuration.
+#
+#  configurable_deps (optional):
+#    Dependencies of this target, which are themselves generated by
+#    library_for_all_configs(). The listed dependencies will be suffixed with
+#    a string that matches the configuration.
+#
+#  extra_deps (optional):
+#    Regular additional deps that don't receive special treatment.
+#
+#  extra_configs (optional):
+#    Any configs needed in addition to the ones above.
+#
+#  snapshot_sources (optional):
+#    Additional sources to include when the configuration has a snapshot.
+#
+#  nosnapshot_sources (optional):
+#    Additional sources to include when the configuration does not have a
+#    snapshot (that is, one of the "nosnapshot" configurations above).
+#
+#  nosnapshot_deps (optional):
+#    Similar to nosnapshot_sources, but for deps.
+template("library_for_all_configs") {
+  assert(defined(invoker.target_type))
+  extra_configs = []
+  if (defined(invoker.extra_configs)) {
+    extra_configs += invoker.extra_configs
+  }
+  configurable_deps = []
+  if (defined(invoker.configurable_deps)) {
+    configurable_deps += invoker.configurable_deps
+  }
+  extra_deps = []
+  if (defined(invoker.extra_deps)) {
+    extra_deps += invoker.extra_deps
+  }
+  not_needed(invoker,
+             [
+               "snapshot_sources",
+               "nosnapshot_sources",
+               "nosnapshot_deps",
+             ])
+  foreach(conf, _all_configs) {
+    target(invoker.target_type, "${target_name}${conf.suffix}") {
+      forward_variables_from(invoker,
+                             "*",
+                             [
+                               "extra_configs",
+                               "extra_deps",
+                               "configurable_deps",
+                             ])
+      if (is_fuchsia) {
+        configs -= [ "//build/config:symbol_visibility_hidden" ]
+      }
+      configs += conf.configs + extra_configs
+      configured_deps = []
+      foreach(dep, configurable_deps) {
+        configured_deps += [ "${dep}${conf.suffix}" ]
+      }
+      deps = configured_deps + extra_deps
+      if (conf.snapshot) {
+        if (defined(invoker.snapshot_sources)) {
+          sources += snapshot_sources
+        }
+      } else {
+        if (defined(invoker.nosnapshot_sources)) {
+          sources += nosnapshot_sources
+        }
+        if (defined(nosnapshot_deps)) {
+          deps += nosnapshot_deps
+        }
+      }
+    }
+  }
+}
diff --git a/runtime/include/dart_api.h b/runtime/include/dart_api.h
index b3fdd96..e287914 100644
--- a/runtime/include/dart_api.h
+++ b/runtime/include/dart_api.h
@@ -571,6 +571,7 @@
   bool reify_generic_functions;
   bool strong;
   bool load_vmservice_library;
+  bool sync_async;
 } Dart_IsolateFlags;
 
 /**
@@ -716,7 +717,7 @@
  */
 typedef void* (*Dart_FileOpenCallback)(const char* name, bool write);
 
-typedef void (*Dart_FileReadCallback)(const uint8_t** data,
+typedef void (*Dart_FileReadCallback)(uint8_t** data,
                                       intptr_t* file_length,
                                       void* stream);
 
@@ -893,12 +894,14 @@
  *
  * \return The new isolate on success, or NULL if isolate creation failed.
  */
-DART_EXPORT Dart_Isolate Dart_CreateIsolateFromKernel(const char* script_uri,
-                                                      const char* main,
-                                                      void* kernel_program,
-                                                      Dart_IsolateFlags* flags,
-                                                      void* callback_data,
-                                                      char** error);
+DART_EXPORT Dart_Isolate
+Dart_CreateIsolateFromKernel(const char* script_uri,
+                             const char* main,
+                             const uint8_t* kernel_buffer,
+                             intptr_t kernel_buffer_size,
+                             Dart_IsolateFlags* flags,
+                             void* callback_data,
+                             char** error);
 /**
  * Shuts down the current isolate. After this call, the current isolate is NULL.
  * Any current scopes created by Dart_EnterScope will be exited. Invokes the
@@ -2929,21 +2932,6 @@
 Dart_LoadScriptFromKernel(const uint8_t* kernel_buffer, intptr_t kernel_size);
 
 /**
- * Constructs an in-memory kernel program form a binary.
- *
- * \param buffer The start of a memory buffer containing the binary format.
- * \param buffer_len The length of the memory buffer.
- * \param callback If not NULL, is called to when buffer is no longer needed.
- *   If it is NULL, then free() is used to free buffer.
- *
- * \return kernel_program The `dart::kernel::Program` object.
- */
-typedef void (*Dart_ReleaseBufferCallback)(uint8_t* buffer);
-DART_EXPORT void* Dart_ReadKernelBinary(const uint8_t* buffer,
-                                        intptr_t buffer_len,
-                                        Dart_ReleaseBufferCallback callback);
-
-/**
  * Gets the library for the root script for the current isolate.
  *
  * If the root script has not yet been set for the current isolate,
diff --git a/runtime/lib/errors_patch.dart b/runtime/lib/errors_patch.dart
index 73ea588..e7c2a2f 100644
--- a/runtime/lib/errors_patch.dart
+++ b/runtime/lib/errors_patch.dart
@@ -175,6 +175,13 @@
 
 @patch
 class NoSuchMethodError {
+  // Deprecated members to be removed.
+  final Object _receiver;
+  final Symbol _memberName;
+  final List _arguments;
+  final Map<Symbol, dynamic> _namedArguments;
+  final List _existingArgumentNames;
+
   // TODO(regis): Move _receiver declaration here:
   // final Object _receiver;
   final _InvocationMirror _invocation;
diff --git a/runtime/lib/invocation_mirror_patch.dart b/runtime/lib/invocation_mirror_patch.dart
index 46bc649..2d9b9c4 100644
--- a/runtime/lib/invocation_mirror_patch.dart
+++ b/runtime/lib/invocation_mirror_patch.dart
@@ -41,6 +41,7 @@
   final List _argumentsDescriptor;
   final List _arguments;
   final bool _isSuperInvocation;
+  final int _delayedTypeArgumentsLen;
 
   // External representation of the invocation mirror; populated on demand.
   Symbol _memberName;
@@ -79,16 +80,20 @@
     return _memberName;
   }
 
+  int get _typeArgsLen {
+    int typeArgsLen = _argumentsDescriptor[_TYPE_ARGS_LEN];
+    return typeArgsLen == 0 ? _delayedTypeArgumentsLen : typeArgsLen;
+  }
+
   List<Type> get typeArguments {
     if (_typeArguments == null) {
-      int typeArgsLen = _argumentsDescriptor[_TYPE_ARGS_LEN];
-      if (typeArgsLen == 0) {
+      if (_typeArgsLen == 0) {
         return _typeArguments = const <Type>[];
       }
       // A TypeArguments object does not have a corresponding Dart class and
       // cannot be accessed as an array in Dart. Therefore, we need a native
       // call to unpack the individual types into a list.
-      _typeArguments = _unpackTypeArguments(_arguments[0], typeArgsLen);
+      _typeArguments = _unpackTypeArguments(_arguments[0], _typeArgsLen);
     }
     return _typeArguments;
   }
@@ -106,7 +111,7 @@
         return _positionalArguments = const [];
       }
       // Exclude receiver and type args in the returned list.
-      int receiverIndex = _argumentsDescriptor[_TYPE_ARGS_LEN] > 0 ? 1 : 0;
+      int receiverIndex = _typeArgsLen > 0 ? 1 : 0;
       _positionalArguments = new _ImmutableList._from(
           _arguments, receiverIndex + 1, numPositionalArguments);
     }
@@ -121,7 +126,7 @@
       if (numNamedArguments == 0) {
         return _namedArguments = const {};
       }
-      int receiverIndex = _argumentsDescriptor[_TYPE_ARGS_LEN] > 0 ? 1 : 0;
+      int receiverIndex = _typeArgsLen > 0 ? 1 : 0;
       _namedArguments = new Map<Symbol, dynamic>();
       for (int i = 0; i < numNamedArguments; i++) {
         int namedEntryIndex = _FIRST_NAMED_ENTRY + 2 * i;
@@ -164,10 +169,12 @@
   }
 
   _InvocationMirror(this._functionName, this._argumentsDescriptor,
-      this._arguments, this._isSuperInvocation, this._type);
+      this._arguments, this._isSuperInvocation, this._type,
+      [this._delayedTypeArgumentsLen = 0]);
 
   _InvocationMirror._withoutType(this._functionName, this._typeArguments,
-      this._positionalArguments, this._namedArguments, this._isSuperInvocation);
+      this._positionalArguments, this._namedArguments, this._isSuperInvocation,
+      [this._delayedTypeArgumentsLen = 0]);
 
   static _allocateInvocationMirror(String functionName,
       List argumentsDescriptor, List arguments, bool isSuperInvocation,
@@ -175,4 +182,19 @@
     return new _InvocationMirror(
         functionName, argumentsDescriptor, arguments, isSuperInvocation, type);
   }
+
+  // This factory is used when creating an `Invocation` for a closure call which
+  // may have delayed type arguments. In that case, the arguments descriptor will
+  // indicate 0 type arguments, but the actual number of type arguments are
+  // passed in `delayedTypeArgumentsLen`. If any type arguments are available,
+  // the type arguments vector will be the first entry in `arguments`.
+  static _allocateInvocationMirrorForClosure(
+      String functionName,
+      List argumentsDescriptor,
+      List arguments,
+      int type,
+      int delayedTypeArgumentsLen) {
+    return new _InvocationMirror(functionName, argumentsDescriptor, arguments,
+        false, type, delayedTypeArgumentsLen);
+  }
 }
diff --git a/runtime/lib/isolate.cc b/runtime/lib/isolate.cc
index 5e29999..f4f53b2 100644
--- a/runtime/lib/isolate.cc
+++ b/runtime/lib/isolate.cc
@@ -357,10 +357,11 @@
   // If we were passed a value then override the default flags state for
   // checked mode.
   if (!checked.IsNull()) {
-    bool val = checked.value();
+    bool is_checked = checked.value();
     Dart_IsolateFlags* flags = state->isolate_flags();
-    flags->enable_asserts = val;
-    flags->enable_type_checks = val;
+    flags->enable_asserts = is_checked;
+    // Do not enable type checks in strong mode.
+    flags->enable_type_checks = is_checked && !flags->strong;
   }
 
   ThreadPool::Task* spawn_task = new SpawnIsolateTask(state);
diff --git a/runtime/observatory/tests/service/async_generator_breakpoint_test.dart b/runtime/observatory/tests/service/async_generator_breakpoint_test.dart
index 6781af7..d96c822 100644
--- a/runtime/observatory/tests/service/async_generator_breakpoint_test.dart
+++ b/runtime/observatory/tests/service/async_generator_breakpoint_test.dart
@@ -1,8 +1,8 @@
 // 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.
-// VMOptions=--error_on_bad_type --error_on_bad_override --verbose-debug
-// VMOptions=--error_on_bad_type --error_on_bad_override --verbose-debug --stacktrace-every=55 --stress-async-stacks
+// VMOptions=--error_on_bad_type --error_on_bad_override --verbose-debug --no-sync-async
+// VMOptions=--error_on_bad_type --error_on_bad_override --verbose-debug --stacktrace-every=55 --stress-async-stacks --no-sync-async
 
 import 'dart:async';
 import 'package:observatory/service_io.dart';
@@ -69,7 +69,8 @@
 
   var hits = [];
 
-  isolate.rootLibrary.evaluate('testerReady = true;').then((result) {
+  isolate.rootLibrary.evaluate('testerReady = true').then((result) {
+    print(result);
     expect((result as Instance).valueAsString, equals('true'));
   });
 
diff --git a/runtime/observatory/tests/service/async_single_step_exception_test.dart b/runtime/observatory/tests/service/async_single_step_exception_test.dart
index 6794fb9..c026f4a 100644
--- a/runtime/observatory/tests/service/async_single_step_exception_test.dart
+++ b/runtime/observatory/tests/service/async_single_step_exception_test.dart
@@ -1,7 +1,7 @@
 // Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
-// VMOptions=--error_on_bad_type --error_on_bad_override  --verbose_debug --async_debugger
+// VMOptions=--error_on_bad_type --error_on_bad_override  --verbose_debug --async_debugger --no-sync-async
 
 import 'dart:developer';
 import 'service_test_common.dart';
diff --git a/runtime/observatory/tests/service/bad_reload_test.dart b/runtime/observatory/tests/service/bad_reload_test.dart
index 8e9aed7..23927e9 100644
--- a/runtime/observatory/tests/service/bad_reload_test.dart
+++ b/runtime/observatory/tests/service/bad_reload_test.dart
@@ -72,9 +72,11 @@
     expect(reasonForCancelling['type'], equals('ReasonForCancelling'));
     expect(reasonForCancelling['message'], contains('library_isnt_here_man'));
 
-    // Invoke test in v2.
-    String v2 = await invokeTest(spawnedIsolate);
-    expect(v2, 'apple');
+    // TODO(32341): enable in Dart 2
+    if (!Platform.executableArguments.contains("--preview_dart_2")) {
+      String v2 = await invokeTest(spawnedIsolate);
+      expect(v2, 'apple');
+    }
   }
 ];
 
diff --git a/runtime/observatory/tests/service/debugger_inspect_test.dart b/runtime/observatory/tests/service/debugger_inspect_test.dart
index c52c42f..4f8f680 100644
--- a/runtime/observatory/tests/service/debugger_inspect_test.dart
+++ b/runtime/observatory/tests/service/debugger_inspect_test.dart
@@ -32,7 +32,7 @@
     });
 
     // Start listening for events first.
-    await isolate.rootLibrary.evaluate('testeeDo();');
+    await isolate.rootLibrary.evaluate('testeeDo()');
     return completer.future;
   },
 ];
diff --git a/runtime/observatory/tests/service/evaluate_activation_test.dart b/runtime/observatory/tests/service/evaluate_activation_test.dart
index fc87190..cb352cd 100644
--- a/runtime/observatory/tests/service/evaluate_activation_test.dart
+++ b/runtime/observatory/tests/service/evaluate_activation_test.dart
@@ -114,7 +114,7 @@
     }
   });
 
-  var result = await rootLib.evaluate('new C().method(3);');
+  var result = await rootLib.evaluate('new C().method(3)');
   print("Result $result");
   expect(hitBreakpoint, isTrue);
 }
@@ -163,7 +163,7 @@
     }
   });
 
-  var result = await rootLib.evaluate('C.method2(3);');
+  var result = await rootLib.evaluate('C.method2(3)');
   print("Result $result");
   expect(hitBreakpoint, isTrue);
 }
@@ -204,7 +204,7 @@
     }
   });
 
-  var result = await rootLib.evaluate('new C().method3(3);');
+  var result = await rootLib.evaluate('new C().method3(3)');
   print("Result $result");
   expect(hitBreakpoint, isTrue);
 }
diff --git a/runtime/observatory/tests/service/evaluate_class_type_parameters_test.dart b/runtime/observatory/tests/service/evaluate_class_type_parameters_test.dart
new file mode 100644
index 0000000..0909420
--- /dev/null
+++ b/runtime/observatory/tests/service/evaluate_class_type_parameters_test.dart
@@ -0,0 +1,58 @@
+// 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:developer';
+import 'package:observatory/service_io.dart';
+import 'package:unittest/unittest.dart';
+import 'service_test_common.dart';
+import 'test_helper.dart';
+
+class A<T> {
+  void foo() {
+    debugger();
+  }
+}
+
+class B<S> extends A<int> {
+  void bar() {
+    debugger();
+  }
+}
+
+testFunction() {
+  var v = new B<String>();
+  v.bar();
+  v.foo();
+}
+
+var tests = <IsolateTest>[
+  hasStoppedAtBreakpoint,
+  (Isolate isolate) async {
+    // Make sure we are in the right place.
+    var stack = await isolate.getStack();
+    var topFrame = 0;
+    expect(stack.type, equals('Stack'));
+    expect(await stack['frames'][topFrame].location.getLine(), 20);
+
+    Instance result = await isolate.evalFrame(topFrame, '"\$S"');
+    print(result);
+    expect(result.valueAsString, equals("String"));
+  },
+  resumeIsolate,
+  hasStoppedAtBreakpoint,
+  (Isolate isolate) async {
+    // Make sure we are in the right place.
+    var stack = await isolate.getStack();
+    var topFrame = 0;
+    expect(stack.type, equals('Stack'));
+    expect(await stack['frames'][topFrame].location.getLine(), 14);
+
+    Instance result = await isolate.evalFrame(topFrame, '"\$T"');
+    print(result);
+    expect(result.valueAsString, equals("int"));
+  },
+  resumeIsolate,
+];
+
+main(args) => runIsolateTests(args, tests, testeeConcurrent: testFunction);
diff --git a/runtime/observatory/tests/service/evaluate_function_type_parameters_test.dart b/runtime/observatory/tests/service/evaluate_function_type_parameters_test.dart
new file mode 100644
index 0000000..1ee01db
--- /dev/null
+++ b/runtime/observatory/tests/service/evaluate_function_type_parameters_test.dart
@@ -0,0 +1,96 @@
+// 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:developer';
+import 'package:observatory/service_io.dart';
+import 'package:unittest/unittest.dart';
+import 'service_test_common.dart';
+import 'test_helper.dart';
+
+topLevel<S>() {
+  debugger();
+
+  void inner1<T>() {
+    debugger();
+  }
+
+  inner1<int>();
+
+  void inner2() {
+    debugger();
+  }
+
+  inner2();
+}
+
+class A {
+  foo<T>() {
+    debugger();
+  }
+}
+
+void testMain() {
+  topLevel<String>();
+  (new A()).foo<int>();
+}
+
+var tests = <IsolateTest>[
+  hasStoppedAtBreakpoint,
+  (Isolate isolate) async {
+    // Make sure we are in the right place.
+    var stack = await isolate.getStack();
+    var topFrame = 0;
+    expect(stack.type, equals('Stack'));
+    expect(await stack['frames'][topFrame].location.getLine(), 14);
+
+    Instance result = await isolate.evalFrame(topFrame, "S.toString()");
+    print(result);
+    expect(result.valueAsString, equals("String"));
+  },
+  resumeIsolate,
+  hasStoppedAtBreakpoint,
+  (Isolate isolate) async {
+    // Make sure we are in the right place.
+    var stack = await isolate.getStack();
+    var topFrame = 0;
+    expect(stack.type, equals('Stack'));
+    expect(await stack['frames'][topFrame].location.getLine(), 16);
+
+    Instance result = await isolate.evalFrame(topFrame, "T.toString()");
+    print(result);
+    expect(result.valueAsString, equals("int"));
+
+    result = await isolate.evalFrame(topFrame, "S.toString()");
+    print(result);
+    expect(result.valueAsString, equals("String"));
+  },
+  resumeIsolate,
+  hasStoppedAtBreakpoint,
+  (Isolate isolate) async {
+    // Make sure we are in the right place.
+    var stack = await isolate.getStack();
+    var topFrame = 0;
+    expect(stack.type, equals('Stack'));
+    expect(await stack['frames'][topFrame].location.getLine(), 22);
+
+    Instance result = await isolate.evalFrame(topFrame, "S.toString()");
+    print(result);
+    expect(result.valueAsString, equals("String"));
+  },
+  resumeIsolate,
+  hasStoppedAtBreakpoint,
+  (Isolate isolate) async {
+    // Make sure we are in the right place.
+    var stack = await isolate.getStack();
+    var topFrame = 0;
+    expect(stack.type, equals('Stack'));
+    expect(await stack['frames'][topFrame].location.getLine(), 30);
+
+    Instance result = await isolate.evalFrame(topFrame, "T.toString()");
+    print(result);
+    expect(result.valueAsString, equals("int"));
+  },
+];
+
+main(args) => runIsolateTests(args, tests, testeeConcurrent: testMain);
diff --git a/runtime/observatory/tests/service/get_user_level_retaining_path_rpc_test.dart b/runtime/observatory/tests/service/get_user_level_retaining_path_rpc_test.dart
index c458396..6211574 100644
--- a/runtime/observatory/tests/service/get_user_level_retaining_path_rpc_test.dart
+++ b/runtime/observatory/tests/service/get_user_level_retaining_path_rpc_test.dart
@@ -40,7 +40,7 @@
   // Expect a simple path through variable x instead of long path filled
   // with VM objects
   (Isolate isolate) async {
-    var target1 = await eval(isolate, 'x;');
+    var target1 = await eval(isolate, 'x');
     var params = {
       'targetId': target1['id'],
       'limit': 100,
@@ -56,7 +56,7 @@
   // Expect a simple path through variable fn instead of long path filled
   // with VM objects
   (Isolate isolate) async {
-    var target2 = await eval(isolate, 'fn;');
+    var target2 = await eval(isolate, 'fn');
     var params = {
       'targetId': target2['id'],
       'limit': 100,
diff --git a/runtime/observatory/tests/service/positive_token_pos_test.dart b/runtime/observatory/tests/service/positive_token_pos_test.dart
index ceb42fc..375b676 100644
--- a/runtime/observatory/tests/service/positive_token_pos_test.dart
+++ b/runtime/observatory/tests/service/positive_token_pos_test.dart
@@ -1,7 +1,7 @@
 // Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
-// VMOptions=--error_on_bad_type --error_on_bad_override  --verbose_debug
+// VMOptions=--error_on_bad_type --error_on_bad_override  --verbose_debug --no-sync-async
 
 import 'dart:developer';
 import 'package:observatory/service_io.dart';
diff --git a/runtime/observatory/tests/service/rewind_test.dart b/runtime/observatory/tests/service/rewind_test.dart
index 7f0d590..b89fa2c8 100644
--- a/runtime/observatory/tests/service/rewind_test.dart
+++ b/runtime/observatory/tests/service/rewind_test.dart
@@ -1,7 +1,7 @@
 // Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
-// VMOptions=--error_on_bad_type --error_on_bad_override
+// VMOptions=--error_on_bad_type --error_on_bad_override --no-sync-async
 
 import 'dart:developer';
 import 'package:observatory/service_io.dart';
diff --git a/runtime/observatory/tests/service/service.status b/runtime/observatory/tests/service/service.status
index 5a699c0..8a40809 100644
--- a/runtime/observatory/tests/service/service.status
+++ b/runtime/observatory/tests/service/service.status
@@ -43,6 +43,7 @@
 # Kernel version of tests
 [ $compiler != dartk ]
 add_breakpoint_rpc_kernel_test: SkipByDesign # kernel specific version of add_breakpoint_rpc_test
+evaluate_function_type_parameters_test: SkipByDesign # only supported in kernel
 
 [ $compiler == precompiler ]
 *: Skip # Issue 24651
@@ -73,6 +74,9 @@
 [ $mode == debug && ($arch == simarm || $arch == simarm64) ]
 *: SkipSlow
 
+[ !$strong && ($compiler == dartk || $compiler == dartkp) ]
+*: Skip
+
 [ ($compiler == none || $compiler == precompiler) && ($runtime == dart_precompiled || $runtime == vm) ]
 evaluate_activation_test/instance: RuntimeError # http://dartbug.com/20047
 evaluate_activation_test/scope: RuntimeError # http://dartbug.com/20047
diff --git a/runtime/observatory/tests/service/service_kernel.status b/runtime/observatory/tests/service/service_kernel.status
index c9b5f1d..8003fb4 100644
--- a/runtime/observatory/tests/service/service_kernel.status
+++ b/runtime/observatory/tests/service/service_kernel.status
@@ -11,7 +11,6 @@
 async_star_step_out_test: RuntimeError # Issue 29158, Async debugging
 async_step_out_test: RuntimeError # Issue 29158, Async debugging
 awaiter_async_stack_contents_test: RuntimeError # Issue 29158, Async debugging
-eval_internal_class_test: RuntimeError
 evaluate_activation_in_method_class_test: RuntimeError
 evaluate_activation_test/instance: RuntimeError
 evaluate_activation_test/scope: RuntimeError
@@ -31,7 +30,6 @@
 complex_reload_test: RuntimeError
 
 [ $arch == simdbc64 && $compiler == dartk ]
-coverage_optimized_function_test: Crash # Please triage
 get_cpu_profile_timeline_rpc_test: Pass, RuntimeError # http://dartbug.com/31794
 pause_on_unhandled_async_exceptions_test: RuntimeError, Timeout # Issue 31765
 
@@ -109,18 +107,40 @@
 async_single_step_exception_test: RuntimeError
 
 [ $compiler == dartk && ($arch == simarm || $arch == simarm64 || $arch == simdbc64) ]
+add_breakpoint_rpc_kernel_test: RuntimeError # Issue #33087
 async_generator_breakpoint_test: Pass, RuntimeError
 bad_reload_test: Skip # Times out on sim architectures, also RuntimeError.
+break_on_activation_test: RuntimeError # Issue #33087
 complex_reload_test: Skip # Times out on sim architectures, also RuntimeError.
 coverage_leaf_function_test: RuntimeError # Please triage.
 coverage_optimized_function_test: RuntimeError # Please triage.
+debugger_inspect_test: RuntimeError, Timeout # Issue #33087
+developer_service_get_isolate_id_test: RuntimeError # Issue #33087
+eval_internal_class_test: RuntimeError # Issue #33087
+eval_test: RuntimeError # Issue #33087
+evaluate_activation_test/none: RuntimeError # Issue #33087
+evaluate_async_closure_test: RuntimeError # Issue #33087
+evaluate_class_type_parameters_test: RuntimeError # Issue 33087
+evaluate_function_type_parameters_test: RuntimeError # Issue 33087
+evaluate_in_async_activation_test: RuntimeError # Issue #33087
+evaluate_in_async_star_activation_test: RuntimeError # Issue #33087
+evaluate_in_frame_rpc_test: RuntimeError # Issue #33087
+evaluate_in_frame_with_scope_test: RuntimeError # Issue #33087
+evaluate_with_scope_test: RuntimeError # Issue #33087
+get_instances_rpc_test: RuntimeError # Issue #33087
 get_object_rpc_test: RuntimeError # Please triage.
+get_retaining_path_rpc_test: RuntimeError # Issue #33087
 get_source_report_test: RuntimeError # Please triage.
+get_user_level_retaining_path_rpc_test: RuntimeError # Issue #33087
+instance_field_order_rpc_test: RuntimeError # Issue #33087
+pause_on_exceptions_test: RuntimeError, Timeout # Issue #33087
 positive_token_pos_test: Pass, RuntimeError
 reload_sources_test: Skip # Times out.
+rewind_optimized_out_test: RuntimeError # Issue #33087
 rewind_test: Pass, RuntimeError
 set_name_rpc_test: RuntimeError # Please triage.
 unused_changes_in_last_reload_test: Skip # Times out on sim architectures.
+valid_source_locations_test: Pass, Slow, Timeout # Issue 33087
 
 [ $compiler == fasta && $strong ]
 add_breakpoint_rpc_test: CompileTimeError
diff --git a/runtime/platform/BUILD.gn b/runtime/platform/BUILD.gn
index 32a9339..6f2cdf9 100644
--- a/runtime/platform/BUILD.gn
+++ b/runtime/platform/BUILD.gn
@@ -2,53 +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("../configs.gni")
 import("platform_sources.gni")
 
-template("build_libdart_platform") {
-  extra_configs = []
-  if (defined(invoker.extra_configs)) {
-    extra_configs += invoker.extra_configs
-  }
-  static_library(target_name) {
-    configs += [
-                 "..:dart_arch_config",
-                 "..:dart_config",
-               ] + extra_configs
-    if (is_fuchsia) {
-      configs -= [ "//build/config:symbol_visibility_hidden" ]
-    }
-    public_configs = [ "../vm:libdart_vm_config" ]
-
-    sources = platform_sources
-
-    include_dirs = [ ".." ]
-  }
-}
-
-build_libdart_platform("libdart_platform") {
-  extra_configs = [
-    "..:dart_maybe_product_config",
-    "..:dart_os_config",
-  ]
-}
-
-build_libdart_platform("libdart_platform_product") {
-  extra_configs = [
-    "..:dart_product_config",
-    "..:dart_os_config",
-  ]
-}
-
-build_libdart_platform("libdart_platform_fuchsia") {
-  extra_configs = [
-    "..:dart_maybe_product_config",
-    "..:dart_os_fuchsia_config",
-  ]
-}
-
-build_libdart_platform("libdart_platform_product_fuchsia") {
-  extra_configs = [
-    "..:dart_product_config",
-    "..:dart_os_fuchsia_config",
-  ]
+library_for_all_configs("libdart_platform") {
+  target_type = "static_library"
+  public_configs = [ "../vm:libdart_vm_config" ]
+  sources = platform_sources
+  include_dirs = [ ".." ]
 }
diff --git a/runtime/platform/growable_array.h b/runtime/platform/growable_array.h
index 32ffcc4..f6c0598 100644
--- a/runtime/platform/growable_array.h
+++ b/runtime/platform/growable_array.h
@@ -70,6 +70,16 @@
     }
   }
 
+  void EnsureLength(intptr_t new_length, const T& default_value) {
+    const intptr_t old_length = length_;
+    if (old_length < new_length) {
+      Resize(new_length);
+      for (intptr_t i = old_length; i < new_length; ++i) {
+        (*this)[i] = default_value;
+      }
+    }
+  }
+
   const T& At(intptr_t index) const { return operator[](index); }
 
   T& Last() const {
diff --git a/runtime/tests/vm/dart/appjit_test.dart b/runtime/tests/vm/dart/appjit_test.dart
new file mode 100644
index 0000000..6fbe998
--- /dev/null
+++ b/runtime/tests/vm/dart/appjit_test.dart
@@ -0,0 +1,86 @@
+// 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=100
+
+// Verify that app-jit snapshot contains dependencies between classes and CHA
+// optimized code.
+
+import 'dart:async';
+import 'dart:io';
+
+import 'package:expect/expect.dart';
+import 'package:path/path.dart' as p;
+
+class Result {
+  final String cmdline;
+  final ProcessResult processResult;
+
+  Result(this.cmdline, this.processResult);
+}
+
+void reportError(Result result, String msg) {
+  print('running ${result.cmdline}:');
+  if (result.processResult.stdout.isNotEmpty) {
+    print('''
+
+Command stdout:
+${result.processResult.stdout}''');
+  }
+
+  if (result.processResult.stderr.isNotEmpty) {
+    print('''
+
+Command stderr:
+${result.processResult.stderr}''');
+  }
+
+  Expect.fail(msg);
+}
+
+void expectOutput(String what, Result result) {
+  if (result.processResult.stdout.trim() != what) {
+    reportError(result, 'Expected test to print \'${what}\' to stdout');
+  }
+}
+
+Future<Result> runDartBinary(String prefix, List<String> arguments) async {
+  final binary = Platform.executable;
+  final actualArguments = <String>[]
+    ..addAll(Platform.executableArguments)
+    ..addAll(arguments);
+  final processResult = await Process.run(binary, actualArguments);
+  final result = new Result(
+      '[$prefix] ${binary} ${actualArguments.join(' ')}', processResult);
+  if (result.processResult.exitCode != 0) {
+    reportError(result,
+        '[$prefix] Process finished with non-zero exit code ${result.processResult.exitCode}');
+  }
+  return result;
+}
+
+const snapshotName = 'app.jit';
+
+void main() async {
+  final Directory temp = Directory.systemTemp.createTempSync();
+  final snapshotPath = p.join(temp.path, 'app.jit');
+  final testPath = Platform.script
+      .toFilePath()
+      .replaceAll(new RegExp(r'_test.dart$'), '_test_body.dart');
+
+  await temp.create();
+  try {
+    final trainingResult = await runDartBinary('TRAINING RUN', [
+      '--snapshot=$snapshotPath',
+      '--snapshot-kind=app-jit',
+      testPath,
+      '--train'
+    ]);
+    expectOutput("OK(Trained)", trainingResult);
+    final runResult = await runDartBinary('RUN FROM SNAPSHOT', [snapshotPath]);
+    expectOutput("OK(Run)", runResult);
+  } finally {
+    await temp.delete(recursive: true);
+  }
+}
diff --git a/runtime/tests/vm/dart/appjit_test_body.dart b/runtime/tests/vm/dart/appjit_test_body.dart
new file mode 100644
index 0000000..c59f720
--- /dev/null
+++ b/runtime/tests/vm/dart/appjit_test_body.dart
@@ -0,0 +1,43 @@
+// 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.
+
+// Verify that app-jit snapshot contains dependencies between classes and CHA
+// optimized code.
+
+import 'package:expect/expect.dart';
+
+class A {
+  void getMyName() => getMyNameImpl();
+
+  void getMyNameImpl() => "A";
+}
+
+class B extends A {
+  void getMyNameImpl() => "B";
+}
+
+final Function makeA = () => new A();
+final Function makeB = () => new B();
+
+void optimizeGetMyName(dynamic obj) {
+  for (var i = 0; i < 100; i++) {
+    obj.getMyName();
+  }
+  Expect.equals("A", obj.getMyName());
+}
+
+void main(List<String> args) {
+  final isTraining = args.contains("--train");
+  final dynamic obj = (isTraining ? makeA : makeB)();
+  if (isTraining) {
+    for (var i = 0; i < 10; i++) {
+      optimizeGetMyName(obj);
+    }
+    Expect.equals('A', obj.getMyName());
+    print('OK(Trained)');
+  } else {
+    Expect.equals('B', obj.getMyName());
+    print('OK(Run)');
+  }
+}
diff --git a/runtime/tests/vm/vm.status b/runtime/tests/vm/vm.status
index 6e45883..d07500e 100644
--- a/runtime/tests/vm/vm.status
+++ b/runtime/tests/vm/vm.status
@@ -54,6 +54,7 @@
 [ $compiler != dartk ]
 cc/IsolateReload_KernelIncrementalCompile: SkipByDesign
 cc/IsolateReload_KernelIncrementalCompileAppAndLib: SkipByDesign
+cc/IsolateReload_KernelIncrementalCompileExpression: SkipByDesign
 cc/IsolateReload_KernelIncrementalCompileGenerics: SkipByDesign
 cc/Mixin_PrivateSuperResolution: Skip
 cc/Mixin_PrivateSuperResolutionCrossLibraryShouldFail: Skip
@@ -146,8 +147,7 @@
 
 [ $compiler == dartk && $runtime == vm ]
 cc/Class_ComputeEndTokenPos: Crash
-cc/DartAPI_IsolateShutdownRunDartCode: Skip # Flaky
-cc/DartAPI_LoadLibrary: Crash # Issue 33048.
+cc/DartAPI_LoadLibrary: Fail, Crash # Issue 33048.
 cc/DebuggerAPI_BreakpointStubPatching: Fail
 cc/DebuggerAPI_GetClosureInfo: Fail
 cc/DebuggerAPI_InterruptIsolate: SkipSlow
@@ -284,6 +284,9 @@
 cc/RegExp_TwoByteString: Skip # TODO(vegorov) These tests don't seem to work if FLAG_interpret_irregexp is switched on by default because they attempt to call regexp functions directly instead of going through JSSyntaxRegExp_ExecuteMatch.
 cc/RegenerateAllocStubs: Skip # This test is meaningless for DBC as allocation stubs are not used.
 
+[ $arch == simdbc64 || $builder_tag == optimization_counter_threshold || $compiler != none ]
+dart/appjit_test: Skip
+
 [ $compiler == dart2analyzer || $compiler == dart2js ]
 dart/data_uri*test: Skip # Data uri's not supported by dart2js or the analyzer.
 
diff --git a/runtime/vm/BUILD.gn b/runtime/vm/BUILD.gn
index 69e3168..dd24564 100644
--- a/runtime/vm/BUILD.gn
+++ b/runtime/vm/BUILD.gn
@@ -30,6 +30,7 @@
 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("vm_sources.gni")
@@ -54,128 +55,28 @@
   }
 }
 
-template("build_libdart_vm") {
-  extra_configs = []
-  if (defined(invoker.extra_configs)) {
-    extra_configs += invoker.extra_configs
+library_for_all_configs("libdart_vm") {
+  target_type = "source_set"
+  if (is_fuchsia) {
+    extra_deps = [
+      # TODO(US-399): Remove time_service specific code when it is no longer
+      # necessary.
+      "//garnet/public/lib/app/cpp",
+      "//garnet/public/lib/time_zone/fidl",
+
+      # TODO(zra): When the platform-specific timeline code is moved out to
+      # the embedder, this can go away.
+      "//zircon/public/lib/fbl",
+      "//zircon/public/lib/trace-engine",
+    ]
   }
-  source_set(target_name) {
-    configs += [
-                 "..:dart_arch_config",
-                 "..:dart_config",
-               ] + extra_configs
-    if (is_fuchsia) {
-      configs -= [ "//build/config:symbol_visibility_hidden" ]
-      deps = [
-        # TODO(US-399): Remove time_service specific code when it is no longer
-        # necessary.
-        "//garnet/public/lib/app/cpp",
-        "//garnet/public/lib/time_zone/fidl",
-
-        # TODO(zra): When the platform-specific timeline code is moved out to
-        # the embedder, this can go away.
-        "//zircon/public/lib/fbl",
-        "//zircon/public/lib/trace-engine",
-      ]
-    }
-    public_configs = [ ":libdart_vm_config" ]
-    set_sources_assignment_filter([
-                                    "*_test.cc",
-                                    "*_test.h",
-                                  ])
-    sources = vm_sources + rebase_path(compiler_sources, ".", "./compiler/")
-    include_dirs = [ ".." ]
-  }
-}
-
-build_libdart_vm("libdart_vm_jit") {
-  extra_configs = [
-    "..:dart_maybe_product_config",
-    "..:dart_os_config",
-  ]
-}
-
-build_libdart_vm("libdart_vm_jit_product") {
-  extra_configs = [
-    "..:dart_product_config",
-    "..:dart_os_config",
-  ]
-}
-
-build_libdart_vm("libdart_vm_precompiled_runtime") {
-  extra_configs = [
-    "..:dart_maybe_product_config",
-    "..:dart_precompiled_runtime_config",
-    "..:dart_os_config",
-  ]
-}
-
-build_libdart_vm("libdart_vm_precompiled_runtime_product") {
-  extra_configs = [
-    "..:dart_product_config",
-    "..:dart_precompiled_runtime_config",
-    "..:dart_os_config",
-  ]
-}
-
-build_libdart_vm("libdart_vm_nosnapshot") {
-  extra_configs = [
-    "..:dart_maybe_product_config",
-    "..:dart_no_snapshot_config",
-    "..:dart_os_config",
-  ]
-}
-
-build_libdart_vm("libdart_vm_nosnapshot_with_precompiler") {
-  extra_configs = [
-    "..:dart_maybe_product_config",
-    "..:dart_precompiler_config",
-    "..:dart_no_snapshot_config",
-    "..:dart_os_config",
-  ]
-}
-
-build_libdart_vm("libdart_vm_nosnapshot_with_precompiler_product") {
-  extra_configs = [
-    "..:dart_product_config",
-    "..:dart_precompiler_config",
-    "..:dart_no_snapshot_config",
-    "..:dart_os_config",
-  ]
-}
-
-build_libdart_vm("libdart_vm_nosnapshot_with_precompiler_fuchsia") {
-  extra_configs = [
-    "..:dart_maybe_product_config",
-    "..:dart_precompiler_config",
-    "..:dart_no_snapshot_config",
-    "..:dart_os_fuchsia_config",
-  ]
-}
-
-build_libdart_vm("libdart_vm_nosnapshot_with_precompiler_product_fuchsia") {
-  extra_configs = [
-    "..:dart_product_config",
-    "..:dart_precompiler_config",
-    "..:dart_no_snapshot_config",
-    "..:dart_os_fuchsia_config",
-  ]
-}
-
-build_libdart_vm("libdart_vm_with_precompiler") {
-  extra_configs = [
-    "..:dart_maybe_product_config",
-    "..:dart_precompiler_config",
-    "..:dart_os_config",
-  ]
-}
-
-build_libdart_vm("libdart_vm_with_precompiler_product") {
-  extra_configs = [
-    "..:dart_product_config",
-    "..:dart_precompiler_config",
-    "..:dart_os_config",
-  ]
+  public_configs = [ ":libdart_vm_config" ]
+  set_sources_assignment_filter([
+                                  "*_test.cc",
+                                  "*_test.h",
+                                ])
+  sources = vm_sources + rebase_path(compiler_sources, ".", "./compiler/")
+  include_dirs = [ ".." ]
 }
 
 template("process_library_source") {
@@ -224,33 +125,6 @@
   }
 }
 
-template("build_libdart_lib") {
-  extra_configs = []
-  if (defined(invoker.extra_configs)) {
-    extra_configs += invoker.extra_configs
-  }
-  extra_deps = []
-  if (defined(invoker.extra_deps)) {
-    extra_deps += invoker.extra_deps
-  }
-  extra_sources = []
-  if (defined(invoker.extra_sources)) {
-    extra_sources += invoker.extra_sources
-  }
-  source_set(target_name) {
-    configs += [
-                 "..:dart_arch_config",
-                 "..:dart_config",
-               ] + extra_configs
-    if (is_fuchsia) {
-      configs -= [ "//build/config:symbol_visibility_hidden" ]
-    }
-    deps = extra_deps
-    sources = extra_sources
-    include_dirs = [ ".." ]
-  }
-}
-
 # This templates expects invoker.sources to be a list of lists.
 # The lists contain the following information about each library:
 #   library name (string)
@@ -300,98 +174,13 @@
 
   all_libsources = rebase_path(invoker.allsources, ".", "../lib")
 
-  build_libdart_lib("libdart_lib_nosnapshot_with_precompiler") {
-    extra_configs = [
-      "..:dart_maybe_product_config",
-      "..:dart_precompiler_config",
-      "..:dart_os_config",
-    ]
-    extra_deps = libdeps
-    extra_sources = all_libsources + [ "bootstrap.cc" ] + liboutputs
-  }
-
-  build_libdart_lib("libdart_lib_nosnapshot_with_precompiler_product") {
-    extra_configs = [
-      "..:dart_product_config",
-      "..:dart_precompiler_config",
-      "..:dart_os_config",
-    ]
-    extra_deps = libdeps
-    extra_sources = all_libsources + [ "bootstrap.cc" ] + liboutputs
-  }
-
-  build_libdart_lib("libdart_lib_nosnapshot_with_precompiler_fuchsia") {
-    extra_configs = [
-      "..:dart_maybe_product_config",
-      "..:dart_precompiler_config",
-      "..:dart_os_fuchsia_config",
-    ]
-    extra_deps = libdeps
-    extra_sources = all_libsources + [ "bootstrap.cc" ] + liboutputs
-  }
-
-  build_libdart_lib("libdart_lib_nosnapshot_with_precompiler_product_fuchsia") {
-    extra_configs = [
-      "..:dart_product_config",
-      "..:dart_precompiler_config",
-      "..:dart_os_fuchsia_config",
-    ]
-    extra_deps = libdeps
-    extra_sources = all_libsources + [ "bootstrap.cc" ] + liboutputs
-  }
-
-  build_libdart_lib("libdart_lib_with_precompiler") {
-    extra_configs = [
-      "..:dart_maybe_product_config",
-      "..:dart_precompiler_config",
-      "..:dart_os_config",
-    ]
-    extra_deps = libdeps
-    extra_sources = all_libsources + [ "bootstrap_nocore.cc" ]
-  }
-
-  build_libdart_lib("libdart_lib_with_precompiler_product") {
-    extra_configs = [
-      "..:dart_product_config",
-      "..:dart_precompiler_config",
-      "..:dart_os_config",
-    ]
-    extra_deps = libdeps
-    extra_sources = all_libsources + [ "bootstrap_nocore.cc" ]
-  }
-
-  build_libdart_lib("libdart_lib_jit") {
-    extra_configs = [
-      "..:dart_maybe_product_config",
-      "..:dart_os_config",
-    ]
-    extra_sources = all_libsources + [ "bootstrap_nocore.cc" ]
-  }
-
-  build_libdart_lib("libdart_lib_jit_product") {
-    extra_configs = [
-      "..:dart_product_config",
-      "..:dart_os_config",
-    ]
-    extra_sources = all_libsources + [ "bootstrap_nocore.cc" ]
-  }
-
-  build_libdart_lib("libdart_lib_precompiled_runtime") {
-    extra_configs = [
-      "..:dart_maybe_product_config",
-      "..:dart_precompiled_runtime_config",
-      "..:dart_os_config",
-    ]
-    extra_sources = all_libsources + [ "bootstrap_nocore.cc" ]
-  }
-
-  build_libdart_lib("libdart_lib_precompiled_runtime_product") {
-    extra_configs = [
-      "..:dart_product_config",
-      "..:dart_precompiled_runtime_config",
-      "..:dart_os_config",
-    ]
-    extra_sources = all_libsources + [ "bootstrap_nocore.cc" ]
+  library_for_all_configs("libdart_lib") {
+    target_type = "source_set"
+    include_dirs = [ ".." ]
+    sources = all_libsources
+    snapshot_sources = [ "bootstrap_nocore.cc" ]
+    nosnapshot_sources = [ "bootstrap.cc" ] + liboutputs
+    nosnapshot_deps = libdeps
   }
 }
 
diff --git a/runtime/vm/bootstrap.cc b/runtime/vm/bootstrap.cc
index 2bd04fa..84d44b4 100644
--- a/runtime/vm/bootstrap.cc
+++ b/runtime/vm/bootstrap.cc
@@ -310,8 +310,12 @@
 }
 
 #if !defined(DART_PRECOMPILED_RUNTIME)
-static RawError* BootstrapFromKernel(Thread* thread, kernel::Program* program) {
+static RawError* BootstrapFromKernel(Thread* thread,
+                                     const uint8_t* kernel_buffer,
+                                     intptr_t kernel_buffer_size) {
   Zone* zone = thread->zone();
+  kernel::Program* program =
+      kernel::Program::ReadFromBuffer(kernel_buffer, kernel_buffer_size, false);
   kernel::KernelLoader loader(program);
   Isolate* isolate = thread->isolate();
 
@@ -336,7 +340,8 @@
 
   // The platform binary may contain other libraries (e.g., dart:_builtin or
   // dart:io) that will not be bundled with application.  Load them now.
-  const Object& result = loader.LoadProgram();
+  const Object& result = Object::Handle(zone, loader.LoadProgram());
+  delete program;
   if (result.IsError()) {
     return Error::Cast(result).raw();
   }
@@ -349,13 +354,16 @@
   return Error::null();
 }
 #else
-static RawError* BootstrapFromKernel(Thread* thread, kernel::Program* program) {
+static RawError* BootstrapFromKernel(Thread* thread,
+                                     const uint8_t* kernel_buffer,
+                                     intptr_t kernel_buffer_size) {
   UNREACHABLE();
   return Error::null();
 }
 #endif
 
-RawError* Bootstrap::DoBootstrapping(kernel::Program* kernel_program) {
+RawError* Bootstrap::DoBootstrapping(const uint8_t* kernel_buffer,
+                                     intptr_t kernel_buffer_size) {
   Thread* thread = Thread::Current();
   Isolate* isolate = thread->isolate();
   Zone* zone = thread->zone();
@@ -378,8 +386,9 @@
     }
   }
 
-  return (kernel_program == NULL) ? BootstrapFromSource(thread)
-                                  : BootstrapFromKernel(thread, kernel_program);
+  return (kernel_buffer == NULL)
+             ? BootstrapFromSource(thread)
+             : BootstrapFromKernel(thread, kernel_buffer, kernel_buffer_size);
 }
 
 }  // namespace dart
diff --git a/runtime/vm/bootstrap.h b/runtime/vm/bootstrap.h
index 0c271b3..fe782ce 100644
--- a/runtime/vm/bootstrap.h
+++ b/runtime/vm/bootstrap.h
@@ -24,7 +24,8 @@
   // bootstrapping.
   // The caller of this function is responsible for managing the kernel
   // program's memory.
-  static RawError* DoBootstrapping(kernel::Program* program);
+  static RawError* DoBootstrapping(const uint8_t* kernel_buffer,
+                                   intptr_t kernel_buffer_size);
 
   static void SetupNativeResolver();
   static bool IsBootstapResolver(Dart_NativeEntryResolver resolver);
diff --git a/runtime/vm/bootstrap_nocore.cc b/runtime/vm/bootstrap_nocore.cc
index 679c41f..9938296 100644
--- a/runtime/vm/bootstrap_nocore.cc
+++ b/runtime/vm/bootstrap_nocore.cc
@@ -70,8 +70,12 @@
   Compiler::CompileClass(cls);
 }
 
-RawError* BootstrapFromKernel(Thread* thread, kernel::Program* program) {
+RawError* BootstrapFromKernel(Thread* thread,
+                              const uint8_t* kernel_buffer,
+                              intptr_t kernel_buffer_size) {
   Zone* zone = thread->zone();
+  kernel::Program* program =
+      kernel::Program::ReadFromBuffer(kernel_buffer, kernel_buffer_size, false);
   kernel::KernelLoader loader(program);
   Isolate* isolate = thread->isolate();
 
@@ -96,7 +100,8 @@
 
   // The platform binary may contain other libraries (e.g., dart:_builtin or
   // dart:io) that will not be bundled with application.  Load them now.
-  const Object& result = loader.LoadProgram();
+  const Object& result = Object::Handle(loader.LoadProgram());
+  delete program;
   if (result.IsError()) {
     return Error::Cast(result).raw();
   }
@@ -109,7 +114,8 @@
   return Error::null();
 }
 
-RawError* Bootstrap::DoBootstrapping(kernel::Program* program) {
+RawError* Bootstrap::DoBootstrapping(const uint8_t* kernel_buffer,
+                                     intptr_t kernel_buffer_size) {
   Thread* thread = Thread::Current();
   Isolate* isolate = thread->isolate();
   Zone* zone = thread->zone();
@@ -132,10 +138,11 @@
     }
   }
 
-  return BootstrapFromKernel(thread, program);
+  return BootstrapFromKernel(thread, kernel_buffer, kernel_buffer_size);
 }
 #else
-RawError* Bootstrap::DoBootstrapping(kernel::Program* program) {
+RawError* Bootstrap::DoBootstrapping(const uint8_t* kernel_buffer,
+                                     intptr_t kernel_buffer_size) {
   UNREACHABLE();
   return Error::null();
 }
diff --git a/runtime/vm/class_finalizer.cc b/runtime/vm/class_finalizer.cc
index a3b0e33..2d94185 100644
--- a/runtime/vm/class_finalizer.cc
+++ b/runtime/vm/class_finalizer.cc
@@ -2712,6 +2712,7 @@
     CollectImmediateSuperInterfaces(cls, &cids);
     RemoveCHAOptimizedCode(cls, cids);
   }
+
   if (cls.is_enum_class()) {
     AllocateEnumValues(cls);
   }
@@ -2765,11 +2766,15 @@
           (sentinel.raw() == field.raw())) {
         continue;
       }
-      field.SetStaticValue(Object::transition_sentinel());
-      result = Compiler::EvaluateStaticInitializer(field);
-      ASSERT(!result.IsError());
-      field.SetStaticValue(Instance::Cast(result), true);
-      field.RecordStore(Instance::Cast(result));
+      // The eager evaluation of the enum values is required for hot-reload (see
+      // commit e3ecc87).
+      if (!FLAG_precompiled_mode) {
+        field.SetStaticValue(Object::transition_sentinel());
+        result = Compiler::EvaluateStaticInitializer(field);
+        ASSERT(!result.IsError());
+        field.SetStaticValue(Instance::Cast(result), true);
+        field.RecordStore(Instance::Cast(result));
+      }
     }
   } else {
     const String& name_prefix =
diff --git a/runtime/vm/clustered_snapshot.cc b/runtime/vm/clustered_snapshot.cc
index e465222..2208c17 100644
--- a/runtime/vm/clustered_snapshot.cc
+++ b/runtime/vm/clustered_snapshot.cc
@@ -256,22 +256,6 @@
     }
   }
 
-  void PostLoad(const Array& refs, Snapshot::Kind kind, Zone* zone) {
-    NOT_IN_PRODUCT(TimelineDurationScope tds(
-        Thread::Current(), Timeline::GetIsolateStream(), "PostLoadClass"));
-
-    Class& cls = Class::Handle(zone);
-    for (intptr_t i = predefined_start_index_; i < predefined_stop_index_;
-         i++) {
-      cls ^= refs.At(i);
-      cls.RehashConstants(zone);
-    }
-    for (intptr_t i = start_index_; i < stop_index_; i++) {
-      cls ^= refs.At(i);
-      cls.RehashConstants(zone);
-    }
-  }
-
  private:
   intptr_t predefined_start_index_;
   intptr_t predefined_stop_index_;
@@ -2100,10 +2084,14 @@
       intptr_t length = handlers->ptr()->num_entries_;
       s->WriteUnsigned(length);
       s->WriteRef(handlers->ptr()->handled_types_data_);
-
-      uint8_t* data = reinterpret_cast<uint8_t*>(handlers->ptr()->data());
-      intptr_t length_in_bytes = length * sizeof(ExceptionHandlerInfo);
-      s->WriteBytes(data, length_in_bytes);
+      for (intptr_t j = 0; j < length; j++) {
+        const ExceptionHandlerInfo& info = handlers->ptr()->data()[j];
+        s->Write<uint32_t>(info.handler_pc_offset);
+        s->Write<int16_t>(info.outer_try_index);
+        s->Write<int8_t>(info.needs_stacktrace);
+        s->Write<int8_t>(info.has_catch_all);
+        s->Write<int8_t>(info.is_generated);
+      }
     }
   }
 
@@ -2142,10 +2130,14 @@
       handlers->ptr()->num_entries_ = length;
       handlers->ptr()->handled_types_data_ =
           reinterpret_cast<RawArray*>(d->ReadRef());
-
-      uint8_t* data = reinterpret_cast<uint8_t*>(handlers->ptr()->data());
-      intptr_t length_in_bytes = length * sizeof(ExceptionHandlerInfo);
-      d->ReadBytes(data, length_in_bytes);
+      for (intptr_t j = 0; j < length; j++) {
+        ExceptionHandlerInfo& info = handlers->ptr()->data()[j];
+        info.handler_pc_offset = d->Read<uint32_t>();
+        info.outer_try_index = d->Read<int16_t>();
+        info.needs_stacktrace = d->Read<int8_t>();
+        info.has_catch_all = d->Read<int8_t>();
+        info.is_generated = d->Read<int8_t>();
+      }
     }
   }
 };
diff --git a/runtime/vm/compiler/aot/precompiler.cc b/runtime/vm/compiler/aot/precompiler.cc
index 29afb6d..5b2415a 100644
--- a/runtime/vm/compiler/aot/precompiler.cc
+++ b/runtime/vm/compiler/aot/precompiler.cc
@@ -510,6 +510,7 @@
     {"dart:core", "_CastError", "_CastError._create"},
     {"dart:core", "_InternalError", "_InternalError."},
     {"dart:core", "_InvocationMirror", "_allocateInvocationMirror"},
+    {"dart:core", "_InvocationMirror", "_allocateInvocationMirrorForClosure"},
     {"dart:core", "_TypeError", "_TypeError._create"},
     {"dart:collection", "::", "_rehashObjects"},
     {"dart:isolate", "IsolateSpawnException", "IsolateSpawnException."},
diff --git a/runtime/vm/compiler/assembler/disassembler_kbc.cc b/runtime/vm/compiler/assembler/disassembler_kbc.cc
index 0fefb14..531cc82 100644
--- a/runtime/vm/compiler/assembler/disassembler_kbc.cc
+++ b/runtime/vm/compiler/assembler/disassembler_kbc.cc
@@ -250,7 +250,6 @@
                                                    const Code& bytecode,
                                                    Object** object,
                                                    uword pc) {
-#if !defined(PRODUCT)
   const uint32_t instr = *reinterpret_cast<uint32_t*>(pc);
   const uint8_t opcode = instr & 0xFF;
   ASSERT(opcode < kOpcodeCount);
@@ -274,9 +273,6 @@
       *object = NULL;
     }
   }
-#else
-  UNREACHABLE();
-#endif
 }
 
 void KernelBytecodeDisassembler::Disassemble(uword start,
diff --git a/runtime/vm/compiler/backend/flow_graph.cc b/runtime/vm/compiler/backend/flow_graph.cc
index 5411f90..4aedb3c 100644
--- a/runtime/vm/compiler/backend/flow_graph.cc
+++ b/runtime/vm/compiler/backend/flow_graph.cc
@@ -1020,8 +1020,9 @@
 
       // Replace the argument descriptor slot with a special parameter.
       if (parsed_function().has_arg_desc_var()) {
-        Definition* defn = new SpecialParameterInstr(
-            SpecialParameterInstr::kArgDescriptor, Thread::kNoDeoptId);
+        Definition* defn =
+            new SpecialParameterInstr(SpecialParameterInstr::kArgDescriptor,
+                                      Thread::kNoDeoptId, graph_entry_);
         AllocateSSAIndexes(defn);
         AddToInitialDefinitions(defn);
         env[ArgumentDescriptorEnvIndex()] = defn;
@@ -1081,10 +1082,34 @@
         }
       }
     }
-  } else if (block_entry->IsCatchBlockEntry()) {
+  } else if (CatchBlockEntryInstr* catch_entry =
+                 block_entry->AsCatchBlockEntry()) {
+    const intptr_t raw_exception_var_envindex =
+        catch_entry->raw_exception_var() != nullptr
+            ? catch_entry->raw_exception_var()->BitIndexIn(
+                  num_direct_parameters_)
+            : -1;
+    const intptr_t raw_stacktrace_var_envindex =
+        catch_entry->raw_stacktrace_var() != nullptr
+            ? catch_entry->raw_stacktrace_var()->BitIndexIn(
+                  num_direct_parameters_)
+            : -1;
+
     // Add real definitions for all locals and parameters.
     for (intptr_t i = 0; i < env->length(); ++i) {
-      ParameterInstr* param = new (zone()) ParameterInstr(i, block_entry);
+      // Replace usages of the raw exception/stacktrace variables with
+      // [SpecialParameterInstr]s.
+      Definition* param = nullptr;
+      if (raw_exception_var_envindex == i) {
+        param = new SpecialParameterInstr(SpecialParameterInstr::kException,
+                                          Thread::kNoDeoptId, catch_entry);
+      } else if (raw_stacktrace_var_envindex == i) {
+        param = new SpecialParameterInstr(SpecialParameterInstr::kStackTrace,
+                                          Thread::kNoDeoptId, catch_entry);
+      } else {
+        param = new (zone()) ParameterInstr(i, block_entry);
+      }
+
       param->set_ssa_temp_index(alloc_ssa_temp_index());  // New SSA temp.
       (*env)[i] = param;
       block_entry->AsCatchBlockEntry()->initial_definitions()->Add(param);
@@ -1106,6 +1131,30 @@
   // Attach environment to the block entry.
   AttachEnvironment(block_entry, env);
 
+#if defined(TARGET_ARCH_DBC)
+  // On DBC the exception/stacktrace variables are in special registers when
+  // entering the catch block.  The only usage of those special registers is
+  // within the catch block.  A possible lazy-deopt at the beginning of the
+  // catch does not need to move those around, since the registers will be
+  // up-to-date when arriving in the unoptimized code and unoptimized code will
+  // take care of moving them to appropriate slots.
+  if (CatchBlockEntryInstr* catch_entry = block_entry->AsCatchBlockEntry()) {
+    Environment* deopt_env = catch_entry->env();
+    const LocalVariable* raw_exception_var = catch_entry->raw_exception_var();
+    const LocalVariable* raw_stacktrace_var = catch_entry->raw_stacktrace_var();
+    if (raw_exception_var != nullptr) {
+      Value* value = deopt_env->ValueAt(
+          raw_exception_var->BitIndexIn(num_direct_parameters_));
+      value->BindToEnvironment(constant_null());
+    }
+    if (raw_stacktrace_var != nullptr) {
+      Value* value = deopt_env->ValueAt(
+          raw_stacktrace_var->BitIndexIn(num_direct_parameters_));
+      value->BindToEnvironment(constant_null());
+    }
+  }
+#endif  // defined(TARGET_ARCH_DBC)
+
   // 2. Process normal instructions.
   for (ForwardInstructionIterator it(block_entry); !it.Done(); it.Advance()) {
     Instruction* current = it.Current();
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler_dbc.cc b/runtime/vm/compiler/backend/flow_graph_compiler_dbc.cc
index 0e9f214..557f69a 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler_dbc.cc
+++ b/runtime/vm/compiler/backend/flow_graph_compiler_dbc.cc
@@ -17,6 +17,7 @@
 #include "vm/instructions.h"
 #include "vm/object_store.h"
 #include "vm/parser.h"
+#include "vm/simulator.h"
 #include "vm/stack_frame.h"
 #include "vm/stub_code.h"
 #include "vm/symbols.h"
@@ -383,6 +384,12 @@
   } else if (source.IsArgsDescRegister()) {
     ASSERT(destination.IsRegister());
     __ LoadArgDescriptorOpt(destination.reg());
+  } else if (source.IsExceptionRegister()) {
+    ASSERT(destination.IsRegister());
+    __ MoveSpecial(destination.reg(), Simulator::kExceptionSpecialIndex);
+  } else if (source.IsStackTraceRegister()) {
+    ASSERT(destination.IsRegister());
+    __ MoveSpecial(destination.reg(), Simulator::kStackTraceSpecialIndex);
   } else if (source.IsConstant() && destination.IsRegister()) {
     if (source.constant_instruction()->representation() == kUnboxedDouble) {
       const Register result = destination.reg();
diff --git a/runtime/vm/compiler/backend/il.h b/runtime/vm/compiler/backend/il.h
index a957568..875f806 100644
--- a/runtime/vm/compiler/backend/il.h
+++ b/runtime/vm/compiler/backend/il.h
@@ -1641,7 +1641,8 @@
                        const LocalVariable& stacktrace_var,
                        bool needs_stacktrace,
                        intptr_t deopt_id,
-                       bool should_restore_closure_context = false)
+                       const LocalVariable* raw_exception_var,
+                       const LocalVariable* raw_stacktrace_var)
       : BlockEntryInstr(block_id, try_index, deopt_id),
         graph_entry_(graph_entry),
         predecessor_(NULL),
@@ -1649,8 +1650,9 @@
         catch_try_index_(catch_try_index),
         exception_var_(exception_var),
         stacktrace_var_(stacktrace_var),
+        raw_exception_var_(raw_exception_var),
+        raw_stacktrace_var_(raw_stacktrace_var),
         needs_stacktrace_(needs_stacktrace),
-        should_restore_closure_context_(should_restore_closure_context),
         handler_token_pos_(handler_token_pos),
         is_generated_(is_generated) {}
 
@@ -1669,6 +1671,11 @@
   const LocalVariable& exception_var() const { return exception_var_; }
   const LocalVariable& stacktrace_var() const { return stacktrace_var_; }
 
+  const LocalVariable* raw_exception_var() const { return raw_exception_var_; }
+  const LocalVariable* raw_stacktrace_var() const {
+    return raw_stacktrace_var_;
+  }
+
   bool needs_stacktrace() const { return needs_stacktrace_; }
 
   bool is_generated() const { return is_generated_; }
@@ -1692,12 +1699,6 @@
     predecessor_ = predecessor;
   }
 
-  bool should_restore_closure_context() const {
-    ASSERT(exception_var_.is_captured() == stacktrace_var_.is_captured());
-    ASSERT(!exception_var_.is_captured() || should_restore_closure_context_);
-    return should_restore_closure_context_;
-  }
-
   GraphEntryInstr* graph_entry_;
   BlockEntryInstr* predecessor_;
   const Array& catch_handler_types_;
@@ -1705,8 +1706,9 @@
   GrowableArray<Definition*> initial_definitions_;
   const LocalVariable& exception_var_;
   const LocalVariable& stacktrace_var_;
+  const LocalVariable* raw_exception_var_;
+  const LocalVariable* raw_stacktrace_var_;
   const bool needs_stacktrace_;
-  const bool should_restore_closure_context_;
   TokenPosition handler_token_pos_;
   bool is_generated_;
 
@@ -2998,12 +3000,23 @@
 // the type arguments of a generic function or an arguments descriptor.
 class SpecialParameterInstr : public TemplateDefinition<0, NoThrow> {
  public:
-  enum SpecialParameterKind { kContext, kTypeArgs, kArgDescriptor };
+  enum SpecialParameterKind {
+    kContext,
+    kTypeArgs,
+    kArgDescriptor,
+    kException,
+    kStackTrace
+  };
 
-  SpecialParameterInstr(SpecialParameterKind kind, intptr_t deopt_id)
-      : TemplateDefinition(deopt_id), kind_(kind) {}
+  SpecialParameterInstr(SpecialParameterKind kind,
+                        intptr_t deopt_id,
+                        BlockEntryInstr* block)
+      : TemplateDefinition(deopt_id), kind_(kind), block_(block) {}
 
   DECLARE_INSTRUCTION(SpecialParameter)
+
+  virtual BlockEntryInstr* GetBlock() { return block_; }
+
   virtual CompileType ComputeType() const;
 
   virtual bool ComputeCanDeoptimize() const { return false; }
@@ -3027,6 +3040,10 @@
         return "kTypeArgs";
       case kArgDescriptor:
         return "kArgDescriptor";
+      case kException:
+        return "kException";
+      case kStackTrace:
+        return "kStackTrace";
     }
     UNREACHABLE();
     return NULL;
@@ -3034,6 +3051,7 @@
 
  private:
   const SpecialParameterKind kind_;
+  BlockEntryInstr* block_;
   DISALLOW_COPY_AND_ASSIGN(SpecialParameterInstr);
 };
 
diff --git a/runtime/vm/compiler/backend/il_arm.cc b/runtime/vm/compiler/backend/il_arm.cc
index 9b5729c..3d7b61d 100644
--- a/runtime/vm/compiler/backend/il_arm.cc
+++ b/runtime/vm/compiler/backend/il_arm.cc
@@ -2888,38 +2888,15 @@
   ASSERT(fp_sp_dist <= 0);
   __ AddImmediate(SP, FP, fp_sp_dist);
 
-  // Auxiliary variables introduced by the try catch can be captured if we are
-  // inside a function with yield/resume points. In this case we first need
-  // to restore the context to match the context at entry into the closure.
-  if (should_restore_closure_context()) {
-    const ParsedFunction& parsed_function = compiler->parsed_function();
-    ASSERT(parsed_function.function().IsClosureFunction());
-    LocalScope* scope = parsed_function.node_sequence()->scope();
-
-    LocalVariable* closure_parameter = scope->VariableAt(0);
-    ASSERT(!closure_parameter->is_captured());
-    __ LoadFromOffset(kWord, R6, FP, closure_parameter->index() * kWordSize);
-    __ LoadFieldFromOffset(kWord, R6, R6, Closure::context_offset());
-
-    const intptr_t context_index =
-        parsed_function.current_context_var()->index();
-    __ StoreToOffset(kWord, R6, FP, context_index * kWordSize);
-  }
-
-  // Initialize exception and stack trace variables.
-  if (exception_var().is_captured()) {
-    ASSERT(stacktrace_var().is_captured());
-    __ StoreIntoObjectOffset(R6,
-                             Context::variable_offset(exception_var().index()),
-                             kExceptionObjectReg);
-    __ StoreIntoObjectOffset(R6,
-                             Context::variable_offset(stacktrace_var().index()),
-                             kStackTraceObjectReg);
-  } else {
-    __ StoreToOffset(kWord, kExceptionObjectReg, FP,
-                     exception_var().index() * kWordSize);
-    __ StoreToOffset(kWord, kStackTraceObjectReg, FP,
-                     stacktrace_var().index() * kWordSize);
+  if (!compiler->is_optimizing()) {
+    if (raw_exception_var_ != nullptr) {
+      __ StoreToOffset(kWord, kExceptionObjectReg, FP,
+                       raw_exception_var_->index() * kWordSize);
+    }
+    if (raw_stacktrace_var_ != nullptr) {
+      __ StoreToOffset(kWord, kStackTraceObjectReg, FP,
+                       raw_stacktrace_var_->index() * kWordSize);
+    }
   }
 }
 
diff --git a/runtime/vm/compiler/backend/il_arm64.cc b/runtime/vm/compiler/backend/il_arm64.cc
index 9c0a698..9a9bc82 100644
--- a/runtime/vm/compiler/backend/il_arm64.cc
+++ b/runtime/vm/compiler/backend/il_arm64.cc
@@ -2637,40 +2637,15 @@
   ASSERT(fp_sp_dist <= 0);
   __ AddImmediate(SP, FP, fp_sp_dist);
 
-  // Auxiliary variables introduced by the try catch can be captured if we are
-  // inside a function with yield/resume points. In this case we first need
-  // to restore the context to match the context at entry into the closure.
-  if (should_restore_closure_context()) {
-    const ParsedFunction& parsed_function = compiler->parsed_function();
-    ASSERT(parsed_function.function().IsClosureFunction());
-    LocalScope* scope = parsed_function.node_sequence()->scope();
-
-    LocalVariable* closure_parameter = scope->VariableAt(0);
-    ASSERT(!closure_parameter->is_captured());
-    __ LoadFromOffset(R28, FP, closure_parameter->index() * kWordSize);
-    __ LoadFieldFromOffset(R28, R28, Closure::context_offset());
-
-    const intptr_t context_index =
-        parsed_function.current_context_var()->index();
-    __ StoreToOffset(R28, FP, context_index * kWordSize);
-  }
-
-  // Initialize exception and stack trace variables.
-  if (exception_var().is_captured()) {
-    ASSERT(stacktrace_var().is_captured());
-    __ StoreIntoObjectOffset(R28,
-                             Context::variable_offset(exception_var().index()),
-                             kExceptionObjectReg);
-    __ StoreIntoObjectOffset(R28,
-                             Context::variable_offset(stacktrace_var().index()),
-                             kStackTraceObjectReg);
-  } else {
-    // Restore stack and initialize the two exception variables:
-    // exception and stack trace variables.
-    __ StoreToOffset(kExceptionObjectReg, FP,
-                     exception_var().index() * kWordSize);
-    __ StoreToOffset(kStackTraceObjectReg, FP,
-                     stacktrace_var().index() * kWordSize);
+  if (!compiler->is_optimizing()) {
+    if (raw_exception_var_ != nullptr) {
+      __ StoreToOffset(kExceptionObjectReg, FP,
+                       raw_exception_var_->index() * kWordSize);
+    }
+    if (raw_stacktrace_var_ != nullptr) {
+      __ StoreToOffset(kStackTraceObjectReg, FP,
+                       raw_stacktrace_var_->index() * kWordSize);
+    }
   }
 }
 
diff --git a/runtime/vm/compiler/backend/il_dbc.cc b/runtime/vm/compiler/backend/il_dbc.cc
index 093c340..c00e4e9 100644
--- a/runtime/vm/compiler/backend/il_dbc.cc
+++ b/runtime/vm/compiler/backend/il_dbc.cc
@@ -1184,69 +1184,18 @@
   if (HasParallelMove()) {
     compiler->parallel_move_resolver()->EmitNativeCode(parallel_move());
   }
+  __ SetFrame(compiler->StackSize());
 
-  Register context_reg = kNoRegister;
-
-  // Auxiliary variables introduced by the try catch can be captured if we are
-  // inside a function with yield/resume points. In this case we first need
-  // to restore the context to match the context at entry into the closure.
-  if (should_restore_closure_context()) {
-    const ParsedFunction& parsed_function = compiler->parsed_function();
-
-    ASSERT(parsed_function.function().IsClosureFunction());
-    LocalScope* scope = parsed_function.node_sequence()->scope();
-
-    LocalVariable* closure_parameter = scope->VariableAt(0);
-    ASSERT(!closure_parameter->is_captured());
-
-    const LocalVariable& current_context_var =
-        *parsed_function.current_context_var();
-
-    context_reg = compiler->is_optimizing()
-                      ? compiler->CatchEntryRegForVariable(current_context_var)
-                      : LocalVarIndex(0, current_context_var.index());
-
-    Register closure_reg;
-    if (closure_parameter->index() > 0) {
-      __ Move(context_reg, LocalVarIndex(0, closure_parameter->index()));
-      closure_reg = context_reg;
-    } else {
-      closure_reg = LocalVarIndex(0, closure_parameter->index());
-    }
-
-    __ LoadField(context_reg, closure_reg,
-                 Closure::context_offset() / kWordSize);
-  }
-
-  if (exception_var().is_captured()) {
-    ASSERT(stacktrace_var().is_captured());
-    ASSERT(context_reg != kNoRegister);
-    // This will be SP[1] register so we are free to use it as a temporary.
-    const Register temp = compiler->StackSize();
-    __ MoveSpecial(temp, Simulator::kExceptionSpecialIndex);
-    __ StoreField(context_reg,
-                  Context::variable_offset(exception_var().index()) / kWordSize,
-                  temp);
-    __ MoveSpecial(temp, Simulator::kStackTraceSpecialIndex);
-    __ StoreField(
-        context_reg,
-        Context::variable_offset(stacktrace_var().index()) / kWordSize, temp);
-  } else {
-    if (compiler->is_optimizing()) {
-      const intptr_t exception_reg =
-          compiler->CatchEntryRegForVariable(exception_var());
-      const intptr_t stacktrace_reg =
-          compiler->CatchEntryRegForVariable(stacktrace_var());
-      __ MoveSpecial(exception_reg, Simulator::kExceptionSpecialIndex);
-      __ MoveSpecial(stacktrace_reg, Simulator::kStackTraceSpecialIndex);
-    } else {
-      __ MoveSpecial(LocalVarIndex(0, exception_var().index()),
+  if (!compiler->is_optimizing()) {
+    if (raw_exception_var_ != nullptr) {
+      __ MoveSpecial(LocalVarIndex(0, raw_exception_var_->index()),
                      Simulator::kExceptionSpecialIndex);
-      __ MoveSpecial(LocalVarIndex(0, stacktrace_var().index()),
+    }
+    if (raw_stacktrace_var_ != nullptr) {
+      __ MoveSpecial(LocalVarIndex(0, raw_stacktrace_var_->index()),
                      Simulator::kStackTraceSpecialIndex);
     }
   }
-  __ SetFrame(compiler->StackSize());
 }
 
 EMIT_NATIVE_CODE(Throw, 0, Location::NoLocation(), LocationSummary::kCall) {
diff --git a/runtime/vm/compiler/backend/il_ia32.cc b/runtime/vm/compiler/backend/il_ia32.cc
index c92b517..e8ec6e3 100644
--- a/runtime/vm/compiler/backend/il_ia32.cc
+++ b/runtime/vm/compiler/backend/il_ia32.cc
@@ -2496,51 +2496,15 @@
   ASSERT(fp_sp_dist <= 0);
   __ leal(ESP, Address(EBP, fp_sp_dist));
 
-  // Auxiliary variables introduced by the try catch can be captured if we are
-  // inside a function with yield/resume points. In this case we first need
-  // to restore the context to match the context at entry into the closure.
-  if (should_restore_closure_context()) {
-    const ParsedFunction& parsed_function = compiler->parsed_function();
-    ASSERT(parsed_function.function().IsClosureFunction());
-    LocalScope* scope = parsed_function.node_sequence()->scope();
-
-    LocalVariable* closure_parameter = scope->VariableAt(0);
-    ASSERT(!closure_parameter->is_captured());
-    __ movl(EDI, Address(EBP, closure_parameter->index() * kWordSize));
-    __ movl(EDI, FieldAddress(EDI, Closure::context_offset()));
-
-#ifdef DEBUG
-    Label ok;
-    __ LoadClassId(EBX, EDI);
-    __ cmpl(EBX, Immediate(kContextCid));
-    __ j(EQUAL, &ok, Assembler::kNearJump);
-    __ Stop("Incorrect context at entry");
-    __ Bind(&ok);
-#endif
-
-    const intptr_t context_index =
-        parsed_function.current_context_var()->index();
-    __ movl(Address(EBP, context_index * kWordSize), EDI);
-  }
-
-  // Initialize exception and stack trace variables.
-  if (exception_var().is_captured()) {
-    ASSERT(stacktrace_var().is_captured());
-    __ StoreIntoObject(
-        EDI,
-        FieldAddress(EDI, Context::variable_offset(exception_var().index())),
-        kExceptionObjectReg);
-    __ StoreIntoObject(
-        EDI,
-        FieldAddress(EDI, Context::variable_offset(stacktrace_var().index())),
-        kStackTraceObjectReg);
-  } else {
-    // Restore stack and initialize the two exception variables:
-    // exception and stack trace variables.
-    __ movl(Address(EBP, exception_var().index() * kWordSize),
-            kExceptionObjectReg);
-    __ movl(Address(EBP, stacktrace_var().index() * kWordSize),
-            kStackTraceObjectReg);
+  if (!compiler->is_optimizing()) {
+    if (raw_exception_var_ != nullptr) {
+      __ movl(Address(EBP, raw_exception_var_->index() * kWordSize),
+              kExceptionObjectReg);
+    }
+    if (raw_stacktrace_var_ != nullptr) {
+      __ movl(Address(EBP, raw_stacktrace_var_->index() * kWordSize),
+              kStackTraceObjectReg);
+    }
   }
 }
 
diff --git a/runtime/vm/compiler/backend/il_test.cc b/runtime/vm/compiler/backend/il_test.cc
index 4792e3c..8fb8da0 100644
--- a/runtime/vm/compiler/backend/il_test.cc
+++ b/runtime/vm/compiler/backend/il_test.cc
@@ -13,9 +13,10 @@
   EXPECT(target_instr->IsBlockEntry());
   EXPECT(!target_instr->IsDefinition());
   SpecialParameterInstr* context = new SpecialParameterInstr(
-      SpecialParameterInstr::kContext, Thread::kNoDeoptId);
+      SpecialParameterInstr::kContext, Thread::kNoDeoptId, target_instr);
   EXPECT(context->IsDefinition());
   EXPECT(!context->IsBlockEntry());
+  EXPECT(context->GetBlock() == target_instr);
 }
 
 TEST_CASE(OptimizationTests) {
diff --git a/runtime/vm/compiler/backend/il_x64.cc b/runtime/vm/compiler/backend/il_x64.cc
index b44d650..cbbd640 100644
--- a/runtime/vm/compiler/backend/il_x64.cc
+++ b/runtime/vm/compiler/backend/il_x64.cc
@@ -2571,49 +2571,15 @@
   ASSERT(fp_sp_dist <= 0);
   __ leaq(RSP, Address(RBP, fp_sp_dist));
 
-  // Auxiliary variables introduced by the try catch can be captured if we are
-  // inside a function with yield/resume points. In this case we first need
-  // to restore the context to match the context at entry into the closure.
-  if (should_restore_closure_context()) {
-    const ParsedFunction& parsed_function = compiler->parsed_function();
-    ASSERT(parsed_function.function().IsClosureFunction());
-    LocalScope* scope = parsed_function.node_sequence()->scope();
-
-    LocalVariable* closure_parameter = scope->VariableAt(0);
-    ASSERT(!closure_parameter->is_captured());
-    __ movq(R12, Address(RBP, closure_parameter->index() * kWordSize));
-    __ movq(R12, FieldAddress(R12, Closure::context_offset()));
-
-#ifdef DEBUG
-    Label ok;
-    __ LoadClassId(RBX, R12);
-    __ cmpq(RBX, Immediate(kContextCid));
-    __ j(EQUAL, &ok, Assembler::kNearJump);
-    __ Stop("Incorrect context at entry");
-    __ Bind(&ok);
-#endif
-
-    const intptr_t context_index =
-        parsed_function.current_context_var()->index();
-    __ movq(Address(RBP, context_index * kWordSize), R12);
-  }
-
-  // Initialize exception and stack trace variables.
-  if (exception_var().is_captured()) {
-    ASSERT(stacktrace_var().is_captured());
-    __ StoreIntoObject(
-        R12,
-        FieldAddress(R12, Context::variable_offset(exception_var().index())),
-        kExceptionObjectReg);
-    __ StoreIntoObject(
-        R12,
-        FieldAddress(R12, Context::variable_offset(stacktrace_var().index())),
-        kStackTraceObjectReg);
-  } else {
-    __ movq(Address(RBP, exception_var().index() * kWordSize),
-            kExceptionObjectReg);
-    __ movq(Address(RBP, stacktrace_var().index() * kWordSize),
-            kStackTraceObjectReg);
+  if (!compiler->is_optimizing()) {
+    if (raw_exception_var_ != nullptr) {
+      __ movq(Address(RBP, raw_exception_var_->index() * kWordSize),
+              kExceptionObjectReg);
+    }
+    if (raw_stacktrace_var_ != nullptr) {
+      __ movq(Address(RBP, raw_stacktrace_var_->index() * kWordSize),
+              kStackTraceObjectReg);
+    }
   }
 }
 
diff --git a/runtime/vm/compiler/backend/linearscan.cc b/runtime/vm/compiler/backend/linearscan.cc
index 10d2c09..f96a09d 100644
--- a/runtime/vm/compiler/backend/linearscan.cc
+++ b/runtime/vm/compiler/backend/linearscan.cc
@@ -595,23 +595,6 @@
         range->DefineAt(catch_entry->start_pos());  // Defined at block entry.
         ProcessInitialDefinition(defn, range, catch_entry);
       }
-      // Block the two fixed registers used by CatchBlockEntryInstr from the
-      // block start to until the end of the instruction so that they are
-      // preserved.
-      intptr_t start = catch_entry->start_pos();
-#if !defined(TARGET_ARCH_DBC)
-      const Register exception_reg = kExceptionObjectReg;
-      const Register stacktrace_reg = kStackTraceObjectReg;
-#else
-      const intptr_t exception_reg =
-          LocalVarIndex(0, catch_entry->exception_var().index());
-      const intptr_t stacktrace_reg =
-          LocalVarIndex(0, catch_entry->stacktrace_var().index());
-#endif
-      BlockLocation(Location::RegisterLocation(exception_reg), start,
-                    ToInstructionEnd(start));
-      BlockLocation(Location::RegisterLocation(stacktrace_reg), start,
-                    ToInstructionEnd(start));
     }
   }
 
@@ -639,11 +622,42 @@
 void FlowGraphAllocator::ProcessInitialDefinition(Definition* defn,
                                                   LiveRange* range,
                                                   BlockEntryInstr* block) {
-#if defined(TARGET_ARCH_DBC)
+  // Save the range end because it may change below.
+  const intptr_t range_end = range->End();
+
+  // TODO(31956): Clean up this code and factor common functionality out.
+  // Consider also making a separate [ProcessInitialDefinition] for
+  // [CatchBlockEntry]'s.
   if (block->IsCatchBlockEntry()) {
-    if (defn->IsParameter()) {
+    if (SpecialParameterInstr* param = defn->AsSpecialParameter()) {
+      Location loc;
+      switch (param->kind()) {
+        case SpecialParameterInstr::kException:
+          loc = Location::ExceptionLocation();
+          break;
+        case SpecialParameterInstr::kStackTrace:
+          loc = Location::StackTraceLocation();
+          break;
+        default:
+          UNREACHABLE();
+      }
+      range->set_assigned_location(loc);
+      AssignSafepoints(defn, range);
+      range->finger()->Initialize(range);
+      SplitInitialDefinitionAt(range, block->lifetime_position() + 1);
+      ConvertAllUses(range);
+
+      // On non-DBC we'll have exception/stacktrace in a register and need to
+      // ensure this register is not available for register allocation during
+      // the [CatchBlockEntry] to ensure it's not overwritten.
+      if (loc.IsRegister()) {
+        BlockLocation(loc, block->lifetime_position(),
+                      block->lifetime_position() + 1);
+      }
+      return;
+#if defined(TARGET_ARCH_DBC)
+    } else if (ParameterInstr* param = defn->AsParameter()) {
       // This must be in sync with FlowGraphCompiler::CatchEntryRegForVariable.
-      ParameterInstr* param = defn->AsParameter();
       intptr_t slot_index = param->index();
       AssignSafepoints(defn, range);
       range->finger()->Initialize(range);
@@ -652,8 +666,8 @@
       SplitInitialDefinitionAt(range, block->lifetime_position() + 2);
       ConvertAllUses(range);
       BlockLocation(Location::RegisterLocation(slot_index), 0, kMaxPosition);
-    } else {
-      ConstantInstr* constant = defn->AsConstant();
+      return;
+    } else if (ConstantInstr* constant = defn->AsConstant()) {
       ASSERT(constant != NULL);
       range->set_assigned_location(Location::Constant(constant));
       range->set_spill_slot(Location::Constant(constant));
@@ -668,13 +682,11 @@
         CompleteRange(tail, Location::kRegister);
       }
       ConvertAllUses(range);
+      return;
+#endif  // defined(TARGET_ARCH_DBC)
     }
-    return;
   }
-#endif
 
-  // Save the range end because it may change below.
-  intptr_t range_end = range->End();
   if (defn->IsParameter()) {
     ParameterInstr* param = defn->AsParameter();
     intptr_t slot_index = param->index();
@@ -705,16 +717,14 @@
     Location loc;
 #if defined(TARGET_ARCH_DBC)
     loc = Location::ArgumentsDescriptorLocation();
-    range->set_assigned_location(loc);
 #else
     loc = Location::RegisterLocation(ARGS_DESC_REG);
-    range->set_assigned_location(loc);
 #endif  // defined(TARGET_ARCH_DBC)
+    range->set_assigned_location(loc);
     if (loc.IsRegister()) {
       AssignSafepoints(defn, range);
       if (range->End() > kNormalEntryPos) {
-        LiveRange* tail = range->SplitAt(kNormalEntryPos);
-        CompleteRange(tail, Location::kRegister);
+        SplitInitialDefinitionAt(range, kNormalEntryPos);
       }
       ConvertAllUses(range);
       return;
@@ -1963,7 +1973,15 @@
     }
   }
 
+  while (idx > spill_slots_.length()) {
+    spill_slots_.Add(kMaxPosition);
+    quad_spill_slots_.Add(false);
+    untagged_spill_slots_.Add(false);
+  }
+
   if (idx == spill_slots_.length()) {
+    idx = spill_slots_.length();
+
     // No free spill slot found. Allocate a new one.
     spill_slots_.Add(0);
     quad_spill_slots_.Add(need_quad);
diff --git a/runtime/vm/compiler/backend/locations.cc b/runtime/vm/compiler/backend/locations.cc
index a01abb2..44c88ee 100644
--- a/runtime/vm/compiler/backend/locations.cc
+++ b/runtime/vm/compiler/backend/locations.cc
@@ -180,8 +180,17 @@
       }
       UNREACHABLE();
 #if TARGET_ARCH_DBC
-    case kArgsDescRegister:
-      return "ArgDesc";
+    case kSpecialDbcRegister:
+      switch (payload()) {
+        case kArgsDescriptorReg:
+          return "ArgDescReg";
+        case kExceptionReg:
+          return "ExceptionReg";
+        case kStackTraceReg:
+          return "StackTraceReg";
+        default:
+          UNREACHABLE();
+      }
 #endif
     default:
       if (IsConstant()) {
diff --git a/runtime/vm/compiler/backend/locations.h b/runtime/vm/compiler/backend/locations.h
index f6ffbab..fd4d576 100644
--- a/runtime/vm/compiler/backend/locations.h
+++ b/runtime/vm/compiler/backend/locations.h
@@ -62,6 +62,14 @@
   static const uword kLocationTagMask = 0x3;
 
  public:
+#if defined(TARGET_ARCH_DBC)
+  enum SpecialDbcRegister{
+      kArgsDescriptorReg,
+      kExceptionReg,
+      kStackTraceReg,
+  };
+#endif
+
   // Constant payload can overlap with kind field so Kind values
   // have to be chosen in a way that their last 2 bits are never
   // the same as kConstantTag or kPairLocationTag.
@@ -99,9 +107,9 @@
     kFpuRegister = 12,
 
 #ifdef TARGET_ARCH_DBC
-    // We use this to signify a special `Location` where the arguments
-    // descriptor can be found on DBC.
-    kArgsDescRegister = 15,
+    // We use this to signify a special `Location` where the different
+    // [SpecialDbcRegister]s can be found on DBC.
+    kSpecialDbcRegister = 15,
 #endif
   };
 
@@ -130,8 +138,9 @@
     COMPILE_ASSERT((kFpuRegister & kLocationTagMask) != kPairLocationTag);
 
 #ifdef TARGET_ARCH_DBC
-    COMPILE_ASSERT((kArgsDescRegister & kLocationTagMask) != kConstantTag);
-    COMPILE_ASSERT((kArgsDescRegister & kLocationTagMask) != kPairLocationTag);
+    COMPILE_ASSERT((kSpecialDbcRegister & kLocationTagMask) != kConstantTag);
+    COMPILE_ASSERT((kSpecialDbcRegister & kLocationTagMask) !=
+                   kPairLocationTag);
 #endif
 
     // Verify tags and tagmask.
@@ -247,12 +256,44 @@
 
   bool IsFpuRegister() const { return kind() == kFpuRegister; }
 
-#ifdef TARGET_ARCH_DBC
   static Location ArgumentsDescriptorLocation() {
-    return Location(kArgsDescRegister, 0);
+#ifdef TARGET_ARCH_DBC
+    return Location(kSpecialDbcRegister, kArgsDescriptorReg);
+#else
+    return Location::RegisterLocation(ARGS_DESC_REG);
+#endif
   }
 
-  bool IsArgsDescRegister() const { return kind() == kArgsDescRegister; }
+  static Location ExceptionLocation() {
+#ifdef TARGET_ARCH_DBC
+    return Location(kSpecialDbcRegister, kExceptionReg);
+#else
+    return Location::RegisterLocation(kExceptionObjectReg);
+#endif
+  }
+
+  static Location StackTraceLocation() {
+#ifdef TARGET_ARCH_DBC
+    return Location(kSpecialDbcRegister, kStackTraceReg);
+#else
+    return Location::RegisterLocation(kStackTraceObjectReg);
+#endif
+  }
+
+#ifdef TARGET_ARCH_DBC
+  bool IsArgsDescRegister() const {
+    return IsSpecialDbcRegister(kArgsDescriptorReg);
+  }
+  bool IsExceptionRegister() const {
+    return IsSpecialDbcRegister(kExceptionReg);
+  }
+  bool IsStackTraceRegister() const {
+    return IsSpecialDbcRegister(kStackTraceReg);
+  }
+
+  bool IsSpecialDbcRegister(SpecialDbcRegister reg) const {
+    return kind() == kSpecialDbcRegister && payload() == reg;
+  }
 #endif
 
   FpuRegister fpu_reg() const {
diff --git a/runtime/vm/compiler/backend/redundancy_elimination.cc b/runtime/vm/compiler/backend/redundancy_elimination.cc
index 2623846..449ace0 100644
--- a/runtime/vm/compiler/backend/redundancy_elimination.cc
+++ b/runtime/vm/compiler/backend/redundancy_elimination.cc
@@ -3157,12 +3157,9 @@
     // not tracked in the environment anyway.
 
     const intptr_t parameter_count = flow_graph->num_direct_parameters();
-    if (!catch_entry->exception_var().is_captured()) {
-      cdefs[catch_entry->exception_var().BitIndexIn(parameter_count)] = NULL;
-    }
-    if (!catch_entry->stacktrace_var().is_captured()) {
-      cdefs[catch_entry->stacktrace_var().BitIndexIn(parameter_count)] = NULL;
-    }
+    cdefs[catch_entry->raw_exception_var()->BitIndexIn(parameter_count)] = NULL;
+    cdefs[catch_entry->raw_stacktrace_var()->BitIndexIn(parameter_count)] =
+        NULL;
 
     for (BlockIterator block_it = flow_graph->reverse_postorder_iterator();
          !block_it.Done(); block_it.Advance()) {
diff --git a/runtime/vm/compiler/backend/type_propagator.cc b/runtime/vm/compiler/backend/type_propagator.cc
index 6b9c5bb..1f0f476 100644
--- a/runtime/vm/compiler/backend/type_propagator.cc
+++ b/runtime/vm/compiler/backend/type_propagator.cc
@@ -1051,6 +1051,13 @@
       return CompileType::FromCid(kTypeArgumentsCid);
     case kArgDescriptor:
       return CompileType::FromCid(kImmutableArrayCid);
+    case kException:
+      return CompileType(CompileType::kNonNullable, kDynamicCid,
+                         &Object::dynamic_type());
+    case kStackTrace:
+      // We cannot use [kStackTraceCid] here because any kind of object can be
+      // used as a stack trace via `new Future.error(..., <obj>)` :-/
+      return CompileType::Dynamic();
   }
   UNREACHABLE();
   return CompileType::Dynamic();
diff --git a/runtime/vm/compiler/frontend/flow_graph_builder.cc b/runtime/vm/compiler/frontend/flow_graph_builder.cc
index c26f4a6..aa65f19 100644
--- a/runtime/vm/compiler/frontend/flow_graph_builder.cc
+++ b/runtime/vm/compiler/frontend/flow_graph_builder.cc
@@ -4116,7 +4116,8 @@
       owner()->AllocateBlockId(), catch_handler_index, owner()->graph_entry(),
       catch_block->handler_types(), try_handler_index,
       catch_block->exception_var(), catch_block->stacktrace_var(),
-      catch_block->needs_stacktrace(), owner()->GetNextDeoptId());
+      catch_block->needs_stacktrace(), owner()->GetNextDeoptId(),
+      &catch_block->exception_var(), &catch_block->stacktrace_var());
   owner()->AddCatchEntry(catch_entry);
   AppendFragment(catch_entry, for_catch);
 
@@ -4162,7 +4163,8 @@
         owner()->AllocateBlockId(), original_handler_index,
         owner()->graph_entry(), types, catch_handler_index,
         catch_block->exception_var(), catch_block->stacktrace_var(),
-        catch_block->needs_stacktrace(), owner()->GetNextDeoptId());
+        catch_block->needs_stacktrace(), owner()->GetNextDeoptId(),
+        &catch_block->exception_var(), &catch_block->stacktrace_var());
     owner()->AddCatchEntry(finally_entry);
     AppendFragment(finally_entry, for_finally);
   }
diff --git a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
index 0e85f68..b943afa 100644
--- a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
+++ b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
@@ -679,7 +679,7 @@
       intptr_t node_offset = reader.ReadUInt32();
       intptr_t md_offset = reader.ReadUInt32();
 
-      ASSERT((node_offset > 0) && (md_offset > 0));
+      ASSERT((node_offset > 0) && (md_offset >= 0));
       ASSERT(node_offset > prev_node_offset);
       prev_node_offset = node_offset;
     }
@@ -747,7 +747,7 @@
 
   intptr_t index = last_mapping_index_;
   intptr_t mapping_node_offset = 0;
-  intptr_t mapping_md_offset = 0;
+  intptr_t mapping_md_offset = -1;
 
   Reader reader(H.metadata_mappings());
   const intptr_t kUInt32Size = 4;
@@ -766,7 +766,7 @@
   last_node_offset_ = node_offset;
 
   if ((index < mappings_num_) && (mapping_node_offset == node_offset)) {
-    ASSERT(mapping_md_offset > 0);
+    ASSERT(mapping_md_offset >= 0);
     return mapping_md_offset;
   } else {
     return -1;
@@ -782,7 +782,7 @@
   }
 
   AlternativeReadingScope alt(&builder_->reader_, &H.metadata_payloads(),
-                              md_offset - MetadataPayloadOffset);
+                              md_offset);
 
   *target_name = builder_->ReadCanonicalNameReference();
   *check_receiver_for_null = builder_->ReadBool();
@@ -860,7 +860,7 @@
   }
 
   AlternativeReadingScope alt(&builder_->reader_, &H.metadata_payloads(),
-                              md_offset - MetadataPayloadOffset);
+                              md_offset);
 
   const int kDynamicUsesBit = 1 << 0;
   const int kNonThisUsesBit = 1 << 1;
@@ -890,7 +890,7 @@
   }
 
   AlternativeReadingScope alt(&builder_->reader_, &H.metadata_payloads(),
-                              md_offset - MetadataPayloadOffset);
+                              md_offset);
 
   const NameIndex kernel_name = builder_->ReadCanonicalNameReference();
   const bool nullable = builder_->ReadBool();
@@ -923,7 +923,7 @@
   }
 
   AlternativeReadingScope alt(&builder_->reader_, &H.metadata_payloads(),
-                              md_offset - MetadataPayloadOffset);
+                              md_offset);
 
   // Read bytecode.
   intptr_t bytecode_size = builder_->reader_.ReadUInt();
@@ -1014,8 +1014,8 @@
         }
       } break;
       case ConstantPoolTag::kICData: {
-        NameIndex target = builder_->ReadCanonicalNameReference();
-        name = H.DartProcedureName(target).raw();
+        StringIndex target = builder_->ReadStringReference();
+        name = H.DartSymbolPlain(target).raw();
         intptr_t arg_desc_index = builder_->ReadUInt();
         ASSERT(arg_desc_index < i);
         array ^= obj_pool.ObjectAt(arg_desc_index);
@@ -1084,12 +1084,10 @@
         obj = H.Canonicalize(Instance::Cast(obj));
         break;
       case ConstantPoolTag::kType:
-        UNIMPLEMENTED();  // Encoding is under discussion with CFE team.
         obj = builder_->type_translator_.BuildType().raw();
         ASSERT(obj.IsAbstractType());
         break;
       case ConstantPoolTag::kTypeArguments:
-        UNIMPLEMENTED();  // Encoding is under discussion with CFE team.
         obj = builder_->type_translator_
                   .BuildTypeArguments(builder_->ReadListLength())
                   .raw();
@@ -2157,6 +2155,9 @@
         ExitScope(builder_->reader_.min_position(),
                   builder_->reader_.max_position());
       }
+
+      FinalizeCatchVariables();
+
       --depth_.catch_;
       return;
     }
@@ -2174,6 +2175,8 @@
 
       VisitStatement();  // read finalizer.
 
+      FinalizeCatchVariables();
+
       --depth_.catch_;
       return;
     }
@@ -2598,6 +2601,30 @@
   variables->Add(v);
 }
 
+void StreamingScopeBuilder::FinalizeExceptionVariable(
+    GrowableArray<LocalVariable*>* variables,
+    GrowableArray<LocalVariable*>* raw_variables,
+    const String& symbol,
+    intptr_t nesting_depth) {
+  // No need to create variables for try/catch-statements inside
+  // nested functions.
+  if (depth_.function_ > 0) return;
+
+  LocalVariable* variable = (*variables)[nesting_depth - 1];
+  LocalVariable* raw_variable;
+  if (variable->is_captured()) {
+    raw_variable =
+        new LocalVariable(TokenPosition::kNoSource, TokenPosition::kNoSource,
+                          symbol, AbstractType::dynamic_type());
+    const bool ok = scope_->AddVariable(raw_variable);
+    ASSERT(ok);
+  } else {
+    raw_variable = variable;
+  }
+  raw_variables->EnsureLength(nesting_depth, nullptr);
+  (*raw_variables)[nesting_depth - 1] = raw_variable;
+}
+
 void StreamingScopeBuilder::AddTryVariables() {
   AddExceptionVariable(&result_->catch_context_variables,
                        ":saved_try_context_var", depth_.try_);
@@ -2610,6 +2637,16 @@
                        depth_.catch_);
 }
 
+void StreamingScopeBuilder::FinalizeCatchVariables() {
+  const intptr_t unique_id = result_->raw_variable_counter_++;
+  FinalizeExceptionVariable(
+      &result_->exception_variables, &result_->raw_exception_variables,
+      GenerateName(":raw_exception", unique_id), depth_.catch_);
+  FinalizeExceptionVariable(
+      &result_->stack_trace_variables, &result_->raw_stack_trace_variables,
+      GenerateName(":raw_stacktrace", unique_id), depth_.catch_);
+}
+
 void StreamingScopeBuilder::AddIteratorVariable() {
   if (depth_.function_ > 0) return;
   if (result_->iterator_variables.length() >= depth_.for_in_) return;
@@ -5191,6 +5228,46 @@
   return instructions;
 }
 
+// If no type arguments are passed to a generic function, we need to fill the
+// type arguments in with the default types stored on the TypeParameter nodes
+// in Kernel.
+Fragment StreamingFlowGraphBuilder::BuildDefaultTypeHandling(
+    const Function& function,
+    intptr_t type_parameters_offset) {
+  if (function.IsGeneric() && I->reify_generic_functions()) {
+    AlternativeReadingScope alt(&reader_);
+    SetOffset(type_parameters_offset);
+    intptr_t num_type_params = ReadListLength();
+    ASSERT(num_type_params == function.NumTypeParameters());
+    TypeArguments& default_types =
+        TypeArguments::ZoneHandle(TypeArguments::New(num_type_params));
+    for (intptr_t i = 0; i < num_type_params; ++i) {
+      TypeParameterHelper helper(this);
+      helper.ReadUntilExcludingAndSetJustRead(
+          TypeParameterHelper::kDefaultType);
+      if (ReadTag() == kSomething) {
+        default_types.SetTypeAt(i, T.BuildType());
+      } else {
+        default_types.SetTypeAt(i, Object::dynamic_type());
+      }
+      helper.Finish();
+    }
+    default_types = default_types.Canonicalize();
+
+    if (!default_types.IsNull()) {
+      // clang-format off
+      return B->TestAnyTypeArgs(/*then=*/{}, /*else=*/{
+          TranslateInstantiatedTypeArguments(default_types),
+          StoreLocal(TokenPosition::kNoSource,
+                     parsed_function()->function_type_arguments()),
+          Drop()
+        });
+      // clang-format on
+    }
+  }
+  return Fragment();
+}
+
 FlowGraph* StreamingFlowGraphBuilder::BuildGraphOfImplicitClosureFunction(
     const Function& function) {
   const Function& parent = Function::ZoneHandle(Z, function.parent_function());
@@ -5227,6 +5304,11 @@
   body +=
       flow_graph_builder_->CheckStackOverflowInPrologue(function.token_pos());
 
+  FunctionNodeHelper function_node_helper(this);
+  function_node_helper.ReadUntilExcluding(FunctionNodeHelper::kTypeParameters);
+
+  body += BuildDefaultTypeHandling(function, ReaderOffset());
+
   intptr_t type_args_len = 0;
   if (I->reify_generic_functions() && function.IsGeneric()) {
     type_args_len = function.NumTypeParameters();
@@ -5235,9 +5317,6 @@
     body += PushArgument();
   }
 
-  FunctionNodeHelper function_node_helper(this);
-  function_node_helper.ReadUntilExcluding(FunctionNodeHelper::kTypeParameters);
-
   if (I->argument_type_checks()) {
     if (!target.NeedsArgumentTypeChecks(I)) {
       // Tearoffs of static methods needs to perform arguments checks since
@@ -5376,27 +5455,13 @@
   body += StoreLocal(TokenPosition::kNoSource, argument_count_var);
   body += Drop();
   if (function.IsGeneric() && Isolate::Current()->reify_generic_functions()) {
-    Fragment test_generic;
-    JoinEntryInstr* join = BuildJoinEntry();
-
-    TargetEntryInstr *passed_type_args, *not_passed_type_args;
-    test_generic += B->LoadArgDescriptor();
-    test_generic += LoadField(ArgumentsDescriptor::type_args_len_offset());
-    test_generic += IntConstant(0);
-    test_generic += BranchIfEqual(&not_passed_type_args, &passed_type_args,
-                                  /*negate=*/false);
-
-    Fragment passed_type_args_frag(passed_type_args);
-    passed_type_args_frag += IntConstant(1);
-    passed_type_args_frag +=
-        StoreLocal(TokenPosition::kNoSource, argument_count_var);
-    passed_type_args_frag += Drop();
-    passed_type_args_frag += Goto(join);
-
-    Fragment not_passed_type_args_frag(not_passed_type_args);
-    not_passed_type_args_frag += Goto(join);
-
-    body += Fragment(test_generic.entry, join);
+    // clang-format off
+    body += flow_graph_builder_->TestAnyTypeArgs(/*then=*/{
+        IntConstant(1),
+        StoreLocal(TokenPosition::kNoSource, argument_count_var),
+        Drop()
+      }, /*else=*/{});
+    // clang-format on
   }
 
   if (function.HasOptionalParameters()) {
@@ -5413,7 +5478,13 @@
   //
   // var arguments = new Array<dynamic>(argument_count);
   //
-  // for (int i = 0; i < argument_count; ++i) {
+  // int i = 0;
+  // if (any type arguments are passed) {
+  //   arguments[0] = function_type_arguments;
+  //   ++i;
+  // }
+  //
+  // for (; i < argument_count; ++i) {
   //   arguments[i] = LoadFpRelativeSlot(
   //       kWordSize * (kParamEndSlotFromFp + argument_count - i));
   // }
@@ -5429,6 +5500,26 @@
     body += StoreLocal(TokenPosition::kNoSource, index);
     body += Drop();
 
+    // if (any type arguments are passed) {
+    //   arguments[0] = function_type_arguments;
+    //   i = 1;
+    // }
+    if (function.IsGeneric() && Isolate::Current()->reify_generic_functions()) {
+      // clang-format off
+      Fragment store_type_arguments = {
+            LoadLocal(arguments),
+            IntConstant(0),
+            LoadFunctionTypeArguments(),
+            StoreIndexed(kArrayCid),
+            Drop(),
+            IntConstant(1),
+            StoreLocal(TokenPosition::kNoSource, index),
+            Drop()
+          };
+      // clang-format on
+      body += B->TestAnyTypeArgs(store_type_arguments, {});
+    }
+
     TargetEntryInstr* body_entry;
     TargetEntryInstr* loop_exit;
 
@@ -5515,10 +5606,6 @@
   body += LoadLocal(arguments);
   body += PushArgument();
 
-  // false -> this is not super NSM
-  body += Constant(Bool::False());
-  body += PushArgument();
-
   if (throw_no_such_method_error) {
     const Function& parent =
         Function::ZoneHandle(Z, function.parent_function());
@@ -5541,12 +5628,30 @@
   }
   body += PushArgument();
 
+  // Push the number of delayed type arguments.
+  if (function.IsClosureFunction()) {
+    LocalVariable* closure =
+        parsed_function()->node_sequence()->scope()->VariableAt(0);
+    body += B->TestDelayedTypeArgs(
+        closure,
+        Fragment({IntConstant(function.NumTypeParameters()),
+                  StoreLocal(TokenPosition::kNoSource, argument_count_var),
+                  Drop()}),
+        Fragment({IntConstant(0),
+                  StoreLocal(TokenPosition::kNoSource, argument_count_var),
+                  Drop()}));
+    body += LoadLocal(argument_count_var);
+  } else {
+    body += IntConstant(0);
+  }
+  body += PushArgument();
+
   const Class& mirror_class =
       Class::Handle(Z, Library::LookupCoreClass(Symbols::InvocationMirror()));
   ASSERT(!mirror_class.IsNull());
   const Function& allocation_function = Function::ZoneHandle(
-      Z, mirror_class.LookupStaticFunction(
-             Library::PrivateCoreLibName(Symbols::AllocateInvocationMirror())));
+      Z, mirror_class.LookupStaticFunction(Library::PrivateCoreLibName(
+             Symbols::AllocateInvocationMirrorForClosure())));
   ASSERT(!allocation_function.IsNull());
   body += StaticCall(TokenPosition::kMinSource, allocation_function,
                      /* argument_count = */ 5, ICData::kStatic);
@@ -5912,6 +6017,9 @@
   // body because it needs to be executed everytime we enter the function -
   // even if we are resuming from the yield.
   Fragment prologue;
+
+  prologue += BuildDefaultTypeHandling(dart_function, type_parameters_offset);
+
   if (dart_function.IsClosureFunction() &&
       dart_function.NumParentTypeParameters() > 0 &&
       I->reify_generic_functions()) {
@@ -10912,51 +11020,39 @@
 
   // Read metadataMappings elements.
   for (uint32_t i = 0; i < metadata_num; ++i) {
-    // Read nodeReferences length.
+    // Read nodeOffsetToMetadataOffset length.
     offset -= kUInt32Size;
-    uint32_t node_references_num = reader.ReadUInt32At(offset);
-
-    // Skip nodeReferences and read nodeOffsetToMetadataOffset length.
-    offset -= node_references_num * kUInt32Size + kUInt32Size;
     uint32_t mappings_num = reader.ReadUInt32At(offset);
 
     // Skip nodeOffsetToMetadataOffset and read tag.
     offset -= mappings_num * 2 * kUInt32Size + kUInt32Size;
     StringIndex tag = StringIndex(reader.ReadUInt32At(offset));
 
+    if (mappings_num == 0) {
+      continue;
+    }
+
     // Check recognized metadata
     if (H.StringEquals(tag, DirectCallMetadataHelper::tag())) {
-      ASSERT(node_references_num == 0);
-
-      if (mappings_num > 0) {
-        if (!FLAG_precompiled_mode) {
-          FATAL("DirectCallMetadata is allowed in precompiled mode only");
-        }
-        direct_call_metadata_helper_.SetMetadataMappings(offset + kUInt32Size,
-                                                         mappings_num);
+      if (!FLAG_precompiled_mode) {
+        FATAL("DirectCallMetadata is allowed in precompiled mode only");
       }
+      direct_call_metadata_helper_.SetMetadataMappings(offset + kUInt32Size,
+                                                       mappings_num);
     } else if (H.StringEquals(tag, InferredTypeMetadataHelper::tag())) {
-      ASSERT(node_references_num == 0);
-
-      if (mappings_num > 0) {
-        if (!FLAG_precompiled_mode) {
-          FATAL("InferredTypeMetadata is allowed in precompiled mode only");
-        }
-        inferred_type_metadata_helper_.SetMetadataMappings(offset + kUInt32Size,
-                                                           mappings_num);
+      if (!FLAG_precompiled_mode) {
+        FATAL("InferredTypeMetadata is allowed in precompiled mode only");
       }
+      inferred_type_metadata_helper_.SetMetadataMappings(offset + kUInt32Size,
+                                                         mappings_num);
     } else if (H.StringEquals(tag, ProcedureAttributesMetadataHelper::tag())) {
-      ASSERT(node_references_num == 0);
-
-      if (mappings_num > 0) {
-        if (!FLAG_precompiled_mode) {
-          FATAL(
-              "ProcedureAttributesMetadata is allowed in precompiled mode "
-              "only");
-        }
-        procedure_attributes_metadata_helper_.SetMetadataMappings(
-            offset + kUInt32Size, mappings_num);
+      if (!FLAG_precompiled_mode) {
+        FATAL(
+            "ProcedureAttributesMetadata is allowed in precompiled mode "
+            "only");
       }
+      procedure_attributes_metadata_helper_.SetMetadataMappings(
+          offset + kUInt32Size, mappings_num);
     } else if (H.StringEquals(tag, BytecodeMetadataHelper::tag())) {
       bytecode_metadata_helper_.SetMetadataMappings(offset + kUInt32Size,
                                                     mappings_num);
diff --git a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h
index 77d8ce6..a8b39a4 100644
--- a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h
+++ b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h
@@ -327,9 +327,6 @@
   bool IsRedirectingFactoryConstructor() {
     return (flags_ & kRedirectingFactoryConstructor) != 0;
   }
-  bool IsNoSuchMethodForwarder() {
-    return (flags_ & kNoSuchMethodForwarder) != 0;
-  }
 
   NameIndex canonical_name_;
   TokenPosition position_;
@@ -825,8 +822,14 @@
                             const char* prefix,
                             intptr_t nesting_depth);
 
+  void FinalizeExceptionVariable(GrowableArray<LocalVariable*>* variables,
+                                 GrowableArray<LocalVariable*>* raw_variables,
+                                 const String& symbol,
+                                 intptr_t nesting_depth);
+
   void AddTryVariables();
   void AddCatchVariables();
+  void FinalizeCatchVariables();
   void AddIteratorVariable();
   void AddSwitchVariable();
 
@@ -1392,6 +1395,10 @@
     kTypeChecksForNoDynamicInvocationsTearOff
   };
 
+  // Does not move the cursor.
+  Fragment BuildDefaultTypeHandling(const Function& function,
+                                    intptr_t type_parameters_offset);
+
   Fragment BuildArgumentTypeChecks(TypeChecksToBuild mode = kDefaultTypeChecks);
 
   Fragment ThrowException(TokenPosition position);
diff --git a/runtime/vm/compiler/frontend/kernel_to_il.cc b/runtime/vm/compiler/frontend/kernel_to_il.cc
index aa1cb20..6b5a9af 100644
--- a/runtime/vm/compiler/frontend/kernel_to_il.cc
+++ b/runtime/vm/compiler/frontend/kernel_to_il.cc
@@ -1178,19 +1178,54 @@
                                            intptr_t handler_index,
                                            bool needs_stacktrace,
                                            bool is_synthesized) {
-  ASSERT(CurrentException()->is_captured() ==
-         CurrentStackTrace()->is_captured());
-  const bool should_restore_closure_context =
-      CurrentException()->is_captured() || CurrentCatchContext()->is_captured();
+  LocalVariable* exception_var = CurrentException();
+  LocalVariable* stacktrace_var = CurrentStackTrace();
+  LocalVariable* raw_exception_var = CurrentRawException();
+  LocalVariable* raw_stacktrace_var = CurrentRawStackTrace();
+
   CatchBlockEntryInstr* entry = new (Z) CatchBlockEntryInstr(
       TokenPosition::kNoSource,  // Token position of catch block.
       is_synthesized,  // whether catch block was synthesized by FE compiler
       AllocateBlockId(), CurrentTryIndex(), graph_entry_, handler_types,
-      handler_index, *CurrentException(), *CurrentStackTrace(),
-      needs_stacktrace, GetNextDeoptId(), should_restore_closure_context);
+      handler_index, *exception_var, *stacktrace_var, needs_stacktrace,
+      GetNextDeoptId(), raw_exception_var, raw_stacktrace_var);
   graph_entry_->AddCatchEntry(entry);
+
   Fragment instructions(entry);
 
+  // Auxiliary variables introduced by the try catch can be captured if we are
+  // inside a function with yield/resume points. In this case we first need
+  // to restore the context to match the context at entry into the closure.
+  const bool should_restore_closure_context =
+      CurrentException()->is_captured() || CurrentCatchContext()->is_captured();
+  LocalVariable* context_variable = parsed_function_->current_context_var();
+  if (should_restore_closure_context) {
+    ASSERT(parsed_function_->function().IsClosureFunction());
+    LocalScope* scope = parsed_function_->node_sequence()->scope();
+
+    LocalVariable* closure_parameter = scope->VariableAt(0);
+    ASSERT(!closure_parameter->is_captured());
+    instructions += LoadLocal(closure_parameter);
+    instructions += LoadField(Closure::context_offset());
+    instructions += StoreLocal(TokenPosition::kNoSource, context_variable);
+    instructions += Drop();
+  }
+
+  if (exception_var->is_captured()) {
+    instructions += LoadLocal(context_variable);
+    instructions += LoadLocal(raw_exception_var);
+    instructions +=
+        StoreInstanceField(TokenPosition::kNoSource,
+                           Context::variable_offset(exception_var->index()));
+  }
+  if (stacktrace_var->is_captured()) {
+    instructions += LoadLocal(context_variable);
+    instructions += LoadLocal(raw_stacktrace_var);
+    instructions +=
+        StoreInstanceField(TokenPosition::kNoSource,
+                           Context::variable_offset(stacktrace_var->index()));
+  }
+
   // :saved_try_context_var can be captured in the context of
   // of the closure, in this case CatchBlockEntryInstr restores
   // :current_context_var to point to closure context in the
@@ -1385,6 +1420,28 @@
   return Fragment(test.entry, join);
 }
 
+Fragment BaseFlowGraphBuilder::TestAnyTypeArgs(Fragment present,
+                                               Fragment absent) {
+  if (parsed_function_->function().IsClosureFunction()) {
+    LocalVariable* closure =
+        parsed_function_->node_sequence()->scope()->VariableAt(0);
+
+    JoinEntryInstr* complete = BuildJoinEntry();
+    JoinEntryInstr* present_entry = BuildJoinEntry();
+
+    Fragment test = TestTypeArgsLen(
+        TestDelayedTypeArgs(closure, Goto(present_entry), absent),
+        Goto(present_entry), 0);
+    test += Goto(complete);
+
+    Fragment(present_entry) + present + Goto(complete);
+
+    return Fragment(test.entry, complete);
+  } else {
+    return TestTypeArgsLen(absent, present, 0);
+  }
+}
+
 Fragment FlowGraphBuilder::RethrowException(TokenPosition position,
                                             int catch_try_index) {
   Fragment instructions;
diff --git a/runtime/vm/compiler/frontend/kernel_to_il.h b/runtime/vm/compiler/frontend/kernel_to_il.h
index 817633f..a22d222 100644
--- a/runtime/vm/compiler/frontend/kernel_to_il.h
+++ b/runtime/vm/compiler/frontend/kernel_to_il.h
@@ -7,6 +7,7 @@
 
 #if !defined(DART_PRECOMPILED_RUNTIME)
 
+#include <functional>
 #include <initializer_list>
 
 #include "vm/growable_array.h"
@@ -484,7 +485,8 @@
         finally_return_variable(NULL),
         setter_value(NULL),
         yield_jump_variable(NULL),
-        yield_context_variable(NULL) {}
+        yield_context_variable(NULL),
+        raw_variable_counter_(0) {}
 
   IntMap<LocalVariable*> locals;
   IntMap<LocalScope*> scopes;
@@ -521,6 +523,12 @@
   GrowableArray<LocalVariable*> stack_trace_variables;
   GrowableArray<LocalVariable*> catch_context_variables;
 
+  // These are used to access the raw exception/stacktrace variables (and are
+  // used to put them into the captured variables in the context).
+  GrowableArray<LocalVariable*> raw_exception_variables;
+  GrowableArray<LocalVariable*> raw_stack_trace_variables;
+  intptr_t raw_variable_counter_;
+
   // For-in iterators, one per for-in nesting level.
   GrowableArray<LocalVariable*> iterator_variables;
 };
@@ -647,6 +655,7 @@
   Fragment TestDelayedTypeArgs(LocalVariable* closure,
                                Fragment present,
                                Fragment absent);
+  Fragment TestAnyTypeArgs(Fragment present, Fragment absent);
 
   JoinEntryInstr* BuildThrowNoSuchMethod();
 
@@ -869,6 +878,12 @@
   LocalVariable* CurrentStackTrace() {
     return scopes_->stack_trace_variables[catch_depth_ - 1];
   }
+  LocalVariable* CurrentRawException() {
+    return scopes_->raw_exception_variables[catch_depth_ - 1];
+  }
+  LocalVariable* CurrentRawStackTrace() {
+    return scopes_->raw_stack_trace_variables[catch_depth_ - 1];
+  }
   LocalVariable* CurrentCatchContext() {
     return scopes_->catch_context_variables[try_depth_];
   }
diff --git a/runtime/vm/compiler/jit/compiler.cc b/runtime/vm/compiler/jit/compiler.cc
index 18225e6..0430ef9 100644
--- a/runtime/vm/compiler/jit/compiler.cc
+++ b/runtime/vm/compiler/jit/compiler.cc
@@ -1043,9 +1043,25 @@
             // We got an error during compilation.
             error = thread->sticky_error();
             thread->clear_sticky_error();
-            if ((error.IsLanguageError() &&
-                 LanguageError::Cast(error).kind() == Report::kBailout) ||
-                error.IsUnhandledException()) {
+
+            if (error.raw() == Object::background_compilation_error().raw()) {
+              if (FLAG_trace_compiler) {
+                THR_Print(
+                    "--> disabling background optimizations for '%s' (will "
+                    "try to re-compile on isolate thread again)\n",
+                    function.ToFullyQualifiedCString());
+              }
+
+              // Ensure we don't attempt to re-compile the function on the
+              // background compiler.
+              function.set_is_background_optimizable(false);
+
+              // Trigger another optimization soon on the main thread.
+              function.SetUsageCounter(FLAG_optimization_counter_threshold);
+            } else if ((error.IsLanguageError() &&
+                        LanguageError::Cast(error).kind() ==
+                            Report::kBailout) ||
+                       error.IsUnhandledException()) {
               if (FLAG_trace_compiler) {
                 THR_Print("--> disabling optimizations for '%s'\n",
                           function.ToFullyQualifiedCString());
@@ -1287,7 +1303,8 @@
   // not currently allowed.
   ASSERT(!thread->IsMutatorThread() || (osr_id != kNoOSRDeoptId) ||
          !FLAG_background_compilation ||
-         BackgroundCompiler::IsDisabled(Isolate::Current()));
+         BackgroundCompiler::IsDisabled(Isolate::Current()) ||
+         !function.is_background_optimizable());
   CompilationPipeline* pipeline =
       CompilationPipeline::New(thread->zone(), function);
   return CompileFunctionHelper(pipeline, function, true, /* optimized */
diff --git a/runtime/vm/compiler_test.cc b/runtime/vm/compiler_test.cc
index 091dd5d..bbc4d16 100644
--- a/runtime/vm/compiler_test.cc
+++ b/runtime/vm/compiler_test.cc
@@ -179,6 +179,10 @@
 }
 
 ISOLATE_UNIT_TEST_CASE(EvalExpressionWithLazyCompile) {
+  {  // Initialize an incremental compiler in DFE mode.
+    TransitionVMToNative transition(thread);
+    TestCase::LoadTestScript("", NULL);
+  }
   Library& lib = Library::Handle(Library::CoreLibrary());
 
   const String& expression = String::Handle(
@@ -193,6 +197,10 @@
 }
 
 ISOLATE_UNIT_TEST_CASE(EvalExpressionExhaustCIDs) {
+  {  // Initialize an incremental compiler in DFE mode.
+    TransitionVMToNative transition(thread);
+    TestCase::LoadTestScript("", NULL);
+  }
   Library& lib = Library::Handle(Library::CoreLibrary());
 
   const String& expression = String::Handle(String::New("3 + 4"));
diff --git a/runtime/vm/dart.cc b/runtime/vm/dart.cc
index 4efa972..09ce27c 100644
--- a/runtime/vm/dart.cc
+++ b/runtime/vm/dart.cc
@@ -137,6 +137,7 @@
   SetFileCallbacks(file_open, file_read, file_write, file_close);
   set_entropy_source_callback(entropy_source);
   OS::InitOnce();
+  NOT_IN_PRODUCT(CodeObservers::InitOnce());
   start_time_micros_ = OS::GetCurrentMonotonicMicros();
   VirtualMemory::InitOnce();
   OSThread::InitOnce();
@@ -152,7 +153,6 @@
   ForwardingCorpse::InitOnce();
   Api::InitOnce();
   NativeSymbolResolver::InitOnce();
-  NOT_IN_PRODUCT(CodeObservers::InitOnce());
   NOT_IN_PRODUCT(Profiler::InitOnce());
   SemiSpace::InitOnce();
   NOT_IN_PRODUCT(Metric::InitOnce());
@@ -504,8 +504,8 @@
                                   const uint8_t* snapshot_instructions,
                                   const uint8_t* shared_data,
                                   const uint8_t* shared_instructions,
-                                  intptr_t snapshot_length,
-                                  kernel::Program* kernel_program,
+                                  const uint8_t* kernel_buffer,
+                                  intptr_t kernel_buffer_size,
                                   void* data) {
   // Initialize the new isolate.
   Thread* T = Thread::Current();
@@ -524,11 +524,11 @@
   }
 
   Error& error = Error::Handle(T->zone());
-  error = Object::Init(I, kernel_program);
+  error = Object::Init(I, kernel_buffer, kernel_buffer_size);
   if (!error.IsNull()) {
     return error.raw();
   }
-  if ((snapshot_data != NULL) && kernel_program == NULL) {
+  if ((snapshot_data != NULL) && kernel_buffer == NULL) {
     // Read the snapshot and setup the initial state.
     NOT_IN_PRODUCT(TimelineDurationScope tds(T, Timeline::GetIsolateStream(),
                                              "IsolateSnapshotReader"));
@@ -567,7 +567,7 @@
       MegamorphicCacheTable::PrintSizes(I);
     }
   } else {
-    if ((vm_snapshot_kind_ != Snapshot::kNone) && kernel_program == NULL) {
+    if ((vm_snapshot_kind_ != Snapshot::kNone) && kernel_buffer == NULL) {
       const String& message =
           String::Handle(String::New("Missing isolate snapshot"));
       return ApiError::New(message);
@@ -592,7 +592,7 @@
       Code::Handle(I->object_store()->megamorphic_miss_code());
   I->set_ic_miss_code(miss_code);
 
-  if ((snapshot_data == NULL) || (kernel_program != NULL)) {
+  if ((snapshot_data == NULL) || (kernel_buffer != NULL)) {
     const Error& error = Error::Handle(I->object_store()->PreallocateObjects());
     if (!error.IsNull()) {
       return error.raw();
@@ -677,6 +677,10 @@
              FLAG_error_on_bad_type);
     ADD_FLAG(error_on_bad_override, enable_error_on_bad_override,
              FLAG_error_on_bad_override);
+    // sync-async and reify_generic_functions also affect deopt_ids.
+    ADD_FLAG(sync_async, sync_async, FLAG_sync_async);
+    ADD_FLAG(reify_generic_functions, reify_generic_functions,
+             FLAG_reify_generic_functions);
     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);
@@ -717,7 +721,9 @@
 }
 
 void Dart::RunShutdownCallback() {
-  Isolate* isolate = Isolate::Current();
+  Thread* thread = Thread::Current();
+  ASSERT(thread->execution_state() == Thread::kThreadInNative);
+  Isolate* isolate = thread->isolate();
   void* callback_data = isolate->init_callback_data();
   Dart_IsolateShutdownCallback callback = Isolate::ShutdownCallback();
   if (callback != NULL) {
diff --git a/runtime/vm/dart.h b/runtime/vm/dart.h
index ce8b5e0..76243b3 100644
--- a/runtime/vm/dart.h
+++ b/runtime/vm/dart.h
@@ -50,8 +50,8 @@
                                      const uint8_t* snapshot_instructions,
                                      const uint8_t* shared_data,
                                      const uint8_t* shared_instructions,
-                                     intptr_t snapshot_length,
-                                     kernel::Program* kernel_program,
+                                     const uint8_t* kernel_buffer,
+                                     intptr_t kernel_buffer_size,
                                      void* data);
   static void RunShutdownCallback();
   static void ShutdownIsolate(Isolate* isolate);
diff --git a/runtime/vm/dart_api_impl.cc b/runtime/vm/dart_api_impl.cc
index 26bb097..02fa964 100644
--- a/runtime/vm/dart_api_impl.cc
+++ b/runtime/vm/dart_api_impl.cc
@@ -1101,8 +1101,8 @@
                                   const uint8_t* snapshot_instructions,
                                   const uint8_t* shared_data,
                                   const uint8_t* shared_instructions,
-                                  intptr_t snapshot_length,
-                                  kernel::Program* kernel_program,
+                                  const uint8_t* kernel_buffer,
+                                  intptr_t kernel_buffer_size,
                                   Dart_IsolateFlags* flags,
                                   void* callback_data,
                                   char** error) {
@@ -1131,14 +1131,14 @@
     // bootstrap library files which call out to a tag handler that may create
     // Api Handles when an error is encountered.
     Dart_EnterScope();
-    const Error& error_obj =
-        Error::Handle(Z, Dart::InitializeIsolate(
-                             snapshot_data, snapshot_instructions, shared_data,
-                             shared_instructions, snapshot_length,
-                             kernel_program, callback_data));
+    const Error& error_obj = Error::Handle(
+        Z,
+        Dart::InitializeIsolate(snapshot_data, snapshot_instructions,
+                                shared_data, shared_instructions, kernel_buffer,
+                                kernel_buffer_size, callback_data));
     if (error_obj.IsNull()) {
 #if defined(DART_NO_SNAPSHOT) && !defined(PRODUCT)
-      if (FLAG_check_function_fingerprints && kernel_program == NULL) {
+      if (FLAG_check_function_fingerprints && kernel_buffer == NULL) {
         Library::CheckFunctionFingerprints();
       }
 #endif  // defined(DART_NO_SNAPSHOT) && !defined(PRODUCT).
@@ -1181,16 +1181,18 @@
                    char** error) {
   API_TIMELINE_DURATION(Thread::Current());
   return CreateIsolate(script_uri, main, snapshot_data, snapshot_instructions,
-                       shared_data, shared_instructions, -1, NULL, flags,
+                       shared_data, shared_instructions, NULL, 0, flags,
                        callback_data, error);
 }
 
-DART_EXPORT Dart_Isolate Dart_CreateIsolateFromKernel(const char* script_uri,
-                                                      const char* main,
-                                                      void* kernel_program,
-                                                      Dart_IsolateFlags* flags,
-                                                      void* callback_data,
-                                                      char** error) {
+DART_EXPORT Dart_Isolate
+Dart_CreateIsolateFromKernel(const char* script_uri,
+                             const char* main,
+                             const uint8_t* kernel_buffer,
+                             intptr_t kernel_buffer_size,
+                             Dart_IsolateFlags* flags,
+                             void* callback_data,
+                             char** error) {
   API_TIMELINE_DURATION(Thread::Current());
   // Setup default flags in case none were passed.
   Dart_IsolateFlags api_flags;
@@ -1199,9 +1201,8 @@
     flags = &api_flags;
   }
   flags->use_dart_frontend = true;
-  return CreateIsolate(script_uri, main, NULL, NULL, NULL, NULL, -1,
-                       reinterpret_cast<kernel::Program*>(kernel_program),
-                       flags, callback_data, error);
+  return CreateIsolate(script_uri, main, NULL, NULL, NULL, NULL, kernel_buffer,
+                       kernel_buffer_size, flags, callback_data, error);
 }
 
 DART_EXPORT void Dart_ShutdownIsolate() {
@@ -5153,17 +5154,6 @@
     lib.SetLoadError(Object::null_instance());
   }
 }
-
-static Dart_Handle LoadKernelProgram(Thread* T,
-                                     const String& url,
-                                     void* kernel) {
-  // NOTE: Now the VM owns the [kernel_program] memory!
-  // We will promptly delete it when done.
-  kernel::Program* program = reinterpret_cast<kernel::Program*>(kernel);
-  const Object& tmp = kernel::KernelLoader::LoadEntireProgram(program);
-  delete program;
-  return Api::NewHandle(T, tmp.raw());
-}
 #endif  // !defined(DART_PRECOMPILED_RUNTIME)
 
 DART_EXPORT Dart_Handle Dart_LoadScript(Dart_Handle url,
@@ -5207,27 +5197,8 @@
 
   Dart_Handle result;
   if (I->use_dart_frontend()) {
-    // TODO(kernel): Fix callers to use Dart_LoadScriptFromKernel.
-    if ((source == Api::Null()) || (source == NULL)) {
-      RETURN_NULL_ERROR(source);
-    }
-    void* kernel_pgm = reinterpret_cast<void*>(source);
-    result = LoadKernelProgram(T, resolved_url_str, kernel_pgm);
-    if (::Dart_IsError(result)) {
-      return result;
-    }
-    library ^= Library::LookupLibrary(T, resolved_url_str);
-    if (library.IsNull()) {
-      // If the URL string does not match, use the library object
-      // returned by the kernel loader.
-      library ^= Api::UnwrapHandle(result);
-    }
-    if (library.IsNull()) {
-      return Api::NewError("%s: Unable to load script '%s' correctly.",
-                           CURRENT_FUNC, resolved_url_str.ToCString());
-    }
-    I->object_store()->set_root_library(library);
-    return Api::NewHandle(T, library.raw());
+    return Api::NewError("%s: Should not be called with using Dart frontend",
+                         CURRENT_FUNC);
   }
 
   const String& source_str = Api::UnwrapStringHandle(Z, source);
@@ -5319,20 +5290,6 @@
 #endif  // defined(DART_PRECOMPILED_RUNTIME)
 }
 
-DART_EXPORT void* Dart_ReadKernelBinary(const uint8_t* buffer,
-                                        intptr_t buffer_len,
-                                        Dart_ReleaseBufferCallback callback) {
-#if defined(DART_PRECOMPILED_RUNTIME)
-  UNREACHABLE();
-  return NULL;
-#else
-  kernel::Program* program =
-      kernel::Program::ReadFromBuffer(buffer, buffer_len);
-  program->set_release_buffer_callback(callback);
-  return program;
-#endif
-}
-
 DART_EXPORT Dart_Handle Dart_LoadScriptFromKernel(const uint8_t* buffer,
                                                   intptr_t buffer_size) {
 #if defined(DART_PRECOMPILED_RUNTIME)
@@ -5360,7 +5317,7 @@
   if (tmp.IsError()) {
     return Api::NewHandle(T, tmp.raw());
   }
-  // TODO(kernel): Setting root library based on whether it has 'main' or not
+  // TODO(32618): Setting root library based on whether it has 'main' or not
   // is not correct because main can be in the exported namespace of a library
   // or it could be a getter.
   if (tmp.IsNull()) {
@@ -5576,13 +5533,8 @@
   }
   Dart_Handle result;
   if (I->use_dart_frontend()) {
-    // TODO(kernel): Fix callers to use Dart_LoadLibraryFromKernel.
-    void* kernel_pgm = reinterpret_cast<void*>(source);
-    result = LoadKernelProgram(T, url_str, kernel_pgm);
-    if (::Dart_IsError(result)) {
-      return result;
-    }
-    return Api::NewHandle(T, Library::LookupLibrary(T, url_str));
+    return Api::NewError("%s: Should not be called with using Dart frontend",
+                         CURRENT_FUNC);
   }
   if (::Dart_IsNull(resolved_url)) {
     resolved_url = url;
diff --git a/runtime/vm/dart_api_impl_test.cc b/runtime/vm/dart_api_impl_test.cc
index 5370e37..52bd15c 100644
--- a/runtime/vm/dart_api_impl_test.cc
+++ b/runtime/vm/dart_api_impl_test.cc
@@ -3394,21 +3394,20 @@
 static Dart_Handle LoadScript(const char* url_str, const char* source) {
   Dart_Handle url = NewString(url_str);
   Dart_Handle result;
-  Dart_Handle script;
   if (!FLAG_use_dart_frontend) {
     result = Dart_SetLibraryTagHandler(TestCase::library_handler);
     EXPECT_VALID(result);
-    script = NewString(source);
+    return Dart_LoadScript(url, Dart_Null(), NewString(source), 0, 0);
   } else {
-    void* kernel_pgm = NULL;
-    char* error =
-        TestCase::CompileTestScriptWithDFE(url_str, source, &kernel_pgm);
+    const uint8_t* kernel_buffer = NULL;
+    intptr_t kernel_buffer_size = 0;
+    char* error = TestCase::CompileTestScriptWithDFE(
+        url_str, source, &kernel_buffer, &kernel_buffer_size);
     if (error != NULL) {
       return Dart_NewApiError(error);
     }
-    script = reinterpret_cast<Dart_Handle>(kernel_pgm);
+    return Dart_LoadScriptFromKernel(kernel_buffer, kernel_buffer_size);
   }
-  return Dart_LoadScript(url, Dart_Null(), script, 0, 0);
 }
 
 VM_UNIT_TEST_CASE(DartAPI_IsolateSetCheckedMode) {
@@ -7177,6 +7176,12 @@
 
 static int64_t add_result = 0;
 static void IsolateShutdownRunDartCodeTestCallback(void* callback_data) {
+  Dart_Isolate isolate = Dart_CurrentIsolate();
+  if (Dart_IsKernelIsolate(isolate) || Dart_IsServiceIsolate(isolate)) {
+    return;
+  } else {
+    ASSERT(add_result == 0);
+  }
   Dart_EnterScope();
   Dart_Handle lib = Dart_RootLibrary();
   EXPECT_VALID(lib);
@@ -7210,12 +7215,10 @@
 
   {
     Dart_EnterScope();
-    Dart_Handle url = NewString(TestCase::url());
-    Dart_Handle source = NewString(kScriptChars);
+    Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL);
+    EXPECT_VALID(lib);
     Dart_Handle result = Dart_SetLibraryTagHandler(TestCase::library_handler);
     EXPECT_VALID(result);
-    Dart_Handle lib = Dart_LoadScript(url, Dart_Null(), source, 0, 0);
-    EXPECT_VALID(lib);
     result = Dart_FinalizeLoading(false);
     EXPECT_VALID(result);
     result = Dart_Invoke(lib, NewString("main"), 0, NULL);
diff --git a/runtime/vm/debugger.cc b/runtime/vm/debugger.cc
index 85adc30..559b954 100644
--- a/runtime/vm/debugger.cc
+++ b/runtime/vm/debugger.cc
@@ -1266,6 +1266,8 @@
                                      const GrowableObjectArray& param_names,
                                      const GrowableObjectArray& param_values) {
   GetDescIndices();
+  bool type_arguments_available = false;
+  TypeArguments& type_arguments = TypeArguments::Handle();
   String& name = String::Handle();
   String& existing_name = String::Handle();
   Object& value = Instance::Handle();
@@ -1273,7 +1275,11 @@
   for (intptr_t i = 0; i < num_variables; i++) {
     TokenPosition ignore;
     VariableAt(i, &name, &ignore, &ignore, &ignore, &value);
-    if (!name.Equals(Symbols::This()) && !IsSyntheticVariableName(name)) {
+    if (name.Equals(Symbols::FunctionTypeArgumentsVar())) {
+      type_arguments_available = true;
+      type_arguments = TypeArguments::RawCast(value.raw());
+    } else if (!name.Equals(Symbols::This()) &&
+               !IsSyntheticVariableName(name)) {
       if (IsPrivateVariableName(name)) {
         name = String::ScrubName(name);
       }
@@ -1295,11 +1301,44 @@
     }
   }
 
+  Array& type_param_names = Array::Handle();
+  if ((function().IsGeneric() || function().HasGenericParent()) &&
+      type_arguments_available) {
+    intptr_t num_vars =
+        function().NumTypeParameters() + function().NumParentTypeParameters();
+    type_param_names = Array::New(num_vars);
+    TypeArguments& type_params = TypeArguments::Handle();
+    TypeParameter& type_param = TypeParameter::Handle();
+    String& name = String::Handle();
+    Function& current = Function::Handle(function().raw());
+    for (intptr_t i = 0; !current.IsNull(); i += current.NumTypeParameters(),
+                  current = current.parent_function()) {
+      type_params = current.type_parameters();
+      for (intptr_t j = 0; j < current.NumTypeParameters(); ++j) {
+        type_param = TypeParameter::RawCast(type_params.TypeAt(j));
+        name = type_param.Name();
+        // Write the names in backwards so they match up with the order of the
+        // types in 'type_arguments'.
+        type_param_names.SetAt(num_vars - (i + j) - 1, name);
+      }
+    }
+    if (type_arguments.IsNull()) {
+      type_arguments = TypeArguments::New(num_vars);
+      for (intptr_t i = 0; i < num_vars; ++i) {
+        type_arguments.SetTypeAt(i, Object::dynamic_type());
+      }
+    }
+    ASSERT(type_arguments.Length() == num_vars);
+  } else {
+    type_param_names = Object::empty_array().raw();
+  }
+
   if (function().is_static()) {
     const Class& cls = Class::Handle(function().Owner());
     return cls.Evaluate(expr,
                         Array::Handle(Array::MakeFixedLength(param_names)),
-                        Array::Handle(Array::MakeFixedLength(param_values)));
+                        Array::Handle(Array::MakeFixedLength(param_values)),
+                        type_param_names, type_arguments);
   } else {
     const Object& receiver = Object::Handle(GetReceiver());
     const Class& method_cls = Class::Handle(function().origin());
@@ -1310,7 +1349,8 @@
     const Instance& inst = Instance::Cast(receiver);
     return inst.Evaluate(method_cls, expr,
                          Array::Handle(Array::MakeFixedLength(param_names)),
-                         Array::Handle(Array::MakeFixedLength(param_values)));
+                         Array::Handle(Array::MakeFixedLength(param_values)),
+                         type_param_names, type_arguments);
   }
   UNREACHABLE();
   return Object::null();
diff --git a/runtime/vm/flag_list.h b/runtime/vm/flag_list.h
index ff62dbf..36452aa 100644
--- a/runtime/vm/flag_list.h
+++ b/runtime/vm/flag_list.h
@@ -74,6 +74,8 @@
     "Emit DWARF line number and inlining info"                                 \
     "in dylib snapshots and don't symbolize stack traces.")                    \
   R(enable_asserts, false, bool, false, "Enable assert statements.")           \
+  P(enable_kernel_expression_compilation, bool, true,                          \
+    "Compile expressions with the Kernel front-end.")                          \
   P(enable_mirrors, bool, true,                                                \
     "Disable to make importing dart:mirrors an error.")                        \
   R(enable_type_checks, false, bool, false, "Enable type checks.")             \
diff --git a/runtime/vm/interpreter.cc b/runtime/vm/interpreter.cc
index 725c385..d8b68f7 100644
--- a/runtime/vm/interpreter.cc
+++ b/runtime/vm/interpreter.cc
@@ -563,7 +563,7 @@
   last_setjmp_buffer_ = NULL;
   top_exit_frame_info_ = 0;
 
-  DEBUG_ONLY(icount_ = 0);
+  DEBUG_ONLY(icount_ = 1);  // So that tracing after 0 traces first bytecode.
 }
 
 Interpreter::~Interpreter() {
@@ -586,6 +586,7 @@
 
 #if defined(DEBUG)
 // Returns true if tracing of executed instructions is enabled.
+// May be called on entry, when icount_ has not been incremented yet.
 DART_FORCE_INLINE bool Interpreter::IsTracingExecution() const {
   return icount_ > FLAG_trace_interpreter_after;
 }
@@ -624,6 +625,12 @@
   frame[3] = reinterpret_cast<RawObject*>(base);
   fp_ = frame + kKBCDartFrameFixedSize;
   thread->set_top_exit_frame_info(reinterpret_cast<uword>(fp_));
+#if defined(DEBUG)
+  if (IsTracingExecution()) {
+    THR_Print("Exiting interpreter 0x%" Px " at fp_ 0x%" Px "\n",
+              reinterpret_cast<uword>(this), reinterpret_cast<uword>(fp_));
+  }
+#endif
 }
 
 // TODO(vegorov): Investigate advantages of using
@@ -1119,10 +1126,10 @@
 // Counts and prints executed bytecode instructions (in DEBUG mode).
 #if defined(DEBUG)
 #define TRACE_INSTRUCTION                                                      \
-  icount_++;                                                                   \
   if (IsTracingExecution()) {                                                  \
     TraceInstruction(pc - 1);                                                  \
-  }
+  }                                                                            \
+  icount_++;
 #else
 #define TRACE_INSTRUCTION
 #endif  // defined(DEBUG)
@@ -1240,6 +1247,31 @@
 // Corner case: handler PC can be a fake marker that marks entry frame, which
 // means exception was not handled in the Dart code. In this case we return
 // caught exception from Interpreter::Call.
+#if defined(DEBUG)
+
+#define HANDLE_EXCEPTION                                                       \
+  do {                                                                         \
+    FP = reinterpret_cast<RawObject**>(fp_);                                   \
+    pc = reinterpret_cast<uint32_t*>(pc_);                                     \
+    if ((reinterpret_cast<uword>(pc) & 2) != 0) { /* Entry frame? */           \
+      fp_ = reinterpret_cast<RawObject**>(fp_[0]);                             \
+      thread->set_top_exit_frame_info(reinterpret_cast<uword>(fp_));           \
+      thread->set_top_resource(top_resource);                                  \
+      thread->set_vm_tag(vm_tag);                                              \
+      if (IsTracingExecution()) {                                              \
+        THR_Print("Returning exception from interpreter 0x%" Px                \
+                  " at fp_ 0x%" Px "\n",                                       \
+                  reinterpret_cast<uword>(this),                               \
+                  reinterpret_cast<uword>(fp_));                               \
+      }                                                                        \
+      return special_[kExceptionSpecialIndex];                                 \
+    }                                                                          \
+    pp_ = InterpreterHelpers::FrameCode(FP)->ptr()->object_pool_;              \
+    goto DispatchAfterException;                                               \
+  } while (0)
+
+#else  // !defined(DEBUG)
+
 #define HANDLE_EXCEPTION                                                       \
   do {                                                                         \
     FP = reinterpret_cast<RawObject**>(fp_);                                   \
@@ -1255,6 +1287,8 @@
     goto DispatchAfterException;                                               \
   } while (0)
 
+#endif  // !defined(DEBUG)
+
 #define HANDLE_RETURN                                                          \
   do {                                                                         \
     pp_ = InterpreterHelpers::FrameCode(FP)->ptr()->object_pool_;              \
@@ -1352,9 +1386,17 @@
   uint32_t op;  // Currently executing op.
   uint16_t rA;  // A component of the currently executing op.
 
-  if (fp_ == NULL) {
+  bool reentering = fp_ != NULL;
+  if (!reentering) {
     fp_ = reinterpret_cast<RawObject**>(stack_);
   }
+#if defined(DEBUG)
+  if (IsTracingExecution()) {
+    THR_Print("%s interpreter 0x%" Px " at fp_ 0x%" Px "\n",
+              reentering ? "Re-entering" : "Entering",
+              reinterpret_cast<uword>(this), reinterpret_cast<uword>(fp_));
+  }
+#endif
 
   // Save current VM tag and mark thread as executing Dart code.
   const uword vm_tag = thread->vm_tag();
@@ -1440,9 +1482,122 @@
 
   {
     BYTECODE(EntryOptional, A_B_C);
-    // TODO(regis): Recover deleted code.
-    // See https://dart-review.googlesource.com/c/sdk/+/25320
-    UNIMPLEMENTED();
+    const uint16_t num_fixed_params = rA;
+    const uint16_t num_opt_pos_params = rB;
+    const uint16_t num_opt_named_params = rC;
+    const intptr_t min_num_pos_args = num_fixed_params;
+    const intptr_t max_num_pos_args = num_fixed_params + num_opt_pos_params;
+
+    // Decode arguments descriptor.
+    const intptr_t arg_count = InterpreterHelpers::ArgDescArgCount(argdesc_);
+    const intptr_t pos_count = InterpreterHelpers::ArgDescPosCount(argdesc_);
+    const intptr_t named_count = (arg_count - pos_count);
+
+    // Check that got the right number of positional parameters.
+    if ((min_num_pos_args > pos_count) || (pos_count > max_num_pos_args)) {
+      goto ClosureNoSuchMethod;
+    }
+
+    // Copy all passed position arguments.
+    RawObject** first_arg = FrameArguments(FP, arg_count);
+    memmove(FP, first_arg, pos_count * kWordSize);
+
+    if (num_opt_named_params != 0) {
+      // This is a function with named parameters.
+      // Walk the list of named parameters and their
+      // default values encoded as pairs of LoadConstant instructions that
+      // follows the entry point and find matching values via arguments
+      // descriptor.
+      RawObject** argdesc_data = argdesc_->ptr()->data();
+
+      intptr_t i = named_count - 1;           // argument position
+      intptr_t j = num_opt_named_params - 1;  // parameter position
+      while ((j >= 0) && (i >= 0)) {
+        // Fetch formal parameter information: name, default value, target slot.
+        const uint32_t load_name = pc[2 * j];
+        const uint32_t load_value = pc[2 * j + 1];
+        ASSERT(KernelBytecode::DecodeOpcode(load_name) ==
+               KernelBytecode::kLoadConstant);
+        ASSERT(KernelBytecode::DecodeOpcode(load_value) ==
+               KernelBytecode::kLoadConstant);
+        const uint8_t reg = KernelBytecode::DecodeA(load_name);
+        ASSERT(reg == KernelBytecode::DecodeA(load_value));
+
+        RawString* name = static_cast<RawString*>(
+            LOAD_CONSTANT(KernelBytecode::DecodeD(load_name)));
+        if (name == argdesc_data[ArgumentsDescriptor::name_index(i)]) {
+          // Parameter was passed. Fetch passed value.
+          const intptr_t arg_index = Smi::Value(static_cast<RawSmi*>(
+              argdesc_data[ArgumentsDescriptor::position_index(i)]));
+          FP[reg] = first_arg[arg_index];
+          i--;  // Consume passed argument.
+        } else {
+          // Parameter was not passed. Fetch default value.
+          FP[reg] = LOAD_CONSTANT(KernelBytecode::DecodeD(load_value));
+        }
+        j--;  // Next formal parameter.
+      }
+
+      // If we have unprocessed formal parameters then initialize them all
+      // using default values.
+      while (j >= 0) {
+        const uint32_t load_name = pc[2 * j];
+        const uint32_t load_value = pc[2 * j + 1];
+        ASSERT(KernelBytecode::DecodeOpcode(load_name) ==
+               KernelBytecode::kLoadConstant);
+        ASSERT(KernelBytecode::DecodeOpcode(load_value) ==
+               KernelBytecode::kLoadConstant);
+        const uint8_t reg = KernelBytecode::DecodeA(load_name);
+        ASSERT(reg == KernelBytecode::DecodeA(load_value));
+
+        FP[reg] = LOAD_CONSTANT(KernelBytecode::DecodeD(load_value));
+        j--;
+      }
+
+      // If we have unprocessed passed arguments that means we have mismatch
+      // between formal parameters and concrete arguments. This can only
+      // occur if the current function is a closure.
+      if (i != -1) {
+        goto ClosureNoSuchMethod;
+      }
+
+      // Skip LoadConstant-s encoding information about named parameters.
+      pc += num_opt_named_params * 2;
+
+      // SP points past copied arguments.
+      SP = FP + num_fixed_params + num_opt_named_params - 1;
+    } else {
+      ASSERT(num_opt_pos_params != 0);
+      if (named_count != 0) {
+        // Function can't have both named and optional positional parameters.
+        // This kind of mismatch can only occur if the current function
+        // is a closure.
+        goto ClosureNoSuchMethod;
+      }
+
+      // Process the list of default values encoded as a sequence of
+      // LoadConstant instructions after EntryOpt bytecode.
+      // Execute only those that correspond to parameters that were not passed.
+      for (intptr_t i = pos_count - num_fixed_params; i < num_opt_pos_params;
+           i++) {
+        const uint32_t load_value = pc[i];
+        ASSERT(KernelBytecode::DecodeOpcode(load_value) ==
+               KernelBytecode::kLoadConstant);
+#if defined(DEBUG)
+        const uint8_t reg = KernelBytecode::DecodeA(load_value);
+        ASSERT((num_fixed_params + i) == reg);
+#endif
+        FP[num_fixed_params + i] =
+            LOAD_CONSTANT(KernelBytecode::DecodeD(load_value));
+      }
+
+      // Skip LoadConstant-s encoding default values for optional positional
+      // parameters.
+      pc += num_opt_pos_params;
+
+      // SP points past the last copied parameter.
+      SP = FP + max_num_pos_args - 1;
+    }
 
     DISPATCH();
   }
@@ -2758,6 +2913,12 @@
       thread->set_top_exit_frame_info(reinterpret_cast<uword>(fp_));
       thread->set_top_resource(top_resource);
       thread->set_vm_tag(vm_tag);
+#if defined(DEBUG)
+      if (IsTracingExecution()) {
+        THR_Print("Returning from interpreter 0x%" Px " at fp_ 0x%" Px "\n",
+                  reinterpret_cast<uword>(this), reinterpret_cast<uword>(fp_));
+      }
+#endif
       return result;
     }
 
diff --git a/runtime/vm/isolate.cc b/runtime/vm/isolate.cc
index 10ec3e4..61af137 100644
--- a/runtime/vm/isolate.cc
+++ b/runtime/vm/isolate.cc
@@ -1611,6 +1611,7 @@
     if (!error.IsNull() && !error.IsUnwindError()) {
       OS::PrintErr("in ShutdownIsolate: %s\n", error.ToErrorCString());
     }
+    TransitionVMToNative transition(thread);
     Dart::RunShutdownCallback();
   }
   // Shut the isolate down.
diff --git a/runtime/vm/isolate.h b/runtime/vm/isolate.h
index bf2f38c..28c0795 100644
--- a/runtime/vm/isolate.h
+++ b/runtime/vm/isolate.h
@@ -140,6 +140,7 @@
   V(NONPRODUCT, asserts, EnableAsserts, enable_asserts, FLAG_enable_asserts)   \
   V(NONPRODUCT, reify_generic_functions, ReifyGenericFunctions,                \
     reify_generic_functions, FLAG_reify_generic_functions)                     \
+  V(NONPRODUCT, sync_async, SyncAsync, sync_async, FLAG_sync_async)            \
   V(NONPRODUCT, strong, Strong, strong, FLAG_strong)                           \
   V(NONPRODUCT, error_on_bad_type, ErrorOnBadType, enable_error_on_bad_type,   \
     FLAG_error_on_bad_type)                                                    \
@@ -850,6 +851,7 @@
   V(ErrorOnBadType)                                                            \
   V(ErrorOnBadOverride)                                                        \
   V(ReifyGenericFunctions)                                                     \
+  V(SyncAsync)                                                                 \
   V(Strong)                                                                    \
   V(UseFieldGuards)                                                            \
   V(UseOsr)                                                                    \
diff --git a/runtime/vm/isolate_reload.cc b/runtime/vm/isolate_reload.cc
index 984de86..b8f24ef 100644
--- a/runtime/vm/isolate_reload.cc
+++ b/runtime/vm/isolate_reload.cc
@@ -614,8 +614,8 @@
         return;
       }
       did_kernel_compilation = true;
-      kernel_program.set(
-          kernel::Program::ReadFromBuffer(retval.kernel, retval.kernel_size));
+      kernel_program.set(kernel::Program::ReadFromBuffer(
+          retval.kernel, retval.kernel_size, true));
     }
 
     kernel_program.get()->set_release_buffer_callback(ReleaseFetchedBytes);
@@ -1501,8 +1501,8 @@
     Become::ElementsForwardIdentity(before, after);
   }
 
-  // Rehash constants map for all classes. Constants are hashed by address, and
-  // addresses may change during a become operation.
+  // Rehash constants map for all classes. Constants are hashed by content, and
+  // content may have changed from fields being added or removed.
   {
     TIMELINE_SCOPE(RehashConstants);
     I->RehashConstants();
diff --git a/runtime/vm/isolate_reload_test.cc b/runtime/vm/isolate_reload_test.cc
index 1362438..48f8763 100644
--- a/runtime/vm/isolate_reload_test.cc
+++ b/runtime/vm/isolate_reload_test.cc
@@ -8,6 +8,7 @@
 #include "vm/debugger_api_impl_test.h"
 #include "vm/globals.h"
 #include "vm/isolate.h"
+#include "vm/kernel_loader.h"
 #include "vm/lockers.h"
 #include "vm/thread_barrier.h"
 #include "vm/thread_pool.h"
@@ -123,15 +124,17 @@
     }};
   // clang-format on
   {
-    void* kernel_pgm = NULL;
+    const uint8_t* kernel_buffer = NULL;
+    intptr_t kernel_buffer_size = 0;
     char* error = TestCase::CompileTestScriptWithDFE(
         "file:///test-app",
         sizeof(updated_sourcefiles) / sizeof(Dart_SourceFile),
-        updated_sourcefiles, &kernel_pgm, true /* incrementally */);
+        updated_sourcefiles, &kernel_buffer, &kernel_buffer_size,
+        true /* incrementally */);
     EXPECT(error == NULL);
-    EXPECT_NOTNULL(kernel_pgm);
+    EXPECT_NOTNULL(kernel_buffer);
 
-    lib = TestCase::ReloadTestKernel(kernel_pgm);
+    lib = TestCase::ReloadTestKernel(kernel_buffer, kernel_buffer_size);
     EXPECT_VALID(lib);
   }
   result = Dart_Invoke(lib, NewString("main"), 0, NULL);
@@ -182,15 +185,17 @@
     }};
   // clang-format on
   {
-    void* kernel_pgm = NULL;
+    const uint8_t* kernel_buffer = NULL;
+    intptr_t kernel_buffer_size = 0;
     char* error = TestCase::CompileTestScriptWithDFE(
         "file:///test-app.dart",
         sizeof(updated_sourcefiles) / sizeof(Dart_SourceFile),
-        updated_sourcefiles, &kernel_pgm, true /* incrementally */);
+        updated_sourcefiles, &kernel_buffer, &kernel_buffer_size,
+        true /* incrementally */);
     EXPECT(error == NULL);
-    EXPECT_NOTNULL(kernel_pgm);
+    EXPECT_NOTNULL(kernel_buffer);
 
-    lib = TestCase::ReloadTestKernel(kernel_pgm);
+    lib = TestCase::ReloadTestKernel(kernel_buffer, kernel_buffer_size);
     EXPECT_VALID(lib);
   }
   result = Dart_Invoke(lib, NewString("main"), 0, NULL);
@@ -257,15 +262,17 @@
     }};
   // clang-format on
   {
-    void* kernel_pgm = NULL;
+    const uint8_t* kernel_buffer = NULL;
+    intptr_t kernel_buffer_size = 0;
     char* error = TestCase::CompileTestScriptWithDFE(
         "file:///test-app.dart",
         sizeof(updated_sourcefiles) / sizeof(Dart_SourceFile),
-        updated_sourcefiles, &kernel_pgm, true /* incrementally */);
+        updated_sourcefiles, &kernel_buffer, &kernel_buffer_size,
+        true /* incrementally */);
     EXPECT(error == NULL);
-    EXPECT_NOTNULL(kernel_pgm);
+    EXPECT_NOTNULL(kernel_buffer);
 
-    lib = TestCase::ReloadTestKernel(kernel_pgm);
+    lib = TestCase::ReloadTestKernel(kernel_buffer, kernel_buffer_size);
     EXPECT_VALID(lib);
   }
   result = Dart_Invoke(lib, NewString("main"), 0, NULL);
diff --git a/runtime/vm/kernel.h b/runtime/vm/kernel.h
index 036e3a4..d297dda 100644
--- a/runtime/vm/kernel.h
+++ b/runtime/vm/kernel.h
@@ -55,6 +55,8 @@
 
 enum LogicalOperator { kAnd, kOr };
 
+typedef void (*Dart_ReleaseBufferCallback)(uint8_t* buffer);
+
 class Program {
  public:
   ~Program() {
@@ -77,18 +79,24 @@
    * "sub program" should not try to release the buffer.
    * @return
    */
-  static Program* ReadFrom(Reader* reader, bool take_buffer_ownership = true);
+  static Program* ReadFrom(Reader* reader, bool take_buffer_ownership = false);
 
   static Program* ReadFromFile(const char* script_uri);
   static Program* ReadFromBuffer(const uint8_t* buffer,
                                  intptr_t buffer_length,
-                                 bool take_buffer_ownership = true);
+                                 bool take_buffer_ownership = false);
 
   bool is_single_program() { return single_program_; }
   NameIndex main_method() { return main_method_reference_; }
   intptr_t source_table_offset() const { return source_table_offset_; }
   intptr_t string_table_offset() const { return string_table_offset_; }
   intptr_t name_table_offset() const { return name_table_offset_; }
+  intptr_t metadata_payloads_offset() const {
+    return metadata_payloads_offset_;
+  }
+  intptr_t metadata_mappings_offset() const {
+    return metadata_mappings_offset_;
+  }
   intptr_t constant_table_offset() { return constant_table_offset_; }
   const uint8_t* kernel_data() { return kernel_data_; }
   intptr_t kernel_data_size() { return kernel_data_size_; }
@@ -115,6 +123,12 @@
   // The offset from the start of the binary to the canonical name table.
   intptr_t name_table_offset_;
 
+  // The offset from the start of the binary to the metadata payloads.
+  intptr_t metadata_payloads_offset_;
+
+  // The offset from the start of the binary to the metadata mappings.
+  intptr_t metadata_mappings_offset_;
+
   // The offset from the start of the binary to the start of the string table.
   intptr_t string_table_offset_;
 
@@ -194,6 +208,7 @@
 
   const dart::TypedData& line_starts_data_;
   KernelLineStartsHelper* helper_;
+  Dart_ReleaseBufferCallback release_callback;
 
   DISALLOW_COPY_AND_ASSIGN(KernelLineStartsReader);
 };
diff --git a/runtime/vm/kernel_binary.cc b/runtime/vm/kernel_binary.cc
index a2fe779..9b97137 100644
--- a/runtime/vm/kernel_binary.cc
+++ b/runtime/vm/kernel_binary.cc
@@ -69,6 +69,8 @@
           SourceTableFieldCountFromFirstLibraryOffset,
       1, 0);
   program->name_table_offset_ = reader->ReadUInt32();
+  program->metadata_payloads_offset_ = reader->ReadUInt32();
+  program->metadata_mappings_offset_ = reader->ReadUInt32();
   program->string_table_offset_ = reader->ReadUInt32();
   program->constant_table_offset_ = reader->ReadUInt32();
 
@@ -90,17 +92,25 @@
         Dart_kKernelTag, Api::Null(),
         Api::NewHandle(thread, String::New(script_uri)));
     if (!Dart_IsError(retval)) {
-      uint64_t data;
-      intptr_t data_len = 0;
       Dart_TypedData_Type data_type;
+      uint8_t* data;
       ASSERT(Dart_IsTypedData(retval));
+
+      uint8_t* kernel_buffer;
+      intptr_t kernel_buffer_size;
       Dart_Handle val = Dart_TypedDataAcquireData(
-          retval, &data_type, reinterpret_cast<void**>(&data), &data_len);
+          retval, &data_type, reinterpret_cast<void**>(&data),
+          &kernel_buffer_size);
       ASSERT(!Dart_IsError(val));
-      ASSERT(data_type == Dart_TypedData_kUint64);
-      ASSERT(data_len == 1);
-      kernel_program = reinterpret_cast<kernel::Program*>(data);
+      ASSERT(data_type == Dart_TypedData_kUint8);
+      kernel_buffer = reinterpret_cast<uint8_t*>(malloc(kernel_buffer_size));
+      memmove(kernel_buffer, data, kernel_buffer_size);
       Dart_TypedDataReleaseData(retval);
+
+      kernel_program =
+          kernel::Program::ReadFromBuffer(kernel_buffer, kernel_buffer_size);
+    } else {
+      THR_Print("tag handler failed: %s\n", Dart_GetError(retval));
     }
   }
   return kernel_program;
diff --git a/runtime/vm/kernel_binary.h b/runtime/vm/kernel_binary.h
index daee540..ba05ff0 100644
--- a/runtime/vm/kernel_binary.h
+++ b/runtime/vm/kernel_binary.h
@@ -16,10 +16,11 @@
 namespace dart {
 namespace kernel {
 
-// Keep in sync with package:kernel/lib/binary/tag.dart.
+// Keep in sync with package:kernel/lib/binary/tag.dart,
+// package:kernel/binary.md.
 
 static const uint32_t kMagicProgramFile = 0x90ABCDEFu;
-static const uint32_t kBinaryFormatVersion = 5;
+static const uint32_t kBinaryFormatVersion = 6;
 
 // Keep in sync with package:kernel/lib/binary/tag.dart
 #define KERNEL_TAG_LIST(V)                                                     \
@@ -156,10 +157,9 @@
 
 static const int SpecializedIntLiteralBias = 3;
 static const int LibraryCountFieldCountFromEnd = 1;
-static const int SourceTableFieldCountFromFirstLibraryOffset = 4;
+static const int SourceTableFieldCountFromFirstLibraryOffset = 6;
 
 static const int HeaderSize = 8;  // 'magic', 'formatVersion'.
-static const int MetadataPayloadOffset = HeaderSize;  // Right after header.
 
 class Reader : public ValueObject {
  public:
diff --git a/runtime/vm/kernel_isolate.cc b/runtime/vm/kernel_isolate.cc
index cf12542..c22b3f5 100644
--- a/runtime/vm/kernel_isolate.cc
+++ b/runtime/vm/kernel_isolate.cc
@@ -52,6 +52,7 @@
 const int KernelIsolate::kUpdateSourcesTag = 1;
 const int KernelIsolate::kAcceptTag = 2;
 const int KernelIsolate::kTrainTag = 3;
+const int KernelIsolate::kCompileExpressionTag = 4;
 
 Dart_IsolateCreateCallback KernelIsolate::create_callback_ = NULL;
 Monitor* KernelIsolate::monitor_ = new Monitor();
@@ -87,6 +88,7 @@
     api_flags.enable_error_on_bad_override = false;
     api_flags.reify_generic_functions = false;
     api_flags.strong = false;
+    api_flags.sync_async = false;
 #if !defined(DART_PRECOMPILER) && !defined(TARGET_ARCH_DBC)
     api_flags.use_field_guards = true;
 #endif
@@ -134,9 +136,6 @@
       OS::Print(DART_KERNEL_ISOLATE_NAME ": ShutdownIsolate\n");
     }
     Isolate* I = reinterpret_cast<Isolate*>(parameter);
-    ASSERT(KernelIsolate::IsKernelIsolate(I));
-    KernelIsolate::SetKernelIsolate(NULL);
-    KernelIsolate::SetLoadPort(ILLEGAL_PORT);
     I->WaitForOutstandingSpawns();
     {
       // Print the error if there is one.  This may execute dart code to
@@ -158,8 +157,14 @@
         OS::PrintErr(DART_KERNEL_ISOLATE_NAME ": Error: %s\n",
                      error.ToErrorCString());
       }
+      TransitionVMToNative transition(T);
       Dart::RunShutdownCallback();
     }
+
+    ASSERT(KernelIsolate::IsKernelIsolate(I));
+    KernelIsolate::SetKernelIsolate(NULL);
+    KernelIsolate::SetLoadPort(ILLEGAL_PORT);
+
     // Shut the isolate down.
     Dart::ShutdownIsolate(I);
     if (FLAG_trace_kernel) {
@@ -341,6 +346,125 @@
   }
 
   Dart_KernelCompilationResult SendAndWaitForResponse(
+      Dart_Port kernel_port,
+      const char* expression,
+      const Array& definitions,
+      const Array& type_definitions,
+      char const* library_uri,
+      char const* klass,
+      bool is_static) {
+    Dart_CObject tag;
+    tag.type = Dart_CObject_kInt32;
+    tag.value.as_int32 = KernelIsolate::kCompileExpressionTag;
+
+    Dart_CObject send_port;
+    send_port.type = Dart_CObject_kSendPort;
+    send_port.value.as_send_port.id = port_;
+    send_port.value.as_send_port.origin_id = ILLEGAL_PORT;
+
+    Dart_CObject expression_object;
+    expression_object.type = Dart_CObject_kString;
+    expression_object.value.as_string = const_cast<char*>(expression);
+
+    Dart_CObject definitions_object;
+    intptr_t num_definitions = definitions.Length();
+    definitions_object.type = Dart_CObject_kArray;
+    definitions_object.value.as_array.length = num_definitions;
+
+    Dart_CObject** definitions_array = new Dart_CObject*[num_definitions];
+    for (intptr_t i = 0; i < num_definitions; ++i) {
+      definitions_array[i] = new Dart_CObject;
+      definitions_array[i]->type = Dart_CObject_kString;
+      definitions_array[i]->value.as_string = const_cast<char*>(
+          String::CheckedHandle(definitions.At(i)).ToCString());
+    }
+    definitions_object.value.as_array.values = definitions_array;
+
+    Dart_CObject type_definitions_object;
+    intptr_t num_type_definitions = type_definitions.Length();
+    type_definitions_object.type = Dart_CObject_kArray;
+    type_definitions_object.value.as_array.length = num_type_definitions;
+
+    Dart_CObject** type_definitions_array =
+        new Dart_CObject*[num_type_definitions];
+    for (intptr_t i = 0; i < num_type_definitions; ++i) {
+      type_definitions_array[i] = new Dart_CObject;
+      type_definitions_array[i]->type = Dart_CObject_kString;
+      type_definitions_array[i]->value.as_string = const_cast<char*>(
+          String::CheckedHandle(type_definitions.At(i)).ToCString());
+    }
+    type_definitions_object.value.as_array.values = type_definitions_array;
+
+    Dart_CObject library_uri_object;
+    library_uri_object.type = Dart_CObject_kString;
+    library_uri_object.value.as_string = const_cast<char*>(library_uri);
+
+    Dart_CObject class_object;
+    if (klass != NULL) {
+      class_object.type = Dart_CObject_kString;
+      class_object.value.as_string = const_cast<char*>(klass);
+    } else {
+      class_object.type = Dart_CObject_kNull;
+    }
+
+    Dart_CObject is_static_object;
+    is_static_object.type = Dart_CObject_kBool;
+    is_static_object.value.as_bool = is_static;
+
+    Isolate* isolate =
+        Thread::Current() != NULL ? Thread::Current()->isolate() : NULL;
+    ASSERT(isolate != NULL);
+    Dart_CObject isolate_id;
+    isolate_id.type = Dart_CObject_kInt64;
+    isolate_id.value.as_int64 =
+        isolate != NULL ? static_cast<int64_t>(isolate->main_port()) : 0;
+
+    Dart_CObject message;
+    message.type = Dart_CObject_kArray;
+    Dart_CObject suppress_warnings;
+    suppress_warnings.type = Dart_CObject_kBool;
+    suppress_warnings.value.as_bool = FLAG_suppress_fe_warnings;
+
+    Dart_CObject dart_sync_async;
+    dart_sync_async.type = Dart_CObject_kBool;
+    dart_sync_async.value.as_bool = isolate->sync_async();
+
+    Dart_CObject* message_arr[] = {&tag,
+                                   &send_port,
+                                   &isolate_id,
+                                   &expression_object,
+                                   &definitions_object,
+                                   &type_definitions_object,
+                                   &library_uri_object,
+                                   &class_object,
+                                   &is_static_object,
+                                   &suppress_warnings,
+                                   &dart_sync_async};
+    message.value.as_array.values = message_arr;
+    message.value.as_array.length = ARRAY_SIZE(message_arr);
+    // Send the message.
+    Dart_PostCObject(kernel_port, &message);
+
+    // Wait for reply to arrive.
+    MonitorLocker ml(monitor_);
+    while (result_.status == Dart_KernelCompilationStatus_Unknown) {
+      ml.Wait();
+    }
+
+    for (intptr_t i = 0; i < num_definitions; ++i) {
+      delete definitions_array[i];
+    }
+    delete[] definitions_array;
+
+    for (intptr_t i = 0; i < num_type_definitions; ++i) {
+      delete type_definitions_array[i];
+    }
+    delete[] type_definitions_array;
+
+    return result_;
+  }
+
+  Dart_KernelCompilationResult SendAndWaitForResponse(
       int request_tag,
       Dart_Port kernel_port,
       const char* script_uri,
@@ -421,7 +545,7 @@
 
     Dart_CObject dart_sync_async;
     dart_sync_async.type = Dart_CObject_kBool;
-    dart_sync_async.value.as_bool = FLAG_sync_async;
+    dart_sync_async.value.as_bool = isolate->sync_async();
 
     Dart_CObject package_config_uri;
     if (package_config != NULL) {
@@ -602,6 +726,27 @@
                                         0, NULL, true, NULL);
 }
 
+Dart_KernelCompilationResult KernelIsolate::CompileExpressionToKernel(
+    const char* expression,
+    const Array& definitions,
+    const Array& type_definitions,
+    const char* library_url,
+    const char* klass,
+    bool is_static) {
+  Dart_Port kernel_port = WaitForKernelPort();
+  if (kernel_port == ILLEGAL_PORT) {
+    Dart_KernelCompilationResult result;
+    result.status = Dart_KernelCompilationStatus_Unknown;
+    result.error = strdup("Error while initializing Kernel isolate");
+    return result;
+  }
+
+  KernelCompilationRequest request;
+  return request.SendAndWaitForResponse(kernel_port, expression, definitions,
+                                        type_definitions, library_url, klass,
+                                        is_static);
+}
+
 Dart_KernelCompilationResult KernelIsolate::UpdateInMemorySources(
     int source_files_count,
     Dart_SourceFile source_files[]) {
diff --git a/runtime/vm/kernel_isolate.h b/runtime/vm/kernel_isolate.h
index f9084cf..2e45b52 100644
--- a/runtime/vm/kernel_isolate.h
+++ b/runtime/vm/kernel_isolate.h
@@ -8,6 +8,7 @@
 #if !defined(DART_PRECOMPILED_RUNTIME)
 
 #include "include/dart_api.h"
+#include "include/dart_native_api.h"
 
 #include "vm/allocation.h"
 #include "vm/dart.h"
@@ -22,6 +23,7 @@
   static const int kUpdateSourcesTag;
   static const int kAcceptTag;
   static const int kTrainTag;
+  static const int kCompileExpressionTag;
 
   static void Run();
 
@@ -46,6 +48,14 @@
       int source_files_count,
       Dart_SourceFile source_files[]);
 
+  static Dart_KernelCompilationResult CompileExpressionToKernel(
+      const char* expression,
+      const Array& definitions,
+      const Array& type_definitions,
+      const char* library_url,
+      const char* klass,
+      bool is_static);
+
  protected:
   static Monitor* monitor_;
   static Dart_IsolateCreateCallback create_callback_;
diff --git a/runtime/vm/kernel_loader.cc b/runtime/vm/kernel_loader.cc
index 6a3358c..abbc676 100644
--- a/runtime/vm/kernel_loader.cc
+++ b/runtime/vm/kernel_loader.cc
@@ -195,7 +195,7 @@
                                         bool process_pending_classes) {
   if (program->is_single_program()) {
     KernelLoader loader(program);
-    return loader.LoadProgram(process_pending_classes);
+    return Object::Handle(loader.LoadProgram(process_pending_classes));
   }
 
   kernel::Reader reader(program->kernel_data(), program->kernel_data_size());
@@ -216,7 +216,7 @@
     Program* subprogram = Program::ReadFrom(&reader, false);
     ASSERT(subprogram->is_single_program());
     KernelLoader loader(subprogram);
-    Object& load_result = loader.LoadProgram(false);
+    Object& load_result = Object::Handle(loader.LoadProgram(false));
     if (load_result.IsError()) return load_result;
 
     if (library.IsNull() && load_result.IsLibrary()) {
@@ -293,27 +293,18 @@
     names.SetUint32(i << 2, reader.ReadUInt());
   }
 
-  // Metadata mappings immediately follow names table.
-  const intptr_t metadata_mappings_start = reader.offset();
-
   // Copy metadata payloads into the VM's heap
-  // TODO(alexmarkov): add more info to program index instead of guessing
-  // the end of metadata payloads by offsets of the libraries.
-  intptr_t metadata_payloads_end = program_->source_table_offset();
-  for (intptr_t i = 0; i < program_->library_count(); ++i) {
-    metadata_payloads_end =
-        Utils::Minimum(metadata_payloads_end, library_offset(i));
-  }
-  ASSERT(metadata_payloads_end >= MetadataPayloadOffset);
+  const intptr_t metadata_payloads_start = program_->metadata_payloads_offset();
   const intptr_t metadata_payloads_size =
-      metadata_payloads_end - MetadataPayloadOffset;
+      program_->metadata_mappings_offset() - metadata_payloads_start;
   TypedData& metadata_payloads =
       TypedData::Handle(Z, TypedData::New(kTypedDataUint8ArrayCid,
                                           metadata_payloads_size, Heap::kOld));
-  reader.CopyDataToVMHeap(metadata_payloads, MetadataPayloadOffset,
+  reader.CopyDataToVMHeap(metadata_payloads, metadata_payloads_start,
                           metadata_payloads_size);
 
   // Copy metadata mappings into the VM's heap
+  const intptr_t metadata_mappings_start = program_->metadata_mappings_offset();
   const intptr_t metadata_mappings_size =
       program_->string_table_offset() - metadata_mappings_start;
   TypedData& metadata_mappings =
@@ -545,7 +536,7 @@
   potential_extension_libraries_ = GrowableObjectArray::null();
 }
 
-Object& KernelLoader::LoadProgram(bool process_pending_classes) {
+RawObject* KernelLoader::LoadProgram(bool process_pending_classes) {
   ASSERT(kernel_program_info_.constants() == Array::null());
 
   if (!program_->is_single_program()) {
@@ -557,15 +548,15 @@
   LongJumpScope jump;
   if (setjmp(*jump.Set()) == 0) {
     const intptr_t length = program_->library_count();
+    Object& last_library = Library::Handle(Z);
     for (intptr_t i = 0; i < length; i++) {
-      LoadLibrary(i);
+      last_library = LoadLibrary(i);
     }
 
     if (process_pending_classes) {
       if (!ClassFinalizer::ProcessPendingClasses()) {
         // Class finalization failed -> sticky error would be set.
-        Error& error = Error::Handle(Z);
-        error = H.thread()->sticky_error();
+        RawError* error = H.thread()->sticky_error();
         H.thread()->clear_sticky_error();
         return error;
       }
@@ -586,19 +577,18 @@
 
     NameIndex main = program_->main_method();
     if (main == -1) {
-      return Library::Handle(Z);
+      return Library::null();
     }
 
     NameIndex main_library = H.EnclosingName(main);
     Library& library = LookupLibrary(main_library);
 
-    return library;
+    return library.raw();
   }
 
   // Either class finalization failed or we caught a compile error.
   // In both cases sticky error would be set.
-  Error& error = Error::Handle(Z);
-  error = thread_->sticky_error();
+  RawError* error = thread_->sticky_error();
   thread_->clear_sticky_error();
   return error;
 }
@@ -683,7 +673,7 @@
   field.set_has_initializer(false);
 }
 
-void KernelLoader::LoadLibrary(intptr_t index) {
+RawLibrary* KernelLoader::LoadLibrary(intptr_t index) {
   if (!program_->is_single_program()) {
     FATAL(
         "Trying to load a concatenated dill file at a time where that is "
@@ -713,15 +703,16 @@
       // snapshot so we skip loading 'dart:vmservice_io'.
       skip_vmservice_library_ = library_helper.canonical_name_;
       ASSERT(H.IsLibrary(skip_vmservice_library_));
-      return;
+      return Library::null();
     }
   }
 
-  Library& library = LookupLibrary(library_helper.canonical_name_);
+  Library& library =
+      Library::Handle(Z, LookupLibrary(library_helper.canonical_name_).raw());
 
   // The Kernel library is external implies that it is already loaded.
   ASSERT(!library_helper.IsExternal() || library.Loaded());
-  if (library.Loaded()) return;
+  if (library.Loaded()) return library.raw();
 
   library_kernel_data_ =
       TypedData::New(kTypedDataUint8ArrayCid, library_size, Heap::kOld);
@@ -846,6 +837,8 @@
   toplevel_class.SetFunctions(Array::Handle(MakeFunctionsArray()));
   classes.Add(toplevel_class, Heap::kOld);
   if (!library.Loaded()) library.SetLoaded();
+
+  return library.raw();
 }
 
 void KernelLoader::LoadLibraryImportsAndExports(Library* library) {
@@ -1304,8 +1297,6 @@
   const String& name = H.DartProcedureName(procedure_helper.canonical_name_);
   bool is_method = in_class && !procedure_helper.IsStatic();
   bool is_abstract = procedure_helper.IsAbstract();
-  bool is_no_such_method_forwarder = procedure_helper.IsNoSuchMethodForwarder();
-
   bool is_external = procedure_helper.IsExternal();
   String* native_name = NULL;
   intptr_t annotation_count;
@@ -1384,10 +1375,9 @@
       Z, Function::New(name, kind,
                        !is_method,  // is_static
                        false,       // is_const
-                       is_abstract && !is_no_such_method_forwarder, is_external,
+                       is_abstract, is_external,
                        native_name != NULL,  // is_native
                        script_class, procedure_helper.position_));
-  function.set_is_no_such_method_forwarder(is_no_such_method_forwarder);
   function.set_end_token_pos(procedure_helper.end_position_);
   functions_.Add(&function);
   function.set_kernel_offset(procedure_offset);
diff --git a/runtime/vm/kernel_loader.h b/runtime/vm/kernel_loader.h
index ed47893..21f4bb2 100644
--- a/runtime/vm/kernel_loader.h
+++ b/runtime/vm/kernel_loader.h
@@ -128,7 +128,7 @@
 
   // Returns the library containing the main procedure, null if there
   // was no main procedure, or a failure object if there was an error.
-  Object& LoadProgram(bool process_pending_classes = true);
+  RawObject* LoadProgram(bool process_pending_classes = true);
 
   // Finds all libraries that have been modified in this incremental
   // version of the kernel program file.
@@ -137,7 +137,7 @@
                                     BitVector* modified_libs,
                                     bool force_reload);
 
-  void LoadLibrary(intptr_t index);
+  RawLibrary* LoadLibrary(intptr_t index);
 
   static void FinishLoading(const Class& klass);
 
diff --git a/runtime/vm/longjump.cc b/runtime/vm/longjump.cc
index e0a3ca7..e41a8c4 100644
--- a/runtime/vm/longjump.cc
+++ b/runtime/vm/longjump.cc
@@ -7,6 +7,7 @@
 #include "include/dart_api.h"
 
 #include "vm/dart_api_impl.h"
+#include "vm/interpreter.h"
 #include "vm/isolate.h"
 #include "vm/object.h"
 #include "vm/object_store.h"
@@ -26,12 +27,22 @@
   // assumes the stack grows from high to low.
   Thread* thread = Thread::Current();
   uword jumpbuf_addr = OSThread::GetCurrentStackPointer();
+
+#if defined(USING_SIMULATOR) && defined(DART_USE_INTERPRETER)
+#error "Simultaneous usage of simulator and interpreter not yet supported."
+#endif  // defined(USING_SIMULATOR) && defined(DART_USE_INTERPRETER)
+
 #if defined(USING_SIMULATOR)
   Simulator* sim = Simulator::Current();
   // When using simulator, only mutator thread should refer to Simulator
   // since there can be only one per isolate.
   uword top_exit_frame_info =
       thread->IsMutatorThread() ? sim->top_exit_frame_info() : 0;
+#elif defined(DART_USE_INTERPRETER)
+  Interpreter* interpreter = Interpreter::Current();
+  ASSERT(interpreter->top_exit_frame_info() == 0);
+  uword top_exit_frame_info = 0;
+  // TODO(regis): Determine if top exit frame is jitted or interpreted.
 #else
   uword top_exit_frame_info = thread->top_exit_frame_info();
 #endif
diff --git a/runtime/vm/native_arguments.h b/runtime/vm/native_arguments.h
index 910e2d6..ea9d33c 100644
--- a/runtime/vm/native_arguments.h
+++ b/runtime/vm/native_arguments.h
@@ -223,7 +223,7 @@
                   RawObject** argv,
                   RawObject** retval)
       : thread_(thread),
-        argc_tag_(ReverseArgOrderBit::update(kReverseArgOrderBit, argc_tag)),
+        argc_tag_(ReverseArgOrderBit::update(true, argc_tag)),
         argv_(argv),
         retval_(retval) {}
 #endif
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index caa190c..c50f3ee 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -34,6 +34,8 @@
 #include "vm/heap.h"
 #include "vm/isolate_reload.h"
 #include "vm/kernel.h"
+#include "vm/kernel_isolate.h"
+#include "vm/kernel_loader.h"
 #include "vm/native_symbol.h"
 #include "vm/object_store.h"
 #include "vm/parser.h"
@@ -1293,12 +1295,14 @@
 // A non-NULL kernel argument indicates (1).  A NULL kernel indicates (2) or
 // (3), depending on whether the VM is compiled with DART_NO_SNAPSHOT defined or
 // not.
-RawError* Object::Init(Isolate* isolate, kernel::Program* kernel_program) {
+RawError* Object::Init(Isolate* isolate,
+                       const uint8_t* kernel_buffer,
+                       intptr_t kernel_buffer_size) {
   Thread* thread = Thread::Current();
   Zone* zone = thread->zone();
   ASSERT(isolate == thread->isolate());
 #if !defined(DART_PRECOMPILED_RUNTIME)
-  const bool is_kernel = (kernel_program != NULL);
+  const bool is_kernel = (kernel_buffer != NULL);
 #endif
   NOT_IN_PRODUCT(TimelineDurationScope tds(thread, Timeline::GetIsolateStream(),
                                            "Object::Init");)
@@ -1813,8 +1817,8 @@
 
     // Finish the initialization by compiling the bootstrap scripts containing
     // the base interfaces and the implementation of the internal classes.
-    const Error& error =
-        Error::Handle(zone, Bootstrap::DoBootstrapping(kernel_program));
+    const Error& error = Error::Handle(
+        zone, Bootstrap::DoBootstrapping(kernel_buffer, kernel_buffer_size));
     if (!error.IsNull()) {
       return error.raw();
     }
@@ -3195,6 +3199,15 @@
   return String::ConcatAll(Array::Handle(Array::MakeFixedLength(src_pieces)));
 }
 
+static RawObject* EvaluateWithDFEHelper(const String& expression,
+                                        const Array& definitions,
+                                        const Array& type_definitions,
+                                        const String& library_url,
+                                        const String& klass,
+                                        bool is_static,
+                                        const Array& arguments,
+                                        const TypeArguments& type_arguments);
+
 RawFunction* Function::EvaluateHelper(const Class& cls,
                                       const String& expr,
                                       const Array& param_names,
@@ -3221,9 +3234,24 @@
   return func.raw();
 }
 
+#if !defined(DART_PRECOMPILED_RUNTIME)
+static void ReleaseFetchedBytes(uint8_t* buffer) {
+  free(buffer);
+}
+#endif
+
 RawObject* Class::Evaluate(const String& expr,
                            const Array& param_names,
                            const Array& param_values) const {
+  return Evaluate(expr, param_names, param_values, Object::empty_array(),
+                  Object::null_type_arguments());
+}
+
+RawObject* Class::Evaluate(const String& expr,
+                           const Array& param_names,
+                           const Array& param_values,
+                           const Array& type_param_names,
+                           const TypeArguments& type_param_values) const {
   ASSERT(Thread::Current()->IsMutatorThread());
   if (id() < kInstanceCid) {
     const Instance& exception = Instance::Handle(
@@ -3232,11 +3260,18 @@
     return UnhandledException::New(exception, stacktrace);
   }
 
-  const Function& eval_func = Function::Handle(
-      Function::EvaluateHelper(*this, expr, param_names, true));
-  const Object& result =
-      Object::Handle(DartEntry::InvokeFunction(eval_func, param_values));
-  return result.raw();
+  if (Library::Handle(library()).kernel_data() == TypedData::null() ||
+      !FLAG_enable_kernel_expression_compilation) {
+    const Function& eval_func = Function::Handle(
+        Function::EvaluateHelper(*this, expr, param_names, true));
+    return DartEntry::InvokeFunction(eval_func, param_values);
+  }
+
+  return EvaluateWithDFEHelper(
+      expr, param_names, type_param_names,
+      String::Handle(Library::Handle(library()).url()),
+      IsTopLevel() ? String::Handle() : String::Handle(UserVisibleName()),
+      !IsTopLevel(), param_values, type_param_values);
 }
 
 // Ensure that top level parsing of the class has been done.
@@ -4637,7 +4672,7 @@
     }
     return false;
   }
-  uword Hash() const { return key_.ComputeCanonicalTableHash(); }
+  uword Hash() const { return key_.CanonicalizeHash(); }
   const Instance& key_;
 
  private:
@@ -4662,7 +4697,7 @@
   static uword Hash(const Object& key) {
     ASSERT(!(key.IsString() || key.IsNumber() || key.IsAbstractType()));
     ASSERT(key.IsInstance());
-    return Instance::Cast(key).ComputeCanonicalTableHash();
+    return Instance::Cast(key).CanonicalizeHash();
   }
   static uword Hash(const CanonicalInstanceKey& key) { return key.Hash(); }
   static RawObject* NewKey(const CanonicalInstanceKey& obj) {
@@ -6067,6 +6102,9 @@
 
 // This field is heavily overloaded:
 //   eval function:           Script expression source
+//   kernel eval function:    Array[0] = Script
+//                            Array[1] = Kernel data
+//                            Array[2] = Kernel offset of enclosing library
 //   signature function:      SignatureData
 //   method extractor:        Function extracted closure function
 //   noSuchMethod dispatcher: Array arguments descriptor
@@ -7057,6 +7095,7 @@
   NOT_IN_PRECOMPILED(result.set_inlining_depth(0));
   NOT_IN_PRECOMPILED(result.set_kernel_offset(0));
   result.set_is_optimizable(is_native ? false : true);
+  result.set_is_background_optimizable(is_native ? false : true);
   result.set_is_inlinable(true);
   result.set_allows_hoisting_check_class(true);
   result.set_allows_bounds_check_generalization(true);
@@ -7539,9 +7578,26 @@
   return PatchClass::Cast(obj).origin_class();
 }
 
+void Function::SetKernelDataAndScript(const Script& script,
+                                      const TypedData& data,
+                                      intptr_t offset) {
+  Array& data_field = Array::Handle(Array::New(3));
+  data_field.SetAt(0, script);
+  data_field.SetAt(1, data);
+  data_field.SetAt(2, Smi::Handle(Smi::New(offset)));
+  set_data(data_field);
+}
+
 RawScript* Function::script() const {
   // NOTE(turnidge): If you update this function, you probably want to
   // update Class::PatchFieldsAndFunctions() at the same time.
+  Object& data = Object::Handle(raw_ptr()->data_);
+  if (data.IsArray()) {
+    Object& script = Object::Handle(Array::Cast(data).At(0));
+    if (script.IsScript()) {
+      return Script::Cast(script).raw();
+    }
+  }
   if (token_pos() == TokenPosition::kMinSource) {
     // Testing for position 0 is an optimization that relies on temporary
     // eval functions having token position 0.
@@ -7566,6 +7622,13 @@
 }
 
 RawTypedData* Function::KernelData() const {
+  Object& data = Object::Handle(raw_ptr()->data_);
+  if (data.IsArray()) {
+    Object& script = Object::Handle(Array::Cast(data).At(0));
+    if (script.IsScript()) {
+      return TypedData::RawCast(Array::Cast(data).At(1));
+    }
+  }
   if (IsClosureFunction()) {
     Function& parent = Function::Handle(parent_function());
     ASSERT(!parent.IsNull());
@@ -7582,6 +7645,13 @@
 }
 
 intptr_t Function::KernelDataProgramOffset() const {
+  Object& data = Object::Handle(raw_ptr()->data_);
+  if (data.IsArray()) {
+    Object& script = Object::Handle(Array::Cast(data).At(0));
+    if (script.IsScript()) {
+      return Smi::Value(Smi::RawCast(Array::Cast(data).At(2)));
+    }
+  }
   if (IsClosureFunction()) {
     Function& parent = Function::Handle(parent_function());
     ASSERT(!parent.IsNull());
@@ -11344,10 +11414,25 @@
 RawObject* Library::Evaluate(const String& expr,
                              const Array& param_names,
                              const Array& param_values) const {
-  // Evaluate the expression as a static function of the toplevel class.
-  Class& top_level_class = Class::Handle(toplevel_class());
-  ASSERT(top_level_class.is_finalized());
-  return top_level_class.Evaluate(expr, param_names, param_values);
+  return Evaluate(expr, param_names, param_values, Array::empty_array(),
+                  TypeArguments::null_type_arguments());
+}
+
+RawObject* Library::Evaluate(const String& expr,
+                             const Array& param_names,
+                             const Array& param_values,
+                             const Array& type_param_names,
+                             const TypeArguments& type_param_values) const {
+  if (kernel_data() == TypedData::null() ||
+      !FLAG_enable_kernel_expression_compilation) {
+    // Evaluate the expression as a static function of the toplevel class.
+    Class& top_level_class = Class::Handle(toplevel_class());
+    ASSERT(top_level_class.is_finalized());
+    return top_level_class.Evaluate(expr, param_names, param_values);
+  }
+  return EvaluateWithDFEHelper(expr, param_names, type_param_names,
+                               String::Handle(url()), String::Handle(), false,
+                               param_values, type_param_values);
 }
 
 void Library::InitNativeWrappersLibrary(Isolate* isolate, bool is_kernel) {
@@ -11404,6 +11489,136 @@
 };
 typedef UnorderedHashMap<LibraryLookupTraits> LibraryLookupMap;
 
+static RawObject* EvaluateWithDFEHelper(const String& expression,
+                                        const Array& definitions,
+                                        const Array& type_definitions,
+                                        const String& library_url,
+                                        const String& klass,
+                                        bool is_static,
+                                        const Array& arguments,
+                                        const TypeArguments& type_arguments) {
+#if defined(DART_PRECOMPILED_RUNTIME)
+  const String& error_str = String::Handle(
+      String::New("Kernel service isolate not available in precompiled mode."));
+  return ApiError::New(error_str);
+#else
+  Isolate* I = Isolate::Current();
+  Thread* T = Thread::Current();
+
+  Dart_KernelCompilationResult compilation_result;
+  {
+    TransitionVMToNative transition(T);
+    compilation_result = KernelIsolate::CompileExpressionToKernel(
+        expression.ToCString(), definitions, type_definitions,
+        library_url.ToCString(), klass.IsNull() ? NULL : klass.ToCString(),
+        is_static);
+  }
+
+  Function& callee = Function::Handle();
+  intptr_t num_cids = I->class_table()->NumCids();
+  intptr_t num_libs =
+      GrowableObjectArray::Handle(I->object_store()->libraries()).Length();
+
+  if (compilation_result.status != Dart_KernelCompilationStatus_Ok) {
+    const String& prefix =
+        String::Handle(String::New("Kernel isolate rejected this request:\n"));
+    const String& error_str = String::Handle(String::Concat(
+        prefix, String::Handle(String::New(compilation_result.error))));
+    free(compilation_result.error);
+    return ApiError::New(error_str);
+  }
+
+  const uint8_t* kernel_file = compilation_result.kernel;
+  intptr_t kernel_length = compilation_result.kernel_size;
+  ASSERT(kernel_file != NULL);
+
+  kernel::Program* kernel_pgm =
+      kernel::Program::ReadFromBuffer(kernel_file, kernel_length, true);
+
+  if (kernel_pgm == NULL) {
+    return ApiError::New(String::Handle(
+        String::New("Kernel isolate returned ill-formed kernel.")));
+  }
+
+  kernel_pgm->set_release_buffer_callback(ReleaseFetchedBytes);
+
+  // Load the program with the debug procedure as a regular, independent
+  // program.
+  kernel::KernelLoader loader(kernel_pgm);
+  loader.LoadProgram();
+  ASSERT(I->class_table()->NumCids() > num_cids &&
+         GrowableObjectArray::Handle(I->object_store()->libraries()).Length() ==
+             num_libs + 1);
+  const String& fake_library_url =
+      String::Handle(String::New("evaluate:source"));
+  const Library& loaded =
+      Library::Handle(Library::LookupLibrary(T, fake_library_url));
+  ASSERT(!loaded.IsNull());
+
+  String& debug_name = String::Handle(
+      String::New(Symbols::Symbol(Symbols::kDebugProcedureNameId)));
+  Class& fake_class = Class::Handle();
+  if (!klass.IsNull()) {
+    fake_class = loaded.LookupClass(String::Handle(String::New(klass)));
+    ASSERT(!fake_class.IsNull());
+    callee = fake_class.LookupFunctionAllowPrivate(debug_name);
+  } else {
+    callee = loaded.LookupFunctionAllowPrivate(debug_name);
+  }
+  ASSERT(!callee.IsNull());
+
+  // Save the loaded library's kernel data to the generic "data" field of the
+  // callee, so it doesn't require access it's parent library during
+  // compilation.
+  callee.SetKernelDataAndScript(Script::Handle(callee.script()),
+                                TypedData::Handle(loaded.kernel_data()),
+                                loaded.kernel_offset());
+
+  // Reparent the callee to the real enclosing class so we can remove the fake
+  // class and library from the object store.
+  const Library& real_library =
+      Library::Handle(Library::LookupLibrary(T, library_url));
+  ASSERT(!real_library.IsNull());
+  Class& real_class = Class::Handle();
+  if (!klass.IsNull()) {
+    real_class = real_library.LookupClass(String::Handle(String::New(klass)));
+  } else {
+    real_class = real_library.toplevel_class();
+  }
+  ASSERT(!real_class.IsNull());
+
+  callee.set_owner(real_class);
+
+  // Unlink the fake library and class from the object store.
+  GrowableObjectArray::Handle(I->object_store()->libraries())
+      .SetLength(num_libs);
+  I->class_table()->SetNumCids(num_cids);
+  if (!fake_class.IsNull()) {
+    fake_class.set_id(kIllegalCid);
+  }
+  LibraryLookupMap libraries_map(I->object_store()->libraries_map());
+  bool removed = libraries_map.Remove(fake_library_url);
+  ASSERT(removed);
+  I->object_store()->set_libraries_map(libraries_map.Release());
+
+  if (type_definitions.Length() == 0) {
+    return DartEntry::InvokeFunction(callee, arguments);
+  }
+
+  intptr_t num_type_args = type_arguments.Length();
+  Array& real_arguments = Array::Handle(Array::New(arguments.Length() + 1));
+  real_arguments.SetAt(0, type_arguments);
+  Object& arg = Object::Handle();
+  for (intptr_t i = 0; i < arguments.Length(); ++i) {
+    arg = arguments.At(i);
+    real_arguments.SetAt(i + 1, arg);
+  }
+  const Array& args_desc = Array::Handle(
+      ArgumentsDescriptor::New(num_type_args, real_arguments.Length()));
+  return DartEntry::InvokeFunction(callee, real_arguments, args_desc);
+#endif
+}
+
 // Returns library with given url in current isolate, or NULL.
 RawLibrary* Library::LookupLibrary(Thread* thread, const String& url) {
   Zone* zone = thread->zone();
@@ -12722,6 +12937,10 @@
   }
   ASSERT(pc_offset >= 0);
   result.SetPcOffset(pc_offset);
+  if (payload_size > 0) {
+    // Ensure leftover bits are deterministic.
+    result.raw()->ptr()->data()[payload_size - 1] = 0;
+  }
   for (intptr_t i = 0; i < length; ++i) {
     result.SetBit(i, bmap->Get(i));
   }
@@ -14625,9 +14844,11 @@
   code.set_compile_timestamp(OS::GetCurrentMonotonicMicros());
   // TODO(regis): Do we need to notify CodeObservers for bytecode too?
   // If so, provide a better name using ToLibNamePrefixedQualifiedCString().
+#ifndef PRODUCT
   CodeObservers::NotifyAll("bytecode", instrs.PayloadStart(),
                            0 /* prologue_offset */, instrs.Size(),
                            false /* optimized */);
+#endif
   {
     NoSafepointScope no_safepoint;
 
@@ -15614,8 +15835,16 @@
                               const String& expr,
                               const Array& param_names,
                               const Array& param_values) const {
-  const Function& eval_func = Function::Handle(
-      Function::EvaluateHelper(method_cls, expr, param_names, false));
+  return Evaluate(method_cls, expr, param_names, param_values,
+                  Object::empty_array(), TypeArguments::null_type_arguments());
+}
+
+RawObject* Instance::Evaluate(const Class& method_cls,
+                              const String& expr,
+                              const Array& param_names,
+                              const Array& param_values,
+                              const Array& type_param_names,
+                              const TypeArguments& type_param_values) const {
   const Array& args = Array::Handle(Array::New(1 + param_values.Length()));
   PassiveObject& param = PassiveObject::Handle();
   args.SetAt(0, *this);
@@ -15623,7 +15852,19 @@
     param = param_values.At(i);
     args.SetAt(i + 1, param);
   }
-  return DartEntry::InvokeFunction(eval_func, args);
+
+  const Library& library = Library::Handle(method_cls.library());
+  if (library.kernel_data() == TypedData::null() ||
+      !FLAG_enable_kernel_expression_compilation) {
+    const Function& eval_func = Function::Handle(
+        Function::EvaluateHelper(method_cls, expr, param_names, false));
+    return DartEntry::InvokeFunction(eval_func, args);
+  }
+  return EvaluateWithDFEHelper(
+      expr, param_names, type_param_names,
+      String::Handle(Library::Handle(method_cls.library()).url()),
+      String::Handle(method_cls.UserVisibleName()), false, args,
+      type_param_values);
 }
 
 RawObject* Instance::HashCode() const {
@@ -15668,20 +15909,22 @@
   return true;
 }
 
-uword Instance::ComputeCanonicalTableHash() const {
-  ASSERT(!IsNull());
+uint32_t Instance::CanonicalizeHash() const {
+  if (IsNull()) {
+    return 2011;
+  }
   NoSafepointScope no_safepoint;
   const intptr_t instance_size = SizeFromClass();
   ASSERT(instance_size != 0);
-  uword hash = instance_size;
+  uint32_t hash = instance_size;
   uword this_addr = reinterpret_cast<uword>(this->raw_ptr());
+  Instance& member = Instance::Handle();
   for (intptr_t offset = Instance::NextFieldOffset(); offset < instance_size;
        offset += kWordSize) {
-    uword value = reinterpret_cast<uword>(
-        *reinterpret_cast<RawObject**>(this_addr + offset));
-    hash = CombineHashes(hash, value);
+    member ^= *reinterpret_cast<RawObject**>(this_addr + offset);
+    hash = CombineHashes(hash, member.CanonicalizeHash());
   }
-  return FinalizeHash(hash, (kBitsPerWord - 1));
+  return FinalizeHash(hash, String::kHashBits);
 }
 
 #if defined(DEBUG)
@@ -19381,6 +19624,10 @@
   return BitwiseEqualsToDouble(Double::Cast(other).value());
 }
 
+uint32_t Double::CanonicalizeHash() const {
+  return Hash64To32(bit_cast<uint64_t>(value()));
+}
+
 RawDouble* Double::New(double d, Heap::Space space) {
   ASSERT(Isolate::Current()->object_store()->double_class() != Class::null());
   Double& result = Double::Handle();
@@ -21782,16 +22029,18 @@
   return true;
 }
 
-uword Array::ComputeCanonicalTableHash() const {
-  ASSERT(!IsNull());
+uint32_t Array::CanonicalizeHash() const {
   NoSafepointScope no_safepoint;
   intptr_t len = Length();
-  uword hash = len;
-  uword value = reinterpret_cast<uword>(GetTypeArguments());
-  hash = CombineHashes(hash, value);
+  if (len == 0) {
+    return 1;
+  }
+  uint32_t hash = len;
+  Instance& member = Instance::Handle(GetTypeArguments());
+  hash = CombineHashes(hash, member.CanonicalizeHash());
   for (intptr_t i = 0; i < len; i++) {
-    value = reinterpret_cast<uword>(At(i));
-    hash = CombineHashes(hash, value);
+    member ^= At(i);
+    hash = CombineHashes(hash, member.CanonicalizeHash());
   }
   return FinalizeHash(hash, kHashBits);
 }
@@ -22408,12 +22657,12 @@
          (memcmp(DataAddr(0), other_typed_data.DataAddr(0), len) == 0);
 }
 
-uword TypedData::ComputeCanonicalTableHash() const {
+uint32_t TypedData::CanonicalizeHash() const {
   const intptr_t len = this->LengthInBytes();
   if (len == 0) {
     return 1;
   }
-  uword hash = len;
+  uint32_t hash = len;
   for (intptr_t i = 0; i < len; i++) {
     hash = CombineHashes(len, GetUint8(i));
   }
diff --git a/runtime/vm/object.h b/runtime/vm/object.h
index a422fe0..c7749c5 100644
--- a/runtime/vm/object.h
+++ b/runtime/vm/object.h
@@ -558,7 +558,9 @@
 
   // Initialize a new isolate either from a Kernel IR, from source, or from a
   // snapshot.
-  static RawError* Init(Isolate* isolate, kernel::Program* program);
+  static RawError* Init(Isolate* isolate,
+                        const uint8_t* kernel_buffer,
+                        intptr_t kernel_buffer_size);
 
   static void MakeUnusedSpaceTraversable(const Object& obj,
                                          intptr_t original_size,
@@ -1363,14 +1365,19 @@
   // Return true on success, or false and error otherwise.
   bool ApplyPatch(const Class& patch, Error* error) const;
 
-  // Evaluate the given expression as if it appeared in a static
-  // method of this class and return the resulting value, or an
-  // error object if evaluating the expression fails. The method has
-  // the formal parameters given in param_names, and is invoked with
-  // the argument values given in param_values.
+  // Evaluate the given expression as if it appeared in a static method of this
+  // class and return the resulting value, or an error object if evaluating the
+  // expression fails. The method has the formal (type) parameters given in
+  // (type_)param_names, and is invoked with the (type)argument values given in
+  // (type_)param_values.
   RawObject* Evaluate(const String& expr,
                       const Array& param_names,
                       const Array& param_values) const;
+  RawObject* Evaluate(const String& expr,
+                      const Array& param_names,
+                      const Array& param_values,
+                      const Array& type_param_names,
+                      const TypeArguments& type_param_values) const;
 
   RawError* EnsureIsFinalized(Thread* thread) const;
 
@@ -2136,6 +2143,7 @@
   void ZeroEdgeCounters() const;
 
   RawClass* Owner() const;
+  void set_owner(const Object& value) const;
   RawClass* origin() const;
   RawScript* script() const;
   RawObject* RawOwner() const { return raw_ptr()->owner_; }
@@ -2504,6 +2512,10 @@
     set_optimized_call_site_count(value);
   }
 
+  void SetKernelDataAndScript(const Script& script,
+                              const TypedData& data,
+                              intptr_t offset);
+
   intptr_t KernelDataProgramOffset() const;
 
   RawTypedData* KernelData() const;
@@ -2857,6 +2869,18 @@
   FOR_EACH_FUNCTION_KIND_BIT(DEFINE_ACCESSORS)
 #undef DEFINE_ACCESSORS
 
+  // Indicates whether this function can be optimized on the background compiler
+  // thread.
+  bool is_background_optimizable() const {
+    return RawFunction::BackgroundOptimizableBit::decode(
+        raw_ptr()->packed_fields_);
+  }
+
+  void set_is_background_optimizable(bool value) const {
+    set_packed_fields(RawFunction::BackgroundOptimizableBit::update(
+        value, raw_ptr()->packed_fields_));
+  }
+
  private:
   void set_ic_data_array(const Array& value) const;
   void SetInstructionsSafe(const Code& value) const;
@@ -2904,7 +2928,6 @@
   void set_name(const String& value) const;
   void set_kind(RawFunction::Kind value) const;
   void set_parent_function(const Function& value) const;
-  void set_owner(const Object& value) const;
   RawFunction* implicit_closure_function() const;
   void set_implicit_closure_function(const Function& value) const;
   RawInstance* implicit_static_closure() const;
@@ -3695,15 +3718,21 @@
 
   static RawLibrary* New(const String& url);
 
-  // Evaluate the given expression as if it appeared in an top-level
-  // method of this library and return the resulting value, or an
-  // error object if evaluating the expression fails. The method has
-  // the formal parameters given in param_names, and is invoked with
-  // the argument values given in param_values.
+  // Evaluate the given expression as if it appeared in an top-level method of
+  // this library and return the resulting value, or an error object if
+  // evaluating the expression fails. The method has the formal (type)
+  // parameters given in (type_)param_names, and is invoked with the (type)
+  // argument values given in (type_)param_values.
   RawObject* Evaluate(const String& expr,
                       const Array& param_names,
                       const Array& param_values) const;
 
+  RawObject* Evaluate(const String& expr,
+                      const Array& param_names,
+                      const Array& param_values,
+                      const Array& type_param_names,
+                      const TypeArguments& type_arguments) const;
+
   // Library scope name dictionary.
   //
   // TODO(turnidge): The Lookup functions are not consistent in how
@@ -5487,7 +5516,7 @@
   virtual bool OperatorEquals(const Instance& other) const;
   bool IsIdenticalTo(const Instance& other) const;
   virtual bool CanonicalizeEquals(const Instance& other) const;
-  virtual uword ComputeCanonicalTableHash() const;
+  virtual uint32_t CanonicalizeHash() const;
 
   intptr_t SizeFromClass() const {
 #if defined(DEBUG)
@@ -5561,16 +5590,23 @@
   // (if not NULL) to call.
   bool IsCallable(Function* function) const;
 
-  // Evaluate the given expression as if it appeared in an instance
-  // method of this instance and return the resulting value, or an
-  // error object if evaluating the expression fails. The method has
-  // the formal parameters given in param_names, and is invoked with
-  // the argument values given in param_values.
+  // Evaluate the given expression as if it appeared in an instance method of
+  // this instance and return the resulting value, or an error object if
+  // evaluating the expression fails. The method has the formal (type)
+  // parameters given in (type_)param_names, and is invoked with the (type)
+  // argument values given in (type_)param_values.
   RawObject* Evaluate(const Class& method_cls,
                       const String& expr,
                       const Array& param_names,
                       const Array& param_values) const;
 
+  RawObject* Evaluate(const Class& method_cls,
+                      const String& expr,
+                      const Array& param_names,
+                      const Array& param_values,
+                      const Array& type_param_names,
+                      const TypeArguments& type_param_values) const;
+
   // Equivalent to invoking hashCode on this instance.
   virtual RawObject* HashCode() const;
 
@@ -5878,6 +5914,10 @@
                                  (len * kBytesPerElement));
   }
 
+  virtual uint32_t CanonicalizeHash() const {
+    // Hash() is not stable until finalization is done.
+    return 0;
+  }
   intptr_t Hash() const;
 
   static RawTypeArguments* New(intptr_t len, Heap::Space space = Heap::kOld);
@@ -5957,6 +5997,7 @@
   virtual bool CanonicalizeEquals(const Instance& other) const {
     return Equals(other);
   }
+  virtual uint32_t CanonicalizeHash() const { return Hash(); }
   virtual bool Equals(const Instance& other) const {
     return IsEquivalent(other);
   }
@@ -6733,10 +6774,7 @@
   virtual bool CanonicalizeEquals(const Instance& other) const {
     return Equals(other);
   }
-  virtual uword ComputeCanonicalTableHash() const {
-    UNREACHABLE();
-    return 0;
-  }
+  virtual uint32_t CanonicalizeHash() const { return AsTruncatedUint32Value(); }
   virtual bool Equals(const Instance& other) const;
 
   virtual RawObject* HashCode() const { return raw(); }
@@ -7013,10 +7051,7 @@
   bool BitwiseEqualsToDouble(double value) const;
   virtual bool OperatorEquals(const Instance& other) const;
   virtual bool CanonicalizeEquals(const Instance& other) const;
-  virtual uword ComputeCanonicalTableHash() const {
-    UNREACHABLE();
-    return 0;
-  }
+  virtual uint32_t CanonicalizeHash() const;
 
   static RawDouble* New(double d, Heap::Space space = Heap::kNew);
 
@@ -7166,10 +7201,7 @@
   virtual bool CanonicalizeEquals(const Instance& other) const {
     return Equals(other);
   }
-  virtual uword ComputeCanonicalTableHash() const {
-    UNREACHABLE();
-    return 0;
-  }
+  virtual uint32_t CanonicalizeHash() const { return Hash(); }
   virtual bool Equals(const Instance& other) const;
 
   intptr_t CompareTo(const String& other) const;
@@ -7844,6 +7876,10 @@
     return value ? Bool::True() : Bool::False();
   }
 
+  virtual uint32_t CanonicalizeHash() const {
+    return raw() == True().raw() ? 1231 : 1237;
+  }
+
  private:
   void set_value(bool value) const {
     StoreNonPointer(&raw_ptr()->value_, value);
@@ -7900,7 +7936,7 @@
   }
 
   virtual bool CanonicalizeEquals(const Instance& other) const;
-  virtual uword ComputeCanonicalTableHash() const;
+  virtual uint32_t CanonicalizeHash() const;
 
   static const intptr_t kBytesPerElement = kWordSize;
   static const intptr_t kMaxElements = kSmiMax / kBytesPerElement;
@@ -8074,10 +8110,6 @@
     UNREACHABLE();
     return false;
   }
-  virtual uword ComputeCanonicalTableHash() const {
-    UNREACHABLE();
-    return 0;
-  }
 
   // We don't expect a growable object array to be canonicalized.
   virtual RawInstance* CheckAndCanonicalize(Thread* thread,
@@ -8253,7 +8285,7 @@
   }
 
   virtual bool CanonicalizeEquals(const Instance& other) const;
-  virtual uword ComputeCanonicalTableHash() const;
+  virtual uint32_t CanonicalizeHash() const;
 
 #define TYPED_GETTER_SETTER(name, type)                                        \
   type Get##name(intptr_t byte_offset) const {                                 \
@@ -8778,7 +8810,9 @@
     // None of the fields of a closure are instances.
     return true;
   }
-
+  virtual uint32_t CanonicalizeHash() const {
+    return Function::Handle(function()).Hash();
+  }
   int64_t ComputeHash() const;
 
   static RawClosure* New(const TypeArguments& instantiator_type_arguments,
diff --git a/runtime/vm/object_test.cc b/runtime/vm/object_test.cc
index 4890d04..0fc1385 100644
--- a/runtime/vm/object_test.cc
+++ b/runtime/vm/object_test.cc
@@ -4495,6 +4495,7 @@
   LinkedHashMap& cc_map = LinkedHashMap::Handle(LinkedHashMap::NewDefault());
 
   // 3. Expect them to have identical structure.
+  TransitionNativeToVM transition(thread);
   CheckIdenticalHashStructure(dart_map, cc_map);
 }
 
diff --git a/runtime/vm/os_fuchsia.cc b/runtime/vm/os_fuchsia.cc
index 879df86..727542f 100644
--- a/runtime/vm/os_fuchsia.cc
+++ b/runtime/vm/os_fuchsia.cc
@@ -14,7 +14,7 @@
 #include <zircon/syscalls/object.h>
 #include <zircon/types.h>
 
-#include <fuchsia/cpp/time_zone.h>
+#include <time_zone/cpp/fidl.h>
 
 #include "lib/app/cpp/environment_services.h"
 
diff --git a/runtime/vm/os_linux.cc b/runtime/vm/os_linux.cc
index 6c28bd6..169b5c9 100644
--- a/runtime/vm/os_linux.cc
+++ b/runtime/vm/os_linux.cc
@@ -11,6 +11,7 @@
 #include <fcntl.h>         // NOLINT
 #include <limits.h>        // NOLINT
 #include <malloc.h>        // NOLINT
+#include <sys/mman.h>      // NOLINT
 #include <sys/resource.h>  // NOLINT
 #include <sys/stat.h>      // NOLINT
 #include <sys/syscall.h>   // NOLINT
@@ -38,7 +39,21 @@
             false,
             "Generate events symbols for profiling with perf");
 
+DEFINE_FLAG(bool,
+            generate_perf_jitdump,
+            false,
+            "Generate jitdump file to use with perf-inject");
+
+DECLARE_FLAG(bool, write_protect_code);
+
 // Linux CodeObservers.
+
+// Simple perf support: generate /tmp/perf-<pid>.map file that maps
+// memory ranges to symbol names for JIT generated code. This allows
+// perf-report to resolve addresses falling into JIT generated code.
+// However perf-annotate does not work in this mode because JIT code
+// is transient and does not exist anymore at the moment when you
+// invoke perf-report.
 class PerfCodeObserver : public CodeObserver {
  public:
   PerfCodeObserver() : out_file_(NULL) {
@@ -89,6 +104,197 @@
   DISALLOW_COPY_AND_ASSIGN(PerfCodeObserver);
 };
 
+// Code observer that generates a JITDUMP[1] file that can be interpreted by
+// perf-inject to generate ELF images for JIT generated code objects, which
+// allows both perf-report and perf-annotate to recognize them.
+//
+// Usage:
+//
+//   $ perf record -k mono dart --generate-perf-jitdump benchmark.dart
+//   $ perf inject -j -i perf.data -o perf.data.jitted
+//   $ perf report -i perf.data.jitted
+//
+// [1] see linux/tools/perf/Documentation/jitdump-specification.txt for
+//     JITDUMP binary format.
+class JitDumpCodeObserver : public CodeObserver {
+ public:
+  JitDumpCodeObserver()
+      : out_file_(nullptr), mapped_(nullptr), mapped_size_(0), code_id_(0) {
+    const intptr_t pid = getpid();
+    char* const filename = OS::SCreate(nullptr, "/tmp/jit-%" Pd ".dump", pid);
+    const int fd = open(filename, O_CREAT | O_TRUNC | O_RDWR);
+    free(filename);
+
+    if (fd == -1) {
+      return;
+    }
+
+    // Map JITDUMP file, this mapping will be recorded by perf. This allows
+    // perf-inject to find this file later.
+    const long page_size = sysconf(_SC_PAGESIZE);  // NOLINT(runtime/int)
+    if (page_size == -1) {
+      close(fd);
+      return;
+    }
+
+    mapped_ =
+        mmap(nullptr, page_size, PROT_READ | PROT_EXEC, MAP_PRIVATE, fd, 0);
+    if (mapped_ == nullptr) {
+      close(fd);
+      return;
+    }
+    mapped_size_ = page_size;
+
+    out_file_ = fdopen(fd, "w+");
+    if (out_file_ == nullptr) {
+      close(fd);
+      return;
+    }
+
+    // Buffer the output to avoid high IO overheads - we are going to be
+    // writing all JIT generated code out.
+    setvbuf(out_file_, nullptr, _IOFBF, 2 * MB);
+
+    // Disable code write protection, constant flickering of page attributes
+    // confuses perf.
+    FLAG_write_protect_code = false;
+
+    // Write JITDUMP header.
+    WriteHeader();
+  }
+
+  ~JitDumpCodeObserver() {
+    if (mapped_ != nullptr) {
+      munmap(mapped_, mapped_size_);
+      mapped_ = nullptr;
+    }
+
+    if (out_file_ != nullptr) {
+      fclose(out_file_);
+      out_file_ = nullptr;
+    }
+  }
+
+  virtual bool IsActive() const {
+    return FLAG_generate_perf_jitdump && (out_file_ != nullptr);
+  }
+
+  virtual void Notify(const char* name,
+                      uword base,
+                      uword prologue_offset,
+                      uword size,
+                      bool optimized) {
+    const char* marker = optimized ? "*" : "";
+    char* buffer = OS::SCreate(Thread::Current()->zone(), "%s%s", marker, name);
+    const size_t name_length = strlen(buffer);
+
+    CodeLoadEvent ev;
+    ev.event = BaseEvent::kLoad;
+    ev.size = sizeof(ev) + (name_length + 1) + size;
+    ev.time_stamp = OS::GetCurrentMonotonicTicks();
+    ev.process_id = getpid();
+    ev.thread_id = syscall(SYS_gettid);
+    ev.vma = base;
+    ev.code_address = base;
+    ev.code_size = size;
+
+    {
+      MutexLocker ml(CodeObservers::mutex());
+      ev.code_id = code_id_++;
+
+      WriteFully(&ev, sizeof(ev));
+      WriteFully(buffer, name_length + 1);
+      WriteFully(reinterpret_cast<void*>(base), size);
+    }
+  }
+
+ private:
+  struct Header {
+    const uint32_t magic = 0x4A695444;
+    const uint32_t version = 1;
+    const uint32_t size = sizeof(Header);
+    uint32_t elf_mach_target;
+    const uint32_t reserved = 0xDEADBEEF;
+    uint32_t process_id;
+    uint64_t time_stamp;
+    const uint64_t flags = 0;
+  };
+
+  struct BaseEvent {
+    enum Event {
+      kLoad = 0,
+      kMove = 1,
+      kDebugInfo = 2,
+      kClose = 3,
+      kUnwindingInfo = 4
+    };
+
+    uint32_t event;
+    uint32_t size;
+    uint64_t time_stamp;
+  };
+
+  struct CodeLoadEvent : BaseEvent {
+    uint32_t process_id;
+    uint32_t thread_id;
+    uint64_t vma;
+    uint64_t code_address;
+    uint64_t code_size;
+    uint64_t code_id;
+  };
+
+  // ELF machine architectures
+  // From linux/include/uapi/linux/elf-em.h
+  static const uint32_t EM_386 = 3;
+  static const uint32_t EM_X86_64 = 62;
+  static const uint32_t EM_ARM = 40;
+  static const uint32_t EM_AARCH64 = 183;
+
+  static uint32_t GetElfMachineArchitecture() {
+#if TARGET_ARCH_IA32
+    return EM_386;
+#elif TARGET_ARCH_X64
+    return EM_X86_64;
+#elif TARGET_ARCH_ARM
+    return EM_ARM;
+#elif TARGET_ARCH_ARM64
+    return EM_AARCH64;
+#else
+    UNREACHABLE();
+    return 0;
+#endif
+  }
+
+  void WriteHeader() {
+    Header header;
+    header.elf_mach_target = GetElfMachineArchitecture();
+    header.process_id = getpid();
+    header.time_stamp = OS::GetCurrentTimeMicros();
+    WriteFully(&header, sizeof(header));
+  }
+
+  void WriteFully(void* buffer, size_t size) {
+    const char* ptr = static_cast<char*>(buffer);
+    while (size > 0) {
+      const size_t written = fwrite(ptr, 1, size, out_file_);
+      if (written == 0) {
+        UNREACHABLE();
+        break;
+      }
+      size -= written;
+      ptr += written;
+    }
+  }
+
+  FILE* out_file_;
+  void* mapped_;
+  long mapped_size_;  // NOLINT(runtime/int)
+
+  intptr_t code_id_;
+
+  DISALLOW_COPY_AND_ASSIGN(JitDumpCodeObserver);
+};
+
 #endif  // !PRODUCT
 
 const char* OS::Name() {
@@ -329,6 +535,10 @@
   if (FLAG_generate_perf_events_symbols) {
     CodeObservers::Register(new PerfCodeObserver);
   }
+
+  if (FLAG_generate_perf_jitdump) {
+    CodeObservers::Register(new JitDumpCodeObserver);
+  }
 #endif  // !PRODUCT
 }
 
diff --git a/runtime/vm/pages.cc b/runtime/vm/pages.cc
index ff43451..df7e04a 100644
--- a/runtime/vm/pages.cc
+++ b/runtime/vm/pages.cc
@@ -1075,14 +1075,6 @@
     set_tasks(tasks() - 1);
     ml.NotifyAll();
   }
-
-  if (compact) {
-    // Const object tables are hashed by address: rehash.
-    SafepointOperationScope safepoint(thread);
-    StackZone zone(thread);
-    HANDLESCOPE(thread);
-    thread->isolate()->RehashConstants();
-  }
 }
 
 void PageSpace::BlockingSweep() {
diff --git a/runtime/vm/parser.cc b/runtime/vm/parser.cc
index 29fb803..ac5cd08 100644
--- a/runtime/vm/parser.cc
+++ b/runtime/vm/parser.cc
@@ -7588,7 +7588,7 @@
   const TokenPosition token_pos = ST(closure_body->token_pos());
 
   Function& completer_constructor = Function::ZoneHandle(Z);
-  if (FLAG_sync_async) {
+  if (I->sync_async()) {
     const Class& completer_class = Class::Handle(
         Z, async_lib.LookupClassAllowPrivate(Symbols::_AsyncAwaitCompleter()));
     ASSERT(!completer_class.IsNull());
@@ -7698,7 +7698,7 @@
 
   current_block_->statements->Add(store_async_catch_error_callback);
 
-  if (FLAG_sync_async) {
+  if (I->sync_async()) {
     // Add to AST:
     //   :async_completer.start(:async_op);
     ArgumentListNode* arguments = new (Z) ArgumentListNode(token_pos);
diff --git a/runtime/vm/program_visitor.cc b/runtime/vm/program_visitor.cc
index 14148be..a6400e8 100644
--- a/runtime/vm/program_visitor.cc
+++ b/runtime/vm/program_visitor.cc
@@ -311,9 +311,7 @@
 
   static Value ValueOf(Pair kv) { return kv; }
 
-  static inline intptr_t Hashcode(Key key) {
-    return key->ComputeCanonicalTableHash();
-  }
+  static inline intptr_t Hashcode(Key key) { return key->CanonicalizeHash(); }
 
   static inline bool IsKeyEqual(Pair pair, Key key) {
     return pair->CanonicalizeEquals(*key);
diff --git a/runtime/vm/raw_object.h b/runtime/vm/raw_object.h
index 2e3e2f1..e62baec 100644
--- a/runtime/vm/raw_object.h
+++ b/runtime/vm/raw_object.h
@@ -779,9 +779,10 @@
     switch (kind) {
       case Snapshot::kFull:
       case Snapshot::kScript:
-      case Snapshot::kFullJIT:
       case Snapshot::kFullAOT:
         return reinterpret_cast<RawObject**>(&ptr()->direct_subclasses_);
+      case Snapshot::kFullJIT:
+        return reinterpret_cast<RawObject**>(&ptr()->dependent_code_);
       case Snapshot::kMessage:
       case Snapshot::kNone:
       case Snapshot::kInvalid:
@@ -888,7 +889,7 @@
   };
 
   static constexpr intptr_t kMaxFixedParametersBits = 15;
-  static constexpr intptr_t kMaxOptionalParametersBits = 15;
+  static constexpr intptr_t kMaxOptionalParametersBits = 14;
 
  private:
   // So that the SkippedCodeFunctions::DetachCode can null out the code fields.
@@ -951,8 +952,13 @@
   typedef BitField<uint32_t, bool, PackedIsNoSuchMethodForwarder::kNextBit, 1>
       PackedHasNamedOptionalParameters;
   typedef BitField<uint32_t,
-                   uint16_t,
+                   bool,
                    PackedHasNamedOptionalParameters::kNextBit,
+                   1>
+      BackgroundOptimizableBit;
+  typedef BitField<uint32_t,
+                   uint16_t,
+                   BackgroundOptimizableBit::kNextBit,
                    kMaxFixedParametersBits>
       PackedNumFixedParameters;
   typedef BitField<uint32_t,
diff --git a/runtime/vm/runtime_entry.cc b/runtime/vm/runtime_entry.cc
index aadb840..645f1ea 100644
--- a/runtime/vm/runtime_entry.cc
+++ b/runtime/vm/runtime_entry.cc
@@ -2015,7 +2015,8 @@
       if (FLAG_enable_inlining_annotations) {
         FATAL("Cannot enable inlining annotations and background compilation");
       }
-      if (!BackgroundCompiler::IsDisabled(isolate)) {
+      if (!BackgroundCompiler::IsDisabled(isolate) &&
+          function.is_background_optimizable()) {
         if (FLAG_background_compilation_stop_alot) {
           BackgroundCompiler::Stop(isolate);
         }
@@ -2026,6 +2027,7 @@
         function.SetUsageCounter(INT_MIN);
         BackgroundCompiler::Start(isolate);
         isolate->background_compiler()->CompileOptimized(function);
+
         // Continue in the same code.
         arguments.SetReturn(function);
         return;
diff --git a/runtime/vm/scopes.cc b/runtime/vm/scopes.cc
index e07e393..e38d191 100644
--- a/runtime/vm/scopes.cc
+++ b/runtime/vm/scopes.cc
@@ -268,6 +268,10 @@
     // Keep :async_stack_trace for asynchronous debugging.
     return false;
   }
+  if (str.raw() == Symbols::FunctionTypeArgumentsVar().raw()) {
+    // Keep :function_type_arguments for accessing type variables in debugging.
+    return false;
+  }
   return str.CharAt(0) == ':';
 }
 
@@ -644,7 +648,8 @@
           (variable->name().raw() == Symbols::ExceptionVar().raw()) ||
           (variable->name().raw() == Symbols::SavedTryContextVar().raw()) ||
           (variable->name().raw() == Symbols::ArgDescVar().raw()) ||
-          (variable->name().raw() == Symbols::FunctionTypeArgumentsVar().raw())) {
+          (variable->name().raw() ==
+           Symbols::FunctionTypeArgumentsVar().raw())) {
         // Don't capture those variables because the VM expects them to be on
         // the stack.
         continue;
diff --git a/runtime/vm/service/service.md b/runtime/vm/service/service.md
index d756a0f..bfbbe3f 100644
--- a/runtime/vm/service/service.md
+++ b/runtime/vm/service/service.md
@@ -241,7 +241,7 @@
 
 If the type of a response begins with the _@_ character, then that
 response is a _reference_. If the type name of a response does not
-begin with the _@_ character, it is the an _object_. A reference is
+begin with the _@_ character, it is an _object_. A reference is
 intended to be a subset of an object which provides enough information
 to generate a reasonable looking reference to the object.
 
@@ -355,7 +355,7 @@
 
 ```
 ReturnType methodName(parameterType1 parameterName1,
-                      parameterType2, parameterName2,
+                      parameterType2 parameterName2,
                       ...)
 ```
 
@@ -377,7 +377,7 @@
 _[optional]_ following the parameter name:
 
 ```
-ReturnType methodName(parameterType parameterName [optional)
+ReturnType methodName(parameterType parameterName [optional])
 ```
 
 A description of the return types and parameter types is provided
diff --git a/runtime/vm/service/service_dev.md b/runtime/vm/service/service_dev.md
index 04581b5..a15efee 100644
--- a/runtime/vm/service/service_dev.md
+++ b/runtime/vm/service/service_dev.md
@@ -244,7 +244,7 @@
 
 If the type of a response begins with the _@_ character, then that
 response is a _reference_. If the type name of a response does not
-begin with the _@_ character, it is the an _object_. A reference is
+begin with the _@_ character, it is an _object_. A reference is
 intended to be a subset of an object which provides enough information
 to generate a reasonable looking reference to the object.
 
@@ -358,7 +358,7 @@
 
 ```
 ReturnType methodName(parameterType1 parameterName1,
-                      parameterType2, parameterName2,
+                      parameterType2 parameterName2,
                       ...)
 ```
 
@@ -380,7 +380,7 @@
 _[optional]_ following the parameter name:
 
 ```
-ReturnType methodName(parameterType parameterName [optional)
+ReturnType methodName(parameterType parameterName [optional])
 ```
 
 A description of the return types and parameter types is provided
diff --git a/runtime/vm/service_isolate.cc b/runtime/vm/service_isolate.cc
index 96acbe5..8431c2a 100644
--- a/runtime/vm/service_isolate.cc
+++ b/runtime/vm/service_isolate.cc
@@ -330,8 +330,6 @@
     }
     Isolate* I = reinterpret_cast<Isolate*>(parameter);
     ASSERT(ServiceIsolate::IsServiceIsolate(I));
-    ServiceIsolate::SetServiceIsolate(NULL);
-    ServiceIsolate::SetServicePort(ILLEGAL_PORT);
     I->WaitForOutstandingSpawns();
     {
       // Print the error if there is one.  This may execute dart code to
@@ -351,8 +349,13 @@
       if (!error.IsNull() && !error.IsUnwindError()) {
         OS::PrintErr("vm-service: Error: %s\n", error.ToErrorCString());
       }
+      TransitionVMToNative transition(T);
       Dart::RunShutdownCallback();
     }
+    ASSERT(ServiceIsolate::IsServiceIsolate(I));
+    ServiceIsolate::SetServiceIsolate(NULL);
+    ServiceIsolate::SetServicePort(ILLEGAL_PORT);
+
     // Shut the isolate down.
     Dart::ShutdownIsolate(I);
     if (FLAG_trace_service) {
diff --git a/runtime/vm/symbols.h b/runtime/vm/symbols.h
index 4b3f6bc..576e903 100644
--- a/runtime/vm/symbols.h
+++ b/runtime/vm/symbols.h
@@ -325,6 +325,7 @@
   V(ForwardingCorpse, "ForwardingCorpse")                                      \
   V(InvocationMirror, "_InvocationMirror")                                     \
   V(AllocateInvocationMirror, "_allocateInvocationMirror")                     \
+  V(AllocateInvocationMirrorForClosure, "_allocateInvocationMirrorForClosure") \
   V(toString, "toString")                                                      \
   V(_lookupHandler, "_lookupHandler")                                          \
   V(_handleMessage, "_handleMessage")                                          \
@@ -450,7 +451,8 @@
   V(PrependTypeArguments, "_prependTypeArguments")                             \
   V(DartDeveloperCausalAsyncStacks, "dart.developer.causal_async_stacks")      \
   V(_AsyncStarListenHelper, "_asyncStarListenHelper")                          \
-  V(GrowRegExpStack, "_growRegExpStack")
+  V(GrowRegExpStack, "_growRegExpStack")                                       \
+  V(DebugProcedureName, ":Eval")
 
 // Contains a list of frequently used strings in a canonicalized form. This
 // list is kept in the vm_isolate in order to share the copy across isolates
diff --git a/runtime/vm/unit_test.cc b/runtime/vm/unit_test.cc
index 10795eb..08becf9 100644
--- a/runtime/vm/unit_test.cc
+++ b/runtime/vm/unit_test.cc
@@ -81,8 +81,6 @@
   }
 }
 
-static void NoopRelease(uint8_t* data) {}
-
 Dart_Isolate TestCase::CreateIsolate(const uint8_t* data_buffer,
                                      intptr_t len,
                                      const uint8_t* instr_buffer,
@@ -97,13 +95,8 @@
     isolate = Dart_CreateIsolate(name, NULL, data_buffer, instr_buffer, NULL,
                                  NULL, &api_flags, data, &err);
   } else {
-    kernel::Program* program = reinterpret_cast<kernel::Program*>(
-        Dart_ReadKernelBinary(data_buffer, len, NoopRelease));
-    if (program != NULL) {
-      isolate = Dart_CreateIsolateFromKernel(name, NULL, program, &api_flags,
-                                             data, &err);
-      delete program;
-    }
+    isolate = Dart_CreateIsolateFromKernel(name, NULL, data_buffer, len,
+                                           &api_flags, data, &err);
   }
   if (isolate == NULL) {
     OS::PrintErr("Creation of isolate failed '%s'\n", err);
@@ -237,7 +230,8 @@
 
 char* TestCase::CompileTestScriptWithDFE(const char* url,
                                          const char* source,
-                                         void** kernel_pgm,
+                                         const uint8_t** kernel_buffer,
+                                         intptr_t* kernel_buffer_size,
                                          bool incrementally) {
   // clang-format off
   Dart_SourceFile sourcefiles[] = {
@@ -248,14 +242,12 @@
       "file:///.packages", "untitled:/"
     }};
   // clang-format on
-  return CompileTestScriptWithDFE(url,
-                                  sizeof(sourcefiles) / sizeof(Dart_SourceFile),
-                                  sourcefiles, kernel_pgm, incrementally);
+  return CompileTestScriptWithDFE(
+      url, sizeof(sourcefiles) / sizeof(Dart_SourceFile), sourcefiles,
+      kernel_buffer, kernel_buffer_size, incrementally);
 }
 
-static void ReleaseFetchedBytes(uint8_t* buffer) {
-  free(buffer);
-}
+#if 0
 
 char* TestCase::CompileTestScriptWithDFE(const char* url,
                                          int sourcefiles_count,
@@ -267,7 +259,13 @@
       url, FLAG_strong ? platform_strong_dill : platform_dill,
       FLAG_strong ? platform_strong_dill_size : platform_dill_size,
       sourcefiles_count, sourcefiles, incrementally, NULL);
+  return ValidateCompilationResult(zone, compilation_result, kernel_pgm);
+}
 
+char* TestCase::ValidateCompilationResult(
+    Zone* zone,
+    Dart_KernelCompilationResult compilation_result,
+    void** kernel_pgm) {
   if (compilation_result.status != Dart_KernelCompilationStatus_Ok) {
     char* result =
         OS::SCreate(zone, "Compilation failed %s", compilation_result.error);
@@ -286,6 +284,41 @@
   }
   return NULL;
 }
+#endif
+
+char* TestCase::CompileTestScriptWithDFE(const char* url,
+                                         int sourcefiles_count,
+                                         Dart_SourceFile sourcefiles[],
+                                         const uint8_t** kernel_buffer,
+                                         intptr_t* kernel_buffer_size,
+                                         bool incrementally) {
+  Zone* zone = Thread::Current()->zone();
+  Dart_KernelCompilationResult compilation_result = Dart_CompileSourcesToKernel(
+      url, FLAG_strong ? platform_strong_dill : platform_dill,
+      FLAG_strong ? platform_strong_dill_size : platform_dill_size,
+      sourcefiles_count, sourcefiles, incrementally, NULL);
+  return ValidateCompilationResult(zone, compilation_result, kernel_buffer,
+                                   kernel_buffer_size);
+}
+
+char* TestCase::ValidateCompilationResult(
+    Zone* zone,
+    Dart_KernelCompilationResult compilation_result,
+    const uint8_t** kernel_buffer,
+    intptr_t* kernel_buffer_size) {
+  if (compilation_result.status != Dart_KernelCompilationStatus_Ok) {
+    char* result =
+        OS::SCreate(zone, "Compilation failed %s", compilation_result.error);
+    free(compilation_result.error);
+    return result;
+  }
+  *kernel_buffer = compilation_result.kernel;
+  *kernel_buffer_size = compilation_result.kernel_size;
+  if (kernel_buffer == NULL) {
+    return OS::SCreate(zone, "front end generated a NULL kernel file");
+  }
+  return NULL;
+}
 
 static Dart_Handle LibraryTagHandler(Dart_LibraryTag tag,
                                      Dart_Handle library,
@@ -456,17 +489,25 @@
     const char* prefixed_lib_uri =
         OS::SCreate(Thread::Current()->zone(), "file:///%s", lib_uri);
     Dart_SourceFile sourcefiles[] = {{prefixed_lib_uri, script}};
-    void* kernel_pgm = NULL;
+    const uint8_t* kernel_buffer = NULL;
+    intptr_t kernel_buffer_size = 0;
     int sourcefiles_count = sizeof(sourcefiles) / sizeof(Dart_SourceFile);
     char* error = TestCase::CompileTestScriptWithDFE(
-        sourcefiles[0].uri, sourcefiles_count, sourcefiles, &kernel_pgm, true);
+        sourcefiles[0].uri, sourcefiles_count, sourcefiles, &kernel_buffer,
+        &kernel_buffer_size, true);
     if (error != NULL) {
       return Dart_NewApiError(error);
     }
-    Dart_Handle url = NewString(prefixed_lib_uri);
-    Dart_Handle lib = Dart_LoadLibrary(
-        url, Dart_Null(), reinterpret_cast<Dart_Handle>(kernel_pgm), 0, 0);
+    Dart_Handle lib =
+        Dart_LoadLibraryFromKernel(kernel_buffer, kernel_buffer_size);
     EXPECT_VALID(lib);
+
+    // TODO(32618): Kernel doesn't correctly represent the root library.
+    lib = Dart_LookupLibrary(Dart_NewStringFromCString(sourcefiles[0].uri));
+    DART_CHECK_VALID(lib);
+    Dart_Handle result = Dart_SetRootLibrary(lib);
+    DART_CHECK_VALID(result);
+
     Dart_SetNativeResolver(lib, resolver, NULL);
     return lib;
   } else {
@@ -482,19 +523,27 @@
                                             bool finalize,
                                             bool incrementally) {
   // First script is the main script.
-  Dart_Handle url = NewString(sourcefiles[0].uri);
   Dart_Handle result = Dart_SetLibraryTagHandler(LibraryTagHandler);
   EXPECT_VALID(result);
-  void* kernel_pgm = NULL;
+  const uint8_t* kernel_buffer = NULL;
+  intptr_t kernel_buffer_size = 0;
   char* error = TestCase::CompileTestScriptWithDFE(
-      sourcefiles[0].uri, sourcefiles_count, sourcefiles, &kernel_pgm,
-      incrementally);
+      sourcefiles[0].uri, sourcefiles_count, sourcefiles, &kernel_buffer,
+      &kernel_buffer_size, incrementally);
   if (error != NULL) {
     return Dart_NewApiError(error);
   }
-  Dart_Handle lib = Dart_LoadScript(
-      url, Dart_Null(), reinterpret_cast<Dart_Handle>(kernel_pgm), 0, 0);
+
+  Dart_Handle lib =
+      Dart_LoadLibraryFromKernel(kernel_buffer, kernel_buffer_size);
   DART_CHECK_VALID(lib);
+
+  // BOGUS: Kernel doesn't correctly represent the root library.
+  lib = Dart_LookupLibrary(Dart_NewStringFromCString(sourcefiles[0].uri));
+  DART_CHECK_VALID(lib);
+  result = Dart_SetRootLibrary(lib);
+  DART_CHECK_VALID(result);
+
   result = Dart_SetNativeResolver(lib, resolver, NULL);
   DART_CHECK_VALID(result);
   if (finalize) {
@@ -586,7 +635,8 @@
   return TriggerReload();
 }
 
-Dart_Handle TestCase::ReloadTestKernel(const void* kernel) {
+Dart_Handle TestCase::ReloadTestKernel(const uint8_t* kernel_buffer,
+                                       intptr_t kernel_buffer_size) {
   return TriggerReload();
 }
 
diff --git a/runtime/vm/unit_test.h b/runtime/vm/unit_test.h
index 5aa1d6a..edb8b8e 100644
--- a/runtime/vm/unit_test.h
+++ b/runtime/vm/unit_test.h
@@ -316,12 +316,14 @@
 
   static char* CompileTestScriptWithDFE(const char* url,
                                         const char* source,
-                                        void** kernel_pgm,
+                                        const uint8_t** kernel_buffer,
+                                        intptr_t* kernel_buffer_size,
                                         bool incrementally = true);
   static char* CompileTestScriptWithDFE(const char* url,
                                         int sourcefiles_count,
                                         Dart_SourceFile sourcefiles[],
-                                        void** kernel_pgm,
+                                        const uint8_t** kernel_buffer,
+                                        intptr_t* kernel_buffer_size,
                                         bool incrementally = true);
   static Dart_Handle LoadTestScript(const char* script,
                                     Dart_NativeEntryResolver resolver,
@@ -362,7 +364,8 @@
 
   // Helper function which reloads the current isolate using |script|.
   static Dart_Handle ReloadTestScript(const char* script);
-  static Dart_Handle ReloadTestKernel(const void* kernel);
+  static Dart_Handle ReloadTestKernel(const uint8_t* kernel_buffer,
+                                      intptr_t kernel_buffer_size);
 
   static void AddTestLib(const char* url, const char* source);
   static const char* GetTestLib(const char* url);
@@ -379,6 +382,11 @@
                                     const char* name,
                                     void* data = NULL);
 
+  static char* ValidateCompilationResult(Zone* zone,
+                                         Dart_KernelCompilationResult result,
+                                         const uint8_t** kernel_buffer,
+                                         intptr_t* kernel_buffer_size);
+
   RunEntry* const run_;
 };
 
diff --git a/sdk/BUILD.gn b/sdk/BUILD.gn
index 5a3cf37..62ea806 100644
--- a/sdk/BUILD.gn
+++ b/sdk/BUILD.gn
@@ -46,6 +46,7 @@
 # ........dartdevk.dart.snapshot
 # ........kernel_summary_worker.dart.snapshot
 # ........pub.dart.snapshot
+# ........pub2.dart.snapshot
 #.........resources/
 #...........dartdoc/
 #..............packages
@@ -133,6 +134,10 @@
     "pub",
     "../utils/pub",
   ],
+  [
+    "pub2",
+    "../utils/pub:pub2",
+  ],
 ]
 
 _full_sdk_snapshots = [
@@ -173,6 +178,10 @@
     "../utils/pub",
   ],
   [
+    "pub2",
+    "../utils/pub:pub2",
+  ],
+  [
     "kernel-service",
     "../utils/kernel-service",
   ],
diff --git a/sdk/bin/dartdevc b/sdk/bin/dartdevc
index 5b75ad2..e0c8e7a 100755
--- a/sdk/bin/dartdevc
+++ b/sdk/bin/dartdevc
@@ -45,4 +45,4 @@
 
 DEV_COMPILER="$DART_ROOT/pkg/dev_compiler/bin/dartdevc.dart"
 
-exec "$DART" "--packages=$DART_ROOT/.packages" "${EXTRA_VM_OPTIONS[@]}" "$DEV_COMPILER" "$SDK_ARG" "$@"
+exec "$DART" "--preview-dart-2" "--packages=$DART_ROOT/.packages" "${EXTRA_VM_OPTIONS[@]}" "$DEV_COMPILER" "$SDK_ARG" "$@"
diff --git a/sdk/bin/dartdevc.bat b/sdk/bin/dartdevc.bat
index fec39e4..d636eee 100644
--- a/sdk/bin/dartdevc.bat
+++ b/sdk/bin/dartdevc.bat
@@ -36,7 +36,7 @@
 
 set DEV_COMPILER=%DART_ROOT%\third_party\pkg\dev_compiler\bin\dartdevc.dart
 
-"%DART%" "--packages=%DART_ROOT%\.packages" %EXTRA_VM_OPTIONS% "DEV_COMPILER%" "%SDK_ARG%" %*
+"%DART%" "--preview-dart-2" "--packages=%DART_ROOT%\.packages" %EXTRA_VM_OPTIONS% "DEV_COMPILER%" "%SDK_ARG%" %*
 
 endlocal
 
diff --git a/sdk/bin/dartdevc_sdk b/sdk/bin/dartdevc_sdk
index 7bc98de..aebe28d 100755
--- a/sdk/bin/dartdevc_sdk
+++ b/sdk/bin/dartdevc_sdk
@@ -28,4 +28,4 @@
 
 # We are running the snapshot in the built SDK.
 DART="$BIN_DIR/dart"
-exec "$DART" "$SNAPSHOT" "$SDK_ARG" "$@"
+exec "$DART" "--preview-dart-2" "$SNAPSHOT" "$SDK_ARG" "$@"
diff --git a/sdk/bin/dartdevc_sdk.bat b/sdk/bin/dartdevc_sdk.bat
index 5dbf707..f931a28 100644
--- a/sdk/bin/dartdevc_sdk.bat
+++ b/sdk/bin/dartdevc_sdk.bat
@@ -22,7 +22,7 @@
 
 set SDK_ARG=--dart-sdk=%SDK_DIR%
 
-"%DART%" "%SNAPSHOT%" "%SDK_ARG%" %*
+"%DART%" "--preview-dart-2" "%SNAPSHOT%" "%SDK_ARG%" %*
 
 endlocal
 
diff --git a/sdk/bin/pub_sdk b/sdk/bin/pub_sdk
index f42f609..74a86ca 100755
--- a/sdk/bin/pub_sdk
+++ b/sdk/bin/pub_sdk
@@ -15,13 +15,20 @@
   echo "$file"
 }
 
+function array_contains() {
+  local needle="$1"
+  local element
+  shift
+  for element; do [ "$element" = "$needle" ] && return 0; done
+  return 1
+}
+
 # Unlike $0, $BASH_SOURCE points to the absolute path of this file.
 PROG_NAME="$(follow_links "$BASH_SOURCE")"
 
 # Handle the case where dart-sdk/bin has been symlinked to.
 BIN_DIR="$(cd "${PROG_NAME%/*}" ; pwd -P)"
 
-SNAPSHOT="$BIN_DIR/snapshots/pub.dart.snapshot"
 
 unset VM_OPTIONS
 declare -a VM_OPTIONS
@@ -34,4 +41,10 @@
 
 # Run the pub snapshot.
 DART="$BIN_DIR/dart"
-exec "$DART" "${VM_OPTIONS[@]}" "$SNAPSHOT" "$@"
+if array_contains "--preview-dart-2" "${VM_OPTIONS[@]}"; then
+  SNAPSHOT="$BIN_DIR/snapshots/pub2.dart.snapshot"
+  exec "$DART" "${VM_OPTIONS[@]}" "$SNAPSHOT" "$@"
+else
+  SNAPSHOT="$BIN_DIR/snapshots/pub.dart.snapshot"
+  exec "$DART" "${VM_OPTIONS[@]}" "$SNAPSHOT" "$@"
+fi
diff --git a/sdk/bin/pub_sdk.bat b/sdk/bin/pub_sdk.bat
index 3ea8f13..1c400bd 100644
--- a/sdk/bin/pub_sdk.bat
+++ b/sdk/bin/pub_sdk.bat
@@ -18,13 +18,21 @@
 IF %SDK_DIR:~-1%==\ set SDK_DIR=%SDK_DIR:~0,-1%
 
 set VM_OPTIONS=
+set USING_DART_2=
 
 rem We allow extra vm options to be passed in through an environment variable.
 if not "_%DART_VM_OPTIONS%_" == "__" (
   set VM_OPTIONS=%VM_OPTIONS% %DART_VM_OPTIONS%
+  for %%o in (%DART_VM_OPTIONS%) do (
+    if "%%o" equ "--preview-dart-2" set USING_DART_2=y
+  )
 )
 
-"%BIN_DIR%\dart" %VM_OPTIONS% "%BIN_DIR%\snapshots\pub.dart.snapshot" %*
+if defined USING_DART_2 (
+  "%BIN_DIR%\dart" %VM_OPTIONS% "%BIN_DIR%\snapshots\pub2.dart.snapshot" %*
+) else (
+  "%BIN_DIR%\dart" %VM_OPTIONS% "%BIN_DIR%\snapshots\pub.dart.snapshot" %*
+)
 
 endlocal
 
@@ -42,4 +50,4 @@
 endlocal & set %~2=%result%
 goto :eof
 
-:end
\ No newline at end of file
+:end
diff --git a/sdk/lib/_internal/js_runtime/lib/async_patch.dart b/sdk/lib/_internal/js_runtime/lib/async_patch.dart
index eef525c..5ef35ee 100644
--- a/sdk/lib/_internal/js_runtime/lib/async_patch.dart
+++ b/sdk/lib/_internal/js_runtime/lib/async_patch.dart
@@ -14,8 +14,6 @@
         wrapException,
         unwrapException;
 
-import 'dart:_isolate_helper' show TimerImpl;
-
 import 'dart:_foreign_helper' show JS, JS_GET_FLAG;
 
 import 'dart:_async_await_error_codes' as async_error_codes;
@@ -111,7 +109,7 @@
   static Timer _createTimer(Duration duration, void callback()) {
     int milliseconds = duration.inMilliseconds;
     if (milliseconds < 0) milliseconds = 0;
-    return new TimerImpl(milliseconds, callback);
+    return new _TimerImpl(milliseconds, callback);
   }
 
   @patch
@@ -119,10 +117,81 @@
       Duration duration, void callback(Timer timer)) {
     int milliseconds = duration.inMilliseconds;
     if (milliseconds < 0) milliseconds = 0;
-    return new TimerImpl.periodic(milliseconds, callback);
+    return new _TimerImpl.periodic(milliseconds, callback);
   }
 }
 
+class _TimerImpl implements Timer {
+  final bool _once;
+  int _handle;
+  int _tick = 0;
+
+  _TimerImpl(int milliseconds, void callback()) : _once = true {
+    if (_hasTimer()) {
+      void internalCallback() {
+        _handle = null;
+        this._tick = 1;
+        callback();
+      }
+
+      _handle = JS('int', 'self.setTimeout(#, #)',
+          convertDartClosureToJS(internalCallback, 0), milliseconds);
+    } else {
+      throw new UnsupportedError('`setTimeout()` not found.');
+    }
+  }
+
+  _TimerImpl.periodic(int milliseconds, void callback(Timer timer))
+      : _once = false {
+    if (_hasTimer()) {
+      int start = JS('int', 'Date.now()');
+      _handle = JS(
+          'int',
+          'self.setInterval(#, #)',
+          convertDartClosureToJS(() {
+            int tick = this._tick + 1;
+            if (milliseconds > 0) {
+              int duration = JS('int', 'Date.now()') - start;
+              if (duration > (tick + 1) * milliseconds) {
+                tick = duration ~/ milliseconds;
+              }
+            }
+            this._tick = tick;
+            callback(this);
+          }, 0),
+          milliseconds);
+    } else {
+      throw new UnsupportedError('Periodic timer.');
+    }
+  }
+
+  @override
+  bool get isActive => _handle != null;
+
+  @override
+  int get tick => _tick;
+
+  @override
+  void cancel() {
+    if (_hasTimer()) {
+      if (_handle == null) return;
+      if (_once) {
+        JS('void', 'self.clearTimeout(#)', _handle);
+      } else {
+        JS('void', 'self.clearInterval(#)', _handle);
+      }
+      _handle = null;
+    } else {
+      throw new UnsupportedError('Canceling a timer.');
+    }
+  }
+}
+
+bool _hasTimer() {
+  requiresPreamble();
+  return JS('', 'self.setTimeout') != null;
+}
+
 class _AsyncAwaitCompleter<T> implements Completer<T> {
   final _completer = new Completer<T>.sync();
   bool isSync;
diff --git a/sdk/lib/_internal/js_runtime/lib/collection_patch.dart b/sdk/lib/_internal/js_runtime/lib/collection_patch.dart
index aab714a..c5d1177 100644
--- a/sdk/lib/_internal/js_runtime/lib/collection_patch.dart
+++ b/sdk/lib/_internal/js_runtime/lib/collection_patch.dart
@@ -125,10 +125,10 @@
   V operator [](Object key) {
     if (_isStringKey(key)) {
       var strings = _strings;
-      return (strings == null) ? null : _getTableEntry(strings, key);
+      return JS('', '#', strings == null ? null : _getTableEntry(strings, key));
     } else if (_isNumericKey(key)) {
       var nums = _nums;
-      return (nums == null) ? null : _getTableEntry(nums, key);
+      return JS('', '#', nums == null ? null : _getTableEntry(nums, key));
     } else {
       return _get(key);
     }
@@ -139,7 +139,7 @@
     if (rest == null) return null;
     var bucket = _getBucket(rest, key);
     int index = _findBucketIndex(bucket, key);
-    return (index < 0) ? null : JS('var', '#[#]', bucket, index + 1);
+    return (index < 0) ? null : JS('', '#[#]', bucket, index + 1);
   }
 
   void operator []=(K key, V value) {
diff --git a/sdk/lib/_internal/js_runtime/lib/constant_map.dart b/sdk/lib/_internal/js_runtime/lib/constant_map.dart
index 9f571b9..3d92fd8 100644
--- a/sdk/lib/_internal/js_runtime/lib/constant_map.dart
+++ b/sdk/lib/_internal/js_runtime/lib/constant_map.dart
@@ -125,7 +125,7 @@
 
   V operator [](Object key) {
     if (!containsKey(key)) return null;
-    return _fetch(key);
+    return JS('', '#', _fetch(key));
   }
 
   // [_fetch] is the indexer for keys for which `containsKey(key)` is true.
diff --git a/sdk/lib/_internal/js_runtime/lib/core_patch.dart b/sdk/lib/_internal/js_runtime/lib/core_patch.dart
index 1b0f1aa..c6ffb11 100644
--- a/sdk/lib/_internal/js_runtime/lib/core_patch.dart
+++ b/sdk/lib/_internal/js_runtime/lib/core_patch.dart
@@ -590,10 +590,16 @@
 
 @patch
 class NoSuchMethodError {
+  final Object _receiver;
+  final Symbol _memberName;
+  final List _arguments;
+  final Map<Symbol, dynamic> _namedArguments;
+  final List _existingArgumentNames;
+
   @patch
-  NoSuchMethodError.withInvocation(Object receiver, Invocation invocation) {
-    // UNIMPLEMENTED
-  }
+  NoSuchMethodError.withInvocation(Object receiver, Invocation invocation)
+      : this(receiver, invocation.memberName, invocation.positionalArguments,
+            invocation.namedArguments);
 
   @patch
   NoSuchMethodError(Object receiver, Symbol memberName,
diff --git a/sdk/lib/_internal/js_runtime/lib/foreign_helper.dart b/sdk/lib/_internal/js_runtime/lib/foreign_helper.dart
index 4c6b4ab..a95f0e4 100644
--- a/sdk/lib/_internal/js_runtime/lib/foreign_helper.dart
+++ b/sdk/lib/_internal/js_runtime/lib/foreign_helper.dart
@@ -177,19 +177,6 @@
     arg19]);
 
 /**
- * Returns the isolate in which this code is running.
- */
-external IsolateContext JS_CURRENT_ISOLATE_CONTEXT();
-
-abstract class IsolateContext {
-  int get id;
-
-  /// Holds a (native) JavaScript instance of Isolate, see
-  /// finishIsolateConstructorFunction in emitter.dart.
-  get isolateStatics;
-}
-
-/**
  * Converts the Dart closure [function] into a JavaScript closure.
  *
  * Warning: This is no different from [RAW_DART_FUNCTION_REF] which means care
diff --git a/sdk/lib/_internal/js_runtime/lib/isolate_helper.dart b/sdk/lib/_internal/js_runtime/lib/isolate_helper.dart
deleted file mode 100644
index 01f890b..0000000
--- a/sdk/lib/_internal/js_runtime/lib/isolate_helper.dart
+++ /dev/null
@@ -1,159 +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.
-
-library _isolate_helper;
-
-import 'dart:async';
-import 'dart:isolate';
-
-import 'dart:_js_embedded_names' show CURRENT_SCRIPT;
-
-import 'dart:_js_helper'
-    show convertDartClosureToJS, random64, requiresPreamble;
-
-import 'dart:_foreign_helper' show JS, JS_EMBEDDED_GLOBAL;
-
-import 'dart:_interceptors' show JSExtendableArray;
-
-/// Returns true if we are currently in a worker context.
-bool isWorker() {
-  requiresPreamble();
-  return JS('', '!self.window && !!self.postMessage');
-}
-
-/// The src url for the script tag that loaded this code.
-String thisScript = computeThisScript();
-
-/// The src url for the script tag that loaded this function.
-///
-/// Used to create JavaScript workers and load deferred libraries.
-String computeThisScript() {
-  var currentScript = JS_EMBEDDED_GLOBAL('', CURRENT_SCRIPT);
-  if (currentScript != null) {
-    return JS('String', 'String(#.src)', currentScript);
-  }
-  // A worker has no script tag - so get an url from a stack-trace.
-  if (isWorker()) return _computeThisScriptFromTrace();
-  // An isolate that doesn't support workers, but doesn't have a
-  // currentScript either. This is most likely a Chrome extension.
-  return null;
-}
-
-String _computeThisScriptFromTrace() {
-  var stack = JS('String|Null', 'new Error().stack');
-  if (stack == null) {
-    // According to Internet Explorer documentation, the stack
-    // property is not set until the exception is thrown. The stack
-    // property was not provided until IE10.
-    stack = JS(
-        'String|Null',
-        '(function() {'
-        'try { throw new Error() } catch(e) { return e.stack }'
-        '})()');
-    if (stack == null) throw new UnsupportedError('No stack trace');
-  }
-  var pattern, matches;
-
-  // This pattern matches V8, Chrome, and Internet Explorer stack
-  // traces that look like this:
-  // Error
-  //     at methodName (URI:LINE:COLUMN)
-  pattern = JS('', r'new RegExp("^ *at [^(]*\\((.*):[0-9]*:[0-9]*\\)$", "m")');
-
-  matches = JS('JSExtendableArray|Null', '#.match(#)', stack, pattern);
-  if (matches != null) return JS('String', '#[1]', matches);
-
-  // This pattern matches Firefox stack traces that look like this:
-  // methodName@URI:LINE
-  pattern = JS('', r'new RegExp("^[^@]*@(.*):[0-9]*$", "m")');
-
-  matches = JS('JSExtendableArray|Null', '#.match(#)', stack, pattern);
-  if (matches != null) return JS('String', '#[1]', matches);
-
-  throw new UnsupportedError('Cannot extract URI from "$stack"');
-}
-
-class ReceivePortImpl extends Stream implements ReceivePort {
-  ReceivePortImpl();
-
-  StreamSubscription listen(void onData(var event),
-      {Function onError, void onDone(), bool cancelOnError}) {
-    throw new UnsupportedError("ReceivePort.listen");
-  }
-
-  void close() {}
-
-  SendPort get sendPort => throw new UnsupportedError("ReceivePort.sendPort");
-}
-
-class TimerImpl implements Timer {
-  final bool _once;
-  int _handle;
-  int _tick = 0;
-
-  TimerImpl(int milliseconds, void callback()) : _once = true {
-    if (_hasTimer()) {
-      void internalCallback() {
-        _handle = null;
-        this._tick = 1;
-        callback();
-      }
-
-      _handle = JS('int', 'self.setTimeout(#, #)',
-          convertDartClosureToJS(internalCallback, 0), milliseconds);
-    } else {
-      throw new UnsupportedError('`setTimeout()` not found.');
-    }
-  }
-
-  TimerImpl.periodic(int milliseconds, void callback(Timer timer))
-      : _once = false {
-    if (_hasTimer()) {
-      int start = JS('int', 'Date.now()');
-      _handle = JS(
-          'int',
-          'self.setInterval(#, #)',
-          convertDartClosureToJS(() {
-            int tick = this._tick + 1;
-            if (milliseconds > 0) {
-              int duration = JS('int', 'Date.now()') - start;
-              if (duration > (tick + 1) * milliseconds) {
-                tick = duration ~/ milliseconds;
-              }
-            }
-            this._tick = tick;
-            callback(this);
-          }, 0),
-          milliseconds);
-    } else {
-      throw new UnsupportedError('Periodic timer.');
-    }
-  }
-
-  @override
-  bool get isActive => _handle != null;
-
-  @override
-  int get tick => _tick;
-
-  @override
-  void cancel() {
-    if (_hasTimer()) {
-      if (_handle == null) return;
-      if (_once) {
-        JS('void', 'self.clearTimeout(#)', _handle);
-      } else {
-        JS('void', 'self.clearInterval(#)', _handle);
-      }
-      _handle = null;
-    } else {
-      throw new UnsupportedError('Canceling a timer.');
-    }
-  }
-}
-
-bool _hasTimer() {
-  requiresPreamble();
-  return JS('', 'self.setTimeout') != null;
-}
diff --git a/sdk/lib/_internal/js_runtime/lib/isolate_patch.dart b/sdk/lib/_internal/js_runtime/lib/isolate_patch.dart
index cdb840b..37e6090 100644
--- a/sdk/lib/_internal/js_runtime/lib/isolate_patch.dart
+++ b/sdk/lib/_internal/js_runtime/lib/isolate_patch.dart
@@ -7,7 +7,6 @@
 import "dart:async";
 import 'dart:_foreign_helper' show JS;
 import 'dart:_js_helper' show patch;
-import 'dart:_isolate_helper' show ReceivePortImpl;
 
 @patch
 class Isolate {
@@ -107,7 +106,7 @@
 @patch
 class ReceivePort {
   @patch
-  factory ReceivePort() = ReceivePortImpl;
+  factory ReceivePort() = _ReceivePortImpl;
 
   @patch
   factory ReceivePort.fromRawReceivePort(RawReceivePort rawPort) {
@@ -115,6 +114,17 @@
   }
 }
 
+class _ReceivePortImpl extends Stream implements ReceivePort {
+  StreamSubscription listen(void onData(var event),
+      {Function onError, void onDone(), bool cancelOnError}) {
+    throw new UnsupportedError("ReceivePort.listen");
+  }
+
+  void close() {}
+
+  SendPort get sendPort => throw new UnsupportedError("ReceivePort.sendPort");
+}
+
 @patch
 class RawReceivePort {
   @patch
diff --git a/sdk/lib/_internal/js_runtime/lib/js_helper.dart b/sdk/lib/_internal/js_runtime/lib/js_helper.dart
index 2af7e18..af67c0e 100644
--- a/sdk/lib/_internal/js_runtime/lib/js_helper.dart
+++ b/sdk/lib/_internal/js_runtime/lib/js_helper.dart
@@ -25,8 +25,6 @@
 
 import 'dart:collection';
 
-import 'dart:_isolate_helper' show thisScript, isWorker;
-
 import 'dart:async' show Completer, DeferredLoadException, Future;
 
 import 'dart:_foreign_helper'
@@ -710,26 +708,6 @@
 }
 
 class Primitives {
-  /// Isolate-unique ID for caching [JsClosureMirror.function].
-  /// Note the initial value is used by the first isolate (or if there are no
-  /// isolates), new isolates will update this value to avoid conflicts by
-  /// calling [initializeStatics].
-  static String mirrorFunctionCacheName = '\$cachedFunction';
-
-  /// Isolate-unique ID for caching [JsInstanceMirror._invoke].
-  static String mirrorInvokeCacheName = '\$cachedInvocation';
-
-  /// Called when creating a new isolate (see _IsolateContext constructor in
-  /// isolate_helper.dart).
-  /// Please don't add complicated code to this method, as it will impact
-  /// start-up performance.
-  static void initializeStatics(int id) {
-    // Benchmarking shows significant performance improvements if this is a
-    // fixed value.
-    mirrorFunctionCacheName += '_$id';
-    mirrorInvokeCacheName += '_$id';
-  }
-
   static int objectHashCode(object) {
     int hash = JS('int|Null', r'#.$identityHash', object);
     if (hash == null) {
@@ -3513,11 +3491,6 @@
   throw new CastErrorImplementation(value, self);
 }
 
-checkMalformedType(value, message) {
-  if (value == null) return value;
-  throw new TypeErrorImplementation.fromMessage(message);
-}
-
 futureOrTest(o, futureOrRti) => checkSubtypeOfRuntimeType(o, futureOrRti);
 
 futureOrCheck(o, futureOrRti) => assertSubtypeOfRuntimeType(o, futureOrRti);
@@ -3798,6 +3771,64 @@
   return JS('String', 'String(#.nonce)', currentScript);
 }
 
+/// Returns true if we are currently in a worker context.
+bool _isWorker() {
+  requiresPreamble();
+  return JS('', '!self.window && !!self.postMessage');
+}
+
+/// The src url for the script tag that loaded this code.
+String thisScript = _computeThisScript();
+
+/// The src url for the script tag that loaded this function.
+///
+/// Used to create JavaScript workers and load deferred libraries.
+String _computeThisScript() {
+  var currentScript = JS_EMBEDDED_GLOBAL('', CURRENT_SCRIPT);
+  if (currentScript != null) {
+    return JS('String', 'String(#.src)', currentScript);
+  }
+  // A worker has no script tag - so get an url from a stack-trace.
+  if (_isWorker()) return _computeThisScriptFromTrace();
+  // An isolate that doesn't support workers, but doesn't have a
+  // currentScript either. This is most likely a Chrome extension.
+  return null;
+}
+
+String _computeThisScriptFromTrace() {
+  var stack = JS('String|Null', 'new Error().stack');
+  if (stack == null) {
+    // According to Internet Explorer documentation, the stack
+    // property is not set until the exception is thrown. The stack
+    // property was not provided until IE10.
+    stack = JS(
+        'String|Null',
+        '(function() {'
+        'try { throw new Error() } catch(e) { return e.stack }'
+        '})()');
+    if (stack == null) throw new UnsupportedError('No stack trace');
+  }
+  var pattern, matches;
+
+  // This pattern matches V8, Chrome, and Internet Explorer stack
+  // traces that look like this:
+  // Error
+  //     at methodName (URI:LINE:COLUMN)
+  pattern = JS('', r'new RegExp("^ *at [^(]*\\((.*):[0-9]*:[0-9]*\\)$", "m")');
+
+  matches = JS('JSExtendableArray|Null', '#.match(#)', stack, pattern);
+  if (matches != null) return JS('String', '#[1]', matches);
+
+  // This pattern matches Firefox stack traces that look like this:
+  // methodName@URI:LINE
+  pattern = JS('', r'new RegExp("^[^@]*@(.*):[0-9]*$", "m")');
+
+  matches = JS('JSExtendableArray|Null', '#.match(#)', stack, pattern);
+  if (matches != null) return JS('String', '#[1]', matches);
+
+  throw new UnsupportedError('Cannot extract URI from "$stack"');
+}
+
 Future<Null> _loadHunk(String hunkName) {
   Future<Null> future = _loadingLibraries[hunkName];
   _eventLog.add(' - _loadHunk: $hunkName');
@@ -3843,7 +3874,7 @@
     } catch (error, stackTrace) {
       failure(error, "invoking dartDeferredLibraryLoader hook", stackTrace);
     }
-  } else if (isWorker()) {
+  } else if (_isWorker()) {
     // We are in a web worker. Load the code with an XMLHttpRequest.
     int index = uri.lastIndexOf('/');
     uri = '${uri.substring(0, index + 1)}$hunkName';
diff --git a/sdk/lib/_internal/js_runtime/lib/js_mirrors.dart b/sdk/lib/_internal/js_runtime/lib/js_mirrors.dart
deleted file mode 100644
index 7aebc9e..0000000
--- a/sdk/lib/_internal/js_runtime/lib/js_mirrors.dart
+++ /dev/null
@@ -1,3096 +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.
-
-library dart._js_mirrors;
-
-import 'dart:_js_embedded_names'
-    show
-        JsGetName,
-        ALL_CLASSES,
-        LAZIES,
-        LIBRARIES,
-        STATICS,
-        TYPE_INFORMATION,
-        TYPEDEF_PREDICATE_PROPERTY_NAME,
-        TYPEDEF_TYPE_PROPERTY_NAME;
-
-import 'dart:collection' show UnmodifiableListView, UnmodifiableMapView;
-
-import 'dart:mirrors';
-
-import 'dart:_foreign_helper'
-    show
-        JS,
-        JS_GET_FLAG,
-        JS_GET_STATIC_STATE,
-        JS_CURRENT_ISOLATE_CONTEXT,
-        JS_EMBEDDED_GLOBAL,
-        JS_GET_NAME;
-
-import 'dart:_internal' as _symbol_dev;
-
-import 'dart:_js_helper'
-    show
-        BoundClosure,
-        CachedInvocation,
-        Closure,
-        JSInvocationMirror,
-        JsCache,
-        Primitives,
-        ReflectionInfo,
-        RuntimeError,
-        TearOffClosure,
-        TypeVariable,
-        UnimplementedNoSuchMethodError,
-        createRuntimeType,
-        createUnmangledInvocationMirror,
-        extractFunctionTypeObjectFrom,
-        getMangledTypeName,
-        getMetadata,
-        getType,
-        getRuntimeType,
-        isDartFunctionType,
-        runtimeTypeToString,
-        setRuntimeTypeInfo,
-        throwInvalidReflectionError,
-        TypeImpl,
-        deferredLoadHook;
-
-import 'dart:_interceptors'
-    show Interceptor, JSArray, JSExtendableArray, getInterceptor;
-
-import 'dart:_js_names';
-
-const String METHODS_WITH_OPTIONAL_ARGUMENTS = r'$methodsWithOptionalArguments';
-
-bool hasReflectableProperty(var jsFunction) {
-  return JS('bool', '# in #', JS_GET_NAME(JsGetName.REFLECTABLE), jsFunction);
-}
-
-/// No-op method that is called to inform the compiler that tree-shaking needs
-/// to be disabled.
-disableTreeShaking() => preserveNames();
-
-/// No-op method that is called to inform the compiler that metadata must be
-/// preserved at runtime.
-preserveMetadata() {}
-
-/// No-op method that is called to inform the compiler that the compiler must
-/// preserve the URIs.
-preserveUris() {}
-
-/// No-op method that is called to inform the compiler that the compiler must
-/// preserve the library names.
-preserveLibraryNames() {}
-
-String getName(Symbol symbol) {
-  preserveNames();
-  return n(symbol);
-}
-
-class JsMirrorSystem implements MirrorSystem {
-  UnmodifiableMapView<Uri, LibraryMirror> _cachedLibraries;
-
-  final IsolateMirror isolate = new JsIsolateMirror();
-
-  JsTypeMirror get dynamicType => _dynamicType;
-  JsTypeMirror get voidType => _voidType;
-
-  static final JsTypeMirror _dynamicType =
-      new JsTypeMirror(const Symbol('dynamic'));
-  static final JsTypeMirror _voidType = new JsTypeMirror(const Symbol('void'));
-
-  static Map<String, List<LibraryMirror>> _librariesByName;
-
-  // Will be set to `true` when we have installed a hook on [deferredLoadHook]
-  // to avoid installing it multiple times.
-  static bool _hasInstalledDeferredLoadHook = false;
-
-  static Map<String, List<LibraryMirror>> get librariesByName {
-    if (_librariesByName == null) {
-      _librariesByName = computeLibrariesByName();
-      if (!_hasInstalledDeferredLoadHook) {
-        _hasInstalledDeferredLoadHook = true;
-        // After a deferred import has been loaded new libraries might have
-        // been created, so in the hook we erase _librariesByName, so it will be
-        // recomputed on the next access.
-        deferredLoadHook = () => _librariesByName = null;
-      }
-    }
-    return _librariesByName;
-  }
-
-  Map<Uri, LibraryMirror> get libraries {
-    if (_cachedLibraries != null) return _cachedLibraries;
-    Map<Uri, LibraryMirror> result = new Map();
-    for (List<LibraryMirror> list in librariesByName.values) {
-      for (LibraryMirror library in list) {
-        result[library.uri] = library;
-      }
-    }
-    return _cachedLibraries =
-        new UnmodifiableMapView<Uri, LibraryMirror>(result);
-  }
-
-  LibraryMirror findLibrary(Symbol libraryName) {
-    return librariesByName[n(libraryName)].single;
-  }
-
-  static Map<String, List<LibraryMirror>> computeLibrariesByName() {
-    disableTreeShaking();
-    var result = new Map<String, List<LibraryMirror>>();
-    var jsLibraries = JS_EMBEDDED_GLOBAL('JSExtendableArray|Null', LIBRARIES);
-    if (jsLibraries == null) return result;
-    for (List data in jsLibraries) {
-      String name = data[0];
-      String uriString = data[1];
-      Uri uri;
-      // The Uri has been compiled out. Create a URI from the simple name.
-      if (uriString != '') {
-        uri = Uri.parse(uriString);
-      } else {
-        uri = new Uri(
-            scheme: 'https',
-            host: 'dartlang.org',
-            path: 'dart2js-stripped-uri',
-            queryParameters: {'lib': name});
-      }
-      List<String> classes = data[2];
-      List<String> functions = data[3];
-      var metadataFunction = data[4];
-      var fields = data[5];
-      bool isRoot = data[6];
-      var globalObject = data[7];
-      List metadata = (metadataFunction == null)
-          ? const []
-          : JS('List', '#()', metadataFunction);
-      var libraries = result.putIfAbsent(name, () => <LibraryMirror>[]);
-      libraries.add(new JsLibraryMirror(s(name), uri, classes, functions,
-          metadata, fields, isRoot, globalObject));
-    }
-    return result;
-  }
-}
-
-abstract class JsMirror implements Mirror {
-  const JsMirror();
-
-  String get _prettyName;
-
-  String toString() => _prettyName;
-
-  // TODO(ahe): Remove this method from the API.
-  MirrorSystem get mirrors => currentJsMirrorSystem;
-
-  _getField(JsMirror receiver) {
-    throw new UnimplementedError();
-  }
-
-  void _setField(JsMirror receiver, Object arg) {
-    throw new UnimplementedError();
-  }
-
-  _loadField(String name) {
-    throw new UnimplementedError();
-  }
-
-  void _storeField(String name, Object arg) {
-    throw new UnimplementedError();
-  }
-}
-
-// This class is somewhat silly in the current implementation.
-class JsIsolateMirror extends JsMirror implements IsolateMirror {
-  final _isolateContext = JS_CURRENT_ISOLATE_CONTEXT();
-
-  String get _prettyName => 'Isolate';
-
-  String get debugName {
-    String id = _isolateContext == null ? 'X' : _isolateContext.id.toString();
-    // Using name similar to what the VM uses.
-    return '${n(rootLibrary.simpleName)}-$id';
-  }
-
-  bool get isCurrent => JS_CURRENT_ISOLATE_CONTEXT() == _isolateContext;
-
-  LibraryMirror get rootLibrary {
-    return currentJsMirrorSystem.libraries.values.firstWhere((LibraryMirror l) {
-      JsLibraryMirror library = l;
-      return library._isRoot;
-    });
-  }
-}
-
-abstract class JsDeclarationMirror extends JsMirror
-    implements DeclarationMirror {
-  final Symbol simpleName;
-
-  const JsDeclarationMirror(this.simpleName);
-
-  Symbol get qualifiedName => computeQualifiedName(owner, simpleName);
-
-  bool get isPrivate => n(simpleName).startsWith('_');
-
-  bool get isTopLevel => owner != null && owner is LibraryMirror;
-
-  // TODO(ahe): This should use qualifiedName.
-  String toString() => "$_prettyName on '${n(simpleName)}'";
-
-  List<JsMethodMirror> get _methods {
-    throw new RuntimeError('Should not call _methods');
-  }
-
-  _invoke(List positionalArguments, Map<Symbol, dynamic> namedArguments) {
-    throw new RuntimeError('Should not call _invoke');
-  }
-
-  // TODO(ahe): Implement this.
-  SourceLocation get location => throw new UnimplementedError();
-}
-
-class JsTypeVariableMirror extends JsTypeMirror implements TypeVariableMirror {
-  final DeclarationMirror owner;
-  final TypeVariable _typeVariable;
-  final int _metadataIndex;
-  TypeMirror _cachedUpperBound;
-
-  JsTypeVariableMirror(
-      TypeVariable typeVariable, this.owner, this._metadataIndex)
-      : this._typeVariable = typeVariable,
-        super(s(typeVariable.name));
-
-  bool operator ==(other) {
-    return (other is JsTypeVariableMirror &&
-        simpleName == other.simpleName &&
-        owner == other.owner);
-  }
-
-  int get hashCode {
-    int code = 0x3FFFFFFF & (JsTypeVariableMirror).hashCode;
-    code ^= 17 * simpleName.hashCode;
-    code ^= 19 * owner.hashCode;
-    return code;
-  }
-
-  String get _prettyName => 'TypeVariableMirror';
-
-  bool get isTopLevel => false;
-  bool get isStatic => false;
-
-  TypeMirror get upperBound {
-    if (_cachedUpperBound != null) return _cachedUpperBound;
-    return _cachedUpperBound = typeMirrorFromRuntimeTypeRepresentation(
-        owner, getType(_typeVariable.bound));
-  }
-
-  bool isSubtypeOf(TypeMirror other) => throw new UnimplementedError();
-  bool isAssignableTo(TypeMirror other) => throw new UnimplementedError();
-
-  _asRuntimeType() => _metadataIndex;
-}
-
-class JsTypeMirror extends JsDeclarationMirror implements TypeMirror {
-  JsTypeMirror(Symbol simpleName) : super(simpleName);
-
-  String get _prettyName => 'TypeMirror';
-
-  DeclarationMirror get owner => null;
-
-  // TODO(ahe): Doesn't match the specification, see http://dartbug.com/11569.
-  bool get isTopLevel => true;
-
-  // TODO(ahe): Implement these.
-  List<InstanceMirror> get metadata => throw new UnimplementedError();
-
-  bool get hasReflectedType => false;
-  Type get reflectedType {
-    throw new UnsupportedError('This type does not support reflectedType');
-  }
-
-  List<TypeVariableMirror> get typeVariables => const <TypeVariableMirror>[];
-  List<TypeMirror> get typeArguments => const <TypeMirror>[];
-
-  bool get isOriginalDeclaration => true;
-  TypeMirror get originalDeclaration => this;
-
-  bool isSubtypeOf(TypeMirror other) => throw new UnimplementedError();
-  bool isAssignableTo(TypeMirror other) => throw new UnimplementedError();
-
-  _asRuntimeType() {
-    if (this == JsMirrorSystem._dynamicType) return null;
-    if (this == JsMirrorSystem._voidType) return null;
-    throw new RuntimeError('Should not call _asRuntimeType');
-  }
-}
-
-class JsLibraryMirror extends JsDeclarationMirror
-    with JsObjectMirror
-    implements LibraryMirror {
-  final Uri _uri;
-  final List<String> _classes;
-  final List<String> _functions;
-  final List _metadata;
-  final String _compactFieldSpecification;
-  final bool _isRoot;
-  final _globalObject;
-  List<JsMethodMirror> _cachedFunctionMirrors;
-  List<VariableMirror> _cachedFields;
-  UnmodifiableMapView<Symbol, ClassMirror> _cachedClasses;
-  UnmodifiableMapView<Symbol, MethodMirror> _cachedFunctions;
-  UnmodifiableMapView<Symbol, MethodMirror> _cachedGetters;
-  UnmodifiableMapView<Symbol, MethodMirror> _cachedSetters;
-  UnmodifiableMapView<Symbol, VariableMirror> _cachedVariables;
-  UnmodifiableMapView<Symbol, Mirror> _cachedMembers;
-  UnmodifiableMapView<Symbol, DeclarationMirror> _cachedDeclarations;
-  UnmodifiableListView<InstanceMirror> _cachedMetadata;
-
-  JsLibraryMirror(
-      Symbol simpleName,
-      this._uri,
-      this._classes,
-      this._functions,
-      this._metadata,
-      this._compactFieldSpecification,
-      this._isRoot,
-      this._globalObject)
-      : super(simpleName) {
-    preserveLibraryNames();
-  }
-
-  String get _prettyName => 'LibraryMirror';
-
-  Uri get uri {
-    preserveUris();
-    return _uri;
-  }
-
-  Symbol get qualifiedName => simpleName;
-
-  List<JsMethodMirror> get _methods => _functionMirrors;
-
-  Map<Symbol, ClassMirror> get __classes {
-    if (_cachedClasses != null) return _cachedClasses;
-    var result = new Map();
-    for (String className in _classes) {
-      var cls = reflectClassByMangledName(className);
-      if (cls is ClassMirror) {
-        cls = cls.originalDeclaration;
-      }
-      if (cls is JsClassMirror) {
-        result[cls.simpleName] = cls;
-        cls._owner = this;
-      } else if (cls is JsTypedefMirror) {
-        result[cls.simpleName] = cls;
-      }
-    }
-    return _cachedClasses =
-        new UnmodifiableMapView<Symbol, ClassMirror>(result);
-  }
-
-  InstanceMirror setField(Symbol fieldName, Object arg) {
-    String name = n(fieldName);
-    if (name.endsWith('=')) throw new ArgumentError('');
-    dynamic mirror = __functions[s('$name=')];
-    if (mirror == null) mirror = __variables[fieldName];
-    if (mirror == null) {
-      throw new NoSuchStaticMethodError.method(
-          null, setterSymbol(fieldName), [arg], null);
-    }
-    mirror._setField(this, arg);
-    return reflect(arg);
-  }
-
-  InstanceMirror getField(Symbol fieldName) {
-    JsMirror mirror = __members[fieldName];
-    if (mirror == null) {
-      throw new NoSuchStaticMethodError.method(null, fieldName, [], null);
-    }
-    if (mirror is! MethodMirror) return reflect(mirror._getField(this));
-    JsMethodMirror methodMirror = mirror;
-    if (methodMirror.isGetter) return reflect(mirror._getField(this));
-    assert(methodMirror.isRegularMethod);
-    var getter = JS('', "#['\$getter']", methodMirror._jsFunction);
-    if (getter == null) throw new UnimplementedError();
-    return reflect(JS('', '#()', getter));
-  }
-
-  InstanceMirror invoke(Symbol memberName, List positionalArguments,
-      [Map<Symbol, dynamic> namedArguments]) {
-    if (namedArguments != null && !namedArguments.isEmpty) {
-      throw new UnsupportedError('Named arguments are not implemented.');
-    }
-    JsDeclarationMirror mirror = __members[memberName];
-
-    if (mirror is JsMethodMirror && !mirror.canInvokeReflectively()) {
-      throwInvalidReflectionError(n(memberName));
-    }
-    if (mirror == null || mirror is JsMethodMirror && mirror.isSetter) {
-      throw new NoSuchStaticMethodError.method(
-          null, memberName, positionalArguments, namedArguments);
-    }
-    if (mirror is JsMethodMirror && !mirror.isGetter) {
-      return reflect(mirror._invoke(positionalArguments, namedArguments));
-    }
-    return getField(memberName)
-        .invoke(#call, positionalArguments, namedArguments);
-  }
-
-  delegate(Invocation invocation) {
-    throw new UnimplementedError();
-  }
-
-  _loadField(String name) {
-    // TODO(ahe): What about lazily initialized fields? See
-    // [JsClassMirror.getField].
-
-    // '$' (JS_GET_STATIC_STATE()) stores state which is read directly, so we
-    // shouldn't use [_globalObject] here.
-    assert(JS('bool', '# in #', name, JS_GET_STATIC_STATE()));
-    return JS('', '#[#]', JS_GET_STATIC_STATE(), name);
-  }
-
-  void _storeField(String name, Object arg) {
-    // '$' (JS_GET_STATIC_STATE()) stores state which is stored directly, so we
-    // shouldn't use [_globalObject] here.
-    assert(JS('bool', '# in #', name, JS_GET_STATIC_STATE()));
-    JS('void', '#[#] = #', JS_GET_STATIC_STATE(), name, arg);
-  }
-
-  List<JsMethodMirror> get _functionMirrors {
-    if (_cachedFunctionMirrors != null) return _cachedFunctionMirrors;
-    var result = new List<JsMethodMirror>();
-    for (int i = 0; i < _functions.length; i++) {
-      String name = _functions[i];
-      var jsFunction = JS('', '#[#]', _globalObject, name);
-      String unmangledName = mangledGlobalNames[name];
-      if (unmangledName == null ||
-          JS('bool', "!!#['\$getterStub']", jsFunction)) {
-        // If there is no unmangledName, [jsFunction] is either a synthetic
-        // implementation detail, or something that is excluded
-        // by @MirrorsUsed.
-        // If it has a getterStub property it is a synthetic stub.
-        // TODO(floitsch): Remove the getterStub hack.
-        continue;
-      }
-      bool isConstructor = unmangledName.startsWith('new ');
-      // Top-level functions are static, but constructors are not.
-      bool isStatic = !isConstructor;
-      if (isConstructor) {
-        unmangledName = unmangledName.substring(4).replaceAll(r'$', '.');
-      }
-      JsMethodMirror mirror = new JsMethodMirror.fromUnmangledName(
-          unmangledName, jsFunction, isStatic, isConstructor);
-      result.add(mirror);
-      mirror._owner = this;
-    }
-    return _cachedFunctionMirrors = result;
-  }
-
-  List<VariableMirror> get _fields {
-    if (_cachedFields != null) return _cachedFields;
-    var result = <VariableMirror>[];
-    parseCompactFieldSpecification(
-        this, _compactFieldSpecification, true, result);
-    return _cachedFields = result;
-  }
-
-  Map<Symbol, MethodMirror> get __functions {
-    if (_cachedFunctions != null) return _cachedFunctions;
-    var result = new Map();
-    for (JsMethodMirror mirror in _functionMirrors) {
-      if (!mirror.isConstructor) result[mirror.simpleName] = mirror;
-    }
-    return _cachedFunctions =
-        new UnmodifiableMapView<Symbol, MethodMirror>(result);
-  }
-
-  Map<Symbol, MethodMirror> get __getters {
-    if (_cachedGetters != null) return _cachedGetters;
-    var result = new Map();
-    // TODO(ahe): Implement this.
-    return _cachedGetters =
-        new UnmodifiableMapView<Symbol, MethodMirror>(result);
-  }
-
-  Map<Symbol, MethodMirror> get __setters {
-    if (_cachedSetters != null) return _cachedSetters;
-    var result = new Map();
-    // TODO(ahe): Implement this.
-    return _cachedSetters =
-        new UnmodifiableMapView<Symbol, MethodMirror>(result);
-  }
-
-  Map<Symbol, VariableMirror> get __variables {
-    if (_cachedVariables != null) return _cachedVariables;
-    var result = new Map();
-    for (JsVariableMirror mirror in _fields) {
-      result[mirror.simpleName] = mirror;
-    }
-    return _cachedVariables =
-        new UnmodifiableMapView<Symbol, VariableMirror>(result);
-  }
-
-  Map<Symbol, Mirror> get __members {
-    if (_cachedMembers != null) return _cachedMembers;
-    Map<Symbol, Mirror> result = new Map.from(__classes);
-    addToResult(Symbol key, Mirror value) {
-      result[key] = value;
-    }
-
-    __functions.forEach(addToResult);
-    __getters.forEach(addToResult);
-    __setters.forEach(addToResult);
-    __variables.forEach(addToResult);
-    return _cachedMembers = new UnmodifiableMapView<Symbol, Mirror>(result);
-  }
-
-  Map<Symbol, DeclarationMirror> get declarations {
-    if (_cachedDeclarations != null) return _cachedDeclarations;
-    var result = new Map<Symbol, DeclarationMirror>();
-    addToResult(Symbol key, Mirror value) {
-      result[key] = value;
-    }
-
-    __members.forEach(addToResult);
-    return _cachedDeclarations =
-        new UnmodifiableMapView<Symbol, DeclarationMirror>(result);
-  }
-
-  List<InstanceMirror> get metadata {
-    if (_cachedMetadata != null) return _cachedMetadata;
-    preserveMetadata();
-    return _cachedMetadata =
-        new UnmodifiableListView<InstanceMirror>(_metadata.map(reflect));
-  }
-
-  // TODO(ahe): Test this getter.
-  DeclarationMirror get owner => null;
-
-  List<LibraryDependencyMirror> get libraryDependencies =>
-      throw new UnimplementedError();
-}
-
-String n(Symbol symbol) => _symbol_dev.Symbol.getName(symbol);
-
-Symbol s(String name) {
-  if (name == null) return null;
-  return new _symbol_dev.Symbol.unvalidated(name);
-}
-
-Symbol setterSymbol(Symbol symbol) => s('${n(symbol)}=');
-
-final JsMirrorSystem currentJsMirrorSystem = new JsMirrorSystem();
-
-InstanceMirror reflect(Object reflectee) {
-  // TODO(sra): This test should be a quick test for something like 'is
-  // Function', but only for classes that implement `Function` via a `call`
-  // method. The JS form of the test could be something like
-  //
-  //     if (reflectee instanceof P.Object && reflectee.$isFunction) ...
-  //
-  // We don't currently have a way get that generated. We should ensure type
-  // analysis can express 'not Interceptor' and recognize a negative type test
-  // against Interceptor can be optimized to the above test. For now we have to
-  // accept the following is compiled to an interceptor-based type check.
-  if (reflectee is Function) {
-    return new JsClosureMirror(reflectee);
-  } else {
-    return new JsInstanceMirror(reflectee);
-  }
-}
-
-TypeMirror reflectType(Type key, [List<Type> typeArguments]) {
-  String mangledName = getMangledTypeName(key);
-  if (typeArguments != null) {
-    if (typeArguments.isEmpty || !typeArguments.every((_) => _ is TypeImpl)) {
-      var message = typeArguments.isEmpty
-          ? 'Type arguments list can not be empty.'
-          : 'Type arguments list must contain only instances of Type.';
-      throw new ArgumentError.value(typeArguments, 'typeArguments', message);
-    }
-    var mangledTypeArguments = typeArguments.map(getMangledTypeName);
-    mangledName = "${mangledName}<${mangledTypeArguments.join(', ')}>";
-  }
-  return reflectClassByMangledName(mangledName);
-}
-
-TypeMirror reflectClassByMangledName(String mangledName) {
-  String unmangledName = mangledGlobalNames[mangledName];
-  if (mangledName == 'dynamic') return JsMirrorSystem._dynamicType;
-  if (mangledName == 'void') return JsMirrorSystem._voidType;
-  if (unmangledName == null) unmangledName = mangledName;
-  return reflectClassByName(s(unmangledName), mangledName);
-}
-
-var classMirrors;
-
-TypeMirror reflectClassByName(Symbol symbol, String mangledName) {
-  if (classMirrors == null) classMirrors = JsCache.allocate();
-  var mirror = JsCache.fetch(classMirrors, mangledName);
-  if (mirror != null) return mirror;
-  disableTreeShaking();
-  int typeArgIndex = mangledName.indexOf('<');
-  if (typeArgIndex != -1) {
-    TypeMirror originalDeclaration =
-        reflectClassByMangledName(mangledName.substring(0, typeArgIndex))
-            .originalDeclaration;
-    if (originalDeclaration is JsTypedefMirror) {
-      throw new UnimplementedError();
-    }
-    mirror = new JsTypeBoundClassMirror(
-        originalDeclaration,
-        // Remove the angle brackets enclosing the type arguments.
-        mangledName.substring(typeArgIndex + 1, mangledName.length - 1));
-    JsCache.update(classMirrors, mangledName, mirror);
-    return mirror;
-  }
-  var allClasses = JS_EMBEDDED_GLOBAL('', ALL_CLASSES);
-  var constructor = JS('var', '#[#]', allClasses, mangledName);
-  if (constructor == null) {
-    // Probably an intercepted class.
-    // TODO(ahe): How to handle intercepted classes?
-    throw new UnsupportedError('Cannot find class for: ${n(symbol)}');
-  }
-  var descriptor = JS('', '#["@"]', constructor);
-  var fields;
-  var fieldsMetadata;
-  if (descriptor == null) {
-    // This is a native class, or an intercepted class.
-    // TODO(ahe): Preserve descriptor for such classes.
-  } else if (JS(
-      'bool', '# in #', TYPEDEF_PREDICATE_PROPERTY_NAME, descriptor)) {
-    // Typedefs are represented as normal classes with two special properties:
-    //   TYPEDEF_PREDICATE_PROPERTY_NAME and TYPEDEF_TYPE_PROPERTY_NAME.
-    // For example:
-    //  MyTypedef: {
-    //     "^": "Object;",
-    //     $typedefType: 58,
-    //     $$isTypedef: true
-    //  }
-    //  The typedefType is the index into the metadata table.
-    int index = JS('int', '#[#]', descriptor, TYPEDEF_TYPE_PROPERTY_NAME);
-    mirror = new JsTypedefMirror(symbol, mangledName, getType(index));
-  } else {
-    fields = JS('', '#[#]', descriptor,
-        JS_GET_NAME(JsGetName.CLASS_DESCRIPTOR_PROPERTY));
-    if (fields is List) {
-      fieldsMetadata = fields.getRange(1, fields.length).toList();
-      fields = fields[0];
-    }
-    if (fields is! String) {
-      // TODO(ahe): This is CSP mode.  Find a way to determine the
-      // fields of this class.
-      fields = '';
-    }
-  }
-
-  if (mirror == null) {
-    var superclassName = fields.split(';')[0];
-    var mixins = superclassName.split('+');
-    if (mixins.length > 1 && mangledGlobalNames[mangledName] == null) {
-      mirror = reflectMixinApplication(mixins, mangledName);
-    } else {
-      ClassMirror classMirror = new JsClassMirror(
-          symbol, mangledName, constructor, fields, fieldsMetadata);
-      List typeVariables =
-          JS('JSExtendableArray|Null', '#.prototype["<>"]', constructor);
-      if (typeVariables == null || typeVariables.length == 0) {
-        mirror = classMirror;
-      } else {
-        String typeArguments = 'dynamic';
-        for (int i = 1; i < typeVariables.length; i++) {
-          typeArguments += ',dynamic';
-        }
-        mirror = new JsTypeBoundClassMirror(classMirror, typeArguments);
-      }
-    }
-  }
-
-  JsCache.update(classMirrors, mangledName, mirror);
-  return mirror;
-}
-
-/// Splits input `typeArguments` string into a list of strings for each argument.
-/// Takes into account nested generic types.
-/// For example, `Map<int, String>, String` will become a list of two items:
-/// `Map<int, String>` and `String`.
-List<String> splitTypeArguments(String typeArguments) {
-  if (typeArguments.indexOf('<') == -1) {
-    return typeArguments.split(',');
-  }
-  var argumentList = new List<String>();
-  int level = 0;
-  String currentTypeArgument = '';
-
-  for (int i = 0; i < typeArguments.length; i++) {
-    var character = typeArguments[i];
-    if (character == ' ') {
-      continue;
-    } else if (character == '<') {
-      currentTypeArgument += character;
-      level++;
-    } else if (character == '>') {
-      currentTypeArgument += character;
-      level--;
-    } else if (character == ',') {
-      if (level > 0) {
-        currentTypeArgument += character;
-      } else {
-        argumentList.add(currentTypeArgument);
-        currentTypeArgument = '';
-      }
-    } else {
-      currentTypeArgument += character;
-    }
-  }
-  argumentList.add(currentTypeArgument);
-  return argumentList;
-}
-
-Map<Symbol, MethodMirror> filterMethods(List<MethodMirror> methods) {
-  var result = new Map();
-  for (JsMethodMirror method in methods) {
-    if (!method.isConstructor && !method.isGetter && !method.isSetter) {
-      result[method.simpleName] = method;
-    }
-  }
-  return result;
-}
-
-Map<Symbol, MethodMirror> filterConstructors(methods) {
-  var result = new Map();
-  for (JsMethodMirror method in methods) {
-    if (method.isConstructor) {
-      result[method.simpleName] = method;
-    }
-  }
-  return result;
-}
-
-Map<Symbol, MethodMirror> filterGetters(
-    List<MethodMirror> methods, Map<Symbol, VariableMirror> fields) {
-  var result = new Map();
-  for (JsMethodMirror method in methods) {
-    if (method.isGetter) {
-      // TODO(ahe): This is a hack to remove getters corresponding to a field.
-      if (fields[method.simpleName] != null) continue;
-
-      result[method.simpleName] = method;
-    }
-  }
-  return result;
-}
-
-Map<Symbol, MethodMirror> filterSetters(
-    List<MethodMirror> methods, Map<Symbol, VariableMirror> fields) {
-  var result = new Map();
-  for (JsMethodMirror method in methods) {
-    if (method.isSetter) {
-      // TODO(ahe): This is a hack to remove setters corresponding to a field.
-      String name = n(method.simpleName);
-      name = name.substring(0, name.length - 1); // Remove '='.
-      if (fields[s(name)] != null) continue;
-
-      result[method.simpleName] = method;
-    }
-  }
-  return result;
-}
-
-Map<Symbol, Mirror> filterMembers(
-    List<MethodMirror> methods, Map<Symbol, VariableMirror> variables) {
-  Map<Symbol, Mirror> result = new Map.from(variables);
-  for (JsMethodMirror method in methods) {
-    if (method.isSetter) {
-      String name = n(method.simpleName);
-      name = name.substring(0, name.length - 1);
-      // Filter-out setters corresponding to variables.
-      if (result[s(name)] is VariableMirror) continue;
-    }
-    // Constructors aren't 'members'.
-    if (method.isConstructor) continue;
-    // Filter out synthetic tear-off stubs
-    if (JS('bool', r'!!#.$getterStub', method._jsFunction)) continue;
-    // Use putIfAbsent to filter-out getters corresponding to variables.
-    result.putIfAbsent(method.simpleName, () => method);
-  }
-  return result;
-}
-
-int counter = 0;
-
-ClassMirror reflectMixinApplication(mixinNames, String mangledName) {
-  disableTreeShaking();
-  var mixins = [];
-  for (String mangledName in mixinNames) {
-    mixins.add(reflectClassByMangledName(mangledName));
-  }
-  var it = mixins.iterator;
-  it.moveNext();
-  var superclass = it.current;
-  while (it.moveNext()) {
-    superclass = new JsMixinApplication(superclass, it.current, mangledName);
-  }
-  return superclass;
-}
-
-class JsMixinApplication extends JsTypeMirror
-    with JsObjectMirror
-    implements ClassMirror {
-  final ClassMirror superclass;
-  final ClassMirror mixin;
-  Symbol _cachedSimpleName;
-  Map<Symbol, MethodMirror> _cachedInstanceMembers;
-
-  JsMixinApplication(
-      ClassMirror superclass, ClassMirror mixin, String mangledName)
-      : this.superclass = superclass,
-        this.mixin = mixin,
-        super(s(mangledName));
-
-  String get _prettyName => 'ClassMirror';
-
-  Symbol get simpleName {
-    if (_cachedSimpleName != null) return _cachedSimpleName;
-    String superName = n(superclass.qualifiedName);
-    return _cachedSimpleName = (superName.contains(' with '))
-        ? s('$superName, ${n(mixin.qualifiedName)}')
-        : s('$superName with ${n(mixin.qualifiedName)}');
-  }
-
-  Symbol get qualifiedName => simpleName;
-
-  // TODO(ahe): Remove this method, only here to silence warning.
-  get _mixin => mixin;
-
-  Map<Symbol, Mirror> get __members => _mixin.__members;
-
-  Map<Symbol, MethodMirror> get __methods => _mixin.__methods;
-
-  Map<Symbol, MethodMirror> get __getters => _mixin.__getters;
-
-  Map<Symbol, MethodMirror> get __setters => _mixin.__setters;
-
-  Map<Symbol, VariableMirror> get __variables => _mixin.__variables;
-
-  Map<Symbol, DeclarationMirror> get declarations => mixin.declarations;
-
-  Map<Symbol, MethodMirror> get instanceMembers {
-    if (_cachedInstanceMembers == null) {
-      var result = new Map<Symbol, MethodMirror>();
-      if (superclass != null) {
-        result.addAll(superclass.instanceMembers);
-      }
-      result.addAll(mixin.instanceMembers);
-      _cachedInstanceMembers = result;
-    }
-    return _cachedInstanceMembers;
-  }
-
-  Map<Symbol, MethodMirror> get staticMembers => mixin.staticMembers;
-
-  _asRuntimeType() => null;
-
-  InstanceMirror invoke(Symbol memberName, List positionalArguments,
-      [Map<Symbol, dynamic> namedArguments]) {
-    throw new NoSuchStaticMethodError.method(
-        null, memberName, positionalArguments, namedArguments);
-  }
-
-  InstanceMirror getField(Symbol fieldName) {
-    throw new NoSuchStaticMethodError.method(null, fieldName, null, null);
-  }
-
-  InstanceMirror setField(Symbol fieldName, Object arg) {
-    throw new NoSuchStaticMethodError.method(
-        null, setterSymbol(fieldName), [arg], null);
-  }
-
-  delegate(Invocation invocation) {
-    throw new UnimplementedError();
-  }
-
-  List<ClassMirror> get superinterfaces => [mixin];
-
-  Map<Symbol, MethodMirror> get __constructors => _mixin.__constructors;
-
-  InstanceMirror newInstance(Symbol constructorName, List positionalArguments,
-      [Map<Symbol, dynamic> namedArguments]) {
-    throw new UnsupportedError(
-        "Can't instantiate mixin application '${n(qualifiedName)}'");
-  }
-
-  bool get isOriginalDeclaration => true;
-
-  ClassMirror get originalDeclaration => this;
-
-  // TODO(ahe): Implement this.
-  List<TypeVariableMirror> get typeVariables {
-    throw new UnimplementedError();
-  }
-
-  List<TypeMirror> get typeArguments => const <TypeMirror>[];
-
-  bool get isAbstract => throw new UnimplementedError();
-
-  bool get isEnum => throw new UnimplementedError();
-
-  bool isSubclassOf(ClassMirror other) {
-    superclass.isSubclassOf(other) || mixin.isSubclassOf(other);
-  }
-
-  bool isSubtypeOf(TypeMirror other) => throw new UnimplementedError();
-
-  bool isAssignableTo(TypeMirror other) => throw new UnimplementedError();
-}
-
-abstract class JsObjectMirror implements ObjectMirror {}
-
-class JsInstanceMirror extends JsObjectMirror implements InstanceMirror {
-  final reflectee;
-
-  JsInstanceMirror(this.reflectee);
-
-  bool get hasReflectee => true;
-
-  ClassMirror get type {
-    // The spec guarantees that `null` is the singleton instance of the `Null`
-    // class.
-    if (reflectee == null) return reflectClass(Null);
-    return reflectType(getRuntimeType(reflectee));
-  }
-
-  InstanceMirror invoke(Symbol memberName, List positionalArguments,
-      [Map<Symbol, dynamic> namedArguments]) {
-    if (namedArguments == null) namedArguments = const {};
-    // We can safely pass positionalArguments to _invoke as it will wrap it in
-    // a JSArray if needed.
-    return _invoke(memberName, JSInvocationMirror.METHOD, positionalArguments,
-        namedArguments);
-  }
-
-  InstanceMirror _invokeMethodWithNamedArguments(String reflectiveName,
-      List positionalArguments, Map<Symbol, dynamic> namedArguments) {
-    assert(namedArguments.isNotEmpty);
-    var interceptor = getInterceptor(reflectee);
-
-    var jsFunction = JS('', '#[#]', interceptor, reflectiveName);
-    if (jsFunction == null) {
-      // TODO(ahe): Invoke noSuchMethod.
-      throw new UnimplementedNoSuchMethodError(
-          'Invoking noSuchMethod with named arguments not implemented');
-    }
-    ReflectionInfo info = new ReflectionInfo(jsFunction);
-    if (jsFunction == null) {
-      // TODO(ahe): Invoke noSuchMethod.
-      throw new UnimplementedNoSuchMethodError(
-          'Invoking noSuchMethod with named arguments not implemented');
-    }
-
-    positionalArguments = new List.from(positionalArguments);
-    // Check the number of positional arguments is valid.
-    if (info.requiredParameterCount != positionalArguments.length) {
-      // TODO(ahe): Invoke noSuchMethod.
-      throw new UnimplementedNoSuchMethodError(
-          'Invoking noSuchMethod with named arguments not implemented');
-    }
-    var defaultArguments = new Map();
-    for (int i = 0; i < info.optionalParameterCount; i++) {
-      var parameterName = info.parameterName(i + info.requiredParameterCount);
-      var defaultValue =
-          getMetadata(info.defaultValue(i + info.requiredParameterCount));
-      defaultArguments[parameterName] = defaultValue;
-    }
-    namedArguments.forEach((Symbol symbol, value) {
-      String parameter = n(symbol);
-      if (defaultArguments.containsKey(parameter)) {
-        defaultArguments[parameter] = value;
-      } else {
-        // Extraneous named argument.
-        // TODO(ahe): Invoke noSuchMethod.
-        throw new UnimplementedNoSuchMethodError(
-            'Invoking noSuchMethod with named arguments not implemented');
-      }
-    });
-    positionalArguments.addAll(defaultArguments.values);
-    // TODO(ahe): Handle intercepted methods.
-    return reflect(
-        JS('', '#.apply(#, #)', jsFunction, reflectee, positionalArguments));
-  }
-
-  /// Grabs hold of the class-specific invocation cache for the reflectee.
-  /// All reflectees with the same class share the same cache. The cache
-  /// maps reflective names to cached invocation objects with enough decoded
-  /// reflective information to know how to to invoke a specific member.
-  get _classInvocationCache {
-    String cacheName = Primitives.mirrorInvokeCacheName;
-    var cacheHolder = (reflectee == null) ? getInterceptor(null) : reflectee;
-    var cache = JS('', r'#.constructor[#]', cacheHolder, cacheName);
-    if (cache == null) {
-      cache = JsCache.allocate();
-      JS('void', r'#.constructor[#] = #', cacheHolder, cacheName, cache);
-    }
-    return cache;
-  }
-
-  String _computeReflectiveName(Symbol symbolName, int type,
-      List positionalArguments, Map<Symbol, dynamic> namedArguments) {
-    String name = n(symbolName);
-    switch (type) {
-      case JSInvocationMirror.GETTER:
-        return name;
-      case JSInvocationMirror.SETTER:
-        return '$name=';
-      case JSInvocationMirror.METHOD:
-        if (namedArguments.isNotEmpty) return '$name*';
-        int nbArgs = positionalArguments.length as int;
-        return '$name:$nbArgs';
-    }
-    throw new RuntimeError('Could not compute reflective name for $name');
-  }
-
-  /**
-   * Returns a `CachedInvocation` or `CachedNoSuchMethodInvocation` for the
-   * given member.
-   *
-   * Caches the result.
-   */
-  _getCachedInvocation(Symbol name, int type, String reflectiveName,
-      List positionalArguments, Map<Symbol, dynamic> namedArguments) {
-    var cache = _classInvocationCache;
-    var cacheEntry = JsCache.fetch(cache, reflectiveName);
-    var result;
-    if (cacheEntry == null) {
-      disableTreeShaking();
-      String mangledName = reflectiveNames[reflectiveName];
-      List<String> argumentNames = const [];
-
-      // TODO(ahe): We don't need to create an invocation mirror here. The
-      // logic from JSInvocationMirror.getCachedInvocation could easily be
-      // inlined here.
-      Invocation invocation = createUnmangledInvocationMirror(
-          name, mangledName, type, positionalArguments, argumentNames);
-
-      cacheEntry =
-          JSInvocationMirror.getCachedInvocation(invocation, reflectee);
-      JsCache.update(cache, reflectiveName, cacheEntry);
-    }
-    return cacheEntry;
-  }
-
-  bool _isReflectable(CachedInvocation cachedInvocation) {
-    // TODO(floitsch): tear-off closure does not guarantee that the
-    // function is reflectable.
-    var method = cachedInvocation.jsFunction;
-    return hasReflectableProperty(method) || reflectee is TearOffClosure;
-  }
-
-  /// Invoke the member specified through name and type on the reflectee.
-  /// As a side-effect, this populates the class-specific invocation cache
-  /// for the reflectee.
-  InstanceMirror _invoke(Symbol name, int type, List positionalArguments,
-      Map<Symbol, dynamic> namedArguments) {
-    String reflectiveName =
-        _computeReflectiveName(name, type, positionalArguments, namedArguments);
-
-    if (namedArguments.isNotEmpty) {
-      // TODO(floitsch): first, make sure it's not a getter.
-      return _invokeMethodWithNamedArguments(
-          reflectiveName, positionalArguments, namedArguments);
-    }
-    var cacheEntry = _getCachedInvocation(
-        name, type, reflectiveName, positionalArguments, namedArguments);
-
-    if (cacheEntry.isNoSuchMethod || !_isReflectable(cacheEntry)) {
-      // Could be that we want to invoke a getter, or get a method.
-      if (type == JSInvocationMirror.METHOD && _instanceFieldExists(name)) {
-        return getField(name)
-            .invoke(#call, positionalArguments, namedArguments);
-      }
-
-      if (type == JSInvocationMirror.SETTER) {
-        // For setters we report the setter name "field=".
-        name = s('${n(name)}=');
-      }
-
-      if (!cacheEntry.isNoSuchMethod) {
-        // Not reflectable.
-        throwInvalidReflectionError(reflectiveName);
-      }
-
-      String mangledName = reflectiveNames[reflectiveName];
-      // TODO(ahe): Get the argument names.
-      List<String> argumentNames = [];
-      Invocation invocation = createUnmangledInvocationMirror(
-          name, mangledName, type, positionalArguments, argumentNames);
-      return reflect(cacheEntry.invokeOn(reflectee, invocation));
-    } else {
-      return reflect(cacheEntry.invokeOn(reflectee, positionalArguments));
-    }
-  }
-
-  InstanceMirror setField(Symbol fieldName, Object arg) {
-    _invoke(fieldName, JSInvocationMirror.SETTER, [arg], const {});
-    return reflect(arg);
-  }
-
-  // JS helpers for getField optimizations.
-  static bool isUndefined(x) => JS('bool', 'typeof # == "undefined"', x);
-  static bool isMissingCache(x) => JS('bool', 'typeof # == "number"', x);
-  static bool isMissingProbe(Symbol symbol) =>
-      JS('bool', 'typeof #.\$p == "undefined"', symbol);
-  static bool isEvalAllowed() => !JS_GET_FLAG('USE_CONTENT_SECURITY_POLICY');
-
-  /// The getter cache is lazily allocated after a couple
-  /// of invocations of [InstanceMirror.getField]. The delay is
-  /// used to avoid too aggressive caching and dynamic function
-  /// generation for rarely used mirrors. The cache is specific to
-  /// this [InstanceMirror] and maps reflective names to functions
-  /// that will invoke the corresponding getter on the reflectee.
-  /// The reflectee is passed to the function as the first argument
-  /// to avoid the overhead of fetching it from this mirror repeatedly.
-  /// The cache is lazily initialized to a JS object so we can
-  /// benefit from "map transitions" in the underlying JavaScript
-  /// engine to speed up cache probing.
-  var _getterCache = 4;
-
-  bool _instanceFieldExists(Symbol name) {
-    int getterType = JSInvocationMirror.GETTER;
-    String getterName =
-        _computeReflectiveName(name, getterType, const [], const {});
-    var getterCacheEntry =
-        _getCachedInvocation(name, getterType, getterName, const [], const {});
-    return !getterCacheEntry.isNoSuchMethod && !getterCacheEntry.isGetterStub;
-  }
-
-  InstanceMirror getField(Symbol fieldName) {
-    FASTPATH:
-    {
-      var cache = _getterCache;
-      if (isMissingCache(cache) || isMissingProbe(fieldName)) break FASTPATH;
-      // If the [fieldName] has an associated probe function, we can use
-      // it to read from the getter cache specific to this [InstanceMirror].
-      var getter = JS('', '#.\$p(#)', fieldName, cache);
-      if (isUndefined(getter)) break FASTPATH;
-      // Call the getter passing the reflectee as the first argument.
-      var value = JS('', '#(#)', getter, reflectee);
-      // The getter has an associate cache of the last [InstanceMirror]
-      // returned to avoid repeated invocations of [reflect]. To validate
-      // the cache, we check that the value returned by the getter is the
-      // same value as last time.
-      if (JS('bool', '# === #.v', value, getter)) {
-        return JS('InstanceMirror', '#.m', getter);
-      } else {
-        var result = reflect(value);
-        JS('void', '#.v = #', getter, value);
-        JS('void', '#.m = #', getter, result);
-        return result;
-      }
-    }
-    return _getFieldSlow(fieldName);
-  }
-
-  InstanceMirror _getFieldSlow(Symbol fieldName) {
-    // First do the slow-case getter invocation. As a side-effect of this,
-    // the invocation cache is filled in so we can query it afterwards.
-    var result =
-        _invoke(fieldName, JSInvocationMirror.GETTER, const [], const {});
-    String name = n(fieldName);
-    var cacheEntry = JsCache.fetch(_classInvocationCache, name);
-    if (cacheEntry.isNoSuchMethod) {
-      return result;
-    }
-
-    // Make sure we have a getter cache in this [InstanceMirror].
-    var cache = _getterCache;
-    if (isMissingCache(cache)) {
-      if ((_getterCache = --cache) != 0) return result;
-      cache = _getterCache = JS('=Object', 'Object.create(null)');
-    }
-
-    // Make sure that symbol [fieldName] has a cache probing function ($p).
-    bool useEval = isEvalAllowed();
-    if (isMissingProbe(fieldName)) {
-      var probe = _newProbeFn(name, useEval);
-      JS('void', '#.\$p = #', fieldName, probe);
-    }
-
-    // Create a new getter function and install it in the cache.
-    var mangledName = cacheEntry.mangledName;
-    var getter = (cacheEntry.isIntercepted)
-        ? _newInterceptedGetterFn(mangledName, useEval)
-        : _newGetterFn(mangledName, useEval);
-    JS('void', '#[#] = #', cache, name, getter);
-
-    // Initialize the last value (v) and last mirror (m) on the
-    // newly generated getter to be a sentinel value that is hard
-    // to get hold of through user code.
-    JS('void', '#.v = #.m = #', getter, getter, cache);
-
-    // Return the result of the slow-path getter invocation.
-    return result;
-  }
-
-  _newProbeFn(String id, bool useEval) {
-    if (useEval) {
-      String body = 'return c.$id;';
-      return JS('', 'new Function("c", #)', body);
-    } else {
-      return JS('', '(function(n){return(function(c){return c[n]})})(#)', id);
-    }
-  }
-
-  _newGetterFn(String name, bool useEval) {
-    if (!useEval) return _newGetterNoEvalFn(name);
-    // We use a comment that associates the generated function with the
-    // class of the reflectee. This makes it more likely that the underlying
-    // JavaScript engine will only share the generated code for accessors on the
-    // same class (through caching of eval'ed code). This makes the
-    // generated call to the getter - e.g. o.get$foo() - much more likely
-    // to be monomorphic and inlineable.
-    String className = JS('String', '#.constructor.name', reflectee);
-    String body = '/* $className */ return o.$name();';
-    return JS('', 'new Function("o", #)', body);
-  }
-
-  _newGetterNoEvalFn(n) =>
-      JS('', '(function(n){return(function(o){return o[n]()})})(#)', n);
-
-  _newInterceptedGetterFn(String name, bool useEval) {
-    var object = reflectee;
-    // It is possible that the interceptor for a given object is the object
-    // itself, so it is important not to share the code that captures the
-    // interceptor between multiple different instances of [InstanceMirror].
-    var interceptor = getInterceptor(object);
-    if (!useEval) return _newInterceptGetterNoEvalFn(name, interceptor);
-    String className = JS('String', '#.constructor.name', interceptor);
-    String functionName = '$className\$$name';
-    String body = '  function $functionName(o){return i.$name(o)}'
-        '  return $functionName;';
-    return JS('', '(new Function("i", #))(#)', body, interceptor);
-  }
-
-  _newInterceptGetterNoEvalFn(n, i) =>
-      JS('', '(function(n,i){return(function(o){return i[n](o)})})(#,#)', n, i);
-
-  delegate(Invocation invocation) {
-    return JSInvocationMirror.invokeFromMirror(invocation, reflectee);
-  }
-
-  operator ==(other) {
-    return other is JsInstanceMirror && identical(reflectee, other.reflectee);
-  }
-
-  int get hashCode {
-    // Avoid hash collisions with the reflectee. This constant is in Smi range
-    // and happens to be the inner padding from RFC 2104.
-    return identityHashCode(reflectee) ^ 0x36363636;
-  }
-
-  String toString() => 'InstanceMirror on ${Error.safeToString(reflectee)}';
-
-  // TODO(ahe): Remove this method from the API.
-  MirrorSystem get mirrors => currentJsMirrorSystem;
-}
-
-/**
- * ClassMirror for generic classes where the type parameters are bound.
- *
- * [typeArguments] will return a list of the type arguments, in contrast
- * to JsClassMirror that returns an empty list since it represents original
- * declarations and classes that are not generic.
- */
-class JsTypeBoundClassMirror extends JsDeclarationMirror
-    implements ClassMirror {
-  final JsClassMirror _class;
-
-  /**
-   * When instantiated this field will hold a string representing the list of
-   * type arguments for the class, i.e. what is inside the outermost angle
-   * brackets. Then, when get typeArguments is called the first time, the string
-   * is parsed into the actual list of TypeMirrors, and stored in
-   * [_cachedTypeArguments]. Due to type substitution of, for instance,
-   * superclasses the mangled name of the class and hence this string is needed
-   * after [_cachedTypeArguments] has been computed.
-   *
-   * If an integer is encountered as a type argument, it represents the type
-   * variable at the corresponding entry in [emitter.globalMetadata].
-   */
-  String _typeArguments;
-
-  UnmodifiableListView<TypeMirror> _cachedTypeArguments;
-  UnmodifiableMapView<Symbol, DeclarationMirror> _cachedDeclarations;
-  UnmodifiableMapView<Symbol, DeclarationMirror> _cachedMembers;
-  UnmodifiableMapView<Symbol, MethodMirror> _cachedConstructors;
-  Map<Symbol, VariableMirror> _cachedVariables;
-  Map<Symbol, MethodMirror> _cachedGetters;
-  Map<Symbol, MethodMirror> _cachedSetters;
-  Map<Symbol, MethodMirror> _cachedMethodsMap;
-  List<JsMethodMirror> _cachedMethods;
-  ClassMirror _superclass;
-  List<ClassMirror> _cachedSuperinterfaces;
-  Map<Symbol, MethodMirror> _cachedInstanceMembers;
-  Map<Symbol, MethodMirror> _cachedStaticMembers;
-
-  JsTypeBoundClassMirror(JsClassMirror originalDeclaration, this._typeArguments)
-      : _class = originalDeclaration,
-        super(originalDeclaration.simpleName);
-
-  String get _prettyName => 'ClassMirror';
-
-  String toString() {
-    String result = '$_prettyName on ${n(simpleName)}';
-    if (typeArguments != null) {
-      result = "$result<${typeArguments.join(', ')}>";
-    }
-    return result;
-  }
-
-  String get _mangledName {
-    for (TypeMirror typeArgument in typeArguments) {
-      if (typeArgument != JsMirrorSystem._dynamicType) {
-        return '${_class._mangledName}<$_typeArguments>';
-      }
-    }
-    // When all type arguments are dynamic, the canonical representation is to
-    // drop them.
-    return _class._mangledName;
-  }
-
-  List<TypeVariableMirror> get typeVariables => _class.typeVariables;
-
-  List<TypeMirror> get typeArguments {
-    if (_cachedTypeArguments != null) return _cachedTypeArguments;
-    var result = <TypeMirror>[];
-
-    addTypeArgument(String typeArgument) {
-      int parsedIndex = int.parse(typeArgument, onError: (_) => -1);
-      if (parsedIndex == -1) {
-        result.add(reflectClassByMangledName(typeArgument.trim()));
-      } else {
-        TypeVariable typeVariable = getMetadata(parsedIndex);
-        TypeMirror owner = reflectClass(typeVariable.owner);
-        TypeVariableMirror typeMirror =
-            new JsTypeVariableMirror(typeVariable, owner, parsedIndex);
-        result.add(typeMirror);
-      }
-    }
-
-    splitTypeArguments(_typeArguments).forEach(addTypeArgument);
-    return _cachedTypeArguments = new UnmodifiableListView(result);
-  }
-
-  List<JsMethodMirror> get _methods {
-    if (_cachedMethods != null) return _cachedMethods;
-    return _cachedMethods = _class._getMethodsWithOwner(this);
-  }
-
-  Map<Symbol, MethodMirror> get __methods {
-    if (_cachedMethodsMap != null) return _cachedMethodsMap;
-    return _cachedMethodsMap =
-        new UnmodifiableMapView<Symbol, MethodMirror>(filterMethods(_methods));
-  }
-
-  Map<Symbol, MethodMirror> get __constructors {
-    if (_cachedConstructors != null) return _cachedConstructors;
-    return _cachedConstructors = new UnmodifiableMapView<Symbol, MethodMirror>(
-        filterConstructors(_methods));
-  }
-
-  Map<Symbol, MethodMirror> get __getters {
-    if (_cachedGetters != null) return _cachedGetters;
-    return _cachedGetters = new UnmodifiableMapView<Symbol, MethodMirror>(
-        filterGetters(_methods, __variables));
-  }
-
-  Map<Symbol, MethodMirror> get __setters {
-    if (_cachedSetters != null) return _cachedSetters;
-    return _cachedSetters = new UnmodifiableMapView<Symbol, MethodMirror>(
-        filterSetters(_methods, __variables));
-  }
-
-  Map<Symbol, VariableMirror> get __variables {
-    if (_cachedVariables != null) return _cachedVariables;
-    var result = new Map();
-    for (JsVariableMirror mirror in _class._getFieldsWithOwner(this)) {
-      result[mirror.simpleName] = mirror;
-    }
-    return _cachedVariables =
-        new UnmodifiableMapView<Symbol, VariableMirror>(result);
-  }
-
-  Map<Symbol, DeclarationMirror> get __members {
-    if (_cachedMembers != null) return _cachedMembers;
-    return _cachedMembers = new UnmodifiableMapView<Symbol, DeclarationMirror>(
-        filterMembers(_methods, __variables));
-  }
-
-  Map<Symbol, DeclarationMirror> get declarations {
-    if (_cachedDeclarations != null) return _cachedDeclarations;
-    Map<Symbol, DeclarationMirror> result =
-        new Map<Symbol, DeclarationMirror>();
-    result.addAll(__members);
-    result.addAll(__constructors);
-    typeVariables.forEach((tv) => result[tv.simpleName] = tv);
-    return _cachedDeclarations =
-        new UnmodifiableMapView<Symbol, DeclarationMirror>(result);
-  }
-
-  Map<Symbol, MethodMirror> get staticMembers {
-    if (_cachedStaticMembers == null) {
-      var result = new Map<Symbol, MethodMirror>();
-      declarations.values.forEach((decl) {
-        if (decl is MethodMirror && decl.isStatic && !decl.isConstructor) {
-          result[decl.simpleName] = decl;
-        }
-        if (decl is VariableMirror && decl.isStatic) {
-          var getterName = decl.simpleName;
-          result[getterName] = new JsSyntheticAccessor(
-              this, getterName, true, true, false, decl);
-          if (!decl.isFinal) {
-            var setterName = setterSymbol(decl.simpleName);
-            result[setterName] = new JsSyntheticAccessor(
-                this, setterName, false, true, false, decl);
-          }
-        }
-      });
-      _cachedStaticMembers = result;
-    }
-    return _cachedStaticMembers;
-  }
-
-  Map<Symbol, MethodMirror> get instanceMembers {
-    if (_cachedInstanceMembers == null) {
-      var result = new Map<Symbol, MethodMirror>();
-      if (superclass != null) {
-        result.addAll(superclass.instanceMembers);
-      }
-      declarations.values.forEach((decl) {
-        if (decl is MethodMirror &&
-            !decl.isStatic &&
-            !decl.isConstructor &&
-            !decl.isAbstract) {
-          result[decl.simpleName] = decl;
-        }
-        if (decl is VariableMirror && !decl.isStatic) {
-          var getterName = decl.simpleName;
-          result[getterName] = new JsSyntheticAccessor(
-              this, getterName, true, false, false, decl);
-          if (!decl.isFinal) {
-            var setterName = setterSymbol(decl.simpleName);
-            result[setterName] = new JsSyntheticAccessor(
-                this, setterName, false, false, false, decl);
-          }
-        }
-      });
-      _cachedInstanceMembers = result;
-    }
-    return _cachedInstanceMembers;
-  }
-
-  InstanceMirror setField(Symbol fieldName, Object arg) {
-    return _class.setField(fieldName, arg);
-  }
-
-  InstanceMirror getField(Symbol fieldName) => _class.getField(fieldName);
-
-  InstanceMirror newInstance(Symbol constructorName, List positionalArguments,
-      [Map<Symbol, dynamic> namedArguments]) {
-    var instance = _class._getInvokedInstance(
-        constructorName, positionalArguments, namedArguments);
-    return reflect(setRuntimeTypeInfo(
-        instance, typeArguments.map(_toRuntimeType).toList()));
-  }
-
-  _asRuntimeType() {
-    return [_class._jsConstructor].addAll(typeArguments.map(_toRuntimeType));
-  }
-
-  static _toRuntimeType(TypeMirror t) {
-    JsTypeMirror typeMirror = t;
-    return typeMirror._asRuntimeType();
-  }
-
-  JsLibraryMirror get owner => _class.owner;
-
-  List<InstanceMirror> get metadata => _class.metadata;
-
-  ClassMirror get superclass {
-    if (_superclass != null) return _superclass;
-
-    var typeInformationContainer = JS_EMBEDDED_GLOBAL('', TYPE_INFORMATION);
-    List<int> typeInformation =
-        JS('List|Null', '#[#]', typeInformationContainer, _class._mangledName);
-    assert(typeInformation != null);
-    var type = getType(typeInformation[0]);
-    return _superclass = typeMirrorFromRuntimeTypeRepresentation(this, type);
-  }
-
-  InstanceMirror invoke(Symbol memberName, List positionalArguments,
-      [Map<Symbol, dynamic> namedArguments]) {
-    return _class.invoke(memberName, positionalArguments, namedArguments);
-  }
-
-  delegate(Invocation invocation) {
-    throw new UnimplementedError();
-  }
-
-  bool get isOriginalDeclaration => false;
-
-  ClassMirror get originalDeclaration => _class;
-
-  List<ClassMirror> get superinterfaces {
-    if (_cachedSuperinterfaces != null) return _cachedSuperinterfaces;
-    return _cachedSuperinterfaces = _class._getSuperinterfacesWithOwner(this);
-  }
-
-  bool get isPrivate => _class.isPrivate;
-
-  bool get isTopLevel => _class.isTopLevel;
-
-  bool get isAbstract => _class.isAbstract;
-
-  bool get isEnum => _class.isEnum;
-
-  bool isSubclassOf(ClassMirror other) => _class.isSubclassOf(other);
-
-  SourceLocation get location => _class.location;
-
-  MirrorSystem get mirrors => _class.mirrors;
-
-  Symbol get qualifiedName => _class.qualifiedName;
-
-  bool get hasReflectedType => true;
-
-  Type get reflectedType => createRuntimeType(_mangledName);
-
-  Symbol get simpleName => _class.simpleName;
-
-  // TODO(ahe): Implement this.
-  ClassMirror get mixin => throw new UnimplementedError();
-
-  bool isSubtypeOf(TypeMirror other) => throw new UnimplementedError();
-
-  bool isAssignableTo(TypeMirror other) => throw new UnimplementedError();
-}
-
-class JsSyntheticAccessor implements MethodMirror {
-  final DeclarationMirror owner;
-  final Symbol simpleName;
-  final bool isGetter;
-  final bool isStatic;
-  final bool isTopLevel;
-
-  /// The field or type that introduces the synthetic accessor.
-  final _target;
-
-  JsSyntheticAccessor(this.owner, this.simpleName, this.isGetter, this.isStatic,
-      this.isTopLevel, this._target);
-
-  bool get isSynthetic => true;
-  bool get isRegularMethod => false;
-  bool get isOperator => false;
-  bool get isConstructor => false;
-  bool get isConstConstructor => false;
-  bool get isGenerativeConstructor => false;
-  bool get isFactoryConstructor => false;
-  bool get isRedirectingConstructor => false;
-  bool get isAbstract => false;
-
-  bool get isSetter => !isGetter;
-  bool get isPrivate => n(simpleName).startsWith('_');
-
-  Symbol get qualifiedName => computeQualifiedName(owner, simpleName);
-  Symbol get constructorName => Symbol.empty;
-
-  TypeMirror get returnType => _target.type;
-  List<ParameterMirror> get parameters {
-    if (isGetter) return const [];
-    return new UnmodifiableListView(
-        [new JsSyntheticSetterParameter(this, this._target)]);
-  }
-
-  List<InstanceMirror> get metadata => const [];
-  String get source => null;
-  SourceLocation get location => throw new UnimplementedError();
-}
-
-class JsSyntheticSetterParameter implements ParameterMirror {
-  final DeclarationMirror owner;
-  final VariableMirror _target;
-
-  JsSyntheticSetterParameter(this.owner, this._target);
-
-  Symbol get simpleName => _target.simpleName;
-  Symbol get qualifiedName => computeQualifiedName(owner, simpleName);
-  TypeMirror get type => _target.type;
-
-  bool get isOptional => false;
-  bool get isNamed => false;
-  bool get isStatic => false;
-  bool get isTopLevel => false;
-  bool get isConst => false;
-  bool get isFinal => true;
-  bool get isPrivate => false;
-  bool get hasDefaultValue => false;
-  InstanceMirror get defaultValue => null;
-  List<InstanceMirror> get metadata => const [];
-  SourceLocation get location => throw new UnimplementedError();
-}
-
-class JsClassMirror extends JsTypeMirror
-    with JsObjectMirror
-    implements ClassMirror {
-  final String _mangledName;
-  final _jsConstructor;
-  final String _fieldsDescriptor;
-  final List _fieldsMetadata;
-  final _jsConstructorCache = JsCache.allocate();
-  List _metadata;
-  ClassMirror _superclass;
-  List<JsMethodMirror> _cachedMethods;
-  List<VariableMirror> _cachedFields;
-  UnmodifiableMapView<Symbol, MethodMirror> _cachedConstructors;
-  UnmodifiableMapView<Symbol, MethodMirror> _cachedMethodsMap;
-  UnmodifiableMapView<Symbol, MethodMirror> _cachedGetters;
-  UnmodifiableMapView<Symbol, MethodMirror> _cachedSetters;
-  UnmodifiableMapView<Symbol, VariableMirror> _cachedVariables;
-  UnmodifiableMapView<Symbol, Mirror> _cachedMembers;
-  UnmodifiableMapView<Symbol, DeclarationMirror> _cachedDeclarations;
-  UnmodifiableListView<InstanceMirror> _cachedMetadata;
-  UnmodifiableListView<ClassMirror> _cachedSuperinterfaces;
-  UnmodifiableListView<TypeVariableMirror> _cachedTypeVariables;
-  Map<Symbol, MethodMirror> _cachedInstanceMembers;
-  Map<Symbol, MethodMirror> _cachedStaticMembers;
-
-  // Set as side-effect of accessing JsLibraryMirror.classes.
-  JsLibraryMirror _owner;
-
-  JsClassMirror(Symbol simpleName, this._mangledName, this._jsConstructor,
-      this._fieldsDescriptor, this._fieldsMetadata)
-      : super(simpleName);
-
-  String get _prettyName => 'ClassMirror';
-
-  Map<Symbol, MethodMirror> get __constructors {
-    if (_cachedConstructors != null) return _cachedConstructors;
-    return _cachedConstructors = new UnmodifiableMapView<Symbol, MethodMirror>(
-        filterConstructors(_methods));
-  }
-
-  _asRuntimeType() {
-    if (typeVariables.isEmpty) return _jsConstructor;
-    var type = [_jsConstructor];
-    for (int i = 0; i < typeVariables.length; i++) {
-      type.add(JsMirrorSystem._dynamicType._asRuntimeType);
-    }
-    return type;
-  }
-
-  List<JsMethodMirror> _getMethodsWithOwner(DeclarationMirror methodOwner) {
-    var prototype = JS('', '#.prototype', _jsConstructor);
-    // The prototype might not have been processed yet, so do that now.
-    JS('', '#[#]()', prototype,
-        JS_GET_NAME(JsGetName.DEFERRED_ACTION_PROPERTY));
-    List<String> keys = extractKeys(prototype);
-    var result = <JsMethodMirror>[];
-    for (String key in keys) {
-      if (isReflectiveDataInPrototype(key)) continue;
-      String simpleName = mangledNames[key];
-      // [simpleName] can be null if [key] represents an implementation
-      // detail, for example, a bailout method, or runtime type support.
-      // It might also be null if the user has limited what is reified for
-      // reflection with metadata.
-      if (simpleName == null) continue;
-      var function = JS('', '#[#]', prototype, key);
-      if (!isOrdinaryReflectableMethod(function)) continue;
-      if (isAliasedSuperMethod(function, key)) continue;
-      var mirror = new JsMethodMirror.fromUnmangledName(
-          simpleName, function, false, false);
-      result.add(mirror);
-      mirror._owner = methodOwner;
-    }
-
-    var statics = JS_EMBEDDED_GLOBAL('', STATICS);
-    keys = extractKeys(JS('', '#[#]', statics, _mangledName));
-    for (String mangledName in keys) {
-      if (isReflectiveDataInPrototype(mangledName)) continue;
-      String unmangledName = mangledName;
-      var jsFunction = JS('', '#[#]', owner._globalObject, mangledName);
-
-      bool isConstructor = false;
-      if (hasReflectableProperty(jsFunction)) {
-        String reflectionName =
-            JS('String|Null', r'#.$reflectionName', jsFunction);
-        if (reflectionName == null) continue;
-        isConstructor = reflectionName.startsWith('new ');
-        if (isConstructor) {
-          reflectionName = reflectionName.substring(4).replaceAll(r'$', '.');
-        }
-        unmangledName = reflectionName;
-      } else {
-        continue;
-      }
-      bool isStatic = !isConstructor; // Constructors are not static.
-      JsMethodMirror mirror = new JsMethodMirror.fromUnmangledName(
-          unmangledName, jsFunction, isStatic, isConstructor);
-      result.add(mirror);
-      mirror._owner = methodOwner;
-    }
-
-    return result;
-  }
-
-  List<JsMethodMirror> get _methods {
-    if (_cachedMethods != null) return _cachedMethods;
-    return _cachedMethods = _getMethodsWithOwner(this);
-  }
-
-  List<VariableMirror> _getFieldsWithOwner(DeclarationMirror fieldOwner) {
-    var result = <VariableMirror>[];
-
-    dynamic instanceFieldSpecfication = _fieldsDescriptor.split(';')[1];
-    if (_fieldsMetadata != null) {
-      instanceFieldSpecfication = <dynamic>[instanceFieldSpecfication]
-        ..addAll(_fieldsMetadata);
-    }
-    parseCompactFieldSpecification(
-        fieldOwner, instanceFieldSpecfication, false, result);
-
-    var statics = JS_EMBEDDED_GLOBAL('', STATICS);
-    var staticDescriptor = JS('', '#[#]', statics, _mangledName);
-    if (staticDescriptor != null) {
-      parseCompactFieldSpecification(
-          fieldOwner,
-          JS('', '#[#]', staticDescriptor,
-              JS_GET_NAME(JsGetName.CLASS_DESCRIPTOR_PROPERTY)),
-          true,
-          result);
-    }
-    return result;
-  }
-
-  List<VariableMirror> get _fields {
-    if (_cachedFields != null) return _cachedFields;
-    return _cachedFields = _getFieldsWithOwner(this);
-  }
-
-  Map<Symbol, MethodMirror> get __methods {
-    if (_cachedMethodsMap != null) return _cachedMethodsMap;
-    return _cachedMethodsMap =
-        new UnmodifiableMapView<Symbol, MethodMirror>(filterMethods(_methods));
-  }
-
-  Map<Symbol, MethodMirror> get __getters {
-    if (_cachedGetters != null) return _cachedGetters;
-    return _cachedGetters = new UnmodifiableMapView<Symbol, MethodMirror>(
-        filterGetters(_methods, __variables));
-  }
-
-  Map<Symbol, MethodMirror> get __setters {
-    if (_cachedSetters != null) return _cachedSetters;
-    return _cachedSetters = new UnmodifiableMapView<Symbol, MethodMirror>(
-        filterSetters(_methods, __variables));
-  }
-
-  Map<Symbol, VariableMirror> get __variables {
-    if (_cachedVariables != null) return _cachedVariables;
-    var result = new Map();
-    for (JsVariableMirror mirror in _fields) {
-      result[mirror.simpleName] = mirror;
-    }
-    return _cachedVariables =
-        new UnmodifiableMapView<Symbol, VariableMirror>(result);
-  }
-
-  Map<Symbol, Mirror> get __members {
-    if (_cachedMembers != null) return _cachedMembers;
-    return _cachedMembers = new UnmodifiableMapView<Symbol, Mirror>(
-        filterMembers(_methods, __variables));
-  }
-
-  Map<Symbol, DeclarationMirror> get declarations {
-    if (_cachedDeclarations != null) return _cachedDeclarations;
-    var result = new Map<Symbol, DeclarationMirror>();
-    addToResult(Symbol key, Mirror value) {
-      result[key] = value;
-    }
-
-    __members.forEach(addToResult);
-    __constructors.forEach(addToResult);
-    typeVariables.forEach((tv) => result[tv.simpleName] = tv);
-    return _cachedDeclarations =
-        new UnmodifiableMapView<Symbol, DeclarationMirror>(result);
-  }
-
-  Map<Symbol, MethodMirror> get staticMembers {
-    if (_cachedStaticMembers == null) {
-      var result = new Map<Symbol, MethodMirror>();
-      declarations.values.forEach((decl) {
-        if (decl is MethodMirror && decl.isStatic && !decl.isConstructor) {
-          result[decl.simpleName] = decl;
-        }
-        if (decl is VariableMirror && decl.isStatic) {
-          var getterName = decl.simpleName;
-          result[getterName] = new JsSyntheticAccessor(
-              this, getterName, true, true, false, decl);
-          if (!decl.isFinal) {
-            var setterName = setterSymbol(decl.simpleName);
-            result[setterName] = new JsSyntheticAccessor(
-                this, setterName, false, true, false, decl);
-          }
-        }
-      });
-      _cachedStaticMembers = result;
-    }
-    return _cachedStaticMembers;
-  }
-
-  Map<Symbol, MethodMirror> get instanceMembers {
-    if (_cachedInstanceMembers == null) {
-      var result = new Map<Symbol, MethodMirror>();
-      if (superclass != null) {
-        result.addAll(superclass.instanceMembers);
-      }
-      declarations.values.forEach((decl) {
-        if (decl is MethodMirror &&
-            !decl.isStatic &&
-            !decl.isConstructor &&
-            !decl.isAbstract) {
-          result[decl.simpleName] = decl;
-        }
-        if (decl is VariableMirror && !decl.isStatic) {
-          var getterName = decl.simpleName;
-          result[getterName] = new JsSyntheticAccessor(
-              this, getterName, true, false, false, decl);
-          if (!decl.isFinal) {
-            var setterName = setterSymbol(decl.simpleName);
-            result[setterName] = new JsSyntheticAccessor(
-                this, setterName, false, false, false, decl);
-          }
-        }
-      });
-      _cachedInstanceMembers = result;
-    }
-    return _cachedInstanceMembers;
-  }
-
-  InstanceMirror setField(Symbol fieldName, Object arg) {
-    JsVariableMirror mirror = __variables[fieldName];
-    if (mirror != null && mirror.isStatic && !mirror.isFinal) {
-      // '$' (JS_GET_STATIC_STATE()) stores state which is stored directly, so
-      // we shouldn't use [JsLibraryMirror._globalObject] here.
-      String jsName = mirror._jsName;
-      if (!JS('bool', '# in #', jsName, JS_GET_STATIC_STATE())) {
-        throw new RuntimeError('Cannot find "$jsName" in current isolate.');
-      }
-      JS('void', '#[#] = #', JS_GET_STATIC_STATE(), jsName, arg);
-      return reflect(arg);
-    }
-    Symbol setterName = setterSymbol(fieldName);
-    if (mirror == null) {
-      JsMethodMirror setter = __setters[setterName];
-      if (setter != null) {
-        setter._invoke([arg], const {});
-        return reflect(arg);
-      }
-    }
-    throw new NoSuchStaticMethodError.method(null, setterName, [arg], null);
-  }
-
-  bool _staticFieldExists(Symbol fieldName) {
-    JsVariableMirror mirror = __variables[fieldName];
-    if (mirror != null) return mirror.isStatic;
-    JsMethodMirror getter = __getters[fieldName];
-    return getter != null && getter.isStatic;
-  }
-
-  InstanceMirror getField(Symbol fieldName) {
-    JsVariableMirror mirror = __variables[fieldName];
-    if (mirror != null && mirror.isStatic) {
-      String jsName = mirror._jsName;
-      // '$' (JS_GET_STATIC_STATE()) stores state which is read directly, so
-      // we shouldn't use [JsLibraryMirror._globalObject] here.
-      if (!JS('bool', '# in #', jsName, JS_GET_STATIC_STATE())) {
-        throw new RuntimeError('Cannot find "$jsName" in current isolate.');
-      }
-      var lazies = JS_EMBEDDED_GLOBAL('', LAZIES);
-      if (JS('bool', '# in #', jsName, lazies)) {
-        String getterName = JS('String', '#[#]', lazies, jsName);
-        return reflect(JS('', '#[#]()', JS_GET_STATIC_STATE(), getterName));
-      } else {
-        return reflect(JS('', '#[#]', JS_GET_STATIC_STATE(), jsName));
-      }
-    }
-    JsMethodMirror getter = __getters[fieldName];
-    if (getter != null && getter.isStatic) {
-      return reflect(getter._invoke(const [], const {}));
-    }
-    // If the fieldName designates a static function we have to return
-    // its closure.
-    JsMethodMirror method = __methods[fieldName];
-    if (method != null && method.isStatic) {
-      // We invoke the same getter that Dart code would execute. During
-      // initialization we have stored that getter on the function (so that
-      // we can find it more easily here).
-      var getter = JS('', "#['\$getter']", method._jsFunction);
-      if (getter == null) throw new UnimplementedError();
-      return reflect(JS('', '#()', getter));
-    }
-    throw new NoSuchStaticMethodError.method(null, fieldName, null, null);
-  }
-
-  _getInvokedInstance(Symbol constructorName, List positionalArguments,
-      [Map<Symbol, dynamic> namedArguments]) {
-    if (namedArguments != null && !namedArguments.isEmpty) {
-      throw new UnsupportedError('Named arguments are not implemented.');
-    }
-    JsMethodMirror mirror =
-        JsCache.fetch(_jsConstructorCache, n(constructorName));
-    if (mirror == null) {
-      mirror = __constructors.values
-          .firstWhere((m) => m.constructorName == constructorName, orElse: () {
-        throw new NoSuchStaticMethodError.method(
-            null, constructorName, positionalArguments, namedArguments);
-      });
-      JsCache.update(_jsConstructorCache, n(constructorName), mirror);
-    }
-    return mirror._invoke(positionalArguments, namedArguments);
-  }
-
-  InstanceMirror newInstance(Symbol constructorName, List positionalArguments,
-      [Map<Symbol, dynamic> namedArguments]) {
-    return reflect(_getInvokedInstance(
-        constructorName, positionalArguments, namedArguments));
-  }
-
-  JsLibraryMirror get owner {
-    if (_owner == null) {
-      for (var list in JsMirrorSystem.librariesByName.values) {
-        for (JsLibraryMirror library in list) {
-          // This will set _owner field on all classes as a side
-          // effect.  This gives us a fast path to reflect on a
-          // class without parsing reflection data.
-          library.__classes;
-        }
-      }
-      if (_owner == null) {
-        throw new StateError('Class "${n(simpleName)}" has no owner');
-      }
-    }
-    return _owner;
-  }
-
-  List<InstanceMirror> get metadata {
-    if (_cachedMetadata != null) return _cachedMetadata;
-    if (_metadata == null) {
-      _metadata = extractMetadata(JS('', '#.prototype', _jsConstructor));
-    }
-    return _cachedMetadata =
-        new UnmodifiableListView<InstanceMirror>(_metadata.map(reflect));
-  }
-
-  ClassMirror get superclass {
-    if (_superclass == null) {
-      var typeInformationContainer = JS_EMBEDDED_GLOBAL('', TYPE_INFORMATION);
-      List<int> typeInformation =
-          JS('List|Null', '#[#]', typeInformationContainer, _mangledName);
-      if (typeInformation != null) {
-        var type = getType(typeInformation[0]);
-        _superclass = typeMirrorFromRuntimeTypeRepresentation(this, type);
-      } else {
-        var superclassName = _fieldsDescriptor.split(';')[0].split(':')[0];
-        // TODO(zarah): Remove special handing of mixins.
-        var mixins = superclassName.split('+');
-        if (mixins.length > 1) {
-          if (mixins.length != 2) {
-            throw new RuntimeError('Strange mixin: $_fieldsDescriptor');
-          }
-          _superclass = reflectClassByMangledName(mixins[0]);
-        } else {
-          // Use _superclass == this to represent class with no superclass
-          // (Object).
-          _superclass = (superclassName == '')
-              ? this
-              : reflectClassByMangledName(superclassName);
-        }
-      }
-    }
-    return _superclass == this ? null : _superclass;
-  }
-
-  InstanceMirror invoke(Symbol memberName, List positionalArguments,
-      [Map<Symbol, dynamic> namedArguments]) {
-    // Mirror API gotcha: Calling [invoke] on a ClassMirror means invoke a
-    // static method.
-
-    if (namedArguments != null && !namedArguments.isEmpty) {
-      throw new UnsupportedError('Named arguments are not implemented.');
-    }
-    JsMethodMirror mirror = __methods[memberName];
-
-    if (mirror == null && _staticFieldExists(memberName)) {
-      return getField(memberName)
-          .invoke(#call, positionalArguments, namedArguments);
-    }
-    if (mirror == null || !mirror.isStatic) {
-      throw new NoSuchStaticMethodError.method(
-          null, memberName, positionalArguments, namedArguments);
-    }
-    if (!mirror.canInvokeReflectively()) {
-      throwInvalidReflectionError(n(memberName));
-    }
-    return reflect(mirror._invoke(positionalArguments, namedArguments));
-  }
-
-  delegate(Invocation invocation) {
-    throw new UnimplementedError();
-  }
-
-  bool get isOriginalDeclaration => true;
-
-  ClassMirror get originalDeclaration => this;
-
-  List<ClassMirror> _getSuperinterfacesWithOwner(DeclarationMirror owner) {
-    var typeInformationContainer = JS_EMBEDDED_GLOBAL('', TYPE_INFORMATION);
-    List<int> typeInformation =
-        JS('List|Null', '#[#]', typeInformationContainer, _mangledName);
-    List<ClassMirror> result = const <ClassMirror>[];
-    if (typeInformation != null) {
-      ClassMirror lookupType(int i) {
-        var type = getType(i);
-        return typeMirrorFromRuntimeTypeRepresentation(owner, type);
-      }
-
-      //We skip the first since it is the supertype.
-      result = typeInformation.skip(1).map(lookupType).toList();
-    }
-
-    return new UnmodifiableListView<ClassMirror>(result);
-  }
-
-  List<ClassMirror> get superinterfaces {
-    if (_cachedSuperinterfaces != null) return _cachedSuperinterfaces;
-    return _cachedSuperinterfaces = _getSuperinterfacesWithOwner(this);
-  }
-
-  List<TypeVariableMirror> get typeVariables {
-    if (_cachedTypeVariables != null) return _cachedTypeVariables;
-    var result = new List<TypeVariableMirror>();
-    List typeVariables =
-        JS('JSExtendableArray|Null', '#.prototype["<>"]', _jsConstructor);
-    if (typeVariables == null) return result;
-    for (int i = 0; i < typeVariables.length; i++) {
-      TypeVariable typeVariable = getMetadata(typeVariables[i]);
-      result
-          .add(new JsTypeVariableMirror(typeVariable, this, typeVariables[i]));
-    }
-    return _cachedTypeVariables = new UnmodifiableListView(result);
-  }
-
-  List<TypeMirror> get typeArguments => const <TypeMirror>[];
-
-  bool get hasReflectedType => typeVariables.length == 0;
-
-  Type get reflectedType {
-    if (!hasReflectedType) {
-      throw new UnsupportedError(
-          'Declarations of generics have no reflected type');
-    }
-    return createRuntimeType(_mangledName);
-  }
-
-  // TODO(ahe): Implement this.
-  ClassMirror get mixin => throw new UnimplementedError();
-
-  bool get isAbstract => throw new UnimplementedError();
-
-  bool get isEnum => throw new UnimplementedError();
-
-  bool isSubclassOf(ClassMirror other) {
-    if (other is! ClassMirror) {
-      throw new ArgumentError(other);
-    }
-    if (other is JsFunctionTypeMirror) {
-      return false;
-    }
-    if (other is JsClassMirror &&
-        JS('bool', '# == #', other._jsConstructor, _jsConstructor)) {
-      return true;
-    } else if (superclass == null) {
-      return false;
-    } else {
-      return superclass.isSubclassOf(other);
-    }
-  }
-}
-
-class JsVariableMirror extends JsDeclarationMirror implements VariableMirror {
-  // TODO(ahe): The values in these fields are virtually untested.
-  final String _jsName;
-  final bool isFinal;
-  final bool isStatic;
-  final _metadataFunction;
-  final DeclarationMirror _owner;
-  final int _type;
-  List _metadata;
-
-  JsVariableMirror(Symbol simpleName, this._jsName, this._type, this.isFinal,
-      this.isStatic, this._metadataFunction, this._owner)
-      : super(simpleName);
-
-  factory JsVariableMirror.from(String descriptor, metadataFunction,
-      JsDeclarationMirror owner, bool isStatic) {
-    List<String> fieldInformation = descriptor.split('-');
-    if (fieldInformation.length == 1) {
-      // The field is not available for reflection.
-      // TODO(ahe): Should return an unreflectable field.
-      return null;
-    }
-
-    String field = fieldInformation[0];
-    int length = field.length;
-    var code = fieldCode(field.codeUnitAt(length - 1));
-    bool isFinal = false;
-    if (code == 0) return null; // Inherited field.
-    bool hasGetter = (code & 3) != 0;
-    bool hasSetter = (code >> 2) != 0;
-    isFinal = !hasSetter;
-    length--;
-    String jsName;
-    String accessorName = jsName = field.substring(0, length);
-    int divider = field.indexOf(':');
-    if (divider > 0) {
-      accessorName = accessorName.substring(0, divider);
-      jsName = field.substring(divider + 1);
-    }
-    var unmangledName;
-    if (isStatic) {
-      unmangledName = mangledGlobalNames[accessorName];
-    } else {
-      String getterPrefix = JS_GET_NAME(JsGetName.GETTER_PREFIX);
-      unmangledName = mangledNames['$getterPrefix$accessorName'];
-    }
-    if (unmangledName == null) unmangledName = accessorName;
-    if (!hasSetter) {
-      // TODO(ahe): This is a hack to handle checked setters in checked mode.
-      var setterName = s('$unmangledName=');
-      for (JsMethodMirror method in owner._methods) {
-        if (method.simpleName == setterName) {
-          isFinal = false;
-          break;
-        }
-      }
-    }
-    int type = int.parse(fieldInformation[1], onError: (_) => null);
-    return new JsVariableMirror(s(unmangledName), jsName, type, isFinal,
-        isStatic, metadataFunction, owner);
-  }
-
-  String get _prettyName => 'VariableMirror';
-
-  TypeMirror get type {
-    return typeMirrorFromRuntimeTypeRepresentation(owner, getType(_type));
-  }
-
-  DeclarationMirror get owner => _owner;
-
-  List<InstanceMirror> get metadata {
-    preserveMetadata();
-    if (_metadata == null) {
-      _metadata = (_metadataFunction == null)
-          ? const []
-          : JS('', '#()', _metadataFunction);
-    }
-    return _metadata.map(reflect).toList();
-  }
-
-  static int fieldCode(int code) {
-    if (code >= 60 && code <= 64) return code - 59;
-    if (code >= 123 && code <= 126) return code - 117;
-    if (code >= 37 && code <= 43) return code - 27;
-    return 0;
-  }
-
-  _getField(JsMirror receiver) => receiver._loadField(_jsName);
-
-  void _setField(JsMirror receiver, Object arg) {
-    if (isFinal) {
-      // TODO(floitsch): when the field is non-static we don't want to have
-      // a mirror as receiver.
-      if (isStatic) {
-        throw new NoSuchStaticMethodError.method(
-            null, setterSymbol(simpleName), [arg], null);
-      }
-      throw new NoSuchMethodError(this, setterSymbol(simpleName), [arg], null);
-    }
-    receiver._storeField(_jsName, arg);
-  }
-
-  // TODO(ahe): Implement this method.
-  bool get isConst => throw new UnimplementedError();
-}
-
-class JsClosureMirror extends JsInstanceMirror implements ClosureMirror {
-  JsClosureMirror(reflectee) : super(reflectee);
-
-  MethodMirror get function {
-    String cacheName = Primitives.mirrorFunctionCacheName;
-    JsMethodMirror cachedFunction;
-    // TODO(ahe): Restore caching.
-    //= JS('JsMethodMirror|Null', r'#.constructor[#]', reflectee, cacheName);
-    if (cachedFunction != null) return cachedFunction;
-    disableTreeShaking();
-    // TODO(ahe): What about optional parameters (named or not).
-    String callPrefix = '${JS_GET_NAME(JsGetName.CALL_PREFIX)}\$';
-
-    String callName = JS(
-        'String|Null',
-        r'''
-          (function(reflectee, callPrefix) {
-            var properties = Object.keys(reflectee.constructor.prototype);
-            var callPrefixLength = callPrefix.length;
-            for (var i = 0; i < properties.length; i++) {
-              var property = properties[i];
-              if (callPrefix == property.substring(0, callPrefixLength) &&
-                  property[callPrefixLength] >= "0" &&
-                  property[callPrefixLength] <= "9") {
-                return property;
-              }
-            }
-            return null;
-          })(#, #)''',
-        reflectee,
-        callPrefix);
-
-    if (callName == null) {
-      throw new RuntimeError('Cannot find callName on "$reflectee"');
-    }
-    // TODO(floitsch): What about optional parameters?
-    int parameterCount = int.parse(callName.split(r'$')[1]);
-    if (reflectee is BoundClosure) {
-      var target = BoundClosure.targetOf(reflectee);
-      var self = BoundClosure.selfOf(reflectee);
-      var name = mangledNames[BoundClosure.nameOf(reflectee)];
-      if (name == null) {
-        throwInvalidReflectionError(name);
-      }
-      cachedFunction =
-          new JsMethodMirror.fromUnmangledName(name, target, false, false);
-    } else {
-      bool isStatic = true; // TODO(ahe): Compute isStatic correctly.
-      var jsFunction = JS('', '#[#]', reflectee, callName);
-      var dummyOptionalParameterCount = 0;
-      cachedFunction = new JsMethodMirror(
-          s(callName),
-          jsFunction,
-          parameterCount,
-          dummyOptionalParameterCount,
-          false,
-          false,
-          isStatic,
-          false,
-          false);
-    }
-    JS('void', r'#.constructor[#] = #', reflectee, cacheName, cachedFunction);
-    return cachedFunction;
-  }
-
-  InstanceMirror apply(List positionalArguments,
-      [Map<Symbol, dynamic> namedArguments]) {
-    return reflect(
-        Function.apply(reflectee, positionalArguments, namedArguments));
-  }
-
-  ClassMirror get type {
-    // Classes that implement [call] do not subclass [Closure], but only
-    // implement [Function], so are rejected by this test.
-    if (reflectee is Closure) {
-      var functionRti = extractFunctionTypeObjectFrom(reflectee);
-      if (functionRti != null) {
-        return new JsFunctionTypeMirror(functionRti, null);
-      }
-    }
-    // Use the JsInstanceMirror method to return the JsClassMirror.
-    // TODO(sra): Should there be a TypeMirror that is both a ClassMirror and
-    // FunctionTypeMirror?
-    return super.type;
-  }
-
-  String toString() => "ClosureMirror on '${Error.safeToString(reflectee)}'";
-
-  // TODO(ahe): Implement this method.
-  String get source => throw new UnimplementedError();
-}
-
-class JsMethodMirror extends JsDeclarationMirror implements MethodMirror {
-  final _jsFunction;
-  final int _requiredParameterCount;
-  final int _optionalParameterCount;
-  final bool isGetter;
-  final bool isSetter;
-  final bool isStatic;
-  final bool isConstructor;
-  final bool isOperator;
-  DeclarationMirror _owner;
-  List _metadata;
-  TypeMirror _returnType;
-  UnmodifiableListView<ParameterMirror> _parameters;
-
-  JsMethodMirror(
-      Symbol simpleName,
-      this._jsFunction,
-      this._requiredParameterCount,
-      this._optionalParameterCount,
-      this.isGetter,
-      this.isSetter,
-      this.isStatic,
-      this.isConstructor,
-      this.isOperator)
-      : super(simpleName);
-
-  factory JsMethodMirror.fromUnmangledName(
-      String name, jsFunction, bool isStatic, bool isConstructor) {
-    List<String> info = name.split(':');
-    name = info[0];
-    bool isOperator = isOperatorName(name);
-    bool isSetter = !isOperator && name.endsWith('=');
-    int requiredParameterCount = 0;
-    int optionalParameterCount = 0;
-    bool isGetter = false;
-    if (info.length == 1) {
-      if (isSetter) {
-        requiredParameterCount = 1;
-      } else {
-        isGetter = true;
-        requiredParameterCount = 0;
-      }
-    } else {
-      ReflectionInfo reflectionInfo = new ReflectionInfo(jsFunction);
-      requiredParameterCount = reflectionInfo.requiredParameterCount;
-      optionalParameterCount = reflectionInfo.optionalParameterCount;
-      assert(int.parse(info[1]) ==
-          requiredParameterCount + optionalParameterCount);
-    }
-    return new JsMethodMirror(
-        s(name),
-        jsFunction,
-        requiredParameterCount,
-        optionalParameterCount,
-        isGetter,
-        isSetter,
-        isStatic,
-        isConstructor,
-        isOperator);
-  }
-
-  String get _prettyName => 'MethodMirror';
-
-  int get _parameterCount => _requiredParameterCount + _optionalParameterCount;
-
-  List<ParameterMirror> get parameters {
-    if (_parameters != null) return _parameters;
-    metadata; // Compute _parameters as a side-effect of extracting metadata.
-    return _parameters;
-  }
-
-  bool canInvokeReflectively() {
-    return hasReflectableProperty(_jsFunction);
-  }
-
-  DeclarationMirror get owner => _owner;
-
-  TypeMirror get returnType {
-    metadata; // Compute _returnType as a side-effect of extracting metadata.
-    return _returnType;
-  }
-
-  List<InstanceMirror> get metadata {
-    if (_metadata == null) {
-      var raw = extractMetadata(_jsFunction);
-      var formals = new List<ParameterMirror>(_parameterCount);
-      ReflectionInfo info = new ReflectionInfo(_jsFunction);
-      if (info != null) {
-        assert(_parameterCount ==
-            info.requiredParameterCount + info.optionalParameterCount);
-        var functionType = info.functionType;
-        var type;
-        if (functionType is int) {
-          type = new JsFunctionTypeMirror(info.computeFunctionRti(null), this);
-          assert(_parameterCount == type.parameters.length);
-        } else if (isTopLevel) {
-          type = new JsFunctionTypeMirror(info.computeFunctionRti(null), owner);
-        } else {
-          TypeMirror ownerType = owner;
-          JsClassMirror ownerClass = ownerType.originalDeclaration;
-          type = new JsFunctionTypeMirror(
-              info.computeFunctionRti(ownerClass._jsConstructor), owner);
-        }
-        // Constructors aren't reified with their return type.
-        if (isConstructor) {
-          _returnType = owner;
-        } else {
-          _returnType = type.returnType;
-        }
-        int i = 0;
-        bool isNamed = info.areOptionalParametersNamed;
-        for (JsParameterMirror parameter in type.parameters) {
-          var name = info.parameterName(i);
-          List<int> annotations = info.parameterMetadataAnnotations(i);
-          var p;
-          if (i < info.requiredParameterCount) {
-            p = new JsParameterMirror(name, this, parameter._type,
-                metadataList: annotations);
-          } else {
-            var defaultValue = info.defaultValue(i);
-            p = new JsParameterMirror(name, this, parameter._type,
-                metadataList: annotations,
-                isOptional: true,
-                isNamed: isNamed,
-                defaultValue: defaultValue);
-          }
-          formals[i++] = p;
-        }
-      }
-      _parameters = new UnmodifiableListView<ParameterMirror>(formals);
-      _metadata = new UnmodifiableListView(raw.map(reflect));
-    }
-    return _metadata;
-  }
-
-  Symbol get constructorName {
-    // TODO(ahe): I believe it is more appropriate to throw an exception or
-    // return null.
-    if (!isConstructor) return Symbol.empty;
-    String name = n(simpleName);
-    int index = name.indexOf('.');
-    if (index == -1) return Symbol.empty;
-    return s(name.substring(index + 1));
-  }
-
-  _invoke(List positionalArguments, Map<Symbol, dynamic> namedArguments) {
-    if (namedArguments != null && !namedArguments.isEmpty) {
-      throw new UnsupportedError('Named arguments are not implemented.');
-    }
-    if (!isStatic && !isConstructor) {
-      throw new RuntimeError('Cannot invoke instance method without receiver.');
-    }
-    int positionalLength = positionalArguments.length;
-    if (positionalLength < _requiredParameterCount ||
-        positionalLength > _parameterCount ||
-        _jsFunction == null) {
-      // TODO(ahe): What receiver to use?
-      throw new NoSuchMethodError(
-          owner, simpleName, positionalArguments, namedArguments);
-    }
-    if (positionalLength < _parameterCount) {
-      // Fill up with default values.
-      // Make a copy so we don't modify the input.
-      positionalArguments = positionalArguments.toList();
-      for (int i = positionalLength; i < parameters.length; i++) {
-        JsParameterMirror parameter = parameters[i];
-        positionalArguments.add(parameter.defaultValue.reflectee);
-      }
-    }
-    // Using JS_GET_STATIC_STATE() ('$') here is actually correct, although
-    // _jsFunction may not be a property of '$', most static functions do not
-    // care who their receiver is. But to lazy getters, it is important that
-    // 'this' is '$'.
-    return JS('', r'#.apply(#, #)', _jsFunction, JS_GET_STATIC_STATE(),
-        new List.from(positionalArguments));
-  }
-
-  _getField(JsMirror receiver) {
-    if (isGetter) {
-      return _invoke([], null);
-    } else {
-      // TODO(ahe): Closurize method.
-      throw new UnimplementedError('getField on $receiver');
-    }
-  }
-
-  _setField(JsMirror receiver, Object arg) {
-    if (isSetter) {
-      return _invoke([arg], null);
-    } else {
-      throw new NoSuchMethodError(this, setterSymbol(simpleName), [], null);
-    }
-  }
-
-  // Abstract methods are tree-shaken away.
-  bool get isAbstract => false;
-
-  // TODO(ahe, 14633): This might not be true for all cases.
-  bool get isSynthetic => false;
-
-  // TODO(ahe): Test this.
-  bool get isRegularMethod => !isGetter && !isSetter && !isConstructor;
-
-  // TODO(ahe): Implement this method.
-  bool get isConstConstructor => throw new UnimplementedError();
-
-  // TODO(ahe): Implement this method.
-  bool get isGenerativeConstructor => throw new UnimplementedError();
-
-  // TODO(ahe): Implement this method.
-  bool get isRedirectingConstructor => throw new UnimplementedError();
-
-  // TODO(ahe): Implement this method.
-  bool get isFactoryConstructor => throw new UnimplementedError();
-
-  // TODO(ahe): Implement this method.
-  String get source => throw new UnimplementedError();
-}
-
-class JsParameterMirror extends JsDeclarationMirror implements ParameterMirror {
-  final DeclarationMirror owner;
-  // A JS object representing the type.
-  final _type;
-
-  final bool isOptional;
-
-  final bool isNamed;
-
-  final int _defaultValue;
-
-  final List<int> metadataList;
-
-  JsParameterMirror(String unmangledName, this.owner, this._type,
-      {this.metadataList: const <int>[],
-      this.isOptional: false,
-      this.isNamed: false,
-      defaultValue})
-      : _defaultValue = defaultValue,
-        super(s(unmangledName));
-
-  String get _prettyName => 'ParameterMirror';
-
-  TypeMirror get type {
-    return typeMirrorFromRuntimeTypeRepresentation(owner, _type);
-  }
-
-  // Only true for static fields, never for a parameter.
-  bool get isStatic => false;
-
-  // TODO(ahe): Implement this.
-  bool get isFinal => false;
-
-  // TODO(ahe): Implement this.
-  bool get isConst => false;
-
-  bool get hasDefaultValue => _defaultValue != null;
-
-  get defaultValue {
-    return hasDefaultValue ? reflect(getMetadata(_defaultValue)) : null;
-  }
-
-  List<InstanceMirror> get metadata {
-    preserveMetadata();
-    return metadataList.map((int i) => reflect(getMetadata(i))).toList();
-  }
-}
-
-class JsTypedefMirror extends JsDeclarationMirror implements TypedefMirror {
-  final String _mangledName;
-  JsFunctionTypeMirror referent;
-
-  JsTypedefMirror(Symbol simpleName, this._mangledName, _typeData)
-      : super(simpleName) {
-    referent = new JsFunctionTypeMirror(_typeData, this);
-  }
-
-  JsFunctionTypeMirror get value => referent;
-
-  String get _prettyName => 'TypedefMirror';
-
-  bool get hasReflectedType => throw new UnimplementedError();
-
-  Type get reflectedType => createRuntimeType(_mangledName);
-
-  // TODO(floitsch): Implement this method.
-  List<TypeVariableMirror> get typeVariables => throw new UnimplementedError();
-
-  // TODO(floitsch): Implement this method.
-  List<TypeMirror> get typeArguments => throw new UnimplementedError();
-
-  bool get isOriginalDeclaration => true;
-
-  TypeMirror get originalDeclaration => this;
-
-  // TODO(floitsch): Implement this method.
-  DeclarationMirror get owner => throw new UnimplementedError();
-
-  // TODO(ahe): Implement this method.
-  List<InstanceMirror> get metadata => throw new UnimplementedError();
-
-  bool isSubtypeOf(TypeMirror other) => throw new UnimplementedError();
-  bool isAssignableTo(TypeMirror other) => throw new UnimplementedError();
-}
-
-// TODO(ahe): Remove this class when API is updated.
-class BrokenClassMirror {
-  bool get hasReflectedType => throw new UnimplementedError();
-  Type get reflectedType => throw new UnimplementedError();
-  ClassMirror get superclass => throw new UnimplementedError();
-  List<ClassMirror> get superinterfaces => throw new UnimplementedError();
-  Map<Symbol, DeclarationMirror> get declarations =>
-      throw new UnimplementedError();
-  Map<Symbol, MethodMirror> get instanceMembers =>
-      throw new UnimplementedError();
-  Map<Symbol, MethodMirror> get staticMembers => throw new UnimplementedError();
-  ClassMirror get mixin => throw new UnimplementedError();
-  InstanceMirror newInstance(Symbol constructorName, List positionalArguments,
-          [Map<Symbol, dynamic> namedArguments]) =>
-      throw new UnimplementedError();
-  InstanceMirror invoke(Symbol memberName, List positionalArguments,
-          [Map<Symbol, dynamic> namedArguments]) =>
-      throw new UnimplementedError();
-  InstanceMirror getField(Symbol fieldName) => throw new UnimplementedError();
-  InstanceMirror setField(Symbol fieldName, Object value) =>
-      throw new UnimplementedError();
-  delegate(Invocation invocation) => throw new UnimplementedError();
-  List<TypeVariableMirror> get typeVariables => throw new UnimplementedError();
-  List<TypeMirror> get typeArguments => throw new UnimplementedError();
-  TypeMirror get originalDeclaration => throw new UnimplementedError();
-  Symbol get simpleName => throw new UnimplementedError();
-  Symbol get qualifiedName => throw new UnimplementedError();
-  bool get isPrivate => throw new UnimplementedError();
-  bool get isTopLevel => throw new UnimplementedError();
-  SourceLocation get location => throw new UnimplementedError();
-  List<InstanceMirror> get metadata => throw new UnimplementedError();
-}
-
-class JsFunctionTypeMirror extends BrokenClassMirror
-    implements FunctionTypeMirror {
-  final _typeData;
-  String _cachedToString;
-  TypeMirror _cachedReturnType;
-  UnmodifiableListView<ParameterMirror> _cachedParameters;
-  Type _cachedReflectedType;
-  DeclarationMirror owner;
-
-  JsFunctionTypeMirror(this._typeData, this.owner);
-
-  bool get _hasReturnType {
-    return JS('bool', '# in #',
-        JS_GET_NAME(JsGetName.FUNCTION_TYPE_RETURN_TYPE_TAG), _typeData);
-  }
-
-  get _returnType {
-    return JS('', '#[#]', _typeData,
-        JS_GET_NAME(JsGetName.FUNCTION_TYPE_RETURN_TYPE_TAG));
-  }
-
-  bool get _isVoid {
-    return JS('bool', '!!#[#]', _typeData,
-        JS_GET_NAME(JsGetName.FUNCTION_TYPE_VOID_RETURN_TAG));
-  }
-
-  bool get _hasArguments {
-    return JS(
-        'bool',
-        '# in #',
-        JS_GET_NAME(JsGetName.FUNCTION_TYPE_REQUIRED_PARAMETERS_TAG),
-        _typeData);
-  }
-
-  List get _arguments {
-    return JS('JSExtendableArray', '#[#]', _typeData,
-        JS_GET_NAME(JsGetName.FUNCTION_TYPE_REQUIRED_PARAMETERS_TAG));
-  }
-
-  bool get _hasOptionalArguments {
-    return JS(
-        'bool',
-        '# in #',
-        JS_GET_NAME(JsGetName.FUNCTION_TYPE_OPTIONAL_PARAMETERS_TAG),
-        _typeData);
-  }
-
-  List get _optionalArguments {
-    return JS('JSExtendableArray', '#[#]', _typeData,
-        JS_GET_NAME(JsGetName.FUNCTION_TYPE_OPTIONAL_PARAMETERS_TAG));
-  }
-
-  bool get _hasNamedArguments {
-    return JS('bool', '# in #',
-        JS_GET_NAME(JsGetName.FUNCTION_TYPE_NAMED_PARAMETERS_TAG), _typeData);
-  }
-
-  get _namedArguments {
-    return JS('=Object', '#[#]', _typeData,
-        JS_GET_NAME(JsGetName.FUNCTION_TYPE_NAMED_PARAMETERS_TAG));
-  }
-
-  bool get isOriginalDeclaration => true;
-
-  bool get isAbstract => false;
-
-  bool get isEnum => false;
-
-  TypeMirror get returnType {
-    if (_cachedReturnType != null) return _cachedReturnType;
-    if (_isVoid) return _cachedReturnType = JsMirrorSystem._voidType;
-    if (!_hasReturnType) return _cachedReturnType = JsMirrorSystem._dynamicType;
-    return _cachedReturnType =
-        typeMirrorFromRuntimeTypeRepresentation(owner, _returnType);
-  }
-
-  List<ParameterMirror> get parameters {
-    if (_cachedParameters != null) return _cachedParameters;
-    var result = <ParameterMirror>[];
-    int parameterCount = 0;
-    if (_hasArguments) {
-      for (var type in _arguments) {
-        result.add(
-            new JsParameterMirror('argument${parameterCount++}', this, type));
-      }
-    }
-    if (_hasOptionalArguments) {
-      for (var type in _optionalArguments) {
-        result.add(
-            new JsParameterMirror('argument${parameterCount++}', this, type));
-      }
-    }
-    if (_hasNamedArguments) {
-      for (var name in extractKeys(_namedArguments)) {
-        var type = JS('', '#[#]', _namedArguments, name);
-        result.add(new JsParameterMirror(name, this, type));
-      }
-    }
-    return _cachedParameters =
-        new UnmodifiableListView<ParameterMirror>(result);
-  }
-
-  bool get hasReflectedType => true;
-  Type get reflectedType => _cachedReflectedType ??=
-      createRuntimeType(runtimeTypeToString(_typeData));
-
-  String _unmangleIfPreserved(String mangled) {
-    String result = unmangleGlobalNameIfPreservedAnyways(mangled);
-    if (result != null) return result;
-    return mangled;
-  }
-
-  String toString() {
-    if (_cachedToString != null) return _cachedToString;
-    var s = "FunctionTypeMirror on '(";
-    var sep = '';
-    if (_hasArguments) {
-      for (var argument in _arguments) {
-        s += sep;
-        s += _unmangleIfPreserved(runtimeTypeToString(argument));
-        sep = ', ';
-      }
-    }
-    if (_hasOptionalArguments) {
-      s += '$sep[';
-      sep = '';
-      for (var argument in _optionalArguments) {
-        s += sep;
-        s += _unmangleIfPreserved(runtimeTypeToString(argument));
-        sep = ', ';
-      }
-      s += ']';
-    }
-    if (_hasNamedArguments) {
-      s += '$sep{';
-      sep = '';
-      for (var name in extractKeys(_namedArguments)) {
-        s += sep;
-        s += '$name: ';
-        s += _unmangleIfPreserved(
-            runtimeTypeToString(JS('', '#[#]', _namedArguments, name)));
-        sep = ', ';
-      }
-      s += '}';
-    }
-    s += ') -> ';
-    if (_isVoid) {
-      s += 'void';
-    } else if (_hasReturnType) {
-      s += _unmangleIfPreserved(runtimeTypeToString(_returnType));
-    } else {
-      s += 'dynamic';
-    }
-    return _cachedToString = "$s'";
-  }
-
-  bool isSubclassOf(ClassMirror other) => false;
-
-  bool isSubtypeOf(TypeMirror other) => throw new UnimplementedError();
-
-  bool isAssignableTo(TypeMirror other) => throw new UnimplementedError();
-
-  // TODO(ahe): Implement this method.
-  MethodMirror get callMethod => throw new UnimplementedError();
-}
-
-int findTypeVariableIndex(List<TypeVariableMirror> typeVariables, String name) {
-  for (int i = 0; i < typeVariables.length; i++) {
-    if (typeVariables[i].simpleName == s(name)) {
-      return i;
-    }
-  }
-  throw new ArgumentError('Type variable not present in list.');
-}
-
-TypeMirror typeMirrorFromRuntimeTypeRepresentation(
-    DeclarationMirror owner, var /*int|List|JsFunction|TypeImpl*/ type) {
-  // TODO(ahe): This method might benefit from using convertRtiToRuntimeType
-  // instead of working on strings.
-  if (type == null) {
-    return JsMirrorSystem._dynamicType;
-  }
-
-  ClassMirror ownerClass;
-  DeclarationMirror context = owner;
-  while (context != null) {
-    if (context is ClassMirror) {
-      ownerClass = context;
-      break;
-    }
-    // TODO(ahe): Get type parameters and arguments from typedefs.
-    if (context is TypedefMirror) break;
-    context = context.owner;
-  }
-
-  String representation;
-  if (type is TypeImpl) {
-    return reflectType(type);
-  } else if (ownerClass == null) {
-    representation = runtimeTypeToString(type);
-  } else if (ownerClass.isOriginalDeclaration) {
-    if (type is num) {
-      // [type] represents a type variable so in the context of an original
-      // declaration the corresponding type variable should be returned.
-      TypeVariable typeVariable = getMetadata(type);
-      List<TypeVariableMirror> typeVariables = ownerClass.typeVariables;
-      int index = findTypeVariableIndex(typeVariables, typeVariable.name);
-      return typeVariables[index];
-    } else {
-      // Nested type variables will be retrieved lazily (the integer
-      // representation is kept in the string) so they are not processed here.
-      representation = runtimeTypeToString(type);
-    }
-  } else {
-    TypeMirror getTypeArgument(int index) {
-      TypeVariable typeVariable = getMetadata(index);
-      int variableIndex =
-          findTypeVariableIndex(ownerClass.typeVariables, typeVariable.name);
-      return ownerClass.typeArguments[variableIndex];
-    }
-
-    if (type is num) {
-      // [type] represents a type variable used as type argument for example
-      // the type argument of Bar: class Foo<T> extends Bar<T> {}
-      TypeMirror typeArgument = getTypeArgument(type);
-      if (typeArgument is JsTypeVariableMirror) return typeArgument;
-    }
-    String substituteTypeVariable(int index) {
-      var typeArgument = getTypeArgument(index);
-      if (typeArgument is JsTypeVariableMirror) {
-        return '${typeArgument._metadataIndex}';
-      }
-      if (typeArgument is! JsClassMirror &&
-          typeArgument is! JsTypeBoundClassMirror) {
-        if (typeArgument == JsMirrorSystem._dynamicType) {
-          return 'dynamic';
-        } else if (typeArgument == JsMirrorSystem._voidType) {
-          return 'void';
-        } else {
-          // TODO(ahe): This case shouldn't happen.
-          return 'dynamic';
-        }
-      }
-      return (typeArgument as dynamic)._mangledName;
-    }
-
-    representation =
-        runtimeTypeToString(type, onTypeVariable: substituteTypeVariable);
-  }
-  if (representation != null) {
-    return reflectClassByMangledName(
-        getMangledTypeName(createRuntimeType(representation)));
-  }
-  String typedefPropertyName = JS_GET_NAME(JsGetName.TYPEDEF_TAG);
-  if (JS('', '#[#]', type, typedefPropertyName) != null) {
-    return typeMirrorFromRuntimeTypeRepresentation(
-        owner, JS('', '#[#]', type, typedefPropertyName));
-  } else if (isDartFunctionType(type)) {
-    return new JsFunctionTypeMirror(type, owner);
-  }
-  return reflectClass(Function);
-}
-
-Symbol computeQualifiedName(DeclarationMirror owner, Symbol simpleName) {
-  if (owner == null) return simpleName;
-  String ownerName = n(owner.qualifiedName);
-  return s('$ownerName.${n(simpleName)}');
-}
-
-List extractMetadata(victim) {
-  preserveMetadata();
-  var metadataFunction;
-  if (JS('bool', 'Object.prototype.hasOwnProperty.call(#, "@")', victim)) {
-    metadataFunction = JS('', '#["@"]', victim);
-  }
-  if (metadataFunction != null) return JS('', '#()', metadataFunction);
-  if (JS('bool', 'typeof # != "function"', victim)) return const [];
-  if (JS('bool', '# in #', r'$metadataIndex', victim)) {
-    return JSArray
-        .markFixedList(JS('JSExtendableArray',
-            r'#.$reflectionInfo.splice(#.$metadataIndex)', victim, victim))
-        .map((i) => getMetadata(i))
-        .toList();
-  }
-  return const [];
-}
-
-void parseCompactFieldSpecification(JsDeclarationMirror owner,
-    fieldSpecification, bool isStatic, List<Mirror> result) {
-  List fieldsMetadata = null;
-  List<String> fields;
-  if (fieldSpecification is List) {
-    fields = splitFields(fieldSpecification[0], ',');
-    fieldsMetadata = fieldSpecification.sublist(1);
-  } else if (fieldSpecification is String) {
-    fields = splitFields(fieldSpecification, ',');
-  } else {
-    fields = [];
-  }
-  int fieldNumber = 0;
-  for (String field in fields) {
-    if (r'$ti' == field) continue; // Strip type info pseudofield.
-    var metadata;
-    if (fieldsMetadata != null) {
-      metadata = fieldsMetadata[fieldNumber++];
-    }
-    var mirror = new JsVariableMirror.from(field, metadata, owner, isStatic);
-    if (mirror != null) {
-      result.add(mirror);
-    }
-  }
-}
-
-/// Similar to [String.split], but returns an empty list if [string] is empty.
-List<String> splitFields(String string, Pattern pattern) {
-  if (string.isEmpty) return <String>[];
-  return string.split(pattern);
-}
-
-bool isOperatorName(String name) {
-  switch (name) {
-    case '==':
-    case '[]':
-    case '*':
-    case '/':
-    case '%':
-    case '~/':
-    case '+':
-    case '<<':
-    case '>>':
-    case '>=':
-    case '>':
-    case '<=':
-    case '<':
-    case '&':
-    case '^':
-    case '|':
-    case '-':
-    case 'unary-':
-    case '[]=':
-    case '~':
-      return true;
-    default:
-      return false;
-  }
-}
-
-/// Returns true if the key represent ancillary reflection data, that is, not a
-/// method.
-bool isReflectiveDataInPrototype(String key) {
-  if (key == JS_GET_NAME(JsGetName.CLASS_DESCRIPTOR_PROPERTY) ||
-      key == METHODS_WITH_OPTIONAL_ARGUMENTS) {
-    return true;
-  }
-  String firstChar = key[0];
-  return firstChar == '*' || firstChar == '+';
-}
-
-/// Returns `true` if [jsFunction] is an ordinary reflectable method and
-/// not a (potentially reflectable) stub or otherwise non-reflectable method.
-bool isOrdinaryReflectableMethod(var jsFunction) {
-  return JS('bool', r'#.$reflectable === 1', jsFunction);
-}
-
-/// Returns true if [key] is only an aliased entry for [function] in the
-/// prototype.
-bool isAliasedSuperMethod(var jsFunction, String key) {
-  var stubName = JS('String|Null', r'#.$stubName', jsFunction);
-  return stubName != null && key != stubName;
-}
-
-class NoSuchStaticMethodError extends Error implements NoSuchMethodError {
-  static const int MISSING_CONSTRUCTOR = 0;
-  static const int MISSING_METHOD = 1;
-  final ClassMirror _cls;
-  final Symbol _name;
-  final List _positionalArguments;
-  final Map<Symbol, dynamic> _namedArguments;
-  final int _kind;
-
-  NoSuchStaticMethodError.missingConstructor(
-      this._cls, this._name, this._positionalArguments, this._namedArguments)
-      : _kind = MISSING_CONSTRUCTOR;
-
-  /// If the given class is `null` the static method/getter/setter is top-level.
-  NoSuchStaticMethodError.method(
-      this._cls, this._name, this._positionalArguments, this._namedArguments)
-      : _kind = MISSING_METHOD;
-
-  String toString() {
-    // TODO(floitsch): show arguments.
-    switch (_kind) {
-      case MISSING_CONSTRUCTOR:
-        return "NoSuchMethodError: No constructor named '${n(_name)}' in class"
-            " '${n(_cls.qualifiedName)}'.";
-      case MISSING_METHOD:
-        if (_cls == null) {
-          return "NoSuchMethodError: No top-level method named '${n(_name)}'.";
-        }
-        return "NoSuchMethodError: No static method named '${n(_name)}' in"
-            " class '${n(_cls.qualifiedName)}'";
-      default:
-        return 'NoSuchMethodError';
-    }
-  }
-}
-
-Symbol getSymbol(String name, LibraryMirror library) {
-  if (_isPublicSymbol(name)) {
-    return new _symbol_dev.Symbol.validated(name);
-  }
-  if (library == null) {
-    throw new ArgumentError('Library required for private symbol name: $name');
-  }
-  if (!_symbol_dev.Symbol.isValidSymbol(name)) {
-    throw new ArgumentError('Not a valid symbol name: $name');
-  }
-  throw new UnimplementedError(
-      'MirrorSystem.getSymbol not implemented for private names');
-}
-
-bool _isPublicSymbol(String name) {
-  // A symbol is public if it doesn't start with '_' and it doesn't
-  // have a part (following a '.') that starts with '_'.
-  const int UNDERSCORE = 0x5f;
-  if (name.isEmpty) return true;
-  int index = -1;
-  do {
-    if (name.codeUnitAt(index + 1) == UNDERSCORE) return false;
-    index = name.indexOf('.', index + 1);
-  } while (index >= 0 && index + 1 < name.length);
-  return true;
-}
diff --git a/sdk/lib/_internal/js_runtime/lib/linked_hash_map.dart b/sdk/lib/_internal/js_runtime/lib/linked_hash_map.dart
index 341ce90..46f945b 100644
--- a/sdk/lib/_internal/js_runtime/lib/linked_hash_map.dart
+++ b/sdk/lib/_internal/js_runtime/lib/linked_hash_map.dart
@@ -98,12 +98,12 @@
       var strings = _strings;
       if (strings == null) return null;
       LinkedHashMapCell cell = _getTableCell(strings, key);
-      return (cell == null) ? null : cell.hashMapCellValue;
+      return JS('', '#', cell == null ? null : cell.hashMapCellValue);
     } else if (_isNumericKey(key)) {
       var nums = _nums;
       if (nums == null) return null;
       LinkedHashMapCell cell = _getTableCell(nums, key);
-      return (cell == null) ? null : cell.hashMapCellValue;
+      return JS('', '#', cell == null ? null : cell.hashMapCellValue);
     } else {
       return internalGet(key);
     }
@@ -116,7 +116,7 @@
     int index = internalFindBucketIndex(bucket, key);
     if (index < 0) return null;
     LinkedHashMapCell cell = JS('var', '#[#]', bucket, index);
-    return cell.hashMapCellValue;
+    return JS('', '#', cell.hashMapCellValue);
   }
 
   void operator []=(K key, V value) {
@@ -182,7 +182,7 @@
     _unlinkCell(cell);
     // TODO(kasperl): Consider getting rid of the bucket list when
     // the length reaches zero.
-    return cell.hashMapCellValue;
+    return JS('', '#', cell.hashMapCellValue);
   }
 
   void clear() {
@@ -197,7 +197,9 @@
     LinkedHashMapCell cell = _first;
     int modifications = _modifications;
     while (cell != null) {
-      action(cell.hashMapCellKey, cell.hashMapCellValue);
+      K key = JS('', '#', cell.hashMapCellKey);
+      V value = JS('', '#', cell.hashMapCellValue);
+      action(key, value);
       if (modifications != _modifications) {
         throw new ConcurrentModificationError(this);
       }
@@ -220,7 +222,7 @@
     if (cell == null) return null;
     _unlinkCell(cell);
     _deleteTableEntry(table, key);
-    return cell.hashMapCellValue;
+    return JS('', '#', cell.hashMapCellValue);
   }
 
   void _modified() {
@@ -398,7 +400,7 @@
     LinkedHashMapCell cell = _map._first;
     int modifications = _map._modifications;
     while (cell != null) {
-      f(cell.hashMapCellKey);
+      f(JS('', '#', cell.hashMapCellKey));
       if (modifications != _map._modifications) {
         throw new ConcurrentModificationError(_map);
       }
@@ -426,7 +428,7 @@
       _current = null;
       return false;
     } else {
-      _current = _cell.hashMapCellKey;
+      _current = JS('', '#', _cell.hashMapCellKey);
       _cell = _cell._next;
       return true;
     }
diff --git a/sdk/lib/_internal/js_runtime/lib/mirrors_patch.dart b/sdk/lib/_internal/js_runtime/lib/mirrors_patch.dart
deleted file mode 100644
index f23a07e..0000000
--- a/sdk/lib/_internal/js_runtime/lib/mirrors_patch.dart
+++ /dev/null
@@ -1,51 +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.
-
-// Patch library for dart:mirrors.
-
-import 'dart:_js_helper' show patch;
-import 'dart:_js_mirrors' as js;
-
-@patch
-class MirrorSystem {
-  @patch
-  LibraryMirror findLibrary(Symbol libraryName) {
-    return libraries.values
-        .singleWhere((library) => library.simpleName == libraryName);
-  }
-
-  @patch
-  static String getName(Symbol symbol) => js.getName(symbol);
-
-  @patch
-  static Symbol getSymbol(String name, [LibraryMirror library]) {
-    return js.getSymbol(name, library);
-  }
-}
-
-@patch
-MirrorSystem currentMirrorSystem() => js.currentJsMirrorSystem;
-
-@patch
-InstanceMirror reflect(Object reflectee) => js.reflect(reflectee);
-
-@patch
-ClassMirror reflectClass(Type key) {
-  if (key is! Type || key == dynamic) {
-    throw new ArgumentError('$key does not denote a class');
-  }
-  TypeMirror tm = reflectType(key);
-  if (tm is! ClassMirror) {
-    throw new ArgumentError("$key does not denote a class");
-  }
-  return (tm as ClassMirror).originalDeclaration;
-}
-
-@patch
-TypeMirror reflectType(Type key, [List<Type> typeArguments]) {
-  if (key == dynamic) {
-    return currentMirrorSystem().dynamicType;
-  }
-  return js.reflectType(key, typeArguments);
-}
diff --git a/sdk/lib/_internal/sdk_library_metadata/lib/libraries.dart b/sdk/lib/_internal/sdk_library_metadata/lib/libraries.dart
index c2ba34e..5e1c046 100644
--- a/sdk/lib/_internal/sdk_library_metadata/lib/libraries.dart
+++ b/sdk/lib/_internal/sdk_library_metadata/lib/libraries.dart
@@ -106,7 +106,7 @@
   "mirrors": const LibraryInfo("mirrors/mirrors.dart",
       categories: "Client,Server",
       maturity: Maturity.UNSTABLE,
-      dart2jsPatchPath: "_internal/js_runtime/lib/mirrors_patch.dart"),
+      dart2jsPatchPath: "_internal/js_runtime/lib/mirrors_patch_cfe.dart"),
   "nativewrappers": const LibraryInfo("html/dartium/nativewrappers.dart",
       categories: "Client",
       implementation: true,
@@ -157,13 +157,6 @@
       categories: "",
       documented: false,
       platforms: DART2JS_PLATFORM),
-  "_isolate_helper": const LibraryInfo(
-      "_internal/js_runtime/lib/isolate_helper.dart",
-      categories: "",
-      documented: false,
-      platforms: DART2JS_PLATFORM),
-  "_js_mirrors": const LibraryInfo("_internal/js_runtime/lib/js_mirrors.dart",
-      categories: "", documented: false, platforms: DART2JS_PLATFORM),
   "_js_names": const LibraryInfo("_internal/js_runtime/lib/js_names.dart",
       categories: "", documented: false, platforms: DART2JS_PLATFORM),
   "_js_primitives": const LibraryInfo(
diff --git a/sdk/lib/core/errors.dart b/sdk/lib/core/errors.dart
index 210d6be..ba2321e 100644
--- a/sdk/lib/core/errors.dart
+++ b/sdk/lib/core/errors.dart
@@ -430,13 +430,6 @@
  * Error thrown by the default implementation of [:noSuchMethod:] on [Object].
  */
 class NoSuchMethodError extends Error {
-  // Deprecated members to be removed.
-  final Object _receiver;
-  final Symbol _memberName;
-  final List _arguments;
-  final Map<Symbol, dynamic> _namedArguments;
-  final List _existingArgumentNames;
-
   /**
    * Create a [NoSuchMethodError] corresponding to a failed method call.
    *
@@ -446,7 +439,6 @@
    * The [invocation] represents the method call that failed. It
    * should not be `null`.
    */
-  @Deprecated("Dart 2.0. Will be renamed to become default constructor")
   external NoSuchMethodError.withInvocation(
       Object receiver, Invocation invocation);
 
@@ -469,14 +461,14 @@
    * The [namedArguments] is a map from [Symbol]s to the values of named
    * arguments that the method was called with.
    *
-   * The optional [existingArgumentNames] is the expected parameters of a
-   * method with the same name on the receiver, if available. This is
-   * the signature of the method that would have been called if the parameters
-   * had matched.
+   * This constructor does not handle type arguments.
+   * To include type variables, create an [Invocation] and use
+   * [NoSuchMethodError.withInvocation].
    */
+  @Deprecated("Use NoSuchMethod.withInvocation instead")
   external NoSuchMethodError(Object receiver, Symbol memberName,
       List positionalArguments, Map<Symbol, dynamic> namedArguments,
-      [List existingArgumentNames = null]);
+      [@deprecated List existingArgumentNames = null]);
 
   external String toString();
 }
diff --git a/sdk/lib/dart_client.platform b/sdk/lib/dart_client.platform
index 0228d99..805ac5c 100644
--- a/sdk/lib/dart_client.platform
+++ b/sdk/lib/dart_client.platform
@@ -47,8 +47,6 @@
 _js_helper: _internal/js_runtime/lib/js_helper.dart
 _interceptors: _internal/js_runtime/lib/interceptors.dart
 _foreign_helper: _internal/js_runtime/lib/foreign_helper.dart
-_isolate_helper: _internal/js_runtime/lib/isolate_helper.dart
-_js_mirrors: _internal/js_runtime/lib/js_mirrors.dart
 _js_names: _internal/js_runtime/lib/js_names.dart
 _js_primitives: _internal/js_runtime/lib/js_primitives.dart
 _js_embedded_names: _internal/js_runtime/lib/shared/embedded_names.dart
diff --git a/sdk/lib/dart_server.platform b/sdk/lib/dart_server.platform
index f1f2d3b..290e1ef 100644
--- a/sdk/lib/dart_server.platform
+++ b/sdk/lib/dart_server.platform
@@ -44,8 +44,6 @@
 _js_helper: _internal/js_runtime/lib/js_helper.dart
 _interceptors: _internal/js_runtime/lib/interceptors.dart
 _foreign_helper: _internal/js_runtime/lib/foreign_helper.dart
-_isolate_helper: _internal/js_runtime/lib/isolate_helper.dart
-_js_mirrors: _internal/js_runtime/lib/js_mirrors.dart
 _js_names: _internal/js_runtime/lib/js_names.dart
 _js_primitives: _internal/js_runtime/lib/js_primitives.dart
 _js_embedded_names: _internal/js_runtime/lib/shared/embedded_names.dart
diff --git a/sdk/lib/dart_shared.platform b/sdk/lib/dart_shared.platform
index 922fb98..e8aa11c 100644
--- a/sdk/lib/dart_shared.platform
+++ b/sdk/lib/dart_shared.platform
@@ -41,8 +41,6 @@
 _js_helper: _internal/js_runtime/lib/js_helper.dart
 _interceptors: _internal/js_runtime/lib/interceptors.dart
 _foreign_helper: _internal/js_runtime/lib/foreign_helper.dart
-_isolate_helper: _internal/js_runtime/lib/isolate_helper.dart
-_js_mirrors: _internal/js_runtime/lib/js_mirrors.dart
 _js_names: _internal/js_runtime/lib/js_names.dart
 _js_primitives: _internal/js_runtime/lib/js_primitives.dart
 _js_embedded_names: _internal/js_runtime/lib/shared/embedded_names.dart
diff --git a/sdk/lib/io/secure_socket.dart b/sdk/lib/io/secure_socket.dart
index 9f2711b..52e41d5 100644
--- a/sdk/lib/io/secure_socket.dart
+++ b/sdk/lib/io/secure_socket.dart
@@ -342,6 +342,15 @@
 abstract class X509Certificate {
   external factory X509Certificate._();
 
+  /// The DER encoded bytes of the certificate.
+  Uint8List get der;
+
+  /// The PEM encoded String of the certificate.
+  String get pem;
+
+  /// The SHA1 hash of the certificate.
+  Uint8List get sha1;
+
   String get subject;
   String get issuer;
   DateTime get startValidity;
diff --git a/sdk/lib/isolate/isolate.dart b/sdk/lib/isolate/isolate.dart
index 496c820..7a677b0 100644
--- a/sdk/lib/isolate/isolate.dart
+++ b/sdk/lib/isolate/isolate.dart
@@ -271,10 +271,13 @@
    * before those methods can complete.
    *
    * If the [checked] parameter is set to `true` or `false`,
-   * the new isolate will run code in checked mode,
-   * respectively in production mode, if possible.
-   * If the parameter is omitted, the new isolate will inherit the
-   * value from the current isolate.
+   * the new isolate will run code in checked mode (enabling asserts and type
+   * checks), respectively in production mode (disabling asserts and type
+   * checks), if possible. If the parameter is omitted, the new isolate will
+   * inherit the value from the current isolate.
+   *
+   * In Dart2 strong mode, the `checked` parameter only controls asserts, but
+   * not type checks.
    *
    * It may not always be possible to honor the `checked` parameter.
    * If the isolate code was pre-compiled, it may not be possible to change
diff --git a/sdk/lib/libraries.json b/sdk/lib/libraries.json
index b1fe827..9f3f684 100644
--- a/sdk/lib/libraries.json
+++ b/sdk/lib/libraries.json
@@ -189,9 +189,6 @@
       "_chrome": {
         "uri": "_chrome/dart2js/chrome_dart2js.dart"
       },
-      "_js_mirrors": {
-        "uri": "_internal/js_runtime/lib/js_mirrors.dart"
-      },
       "js": {
         "uri": "js/dart2js/js_dart2js.dart"
       },
@@ -248,9 +245,6 @@
         "patches": "_internal/js_runtime/lib/convert_patch.dart",
         "uri": "convert/convert.dart"
       },
-      "_isolate_helper": {
-        "uri": "_internal/js_runtime/lib/isolate_helper.dart"
-      },
       "math": {
         "patches": "_internal/js_runtime/lib/math_patch.dart",
         "uri": "math/math.dart"
@@ -307,9 +301,6 @@
       "js": {
         "uri": "js/dart2js/js_dart2js.dart"
       },
-      "_js_mirrors": {
-        "uri": "_internal/js_runtime/lib/js_mirrors.dart"
-      },
       "_native_typed_data": {
         "uri": "_internal/js_runtime/lib/native_typed_data.dart"
       },
@@ -348,9 +339,6 @@
         "patches": "_internal/js_runtime/lib/convert_patch.dart",
         "uri": "convert/convert.dart"
       },
-      "_isolate_helper": {
-        "uri": "_internal/js_runtime/lib/isolate_helper.dart"
-      },
       "math": {
         "patches": "_internal/js_runtime/lib/math_patch.dart",
         "uri": "math/math.dart"
@@ -360,4 +348,4 @@
       }
     }
   }
-}
\ No newline at end of file
+}
diff --git a/sdk/lib/libraries.yaml b/sdk/lib/libraries.yaml
index eb7ae2e..92c2391 100644
--- a/sdk/lib/libraries.yaml
+++ b/sdk/lib/libraries.yaml
@@ -242,12 +242,6 @@
     _foreign_helper:
       uri: "_internal/js_runtime/lib/foreign_helper.dart"
 
-    _isolate_helper:
-      uri: "_internal/js_runtime/lib/isolate_helper.dart"
-
-    _js_mirrors:
-      uri: "_internal/js_runtime/lib/js_mirrors.dart"
-
     _js_names:
       uri: "_internal/js_runtime/lib/js_names.dart"
 
@@ -337,12 +331,6 @@
     _foreign_helper:
       uri: "_internal/js_runtime/lib/foreign_helper.dart"
 
-    _isolate_helper:
-      uri: "_internal/js_runtime/lib/isolate_helper.dart"
-
-    _js_mirrors:
-      uri: "_internal/js_runtime/lib/js_mirrors.dart"
-
     _js_names:
       uri: "_internal/js_runtime/lib/js_names.dart"
 
diff --git a/sdk/lib/mirrors/mirrors.dart b/sdk/lib/mirrors/mirrors.dart
index 0811fdb..bbbb7b9 100644
--- a/sdk/lib/mirrors/mirrors.dart
+++ b/sdk/lib/mirrors/mirrors.dart
@@ -1241,6 +1241,7 @@
  * will ensure that the target `Bar` from the current library and from library
  * `foo` is available for reflection. See also [override].
  */
+@Deprecated("No longer has any effect. Will be removed in a later release.")
 class MirrorsUsed {
   // Note: the fields of this class are untyped.  This is because the most
   // convenient way to specify symbols today is using a single string. In
diff --git a/tests/co19/co19-dart2js.status b/tests/co19/co19-dart2js.status
index d802885..d758bc1 100644
--- a/tests/co19/co19-dart2js.status
+++ b/tests/co19/co19-dart2js.status
@@ -1466,6 +1466,7 @@
 LibTest/typed_data/Uint8ClampedList/map_A02_t01: Pass, Slow # Please triage this failure.
 
 [ $compiler == dart2js && $runtime == d8 ]
+Language/Statements/Continue/async_loops_t10: Skip # Issue 33150
 LibTest/typed_data/Float32x4List/Float32x4List.view_A06_t01: Fail # co19-roll r587: Please triage this failure
 LibTest/typed_data/Int32x4/operator_OR_A01_t01: RuntimeError # Issue 7728, timer not supported in jsshell
 
diff --git a/tests/compiler/dart2js/codegen/expect_annotations_test.dart b/tests/compiler/dart2js/codegen/expect_annotations_test.dart
index bff2af5..e5d0770f 100644
--- a/tests/compiler/dart2js/codegen/expect_annotations_test.dart
+++ b/tests/compiler/dart2js/codegen/expect_annotations_test.dart
@@ -7,6 +7,7 @@
 import 'package:compiler/src/compiler.dart';
 import 'package:compiler/src/elements/entities.dart';
 import 'package:compiler/src/js_backend/annotations.dart' as optimizerHints;
+import 'package:compiler/src/types/masks.dart';
 import 'package:compiler/src/types/types.dart';
 import 'package:compiler/src/world.dart' show ClosedWorld;
 import '../inference/type_mask_test_helper.dart';
diff --git a/tests/compiler/dart2js/codegen/trust_type_annotations_test.dart b/tests/compiler/dart2js/codegen/trust_type_annotations_test.dart
index 4e8b777..615226b 100644
--- a/tests/compiler/dart2js/codegen/trust_type_annotations_test.dart
+++ b/tests/compiler/dart2js/codegen/trust_type_annotations_test.dart
@@ -6,7 +6,7 @@
 import "package:async_helper/async_helper.dart";
 import 'package:compiler/src/commandline_options.dart';
 import 'package:compiler/src/elements/entities.dart';
-import '../compiler_helper.dart';
+import 'package:compiler/src/types/masks.dart';
 import '../memory_compiler.dart';
 
 const String TEST = """
diff --git a/tests/compiler/dart2js/codegen/type_inference8_test.dart b/tests/compiler/dart2js/codegen/type_inference8_test.dart
index 502aa96..7940d5e 100644
--- a/tests/compiler/dart2js/codegen/type_inference8_test.dart
+++ b/tests/compiler/dart2js/codegen/type_inference8_test.dart
@@ -7,7 +7,7 @@
 import "package:async_helper/async_helper.dart";
 import "package:compiler/src/commandline_options.dart";
 import "package:compiler/src/constants/values.dart";
-import "package:compiler/src/types/types.dart";
+import "package:compiler/src/types/masks.dart";
 import "package:expect/expect.dart";
 import '../memory_compiler.dart';
 
diff --git a/tests/compiler/dart2js/compiler_helper.dart b/tests/compiler/dart2js/compiler_helper.dart
index f1505be..50d9225 100644
--- a/tests/compiler/dart2js/compiler_helper.dart
+++ b/tests/compiler/dart2js/compiler_helper.dart
@@ -11,9 +11,7 @@
 
 import 'package:compiler/src/common_elements.dart';
 
-import 'package:compiler/src/elements/elements.dart';
 import 'package:compiler/src/elements/entities.dart';
-export 'package:compiler/src/elements/elements.dart';
 
 import 'package:compiler/src/js_backend/js_backend.dart' as js;
 
@@ -23,8 +21,6 @@
 export 'package:compiler/src/diagnostics/source_span.dart';
 export 'package:compiler/src/diagnostics/spannable.dart';
 
-export 'package:compiler/src/types/types.dart' show TypeMask;
-
 import 'package:compiler/src/util/util.dart';
 export 'package:compiler/src/util/util.dart';
 
@@ -32,8 +28,6 @@
 
 import 'package:compiler/src/compiler.dart' show Compiler;
 
-export 'package:compiler/src/tree/tree.dart';
-
 import 'memory_compiler.dart';
 
 import 'output_collector.dart';
@@ -129,17 +123,6 @@
   return outputCollector.getOutput('', OutputType.js);
 }
 
-Element findElement(compiler, String name, [Uri library]) {
-  LibraryElement lib = compiler.frontendStrategy.elementEnvironment.mainLibrary;
-  if (library != null) {
-    lib = compiler.libraryLoader.lookupLibrary(library);
-    Expect.isNotNull(lib, 'Could not locate library $library.');
-  }
-  var element = lib.find(name);
-  Expect.isNotNull(element, 'Could not locate $name.');
-  return element;
-}
-
 String anyIdentifier = "[a-zA-Z][a-zA-Z0-9]*";
 
 String getIntTypeCheck(String variable) {
diff --git a/tests/compiler/dart2js/deferred_loading/data/basic_deferred.dart b/tests/compiler/dart2js/deferred_loading/data/basic_deferred.dart
index b7d44ab..2c0951c 100644
--- a/tests/compiler/dart2js/deferred_loading/data/basic_deferred.dart
+++ b/tests/compiler/dart2js/deferred_loading/data/basic_deferred.dart
@@ -4,6 +4,6 @@
 import '../libs/basic_deferred_lib.dart' deferred as lib;
 
 /*element: main:OutputUnit(main, {})*/
-main() => lib.loadLibrary().then((_) {
+main() => lib.loadLibrary().then(/*OutputUnit(main, {})*/ (_) {
       (lib.funky)();
     });
diff --git a/tests/compiler/dart2js/deferred_loading/data/deferred_class.dart b/tests/compiler/dart2js/deferred_loading/data/deferred_class.dart
index 0ded6cf..b688215 100644
--- a/tests/compiler/dart2js/deferred_loading/data/deferred_class.dart
+++ b/tests/compiler/dart2js/deferred_loading/data/deferred_class.dart
@@ -6,7 +6,7 @@
 
 /*element: main:OutputUnit(main, {})*/
 main() {
-  lib.loadLibrary().then((_) {
+  lib.loadLibrary().then(/*OutputUnit(main, {})*/ (_) {
     return new lib.MyClass().foo(87);
   });
 }
diff --git a/tests/compiler/dart2js/deferred_loading/data/deferred_constant1.dart b/tests/compiler/dart2js/deferred_loading/data/deferred_constant1.dart
index b3d820a..99f8444 100644
--- a/tests/compiler/dart2js/deferred_loading/data/deferred_constant1.dart
+++ b/tests/compiler/dart2js/deferred_loading/data/deferred_constant1.dart
@@ -9,7 +9,7 @@
 main() async {
   C1.value;
   print(const C(4));
-  () => print(const C(5));
+  /*OutputUnit(main, {})*/ () => print(const C(5));
   await lib2.loadLibrary();
   lib2.C2.value;
   lib2.C3.value;
diff --git a/tests/compiler/dart2js/deferred_loading/data/deferred_constant2.dart b/tests/compiler/dart2js/deferred_loading/data/deferred_constant2.dart
index 9f82270..f8821ae 100644
--- a/tests/compiler/dart2js/deferred_loading/data/deferred_constant2.dart
+++ b/tests/compiler/dart2js/deferred_loading/data/deferred_constant2.dart
@@ -8,7 +8,7 @@
 
 /*element: main:OutputUnit(main, {})*/
 main() {
-  lib.loadLibrary().then((_) {
+  lib.loadLibrary().then(/*OutputUnit(main, {})*/ (_) {
     Expect.equals(499, lib.C1.value);
   });
 }
diff --git a/tests/compiler/dart2js/deferred_loading/data/deferred_fail_and_retry.dart b/tests/compiler/dart2js/deferred_loading/data/deferred_fail_and_retry.dart
index 819032b..80b59bf 100644
--- a/tests/compiler/dart2js/deferred_loading/data/deferred_fail_and_retry.dart
+++ b/tests/compiler/dart2js/deferred_loading/data/deferred_fail_and_retry.dart
@@ -34,14 +34,14 @@
   ]);
 
   asyncStart();
-  lib.loadLibrary().then((_) {
+  lib.loadLibrary().then(/*OutputUnit(main, {})*/ (_) {
     Expect.fail("Library should not have loaded");
-  }, onError: (error) {
-    lib.loadLibrary().then((_) {
+  }, onError: /*OutputUnit(main, {})*/ (error) {
+    lib.loadLibrary().then(/*OutputUnit(main, {})*/ (_) {
       Expect.equals("loaded", lib.foo());
-    }, onError: (error) {
+    }, onError: /*OutputUnit(main, {})*/ (error) {
       Expect.fail("Library should have loaded this time");
-    }).whenComplete(() {
+    }).whenComplete(/*OutputUnit(main, {})*/ () {
       asyncEnd();
     });
   });
diff --git a/tests/compiler/dart2js/deferred_loading/data/deferred_function.dart b/tests/compiler/dart2js/deferred_loading/data/deferred_function.dart
index d8895f7..6f809df 100644
--- a/tests/compiler/dart2js/deferred_loading/data/deferred_function.dart
+++ b/tests/compiler/dart2js/deferred_loading/data/deferred_function.dart
@@ -14,7 +14,7 @@
 
 /*element: main:OutputUnit(main, {})*/
 main() {
-  lib.loadLibrary().then((_) {
+  lib.loadLibrary().then(/*OutputUnit(main, {})*/ (_) {
     lib.foo('b');
     readFoo();
   });
diff --git a/tests/compiler/dart2js/deferred_loading/data/deferred_overlapping.dart b/tests/compiler/dart2js/deferred_loading/data/deferred_overlapping.dart
index ea2354b..754ee48 100644
--- a/tests/compiler/dart2js/deferred_loading/data/deferred_overlapping.dart
+++ b/tests/compiler/dart2js/deferred_loading/data/deferred_overlapping.dart
@@ -8,9 +8,9 @@
 // lib1.C1 and lib2.C2 has a shared base class. It will go in its own hunk.
 /*element: main:OutputUnit(main, {})*/
 void main() {
-  lib1.loadLibrary().then((_) {
+  lib1.loadLibrary().then(/*OutputUnit(main, {})*/ (_) {
     new lib1.C1();
-    lib2.loadLibrary().then((_) {
+    lib2.loadLibrary().then(/*OutputUnit(main, {})*/ (_) {
       new lib2.C2();
     });
   });
diff --git a/tests/compiler/dart2js/deferred_loading/data/dont_inline_deferred_global.dart b/tests/compiler/dart2js/deferred_loading/data/dont_inline_deferred_global.dart
index 58669a5..3e42dd2 100644
--- a/tests/compiler/dart2js/deferred_loading/data/dont_inline_deferred_global.dart
+++ b/tests/compiler/dart2js/deferred_loading/data/dont_inline_deferred_global.dart
@@ -6,7 +6,7 @@
 
 /*element: main:OutputUnit(main, {})*/
 void main() {
-  lib.loadLibrary().then((_) {
+  lib.loadLibrary().then(/*OutputUnit(main, {})*/ (_) {
     print(lib.finalVar);
     print(lib.globalVar);
     lib.globalVar = "foobar";
diff --git a/tests/compiler/dart2js/deferred_loading/data/static_separate.dart b/tests/compiler/dart2js/deferred_loading/data/static_separate.dart
new file mode 100644
index 0000000..ac5b27d
--- /dev/null
+++ b/tests/compiler/dart2js/deferred_loading/data/static_separate.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.
+
+// The class lib1.C is referenced via lib1
+// The static function lib1.C.foo is referenced via lib2
+// Dart2js will put them in separate hunks.
+// Similarly for C2, ..., C5.
+
+import "package:expect/expect.dart";
+import "package:async_helper/async_helper.dart";
+import "../libs/static_separate_lib1.dart" deferred as lib1;
+import "../libs/static_separate_lib2.dart" deferred as lib2;
+
+/*element: main:OutputUnit(main, {})*/
+void main() {
+  asyncStart();
+  Expect.throws(/*OutputUnit(main, {})*/ () => new lib1.C());
+  lib1.loadLibrary().then(/*OutputUnit(main, {})*/ (_) {
+    lib2.loadLibrary().then(/*OutputUnit(main, {})*/ (_) {
+      print("HERE");
+      Expect.equals(1, new lib1.C().bar());
+      var x = new lib1.C2();
+      Expect.mapEquals({1: 2}, x.bar);
+      x.bar = {2: 3};
+      Expect.mapEquals({2: 3}, x.bar);
+
+      Expect.equals(lib1.x, new lib1.C3().bar);
+      Expect.mapEquals({lib1.x: lib1.x}, new lib1.C4().bar);
+      Expect.equals(1, new lib1.C5().bar());
+
+      lib2.foo();
+      asyncEnd();
+    });
+  });
+}
diff --git a/tests/compiler/dart2js/deferred_loading/deferred_loading_test.dart b/tests/compiler/dart2js/deferred_loading/deferred_loading_test.dart
index 8abed7c..cef5d1b 100644
--- a/tests/compiler/dart2js/deferred_loading/deferred_loading_test.dart
+++ b/tests/compiler/dart2js/deferred_loading/deferred_loading_test.dart
@@ -4,6 +4,7 @@
 
 import 'dart:io' hide Link;
 import 'package:async_helper/async_helper.dart';
+import 'package:compiler/src/closure.dart';
 import 'package:compiler/src/common.dart';
 import 'package:compiler/src/compiler.dart';
 import 'package:compiler/src/deferred_load.dart';
@@ -87,44 +88,73 @@
 void computeKernelOutputUnitData(
     Compiler compiler, MemberEntity member, Map<Id, ActualData> actualMap,
     {bool verbose: false}) {
-  OutputUnitData data = compiler.backend.outputUnitData;
-  String value = outputUnitString(data.outputUnitForEntity(member));
-
   KernelBackendStrategy backendStrategy = compiler.backendStrategy;
   KernelToElementMapForBuilding elementMap = backendStrategy.elementMap;
   MemberDefinition definition = elementMap.getMemberDefinition(member);
+  new TypeMaskIrComputer(
+          compiler.reporter,
+          actualMap,
+          elementMap,
+          member,
+          compiler.backend.outputUnitData,
+          backendStrategy.closureDataLookup as ClosureDataLookup<ir.Node>)
+      .run(definition.node);
+}
 
-  _registerValue(
-      computeEntityId(definition.node),
-      value,
-      member,
-      computeSourceSpanFromTreeNode(definition.node),
-      actualMap,
-      compiler.reporter);
+/// IR visitor for computing inference data for a member.
+class TypeMaskIrComputer extends IrDataExtractor {
+  final KernelToElementMapForBuilding _elementMap;
+  final OutputUnitData _data;
+  final ClosureDataLookup<ir.Node> _closureDataLookup;
 
-  ir.Member memberNode = definition.node;
-  if (memberNode is ir.Field && memberNode.isConst) {
-    ir.Expression node = memberNode.initializer;
-    ConstantValue constant = elementMap.getConstantValue(node);
-    if (constant.isPrimitive) return;
-    SourceSpan span = computeSourceSpanFromTreeNode(node);
-    if (node is ir.ConstructorInvocation ||
-        node is ir.ListLiteral ||
-        (node is ir.MapLiteral && node.keyType == null)) {
-      // Adjust the source-span to match the AST-based location. The kernel FE
-      // skips the "const" keyword for the expression offset and any prefix in
-      // front of the constructor. The "-6" is an approximation assuming that
-      // there is just a single space after "const" and no prefix.
-      // TODO(sigmund): offsets should be fixed in the FE instead.
-      span = new SourceSpan(span.uri, span.begin - 6, span.end - 6);
+  TypeMaskIrComputer(
+      DiagnosticReporter reporter,
+      Map<Id, ActualData> actualMap,
+      this._elementMap,
+      MemberEntity member,
+      this._data,
+      this._closureDataLookup)
+      : super(reporter, actualMap);
+
+  String getMemberValue(MemberEntity member) {
+    return outputUnitString(_data.outputUnitForEntity(member));
+  }
+
+  @override
+  String computeMemberValue(Id id, ir.Member node) {
+    if (node is ir.Field && node.isConst) {
+      ir.Expression initializer = node.initializer;
+      ConstantValue constant = _elementMap.getConstantValue(initializer);
+      if (!constant.isPrimitive) {
+        SourceSpan span = computeSourceSpanFromTreeNode(initializer);
+        if (initializer is ir.ConstructorInvocation) {
+          // Adjust the source-span to match the AST-based location. The kernel FE
+          // skips the "const" keyword for the expression offset and any prefix in
+          // front of the constructor. The "-6" is an approximation assuming that
+          // there is just a single space after "const" and no prefix.
+          // TODO(sigmund): offsets should be fixed in the FE instead.
+          span = new SourceSpan(span.uri, span.begin - 6, span.end - 6);
+        }
+        _registerValue(
+            new NodeId(span.begin, IdKind.node),
+            outputUnitString(_data.outputUnitForConstant(constant)),
+            node,
+            span,
+            actualMap,
+            reporter);
+      }
     }
-    _registerValue(
-        new NodeId(span.begin, IdKind.node),
-        outputUnitString(data.outputUnitForConstant(constant)),
-        member,
-        span,
-        actualMap,
-        compiler.reporter);
+
+    return getMemberValue(_elementMap.getMember(node));
+  }
+
+  @override
+  String computeNodeValue(Id id, ir.TreeNode node) {
+    if (node is ir.FunctionExpression || node is ir.FunctionDeclaration) {
+      ClosureRepresentationInfo info = _closureDataLookup.getClosureInfo(node);
+      return getMemberValue(info.callMethod);
+    }
+    return null;
   }
 }
 
diff --git a/tests/compiler/dart2js/deferred_loading/libs/dont_inline_deferred_constants_main.dart b/tests/compiler/dart2js/deferred_loading/libs/dont_inline_deferred_constants_main.dart
index 494a35d..a8f56bd 100644
--- a/tests/compiler/dart2js/deferred_loading/libs/dont_inline_deferred_constants_main.dart
+++ b/tests/compiler/dart2js/deferred_loading/libs/dont_inline_deferred_constants_main.dart
@@ -22,8 +22,8 @@
 
 /*element: main:OutputUnit(main, {})*/
 void main() {
-  lib1.loadLibrary().then((_) {
-    lib2.loadLibrary().then((_) {
+  lib1.loadLibrary().then(/*OutputUnit(main, {})*/ (_) {
+    lib2.loadLibrary().then(/*OutputUnit(main, {})*/ (_) {
       lib1.foo();
       lib2.foo();
       print(lib1.C1);
diff --git a/tests/compiler/dart2js/deferred_loading/libs/static_separate_lib1.dart b/tests/compiler/dart2js/deferred_loading/libs/static_separate_lib1.dart
new file mode 100644
index 0000000..d95536e
--- /dev/null
+++ b/tests/compiler/dart2js/deferred_loading/libs/static_separate_lib1.dart
@@ -0,0 +1,95 @@
+// 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.
+
+library lib1;
+
+/*class: ConstClass:OutputUnit(2, {lib1, lib2})*/
+class ConstClass {
+  /*element: ConstClass.x:OutputUnit(2, {lib1, lib2})*/
+  final x;
+
+  /*element: ConstClass.:OutputUnit(2, {lib1, lib2})*/
+  const ConstClass(this.x);
+}
+
+/*element: x:OutputUnit(2, {lib1, lib2})*/
+var x = const ConstClass(const ConstClass(1));
+
+/*class: C:OutputUnit(1, {lib1})*/
+class C {
+  /*element: C.foo:OutputUnit(3, {lib2})*/
+  static foo() {
+    /*OutputUnit(3, {lib2})*/ () {}(); // Hack to avoid inlining.
+    return 1;
+  }
+
+  /*element: C.:OutputUnit(1, {lib1})*/
+  C();
+
+  /*element: C.bar:OutputUnit(1, {lib1})*/
+  bar() {
+    /*OutputUnit(1, {lib1})*/ () {}(); // Hack to avoid inlining.
+    return 1;
+  }
+}
+
+/*class: C1:OutputUnit(main, {})*/
+class C1 {
+  /*element: C1.foo:OutputUnit(3, {lib2})*/
+  static var foo = const {};
+  var bar = const {};
+}
+
+/*class: C2:OutputUnit(1, {lib1})*/
+class C2 {
+  /*element: C2.foo:OutputUnit(3, {lib2})*/
+  static var foo = new Map<int, int>.from({1: 2});
+
+  /*element: C2.bar:OutputUnit(1, {lib1})*/
+  var bar = new Map<int, int>.from({1: 2});
+
+  /*element: C2.:OutputUnit(1, {lib1})*/
+  C2();
+}
+
+/*class: C3:OutputUnit(1, {lib1})*/
+class C3 {
+  /*element: C3.foo:OutputUnit(3, {lib2})*/
+  static final foo = const ConstClass(const ConstClass(1));
+
+  /*element: C3.bar:OutputUnit(1, {lib1})*/
+  final bar = const ConstClass(const ConstClass(1));
+
+  /*element: C3.:OutputUnit(1, {lib1})*/
+  C3();
+}
+
+/*class: C4:OutputUnit(1, {lib1})*/
+class C4 {
+  /*element: C4.foo:OutputUnit(3, {lib2})*/
+  static final foo = new Map<ConstClass, ConstClass>.from({x: x});
+
+  /*element: C4.bar:OutputUnit(1, {lib1})*/
+  final bar = new Map<ConstClass, ConstClass>.from({x: x});
+
+  /*element: C4.:OutputUnit(1, {lib1})*/
+  C4();
+}
+
+/*class: C5:OutputUnit(1, {lib1})*/
+class C5 {
+  /*element: C5.foo:OutputUnit(3, {lib2})*/
+  static const foo = /*OutputUnit(3, {lib2})*/ const [
+    const {1: 3}
+  ];
+
+  /*element: C5.:OutputUnit(1, {lib1})*/
+  C5();
+
+  /*element: C5.bar:OutputUnit(1, {lib1})*/
+  bar() {
+    /*OutputUnit(1, {lib1})*/ () {}(); // Hack to avoid inlining.
+    return 1;
+  }
+}
diff --git a/tests/compiler/dart2js/deferred_loading/libs/static_separate_lib2.dart b/tests/compiler/dart2js/deferred_loading/libs/static_separate_lib2.dart
new file mode 100644
index 0000000..4358474
--- /dev/null
+++ b/tests/compiler/dart2js/deferred_loading/libs/static_separate_lib2.dart
@@ -0,0 +1,24 @@
+// 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.
+
+library lib2;
+
+import "package:expect/expect.dart";
+import "static_separate_lib1.dart";
+
+/*element: foo:OutputUnit(3, {lib2})*/
+foo() {
+  Expect.equals(1, C.foo());
+  Expect.mapEquals({}, C1.foo);
+
+  Expect.mapEquals({1: 2}, C2.foo);
+  C2.foo = {1: 2};
+  Expect.mapEquals({1: 2}, C2.foo);
+
+  Expect.equals(x, C3.foo);
+  Expect.mapEquals({x: x}, C4.foo);
+  Expect.listEquals([
+    const {1: 3}
+  ], C5.foo);
+}
diff --git a/tests/compiler/dart2js/deferred_loading/libs/type_argument_dependency_lib1.dart b/tests/compiler/dart2js/deferred_loading/libs/type_argument_dependency_lib1.dart
index 37095d3..d785ac6 100644
--- a/tests/compiler/dart2js/deferred_loading/libs/type_argument_dependency_lib1.dart
+++ b/tests/compiler/dart2js/deferred_loading/libs/type_argument_dependency_lib1.dart
@@ -5,4 +5,4 @@
 import 'type_argument_dependency_lib2.dart';
 
 /*element: doCast:OutputUnit(main, {})*/
-doCast(List<dynamic> l) => l.cast<B>().map((x) => 1);
+doCast(List<dynamic> l) => l.cast<B>().map(/*OutputUnit(main, {})*/ (x) => 1);
diff --git a/tests/compiler/dart2js/dill_loader_test.dart b/tests/compiler/dart2js/dill_loader_test.dart
index 4192756..e1fd6b1 100644
--- a/tests/compiler/dart2js/dill_loader_test.dart
+++ b/tests/compiler/dart2js/dill_loader_test.dart
@@ -2,16 +2,11 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-import 'dart:async';
 import 'memory_compiler.dart';
 import 'package:async_helper/async_helper.dart';
 import 'package:compiler/src/common_elements.dart';
-import 'package:compiler/src/diagnostics/spannable.dart' show Spannable;
 import 'package:compiler/src/elements/entities.dart'
     show LibraryEntity, ClassEntity;
-import 'package:compiler/src/io/source_file.dart' show Binary;
-import 'package:compiler/src/library_loader.dart' show ScriptLoader;
-import 'package:compiler/src/script.dart' show Script;
 import 'package:compiler/src/apiimpl.dart' show CompilerImpl;
 import "package:expect/expect.dart";
 import 'package:front_end/src/api_prototype/front_end.dart';
@@ -21,17 +16,6 @@
 import 'package:front_end/src/compute_platform_binaries_location.dart'
     show computePlatformBinariesLocation;
 
-class TestScriptLoader implements ScriptLoader {
-  CompilerImpl compiler;
-  TestScriptLoader(this.compiler);
-
-  Future<Script> readScript(Uri uri, [Spannable spannable]) =>
-      compiler.readScript(uri, spannable);
-
-  Future<Binary> readBinary(Uri uri, [Spannable spannable]) =>
-      compiler.readBinary(uri, spannable);
-}
-
 /// Test that the compiler can successfully read in .dill kernel files rather
 /// than just string source files.
 main() {
diff --git a/tests/compiler/dart2js/end_to_end/diagnostic_reporter_helper.dart b/tests/compiler/dart2js/end_to_end/diagnostic_reporter_helper.dart
index 7a3c4c7..a04734f 100644
--- a/tests/compiler/dart2js/end_to_end/diagnostic_reporter_helper.dart
+++ b/tests/compiler/dart2js/end_to_end/diagnostic_reporter_helper.dart
@@ -10,7 +10,6 @@
 import 'package:compiler/src/diagnostics/spannable.dart';
 import 'package:compiler/src/elements/entities.dart';
 import 'package:compiler/src/options.dart';
-import 'package:front_end/src/fasta/scanner.dart';
 
 abstract class DiagnosticReporterWrapper extends DiagnosticReporter {
   DiagnosticReporter get reporter;
@@ -64,9 +63,6 @@
   }
 
   @override
-  SourceSpan spanFromToken(Token token) => reporter.spanFromToken(token);
-
-  @override
   withCurrentElement(Entity element, f()) {
     return reporter.withCurrentElement(element, f);
   }
diff --git a/tests/compiler/dart2js/equivalence/check_functions.dart b/tests/compiler/dart2js/equivalence/check_functions.dart
index 1a0222c..149894a 100644
--- a/tests/compiler/dart2js/equivalence/check_functions.dart
+++ b/tests/compiler/dart2js/equivalence/check_functions.dart
@@ -6,1248 +6,8 @@
 
 library dart2js.equivalence.functions;
 
-import 'package:expect/expect.dart';
-import 'package:compiler/src/common/resolution.dart';
-import 'package:compiler/src/common_elements.dart';
-import 'package:compiler/src/compiler.dart';
-import 'package:compiler/src/constants/values.dart';
-import 'package:compiler/src/elements/elements.dart';
-import 'package:compiler/src/elements/entities.dart';
-import 'package:compiler/src/elements/types.dart';
-import 'package:compiler/src/enqueue.dart';
 import 'package:compiler/src/js/js_debug.dart' as js;
-import 'package:compiler/src/js_backend/backend.dart';
-import 'package:compiler/src/js_backend/backend_usage.dart';
-import 'package:compiler/src/js_backend/enqueuer.dart';
-import 'package:compiler/src/js_backend/native_data.dart';
-import 'package:compiler/src/js_backend/interceptor_data.dart';
-import 'package:compiler/src/js_emitter/code_emitter_task.dart';
-import 'package:compiler/src/js_emitter/model.dart';
-import 'package:compiler/src/universe/class_set.dart';
-import 'package:compiler/src/universe/world_builder.dart';
-import 'package:compiler/src/world.dart';
 import 'package:js_ast/js_ast.dart' as js;
-import 'equivalence_helper.dart';
-import 'check_helpers.dart';
-
-void checkClosedWorlds(ClosedWorld closedWorld1, ClosedWorld closedWorld2,
-    {TestStrategy strategy: const TestStrategy(),
-    bool allowExtra: false,
-    bool verbose: false,
-    bool allowMissingClosureClasses: false}) {
-  if (verbose) {
-    print(closedWorld1.dump());
-    print(closedWorld2.dump());
-  }
-  checkClassHierarchyNodes(
-      closedWorld1,
-      closedWorld2,
-      closedWorld1
-          .getClassHierarchyNode(closedWorld1.commonElements.objectClass),
-      closedWorld2
-          .getClassHierarchyNode(closedWorld2.commonElements.objectClass),
-      strategy.elementEquivalence,
-      verbose: verbose,
-      allowMissingClosureClasses: allowMissingClosureClasses);
-
-  checkNativeData(closedWorld1.nativeData, closedWorld2.nativeData,
-      strategy: strategy, allowExtra: allowExtra, verbose: verbose);
-  checkInterceptorData(closedWorld1.interceptorData,
-      closedWorld2.interceptorData, strategy.elementEquivalence,
-      verbose: verbose);
-}
-
-void checkNativeData(NativeDataImpl data1, NativeDataImpl data2,
-    {TestStrategy strategy: const TestStrategy(),
-    bool allowExtra: false,
-    bool verbose: false}) {
-  checkMapEquivalence(data1, data2, 'nativeMemberName', data1.nativeMemberName,
-      data2.nativeMemberName, strategy.elementEquivalence, equality,
-      allowExtra: allowExtra);
-
-  checkMapEquivalence(
-      data1,
-      data2,
-      'nativeMethodBehavior',
-      data1.nativeMethodBehavior,
-      data2.nativeMethodBehavior,
-      strategy.elementEquivalence,
-      (a, b) => testNativeBehavior(a, b, strategy: strategy),
-      allowExtra: allowExtra);
-
-  checkMapEquivalence(
-      data1,
-      data2,
-      'nativeFieldLoadBehavior',
-      data1.nativeFieldLoadBehavior,
-      data2.nativeFieldLoadBehavior,
-      strategy.elementEquivalence,
-      (a, b) => testNativeBehavior(a, b, strategy: strategy),
-      allowExtra: allowExtra);
-
-  checkMapEquivalence(
-      data1,
-      data2,
-      'nativeFieldStoreBehavior',
-      data1.nativeFieldStoreBehavior,
-      data2.nativeFieldStoreBehavior,
-      strategy.elementEquivalence,
-      (a, b) => testNativeBehavior(a, b, strategy: strategy),
-      allowExtra: allowExtra);
-
-  checkMapEquivalence(
-      data1,
-      data2,
-      'jsInteropLibraryNames',
-      data1.jsInteropLibraries,
-      data2.jsInteropLibraries,
-      strategy.elementEquivalence,
-      equality);
-
-  checkSetEquivalence(
-      data1,
-      data2,
-      'anonymousJsInteropClasses',
-      data1.anonymousJsInteropClasses,
-      data2.anonymousJsInteropClasses,
-      strategy.elementEquivalence);
-
-  checkMapEquivalence(
-      data1,
-      data2,
-      'jsInteropClassNames',
-      data1.jsInteropClasses,
-      data2.jsInteropClasses,
-      strategy.elementEquivalence,
-      equality);
-
-  checkMapEquivalence(
-      data1,
-      data2,
-      'jsInteropMemberNames',
-      data1.jsInteropMembers,
-      data2.jsInteropMembers,
-      strategy.elementEquivalence,
-      equality);
-}
-
-void checkInterceptorData(InterceptorDataImpl data1, InterceptorDataImpl data2,
-    bool elementEquivalence(Entity a, Entity b),
-    {bool verbose: false}) {
-  checkMapEquivalence(
-      data1,
-      data2,
-      'interceptedElements',
-      data1.interceptedMembers,
-      data2.interceptedMembers,
-      equality,
-      (a, b) => areSetsEquivalent(a, b, elementEquivalence));
-
-  checkSetEquivalence(data1, data2, 'interceptedClasses',
-      data1.interceptedClasses, data2.interceptedClasses, elementEquivalence);
-
-  checkSetEquivalence(
-      data1,
-      data2,
-      'classesMixedIntoInterceptedClasses',
-      data1.classesMixedIntoInterceptedClasses,
-      data2.classesMixedIntoInterceptedClasses,
-      elementEquivalence);
-}
-
-void checkClassHierarchyNodes(
-    ClosedWorld closedWorld1,
-    ClosedWorld closedWorld2,
-    ClassHierarchyNode node1,
-    ClassHierarchyNode node2,
-    bool elementEquivalence(Entity a, Entity b),
-    {bool verbose: false,
-    bool allowMissingClosureClasses: false}) {
-  if (verbose) {
-    print('Checking $node1 vs $node2');
-  }
-  ClassEntity cls1 = node1.cls;
-  ClassEntity cls2 = node2.cls;
-  Expect.isTrue(elementEquivalence(cls1, cls2),
-      "Element identity mismatch for ${cls1} vs ${cls2}.");
-  Expect.equals(
-      node1.isDirectlyInstantiated,
-      node2.isDirectlyInstantiated,
-      "Value mismatch for 'isDirectlyInstantiated' "
-      "for ${cls1} vs ${cls2}.");
-  Expect.equals(
-      node1.isIndirectlyInstantiated,
-      node2.isIndirectlyInstantiated,
-      "Value mismatch for 'isIndirectlyInstantiated' "
-      "for ${node1.cls} vs ${node2.cls}.");
-  // TODO(johnniwinther): Enforce a canonical and stable order on direct
-  // subclasses.
-  for (ClassHierarchyNode child in node1.directSubclasses) {
-    bool found = false;
-    for (ClassHierarchyNode other in node2.directSubclasses) {
-      ClassEntity child1 = child.cls;
-      ClassEntity child2 = other.cls;
-      if (elementEquivalence(child1, child2)) {
-        checkClassHierarchyNodes(
-            closedWorld1, closedWorld2, child, other, elementEquivalence,
-            verbose: verbose,
-            allowMissingClosureClasses: allowMissingClosureClasses);
-        found = true;
-        break;
-      }
-    }
-    if (!found && (!child.cls.isClosure || !allowMissingClosureClasses)) {
-      if (child.isInstantiated) {
-        print('Missing subclass ${child.cls} of ${node1.cls} '
-            'in ${node2.directSubclasses}');
-        print(closedWorld1.dump(
-            verbose ? closedWorld1.commonElements.objectClass : node1.cls));
-        print(closedWorld2.dump(
-            verbose ? closedWorld2.commonElements.objectClass : node2.cls));
-      }
-      Expect.isFalse(
-          child.isInstantiated,
-          'Missing subclass ${child.cls} of ${node1.cls} in '
-          '${node2.directSubclasses}');
-    }
-  }
-  checkMixinUses(
-      closedWorld1, closedWorld2, node1.cls, node2.cls, elementEquivalence,
-      verbose: verbose);
-  ClassSet classSet1 = closedWorld1.getClassSet(cls1);
-  ClassSet classSet2 = closedWorld2.getClassSet(cls2);
-  Expect.isNotNull(classSet1, "Missing ClassSet for $cls1");
-  Expect.isNotNull(classSet2, "Missing ClassSet for $cls2");
-  checkClassSets(
-      closedWorld1, closedWorld2, classSet1, classSet2, elementEquivalence,
-      verbose: verbose, allowMissingClosureClasses: allowMissingClosureClasses);
-}
-
-void checkClassSets(
-    ClosedWorld closedWorld1,
-    ClosedWorld closedWorld2,
-    ClassSet classSet1,
-    ClassSet classSet2,
-    bool elementEquivalence(Entity a, Entity b),
-    {bool verbose: false,
-    bool allowMissingClosureClasses: false}) {
-  for (ClassHierarchyNode child in classSet1.subtypeNodes) {
-    bool found = false;
-    for (ClassHierarchyNode other in classSet2.subtypeNodes) {
-      ClassEntity child1 = child.cls;
-      ClassEntity child2 = other.cls;
-      if (elementEquivalence(child1, child2)) {
-        found = true;
-        break;
-      }
-    }
-    if (!found && (!child.cls.isClosure || !allowMissingClosureClasses)) {
-      if (child.isInstantiated) {
-        print('Missing subtype ${child.cls} of ${classSet1.cls} '
-            'in ${classSet2.subtypeNodes}');
-        print(closedWorld1.dump(
-            verbose ? closedWorld1.commonElements.objectClass : classSet1.cls));
-        print(closedWorld2.dump(
-            verbose ? closedWorld2.commonElements.objectClass : classSet2.cls));
-      }
-      Expect.isFalse(
-          child.isInstantiated,
-          'Missing subclass ${child.cls} of ${classSet1.cls} in '
-          '${classSet2.subtypeNodes}');
-    }
-  }
-}
-
-void checkMixinUses(
-    ClosedWorld closedWorld1,
-    ClosedWorld closedWorld2,
-    ClassEntity class1,
-    ClassEntity class2,
-    bool elementEquivalence(Entity a, Entity b),
-    {bool verbose: false}) {
-  checkSets(closedWorld1.mixinUsesOf(class1), closedWorld2.mixinUsesOf(class2),
-      "Mixin uses of $class1 vs $class2", elementEquivalence,
-      verbose: verbose);
-}
-
-/// Check member property equivalence between all members common to [compiler1]
-/// and [compiler2].
-void checkLoadedLibraryMembers(
-    Compiler compiler1,
-    Compiler compiler2,
-    bool hasProperty(Element member1),
-    void checkMemberProperties(Compiler compiler1, Element member1,
-        Compiler compiler2, Element member2,
-        {bool verbose}),
-    {bool verbose: false}) {
-  void checkMembers(Element member1, Element member2) {
-    if (member1.isClass && member2.isClass) {
-      ClassElement class1 = member1;
-      ClassElement class2 = member2;
-      if (!class1.isResolved) return;
-
-      if (hasProperty(member1)) {
-        if (areElementsEquivalent(member1, member2)) {
-          checkMemberProperties(compiler1, member1, compiler2, member2,
-              verbose: verbose);
-        }
-      }
-
-      class1.forEachLocalMember((m1) {
-        checkMembers(m1, class2.localLookup(m1.name));
-      });
-      ClassElement superclass1 = class1.superclass;
-      ClassElement superclass2 = class2.superclass;
-      while (superclass1 != null && superclass1.isUnnamedMixinApplication) {
-        for (ConstructorElement c1 in superclass1.constructors) {
-          checkMembers(c1, superclass2.lookupConstructor(c1.name));
-        }
-        superclass1 = superclass1.superclass;
-        superclass2 = superclass2.superclass;
-      }
-      return;
-    }
-
-    if (!hasProperty(member1)) {
-      return;
-    }
-
-    if (member2 == null) {
-      throw 'Missing member for ${member1}';
-    }
-
-    if (areElementsEquivalent(member1, member2)) {
-      checkMemberProperties(compiler1, member1, compiler2, member2,
-          verbose: verbose);
-    }
-  }
-
-  for (LibraryElement library1 in compiler1.libraryLoader.libraries) {
-    LibraryElement library2 =
-        compiler2.libraryLoader.lookupLibrary(library1.canonicalUri);
-    if (library2 != null) {
-      library1.forEachLocalMember((Element member1) {
-        checkMembers(member1, library2.localLookup(member1.name));
-      });
-    }
-  }
-}
-
-/// Check equivalence of all resolution impacts.
-void checkAllImpacts(Compiler compiler1, Compiler compiler2,
-    {bool verbose: false}) {
-  checkLoadedLibraryMembers(compiler1, compiler2, (Element member1) {
-    return compiler1.resolution.hasResolutionImpact(member1);
-  }, checkImpacts, verbose: verbose);
-}
-
-/// Check equivalence of resolution impact for [member1] and [member2].
-void checkImpacts(
-    Compiler compiler1, Element member1, Compiler compiler2, Element member2,
-    {bool verbose: false}) {
-  ResolutionImpact impact1 = compiler1.resolution.getResolutionImpact(member1);
-  ResolutionImpact impact2 = compiler2.resolution.getResolutionImpact(member2);
-
-  if (impact1 == null && impact2 == null) return;
-
-  if (verbose) {
-    print('Checking impacts for $member1 vs $member2');
-  }
-
-  if (impact1 == null) {
-    throw 'Missing impact for $member1. $member2 has $impact2';
-  }
-  if (impact2 == null) {
-    throw 'Missing impact for $member2. $member1 has $impact1';
-  }
-
-  testResolutionImpactEquivalence(impact1, impact2,
-      strategy: const CheckStrategy());
-}
-
-void checkNativeClasses(
-    Compiler compiler1, Compiler compiler2, TestStrategy strategy) {
-  Iterable<ClassEntity> nativeClasses1 = compiler1
-      .backend.nativeResolutionEnqueuerForTesting.nativeClassesForTesting;
-  Iterable<ClassEntity> nativeClasses2 = compiler2
-      .backend.nativeResolutionEnqueuerForTesting.nativeClassesForTesting;
-
-  checkSetEquivalence(compiler1, compiler2, 'nativeClasses', nativeClasses1,
-      nativeClasses2, strategy.elementEquivalence);
-
-  Iterable<ClassEntity> liveNativeClasses1 =
-      compiler1.backend.nativeResolutionEnqueuerForTesting.liveNativeClasses;
-  Iterable<ClassEntity> liveNativeClasses2 =
-      compiler2.backend.nativeResolutionEnqueuerForTesting.liveNativeClasses;
-
-  checkSetEquivalence(compiler1, compiler2, 'liveNativeClasses',
-      liveNativeClasses1, liveNativeClasses2, strategy.elementEquivalence);
-}
-
-void checkNativeBasicData(NativeBasicDataImpl data1, NativeBasicDataImpl data2,
-    TestStrategy strategy) {
-  checkMapEquivalence(
-      data1,
-      data2,
-      'nativeClassTagInfo',
-      data1.nativeClassTagInfo,
-      data2.nativeClassTagInfo,
-      strategy.elementEquivalence,
-      (a, b) => a == b);
-  checkSetEquivalence(
-      data1,
-      data2,
-      'jsInteropLibraries',
-      data1.jsInteropLibraries.keys,
-      data2.jsInteropLibraries.keys,
-      strategy.elementEquivalence);
-  checkSetEquivalence(
-      data1,
-      data2,
-      'jsInteropClasses',
-      data1.jsInteropClasses.keys,
-      data2.jsInteropClasses.keys,
-      strategy.elementEquivalence);
-}
-
-void checkBackendUsage(
-    BackendUsageImpl usage1, BackendUsageImpl usage2, TestStrategy strategy) {
-  checkSetEquivalence(
-      usage1,
-      usage2,
-      'globalClassDependencies',
-      usage1.globalClassDependencies,
-      usage2.globalClassDependencies,
-      strategy.elementEquivalence);
-  checkSetEquivalence(
-      usage1,
-      usage2,
-      'globalFunctionDependencies',
-      usage1.globalFunctionDependencies,
-      usage2.globalFunctionDependencies,
-      strategy.elementEquivalence);
-  checkSetEquivalence(
-      usage1,
-      usage2,
-      'helperClassesUsed',
-      usage1.helperClassesUsed,
-      usage2.helperClassesUsed,
-      strategy.elementEquivalence);
-  checkSetEquivalence(
-      usage1,
-      usage2,
-      'helperFunctionsUsed',
-      usage1.helperFunctionsUsed,
-      usage2.helperFunctionsUsed,
-      strategy.elementEquivalence);
-  check(
-      usage1,
-      usage2,
-      'needToInitializeIsolateAffinityTag',
-      usage1.needToInitializeIsolateAffinityTag,
-      usage2.needToInitializeIsolateAffinityTag);
-  check(
-      usage1,
-      usage2,
-      'needToInitializeDispatchProperty',
-      usage1.needToInitializeDispatchProperty,
-      usage2.needToInitializeDispatchProperty);
-  check(usage1, usage2, 'requiresPreamble', usage1.requiresPreamble,
-      usage2.requiresPreamble);
-  check(usage1, usage2, 'isInvokeOnUsed', usage1.isInvokeOnUsed,
-      usage2.isInvokeOnUsed);
-  check(usage1, usage2, 'isRuntimeTypeUsed', usage1.isRuntimeTypeUsed,
-      usage2.isRuntimeTypeUsed);
-  check(usage1, usage2, 'isFunctionApplyUsed', usage1.isFunctionApplyUsed,
-      usage2.isFunctionApplyUsed);
-  check(usage1, usage2, 'isNoSuchMethodUsed', usage1.isNoSuchMethodUsed,
-      usage2.isNoSuchMethodUsed);
-}
-
-checkElementEnvironment(ElementEnvironment env1, ElementEnvironment env2,
-    DartTypes types1, DartTypes types2, TestStrategy strategy,
-    {bool checkConstructorBodies: false}) {
-  strategy.testElements(
-      env1, env2, 'mainLibrary', env1.mainLibrary, env2.mainLibrary);
-  strategy.testElements(
-      env1, env2, 'mainFunction', env1.mainFunction, env2.mainFunction);
-
-  Iterable<ConstantValue> filterMetadata(Iterable<ConstantValue> constants) {
-    const skippedMetadata = const [
-      // Annotations on patches are not included in the patched sdk.
-      'ConstructedConstant(_Patch())',
-      'ConstructedConstant(NoInline())',
-
-      // Inserted by TargetImplementation. Should only be in the VM target.
-      'ConstructedConstant(ExternalName(name=StringConstant("")))',
-    ];
-
-    return constants
-        .where((c) => !skippedMetadata.contains(c.toStructuredText()));
-  }
-
-  Iterable<LibraryEntity> filterLibraries(Iterable<LibraryEntity> libraries) {
-    List<Uri> skippedLibraries = [
-      Uri.parse('dart:mirrors'),
-      Uri.parse('dart:_js_mirrors'),
-      Uri.parse('dart:js'),
-      Uri.parse('dart:_js'),
-      Uri.parse('dart:js_util'),
-      Uri.parse('dart:_chrome'),
-      Uri.parse('dart:io'),
-      Uri.parse('dart:_http'),
-      Uri.parse('dart:developer'),
-    ];
-    return libraries.where((l) => !skippedLibraries.contains(l.canonicalUri));
-  }
-
-  checkMembers(MemberEntity member1, MemberEntity member2) {
-    Expect.equals(env1.isDeferredLoadLibraryGetter(member1),
-        env2.isDeferredLoadLibraryGetter(member2));
-
-    checkListEquivalence(
-        member1,
-        member2,
-        'metadata',
-        filterMetadata(env1.getMemberMetadata(member1)),
-        filterMetadata(env2.getMemberMetadata(member2)),
-        strategy.testConstantValues);
-
-    if (member1 is FunctionEntity && member2 is FunctionEntity) {
-      if (member1 is ConstructorElement &&
-          member1.definingConstructor != null) {
-        // TODO(johnniwinther): Test these. Currently these are sometimes
-        // correctly typed, sometimes using dynamic instead of parameter and
-        // return types.
-        return;
-      }
-      check(member1, member2, 'getFunctionType', env1.getFunctionType(member1),
-          env2.getFunctionType(member2), strategy.typeEquivalence);
-    }
-
-    check(
-        member1, member2, "isTopLevel", member1.isTopLevel, member2.isTopLevel);
-    check(member1, member2, "isStatic", member1.isStatic, member2.isStatic);
-    check(member1, member2, "isInstanceMember", member1.isInstanceMember,
-        member2.isInstanceMember);
-    check(member1, member2, "isConstructor", member1.isConstructor,
-        member2.isConstructor);
-    check(member1, member2, "isField", member1.isField, member2.isField);
-    check(
-        member1, member2, "isFunction", member1.isFunction, member2.isFunction);
-    check(member1, member2, "isGetter", member1.isGetter, member2.isGetter);
-    check(member1, member2, "isSetter", member1.isSetter, member2.isSetter);
-    check(member1, member2, "isAssignable", member1.isAssignable,
-        member2.isAssignable);
-    check(member1, member2, "isConst", member1.isConst, member2.isConst);
-    check(
-        member1, member2, "isAbstract", member1.isAbstract, member2.isAbstract);
-
-    if (member1 is FunctionEntity) {
-      FunctionEntity function1 = member1;
-      FunctionEntity function2 = member2;
-      check(function1, function2, "isExternal", function1.isExternal,
-          function2.isExternal);
-      check(function1, function2, "parameterStructure",
-          function1.parameterStructure, function2.parameterStructure);
-      check(function1, function2, "asyncMarker", function1.asyncMarker,
-          function2.asyncMarker);
-    }
-
-    if (member1 is ConstructorEntity) {
-      ConstructorEntity constructor1 = member1;
-      ConstructorEntity constructor2 = member2;
-      check(
-          constructor1,
-          constructor2,
-          "isGenerativeConstructor",
-          constructor1.isGenerativeConstructor,
-          constructor2.isGenerativeConstructor);
-      check(constructor1, constructor2, "isFactoryConstructor",
-          constructor1.isFactoryConstructor, constructor2.isFactoryConstructor);
-      check(
-          constructor1,
-          constructor2,
-          "isFromEnvironmentConstructor",
-          constructor1.isFromEnvironmentConstructor,
-          constructor2.isFromEnvironmentConstructor);
-    }
-  }
-
-  checkSetEquivalence(env1, env2, 'libraries', filterLibraries(env1.libraries),
-      filterLibraries(env2.libraries), strategy.elementEquivalence,
-      onSameElement: (LibraryEntity lib1, LibraryEntity lib2) {
-    Expect.identical(lib1, env1.lookupLibrary(lib1.canonicalUri));
-    Expect.identical(lib2, env2.lookupLibrary(lib2.canonicalUri));
-
-    // TODO(johnniwinther): Check libraryName.
-
-    List<ClassEntity> classes2 = <ClassEntity>[];
-    env1.forEachClass(lib1, (ClassEntity cls1) {
-      Expect.identical(cls1, env1.lookupClass(lib1, cls1.name));
-
-      String className = cls1.name;
-      ClassEntity cls2 = env2.lookupClass(lib2, className);
-      Expect.isNotNull(cls2, 'Missing class $className in $lib2');
-      Expect.identical(cls2, env2.lookupClass(lib2, cls2.name));
-
-      check(lib1, lib2, 'class:${className}', cls1, cls2,
-          strategy.elementEquivalence);
-
-      Expect.equals(env1.isGenericClass(cls1), env2.isGenericClass(cls2));
-
-      check(
-          cls1,
-          cls2,
-          'superclass',
-          env1.getSuperClass(cls1, skipUnnamedMixinApplications: false),
-          env2.getSuperClass(cls2, skipUnnamedMixinApplications: false),
-          strategy.elementEquivalence);
-      check(
-          cls1,
-          cls2,
-          'superclass',
-          env1.getSuperClass(cls1, skipUnnamedMixinApplications: true),
-          env2.getSuperClass(cls2, skipUnnamedMixinApplications: true),
-          strategy.elementEquivalence);
-
-      InterfaceType thisType1 = env1.getThisType(cls1);
-      InterfaceType thisType2 = env2.getThisType(cls2);
-      check(cls1, cls2, 'thisType', thisType1, thisType2,
-          strategy.typeEquivalence);
-      check(cls1, cls2, 'rawType', env1.getRawType(cls1), env2.getRawType(cls2),
-          strategy.typeEquivalence);
-      check(
-          cls1,
-          cls2,
-          'createInterfaceType',
-          env1.createInterfaceType(cls1, thisType1.typeArguments),
-          env2.createInterfaceType(cls2, thisType2.typeArguments),
-          strategy.typeEquivalence);
-
-      check(cls1, cls2, 'isGenericClass', env1.isGenericClass(cls1),
-          env2.isGenericClass(cls2));
-      check(cls1, cls2, 'isMixinApplication', env1.isMixinApplication(cls1),
-          env2.isMixinApplication(cls2));
-      check(
-          cls1,
-          cls2,
-          'isUnnamedMixinApplication',
-          env1.isUnnamedMixinApplication(cls1),
-          env2.isUnnamedMixinApplication(cls2));
-      check(
-          cls1,
-          cls2,
-          'getEffectiveMixinClass',
-          env1.getEffectiveMixinClass(cls1),
-          env2.getEffectiveMixinClass(cls2),
-          strategy.elementEquivalence);
-
-      // TODO(johnniwinther): Check type variable bounds.
-
-      check(cls1, cls2, 'callType', types1.getCallType(thisType1),
-          types2.getCallType(thisType2), strategy.typeEquivalence);
-
-      List<InterfaceType> supertypes1 = <InterfaceType>[];
-      env1.forEachSupertype(cls1, supertypes1.add);
-      List<InterfaceType> supertypes2 = <InterfaceType>[];
-      env2.forEachSupertype(cls2, supertypes2.add);
-      checkLists(supertypes1, supertypes2, 'supertypes on $cls1, $cls2',
-          strategy.typeEquivalence);
-
-      List<ClassEntity> mixins1 = <ClassEntity>[];
-      env1.forEachMixin(cls1, mixins1.add);
-      List<ClassEntity> mixins2 = <ClassEntity>[];
-      env2.forEachMixin(cls2, mixins2.add);
-      checkLists(mixins1, mixins2, 'mixins on $cls1, $cls2',
-          strategy.elementEquivalence);
-
-      Map<MemberEntity, ClassEntity> members1 = <MemberEntity, ClassEntity>{};
-      Set<String> memberNames1 = new Set<String>();
-      Map<MemberEntity, ClassEntity> members2 = <MemberEntity, ClassEntity>{};
-      Set<String> memberNames2 = new Set<String>();
-      env1.forEachClassMember(cls1,
-          (ClassEntity declarer1, MemberEntity member1) {
-        if (cls1 == declarer1) {
-          Expect.identical(
-              member1,
-              env1.lookupLocalClassMember(cls1, member1.name,
-                  setter: member1.isSetter));
-        }
-        if (!memberNames1.contains(member1.name)) {
-          Expect.identical(
-              member1,
-              env1.lookupClassMember(cls1, member1.name,
-                  setter: member1.isSetter));
-        }
-        memberNames1.add(member1.name);
-        members1[member1] = declarer1;
-      });
-      env2.forEachClassMember(cls2,
-          (ClassEntity declarer2, MemberEntity member2) {
-        if (cls2 == declarer2) {
-          Expect.identical(
-              member2,
-              env2.lookupLocalClassMember(cls2, member2.name,
-                  setter: member2.isSetter));
-        }
-        if (!memberNames2.contains(member2.name)) {
-          Expect.identical(
-              member2,
-              env2.lookupClassMember(cls2, member2.name,
-                  setter: member2.isSetter));
-        }
-        memberNames2.add(member2.name);
-        members2[member2] = declarer2;
-      });
-      checkMapEquivalence(cls1, cls2, 'members', members1, members2, (a, b) {
-        bool result = strategy.elementEquivalence(a, b);
-        if (result) checkMembers(a, b);
-        return result;
-      }, strategy.elementEquivalence);
-
-      Set<ConstructorEntity> constructors2 = new Set<ConstructorEntity>();
-      env1.forEachConstructor(cls1, (ConstructorEntity constructor1) {
-        Expect.identical(
-            constructor1, env1.lookupConstructor(cls1, constructor1.name));
-
-        String constructorName = constructor1.name;
-        ConstructorEntity constructor2 =
-            env2.lookupConstructor(cls2, constructorName);
-        Expect.isNotNull(
-            constructor2, "Missing constructor for $constructor1 in $cls2 ");
-        Expect.identical(
-            constructor2, env2.lookupConstructor(cls2, constructor2.name));
-
-        constructors2.add(constructor2);
-
-        check(cls1, cls2, 'constructor:${constructorName}', constructor1,
-            constructor2, strategy.elementEquivalence);
-
-        checkMembers(constructor1, constructor2);
-      });
-      env2.forEachConstructor(cls2, (ConstructorEntity constructor2) {
-        Expect.isTrue(constructors2.contains(constructor2),
-            "Extra constructor $constructor2 in $cls2");
-      });
-
-      if (checkConstructorBodies) {
-        Set<ConstructorBodyEntity> constructorBodies1 =
-            new Set<ConstructorBodyEntity>();
-        Set<ConstructorBodyEntity> constructorBodies2 =
-            new Set<ConstructorBodyEntity>();
-        env1.forEachConstructorBody(cls1,
-            (ConstructorBodyEntity constructorBody1) {
-          constructorBodies1.add(constructorBody1);
-        });
-        env2.forEachConstructorBody(cls2,
-            (ConstructorBodyEntity constructorBody2) {
-          constructorBodies2.add(constructorBody2);
-        });
-        checkSetEquivalence(cls1, cls2, 'constructor-bodies',
-            constructorBodies1, constructorBodies2, strategy.elementEquivalence,
-            onSameElement: (ConstructorBodyEntity constructorBody1,
-                ConstructorBodyEntity constructorBody2) {
-          check(constructorBody1, constructorBody2, 'name',
-              constructorBody1.name, constructorBody2.name);
-
-          checkMembers(constructorBody1, constructorBody2);
-        });
-      }
-      classes2.add(cls2);
-    });
-    env2.forEachClass(lib2, (ClassEntity cls2) {
-      Expect.isTrue(classes2.contains(cls2), "Extra class $cls2 in $lib2");
-    });
-
-    Set<MemberEntity> members2 = new Set<MemberEntity>();
-    env1.forEachLibraryMember(lib1, (MemberEntity member1) {
-      Expect.identical(
-          member1,
-          env1.lookupLibraryMember(lib1, member1.name,
-              setter: member1.isSetter));
-
-      String memberName = member1.name;
-      MemberEntity member2 =
-          env2.lookupLibraryMember(lib2, memberName, setter: member1.isSetter);
-      Expect.isNotNull(member2, 'Missing member for $member1 in $lib2');
-      Expect.identical(
-          member2,
-          env2.lookupLibraryMember(lib2, member2.name,
-              setter: member2.isSetter));
-
-      members2.add(member2);
-
-      check(lib1, lib2, 'member:${memberName}', member1, member2,
-          strategy.elementEquivalence);
-
-      checkMembers(member1, member2);
-    });
-    env2.forEachLibraryMember(lib2, (MemberEntity member2) {
-      Expect.isTrue(
-          members2.contains(member2), "Extra member $member2 in $lib2");
-    });
-  });
-  // TODO(johnniwinther): Check getLocalFunctionType and getUnaliasedType ?
-}
-
-bool areInstantiationInfosEquivalent(
-    InstantiationInfo info1,
-    InstantiationInfo info2,
-    bool elementEquivalence(Entity a, Entity b),
-    bool typeEquivalence(DartType a, DartType b)) {
-  checkMaps(
-      info1.instantiationMap,
-      info2.instantiationMap,
-      'instantiationMap of\n   '
-      '${info1.instantiationMap}\nvs ${info2.instantiationMap}',
-      elementEquivalence,
-      (a, b) => areSetsEquivalent(
-          a, b, (a, b) => areInstancesEquivalent(a, b, typeEquivalence)));
-  return true;
-}
-
-bool areInstancesEquivalent(Instance instance1, Instance instance2,
-    bool typeEquivalence(DartType a, DartType b)) {
-  InterfaceType type1 = instance1.type;
-  InterfaceType type2 = instance2.type;
-  return typeEquivalence(type1, type2) &&
-      instance1.kind == instance2.kind &&
-      instance1.isRedirection == instance2.isRedirection;
-}
-
-bool areAbstractUsagesEquivalent(AbstractUsage usage1, AbstractUsage usage2) {
-  return usage1.hasSameUsage(usage2);
-}
-
-bool _areEntitiesEquivalent(a, b) => areElementsEquivalent(a, b);
-
-void checkResolutionEnqueuers(
-    BackendUsage backendUsage1,
-    BackendUsage backendUsage2,
-    ResolutionEnqueuer enqueuer1,
-    ResolutionEnqueuer enqueuer2,
-    {bool elementEquivalence(Entity a, Entity b): _areEntitiesEquivalent,
-    bool typeEquivalence(DartType a, DartType b): areTypesEquivalent,
-    bool elementFilter(Entity element),
-    bool verbose: false,
-    List<String> skipClassUsageTesting: const <String>[]}) {
-  elementFilter ??= (_) => true;
-
-  ResolutionWorldBuilderBase worldBuilder1 = enqueuer1.worldBuilder;
-  ResolutionWorldBuilderBase worldBuilder2 = enqueuer2.worldBuilder;
-
-  checkSets(worldBuilder1.instantiatedTypes, worldBuilder2.instantiatedTypes,
-      "Instantiated types mismatch", typeEquivalence,
-      verbose: verbose);
-
-  checkSets(
-      worldBuilder1.directlyInstantiatedClasses,
-      worldBuilder2.directlyInstantiatedClasses,
-      "Directly instantiated classes mismatch",
-      elementEquivalence,
-      verbose: verbose);
-
-  checkMaps(
-      worldBuilder1.getInstantiationMap(),
-      worldBuilder2.getInstantiationMap(),
-      "Instantiated classes mismatch",
-      elementEquivalence,
-      (a, b) => areInstantiationInfosEquivalent(
-          a, b, elementEquivalence, typeEquivalence),
-      verbose: verbose);
-
-  checkSets(enqueuer1.processedEntities, enqueuer2.processedEntities,
-      "Processed element mismatch", elementEquivalence,
-      elementFilter: elementFilter, verbose: verbose);
-
-  checkSets(worldBuilder1.isChecks, worldBuilder2.isChecks, "Is-check mismatch",
-      typeEquivalence,
-      verbose: verbose);
-
-  checkSets(worldBuilder1.closurizedMembers, worldBuilder2.closurizedMembers,
-      "closurizedMembers", elementEquivalence,
-      verbose: verbose);
-  checkSets(worldBuilder1.fieldSetters, worldBuilder2.fieldSetters,
-      "fieldSetters", elementEquivalence,
-      verbose: verbose);
-  checkSets(
-      worldBuilder1.methodsNeedingSuperGetter,
-      worldBuilder2.methodsNeedingSuperGetter,
-      "methodsNeedingSuperGetter",
-      elementEquivalence,
-      verbose: verbose);
-
-  checkMaps(
-      worldBuilder1.classUsageForTesting,
-      worldBuilder2.classUsageForTesting,
-      'classUsageForTesting',
-      elementEquivalence,
-      areAbstractUsagesEquivalent,
-      keyFilter: (c) => !skipClassUsageTesting.contains(c.name),
-      verbose: verbose);
-
-  checkMaps(
-      worldBuilder1.staticMemberUsageForTesting,
-      worldBuilder2.staticMemberUsageForTesting,
-      'staticMemberUsageForTesting',
-      elementEquivalence,
-      areAbstractUsagesEquivalent,
-      keyFilter: elementFilter,
-      verbose: verbose);
-  checkMaps(
-      worldBuilder1.instanceMemberUsageForTesting,
-      worldBuilder2.instanceMemberUsageForTesting,
-      'instanceMemberUsageForTesting',
-      elementEquivalence,
-      areAbstractUsagesEquivalent,
-      verbose: verbose);
-
-  Expect.equals(backendUsage1.isInvokeOnUsed, backendUsage2.isInvokeOnUsed,
-      "JavaScriptBackend.hasInvokeOnSupport mismatch");
-  Expect.equals(
-      backendUsage1.isFunctionApplyUsed,
-      backendUsage1.isFunctionApplyUsed,
-      "JavaScriptBackend.hasFunctionApplySupport mismatch");
-  Expect.equals(
-      backendUsage1.isRuntimeTypeUsed,
-      backendUsage2.isRuntimeTypeUsed,
-      "JavaScriptBackend.hasRuntimeTypeSupport mismatch");
-}
-
-void checkCodegenEnqueuers(CodegenEnqueuer enqueuer1, CodegenEnqueuer enqueuer2,
-    {bool elementEquivalence(Entity a, Entity b): _areEntitiesEquivalent,
-    bool typeEquivalence(DartType a, DartType b): areTypesEquivalent,
-    bool elementFilter(Element element),
-    bool verbose: false}) {
-  CodegenWorldBuilderImpl worldBuilder1 = enqueuer1.worldBuilder;
-  CodegenWorldBuilderImpl worldBuilder2 = enqueuer2.worldBuilder;
-
-  checkSets(worldBuilder1.instantiatedTypes, worldBuilder2.instantiatedTypes,
-      "Instantiated types mismatch", typeEquivalence,
-      verbose: verbose);
-
-  checkSets(
-      worldBuilder1.directlyInstantiatedClasses,
-      worldBuilder2.directlyInstantiatedClasses,
-      "Directly instantiated classes mismatch",
-      elementEquivalence,
-      verbose: verbose);
-
-  checkSets(enqueuer1.processedEntities, enqueuer2.processedEntities,
-      "Processed element mismatch", elementEquivalence, elementFilter: (e) {
-    return elementFilter != null ? elementFilter(e) : true;
-  }, verbose: verbose);
-
-  checkSets(worldBuilder1.isChecks, worldBuilder2.isChecks, "Is-check mismatch",
-      typeEquivalence,
-      verbose: verbose);
-
-  checkSets(
-      worldBuilder1.allReferencedStaticFields,
-      worldBuilder2.allReferencedStaticFields,
-      "Directly instantiated classes mismatch",
-      elementEquivalence,
-      verbose: verbose);
-  checkSets(worldBuilder1.closurizedMembers, worldBuilder2.closurizedMembers,
-      "closurizedMembers", elementEquivalence,
-      verbose: verbose);
-  checkSets(worldBuilder1.processedClasses, worldBuilder2.processedClasses,
-      "processedClasses", elementEquivalence,
-      verbose: verbose);
-  checkSets(
-      worldBuilder1.methodsNeedingSuperGetter,
-      worldBuilder2.methodsNeedingSuperGetter,
-      "methodsNeedingSuperGetter",
-      elementEquivalence,
-      verbose: verbose);
-  checkSets(
-      worldBuilder1.staticFunctionsNeedingGetter,
-      worldBuilder2.staticFunctionsNeedingGetter,
-      "staticFunctionsNeedingGetter",
-      elementEquivalence,
-      verbose: verbose);
-
-  checkMaps(
-      worldBuilder1.classUsageForTesting,
-      worldBuilder2.classUsageForTesting,
-      'classUsageForTesting',
-      elementEquivalence,
-      areAbstractUsagesEquivalent,
-      verbose: verbose);
-  checkMaps(
-      worldBuilder1.staticMemberUsageForTesting,
-      worldBuilder2.staticMemberUsageForTesting,
-      'staticMemberUsageForTesting',
-      elementEquivalence,
-      areAbstractUsagesEquivalent,
-      verbose: verbose);
-  checkMaps(
-      worldBuilder1.instanceMemberUsageForTesting,
-      worldBuilder2.instanceMemberUsageForTesting,
-      'instanceMemberUsageForTesting',
-      elementEquivalence,
-      areAbstractUsagesEquivalent,
-      verbose: verbose);
-}
-
-// TODO(johnniwinther): Check all emitter properties.
-void checkEmitters(
-    CodeEmitterTask emitter1, CodeEmitterTask emitter2, TestStrategy strategy,
-    {bool elementEquivalence(Entity a, Entity b): _areEntitiesEquivalent,
-    bool typeEquivalence(DartType a, DartType b): areTypesEquivalent,
-    bool elementFilter(Element element),
-    bool verbose: false}) {
-  checkEmitterPrograms(emitter1.emitter.programForTesting,
-      emitter2.emitter.programForTesting, strategy);
-
-  checkSets(
-      emitter1.typeTestRegistry.rtiNeededClasses,
-      emitter2.typeTestRegistry.rtiNeededClasses,
-      "TypeTestRegistry rti needed classes mismatch",
-      strategy.elementEquivalence,
-      verbose: verbose);
-}
-
-void checkEmitterPrograms(
-    Program program1, Program program2, TestStrategy strategy) {
-  checkLists(program1.fragments, program2.fragments, 'fragments',
-      (a, b) => a.outputFileName == b.outputFileName,
-      onSameElement: (a, b) =>
-          checkEmitterFragments(program1, program2, a, b, strategy));
-  checkLists(
-      program1.holders, program2.holders, 'holders', (a, b) => a.name == b.name,
-      onSameElement: checkEmitterHolders);
-  check(program1, program2, 'outputContainsConstantList',
-      program1.outputContainsConstantList, program2.outputContainsConstantList);
-  check(program1, program2, 'needsNativeSupport', program1.needsNativeSupport,
-      program2.needsNativeSupport);
-  check(program1, program2, 'hasSoftDeferredClasses',
-      program1.hasSoftDeferredClasses, program2.hasSoftDeferredClasses);
-  checkMaps(
-      program1.loadMap,
-      program2.loadMap,
-      'loadMap',
-      equality,
-      (a, b) => areSetsEquivalent(
-          a, b, (a, b) => a.outputFileName == b.outputFileName));
-  checkMaps(program1.symbolsMap, program2.symbolsMap, 'symbolsMap',
-      (a, b) => a.key == b.key, equality);
-
-  check(
-      program1,
-      program2,
-      'typeToInterceptorMap',
-      program1.typeToInterceptorMap,
-      program2.typeToInterceptorMap,
-      areJsNodesEquivalent,
-      js.nodeToString);
-}
-
-void checkEmitterFragments(Program program1, Program program2,
-    Fragment fragment1, Fragment fragment2, TestStrategy strategy) {
-  // TODO(johnniwinther): Check outputUnit.
-  checkLists(fragment1.libraries, fragment2.libraries, 'libraries',
-      (a, b) => a.element.canonicalUri == b.element.canonicalUri,
-      onSameElement: (a, b) => checkEmitterLibraries(a, b, strategy));
-  checkLists(fragment1.constants, fragment2.constants, 'constants',
-      (a, b) => a.name.key == b.name.key,
-      onSameElement: (a, b) => checkEmitterConstants(a, b, strategy));
-  checkLists(fragment1.staticNonFinalFields, fragment2.staticNonFinalFields,
-      'staticNonFinalFields', (a, b) => a.name.key == b.name.key,
-      onSameElement: checkEmitterStaticFields);
-  checkLists(
-      fragment1.staticLazilyInitializedFields,
-      fragment2.staticLazilyInitializedFields,
-      'staticLazilyInitializedFields',
-      (a, b) => a.name.key == b.name.key,
-      onSameElement: checkEmitterStaticFields);
-  check(fragment1, fragment2, 'isMainFragment', fragment1.isMainFragment,
-      fragment2.isMainFragment);
-  if (fragment1 is MainFragment && fragment2 is MainFragment) {
-    check(fragment1, fragment2, 'invokeMain', fragment1.invokeMain,
-        fragment2.invokeMain, areJsNodesEquivalent, js.nodeToString);
-  } else if (fragment1 is DeferredFragment && fragment2 is DeferredFragment) {
-    check(fragment1, fragment2, 'name', fragment1.name, fragment2.name);
-  }
-
-  check(
-      program1,
-      program2,
-      'metadataForOutputUnit',
-      program1.metadataForOutputUnit(fragment1.outputUnit),
-      program2.metadataForOutputUnit(fragment2.outputUnit),
-      areJsNodesEquivalent,
-      js.nodeToString);
-
-  check(
-      program1,
-      program2,
-      'metadataTypesForOutputUnit',
-      program1.metadataTypesForOutputUnit(fragment1.outputUnit),
-      program2.metadataTypesForOutputUnit(fragment2.outputUnit),
-      areJsNodesEquivalent,
-      js.nodeToString);
-}
-
-void checkEmitterLibraries(
-    Library library1, Library library2, TestStrategy strategy) {
-  check(library1, library2, 'uri', library1.uri, library2.uri);
-  checkLists(library1.classes, library2.classes, 'classes',
-      (a, b) => a.name.key == b.name.key,
-      onSameElement: (a, b) => checkEmitterClasses(a, b, strategy));
-  checkLists(library1.statics, library2.statics, 'statics',
-      (a, b) => a.name.key == b.name.key,
-      onSameElement: (a, b) => checkEmitterMethods(a, b, strategy));
-  checkLists(
-      library1.staticFieldsForReflection,
-      library2.staticFieldsForReflection,
-      'staticFieldsForReflection on $library1/$library2',
-      (a, b) => a.name.key == b.name.key,
-      onSameElement: checkEmitterFields);
-}
-
-void checkEmitterClasses(Class class1, Class class2, TestStrategy strategy) {
-  checkLists(class1.methods, class2.methods, 'methods',
-      (a, b) => a.name.key == b.name.key,
-      onSameElement: (a, b) => checkEmitterMethods(a, b, strategy));
-  checkLists(class1.fields, class2.fields, 'fields',
-      (a, b) => a.name.key == b.name.key,
-      onSameElement: checkEmitterFields);
-  checkLists(class1.isChecks, class2.isChecks, 'isChecks',
-      (a, b) => a.name.key == b.name.key,
-      onSameElement: (a, b) => checkEmitterMethods(a, b, strategy));
-  checkLists(class1.checkedSetters, class2.checkedSetters, 'checkedSetters',
-      (a, b) => a.name.key == b.name.key,
-      onSameElement: (a, b) => checkEmitterMethods(a, b, strategy));
-  checkLists(class1.callStubs, class2.callStubs, 'callStubs',
-      (a, b) => a.name.key == b.name.key,
-      onSameElement: (a, b) => checkEmitterMethods(a, b, strategy));
-  checkLists(class1.noSuchMethodStubs, class2.noSuchMethodStubs,
-      'noSuchMethodStubs', (a, b) => a.name.key == b.name.key,
-      onSameElement: (a, b) => checkEmitterMethods(a, b, strategy));
-  checkLists(
-      class1.staticFieldsForReflection,
-      class2.staticFieldsForReflection,
-      'staticFieldsForReflection on $class1/$class2',
-      (a, b) => a.name.key == b.name.key,
-      onSameElement: checkEmitterFields);
-
-  check(class1, class2, 'superclassName', class1.superclassName?.key,
-      class2.superclassName?.key);
-  check(class1, class2, 'isMixinApplication', class1.isMixinApplication,
-      class2.isMixinApplication);
-  check(class1, class2, 'hasRtiField', class1.hasRtiField, class2.hasRtiField);
-  check(class1, class2, 'onlyForRti', class1.onlyForRti, class2.onlyForRti);
-  check(class1, class2, 'isDirectlyInstantiated', class1.isDirectlyInstantiated,
-      class2.isDirectlyInstantiated);
-  check(class1, class2, 'isNative', class1.isNative, class2.isNative);
-  check(class1, class2, 'isClosureBaseClass', class1.isClosureBaseClass,
-      class2.isClosureBaseClass);
-  check(class1, class2, 'isSoftDeferred', class1.isSoftDeferred,
-      class2.isSoftDeferred);
-  check(class1, class2, 'isEager', class1.isEager, class2.isEager);
-  checkEmitterHolders(class1.holder, class2.holder);
-}
-
-void checkEmitterMethods(
-    Method method1, Method method2, TestStrategy strategy) {
-  check(method1, method2, 'code', method1.code, method2.code,
-      areJsNodesEquivalent, js.nodeToString);
-  check(method1, method2, 'is ParameterStubMethod',
-      method1 is ParameterStubMethod, method2 is ParameterStubMethod);
-  if (method1 is ParameterStubMethod && method2 is ParameterStubMethod) {
-    check(method1, method2, 'callName', method1.callName?.key,
-        method2.callName?.key);
-  }
-  check(method1, method2, 'is DartMethod', method1 is DartMethod,
-      method2 is DartMethod);
-  if (method1 is DartMethod && method2 is DartMethod) {
-    check(method1, method2, 'callName', method1.callName?.key,
-        method2.callName?.key);
-    check(method1, method2, 'needsTearOff', method1.needsTearOff,
-        method2.needsTearOff);
-    check(method1, method2, 'tearOffName', method1.tearOffName?.key,
-        method2.tearOffName?.key);
-    checkLists(method1.parameterStubs, method2.parameterStubs, 'parameterStubs',
-        (a, b) => a.name.key == b.name.key,
-        onSameElement: (a, b) => checkEmitterMethods(a, b, strategy));
-    check(method1, method2, 'canBeApplied', method1.canBeApplied,
-        method2.canBeApplied);
-    check(method1, method2, 'canBeReflected', method1.canBeReflected,
-        method2.canBeReflected);
-    check(method1, method2, 'functionType', method1.functionType,
-        method2.functionType, areJsNodesEquivalent, js.nodeToString);
-    check(method1, method2, 'requiredParameterCount',
-        method1.requiredParameterCount, method2.requiredParameterCount);
-    if (method1.optionalParameterDefaultValues == null &&
-        method2.optionalParameterDefaultValues == null) {
-      // Nothing to test.
-    } else if (method1.optionalParameterDefaultValues is List &&
-        method2.optionalParameterDefaultValues is List) {
-      checkLists(
-          method1.optionalParameterDefaultValues,
-          method2.optionalParameterDefaultValues,
-          'optionalParameterDefaultValues',
-          strategy.constantValueEquivalence);
-    } else if (method1.optionalParameterDefaultValues is Map &&
-        method2.optionalParameterDefaultValues is Map) {
-      checkMaps(
-          method1.optionalParameterDefaultValues,
-          method2.optionalParameterDefaultValues,
-          'optionalParameterDefaultValues',
-          equality,
-          strategy.constantValueEquivalence);
-    } else {
-      check(
-          method1,
-          method2,
-          'optionalParameterDefaultValues',
-          method1.optionalParameterDefaultValues,
-          method2.optionalParameterDefaultValues);
-    }
-  }
-}
-
-void checkEmitterFields(Field field1, Field field2) {
-  check(field1, field2, 'accessorName', field1.accessorName?.key,
-      field2.accessorName?.key);
-  check(field1, field2, 'getterFlags', field1.getterFlags, field2.getterFlags);
-  check(field1, field2, 'setterFlags', field1.setterFlags, field2.setterFlags);
-  check(field1, field2, 'needsCheckedSetter', field1.needsCheckedSetter,
-      field2.needsCheckedSetter);
-}
-
-void checkEmitterConstants(
-    Constant constant1, Constant constant2, TestStrategy strategy) {
-  checkEmitterHolders(constant1.holder, constant2.holder);
-  check(constant1, constant2, 'value', constant1.value, constant2.value,
-      strategy.constantValueEquivalence);
-}
-
-void checkEmitterStaticFields(StaticField field1, StaticField field2) {
-  check(field1, field2, 'code', field1.code, field2.code, areJsNodesEquivalent,
-      js.nodeToString);
-  check(field1, field2, 'isFinal', field1.isFinal, field2.isFinal);
-  check(field1, field2, 'isLazy', field1.isLazy, field2.isLazy);
-  checkEmitterHolders(field1.holder, field2.holder);
-}
-
-void checkEmitterHolders(Holder holder1, Holder holder2) {
-  check(holder1, holder2, 'name', holder1.name, holder2.name);
-  check(holder1, holder2, 'index', holder1.index, holder2.index);
-  check(holder1, holder2, 'isStaticStateHolder', holder1.isStaticStateHolder,
-      holder2.isStaticStateHolder);
-  check(holder1, holder2, 'isConstantsHolder', holder1.isConstantsHolder,
-      holder2.isConstantsHolder);
-}
-
-void checkGeneratedCode(JavaScriptBackend backend1, JavaScriptBackend backend2,
-    {bool elementEquivalence(Entity a, Entity b): _areEntitiesEquivalent}) {
-  checkMaps(backend1.generatedCode, backend2.generatedCode, 'generatedCode',
-      elementEquivalence, areJsNodesEquivalent,
-      valueToString: js.nodeToString);
-}
 
 bool areJsNodesEquivalent(js.Node node1, js.Node node2) {
   return new JsEquivalenceVisitor().testNodes(node1, node2);
diff --git a/tests/compiler/dart2js/equivalence/check_helpers.dart b/tests/compiler/dart2js/equivalence/check_helpers.dart
index 4a52acc..cef161e 100644
--- a/tests/compiler/dart2js/equivalence/check_helpers.dart
+++ b/tests/compiler/dart2js/equivalence/check_helpers.dart
@@ -6,15 +6,9 @@
 
 library dart2js.equivalence.helpers;
 
-import 'package:compiler/src/constants/expressions.dart';
-import 'package:compiler/src/constants/values.dart';
-import 'package:compiler/src/elements/entities.dart';
-import 'package:compiler/src/elements/resolution_types.dart';
 import 'package:compiler/src/elements/types.dart';
 import 'package:expect/expect.dart';
 
-import 'equivalence_helper.dart';
-
 Check currentCheck;
 
 class Check {
@@ -66,66 +60,8 @@
   }
 }
 
-/// Strategy for checking equivalence.
-///
-/// Use this strategy to fail early with contextual information in the event of
-/// inequivalence.
-class CheckStrategy extends TestStrategy {
-  const CheckStrategy(
-      {Equivalence<Entity> elementEquivalence: areEntitiesEquivalent,
-      Equivalence<DartType> typeEquivalence: areTypesEquivalent,
-      Equivalence<ConstantExpression> constantEquivalence:
-          areConstantsEquivalent,
-      Equivalence<ConstantValue> constantValueEquivalence:
-          areConstantValuesEquivalent})
-      : super(
-            elementEquivalence: elementEquivalence,
-            typeEquivalence: typeEquivalence,
-            constantEquivalence: constantEquivalence,
-            constantValueEquivalence: constantValueEquivalence);
-
-  TestStrategy get testOnly => new TestStrategy(
-      elementEquivalence: elementEquivalence,
-      typeEquivalence: typeEquivalence,
-      constantEquivalence: constantEquivalence,
-      constantValueEquivalence: constantValueEquivalence);
-
-  @override
-  bool test<T>(var object1, var object2, String property, T value1, T value2,
-      [bool equivalence(T a, T b) = equality]) {
-    return check(object1, object2, property, value1, value2, equivalence);
-  }
-
-  @override
-  bool testLists(
-      Object object1, Object object2, String property, List list1, List list2,
-      [bool elementEquivalence(a, b) = equality]) {
-    return checkListEquivalence(object1, object2, property, list1, list2,
-        (o1, o2, p, v1, v2) {
-      if (!elementEquivalence(v1, v2)) {
-        throw "$o1.$p = '${v1}' <> "
-            "$o2.$p = '${v2}'";
-      }
-    });
-  }
-
-  @override
-  bool testSets<E>(var object1, var object2, String property, Iterable<E> set1,
-      Iterable<E> set2,
-      [bool elementEquivalence(E a, E b) = equality]) {
-    return checkSetEquivalence(
-        object1, object2, property, set1, set2, elementEquivalence);
-  }
-
-  @override
-  bool testMaps<K, V>(
-      var object1, var object2, String property, Map<K, V> map1, Map<K, V> map2,
-      [bool keyEquivalence(K a, K b) = equality,
-      bool valueEquivalence(V a, V b) = equality]) {
-    return checkMapEquivalence(object1, object2, property, map1, map2,
-        keyEquivalence, valueEquivalence);
-  }
-}
+/// Equality based equivalence function.
+bool equality(a, b) => a == b;
 
 /// Check that the values [property] of [object1] and [object2], [value1] and
 /// [value2] respectively, are equal and throw otherwise.
@@ -266,110 +202,6 @@
   return true;
 }
 
-/// Checks the equivalence of the identity (but not properties) of [element1]
-/// and [element2].
-///
-/// Uses [object1], [object2] and [property] to provide context for failures.
-bool checkElementIdentities(Object object1, Object object2, String property,
-    Entity element1, Entity element2) {
-  if (identical(element1, element2)) return true;
-  return check(
-      object1, object2, property, element1, element2, areEntitiesEquivalent);
-}
-
-/// Checks the pair-wise equivalence of the identity (but not properties) of the
-/// elements in [list] and [list2].
-///
-/// Uses [object1], [object2] and [property] to provide context for failures.
-bool checkElementListIdentities(Object object1, Object object2, String property,
-    Iterable<Entity> list1, Iterable<Entity> list2) {
-  return checkListEquivalence(
-      object1, object2, property, list1, list2, checkElementIdentities);
-}
-
-/// Checks the equivalence of [DartType]s [type1] and [type2].
-///
-/// Uses [object1], [object2] and [property] to provide context for failures.
-bool checkDartTypes(Object object1, Object object2, String property,
-        DartType type1, DartType type2) =>
-    checkTypes(object1, object2, property, type1, type2);
-
-/// Checks the equivalence of [type1] and [type2].
-///
-/// Uses [object1], [object2] and [property] to provide context for failures.
-bool checkTypes(Object object1, Object object2, String property,
-    ResolutionDartType type1, ResolutionDartType type2) {
-  if (identical(type1, type2)) return true;
-  if (type1 == null || type2 == null) {
-    return check(object1, object2, property, type1, type2);
-  } else {
-    return check(object1, object2, property, type1, type2,
-        (a, b) => const TypeEquivalence(const CheckStrategy()).visit(a, b));
-  }
-}
-
-/// Checks the pair-wise equivalence of the types in [list1] and [list2].
-///
-/// Uses [object1], [object2] and [property] to provide context for failures.
-bool checkTypeLists(Object object1, Object object2, String property,
-    List<DartType> list1, List<DartType> list2) {
-  return checkListEquivalence(
-      object1, object2, property, list1, list2, checkDartTypes);
-}
-
-/// Checks the equivalence of [exp1] and [exp2].
-///
-/// Uses [object1], [object2] and [property] to provide context for failures.
-bool checkConstants(Object object1, Object object2, String property,
-    ConstantExpression exp1, ConstantExpression exp2) {
-  if (identical(exp1, exp2)) return true;
-  if (exp1 == null || exp2 == null) {
-    return check(object1, object2, property, exp1, exp2);
-  } else {
-    return check(object1, object2, property, exp1, exp2,
-        (a, b) => const ConstantEquivalence(const CheckStrategy()).visit(a, b));
-  }
-}
-
-/// Checks the equivalence of [value1] and [value2].
-///
-/// Uses [object1], [object2] and [property] to provide context for failures.
-bool checkConstantValues(Object object1, Object object2, String property,
-    ConstantValue value1, ConstantValue value2) {
-  if (identical(value1, value2)) return true;
-  if (value1 == null || value2 == null) {
-    return check(object1, object2, property, value1, value2);
-  } else {
-    return check(
-        object1,
-        object2,
-        property,
-        value1,
-        value2,
-        (a, b) =>
-            const ConstantValueEquivalence(const CheckStrategy()).visit(a, b));
-  }
-}
-
-/// Checks the pair-wise equivalence of the constants in [list1] and [list2].
-///
-/// Uses [object1], [object2] and [property] to provide context for failures.
-bool checkConstantLists(Object object1, Object object2, String property,
-    List<ConstantExpression> list1, List<ConstantExpression> list2) {
-  return checkListEquivalence(
-      object1, object2, property, list1, list2, checkConstants);
-}
-
-/// Checks the pair-wise equivalence of the constants values in [list1] and
-/// [list2].
-///
-/// Uses [object1], [object2] and [property] to provide context for failures.
-bool checkConstantValueLists(Object object1, Object object2, String property,
-    List<ConstantValue> list1, List<ConstantValue> list2) {
-  return checkListEquivalence(
-      object1, object2, property, list1, list2, checkConstantValues);
-}
-
 void checkLists<T>(List<T> list1, List<T> list2, String messagePrefix,
     bool sameElement(T a, T b),
     {bool verbose: false,
diff --git a/tests/compiler/dart2js/equivalence/equivalence_helper.dart b/tests/compiler/dart2js/equivalence/equivalence_helper.dart
deleted file mode 100644
index 45437a9..0000000
--- a/tests/compiler/dart2js/equivalence/equivalence_helper.dart
+++ /dev/null
@@ -1,2310 +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.
-
-/// Functions for asserting equivalence across different compiler
-/// implementations.
-
-library dart2js.test.equivalence;
-
-import 'package:compiler/src/closure.dart';
-import 'package:compiler/src/common/resolution.dart';
-import 'package:compiler/src/constants/expressions.dart';
-import 'package:compiler/src/constants/values.dart';
-import 'package:compiler/src/elements/elements.dart';
-import 'package:compiler/src/elements/entities.dart';
-import 'package:compiler/src/elements/jumps.dart';
-import 'package:compiler/src/elements/modelx.dart';
-import 'package:compiler/src/elements/names.dart';
-import 'package:compiler/src/elements/resolution_types.dart';
-import 'package:compiler/src/elements/types.dart';
-import 'package:compiler/src/elements/visitor.dart';
-import 'package:compiler/src/native/native.dart'
-    show NativeBehavior, SpecialType;
-import 'package:compiler/src/resolution/access_semantics.dart';
-import 'package:compiler/src/resolution/send_structure.dart';
-import 'package:compiler/src/resolution/tree_elements.dart';
-import 'package:compiler/src/tree/nodes.dart';
-import 'package:compiler/src/universe/feature.dart';
-import 'package:compiler/src/universe/selector.dart';
-import 'package:compiler/src/universe/use.dart';
-import 'package:compiler/src/util/util.dart';
-
-import 'package:front_end/src/fasta/scanner.dart';
-
-typedef bool Equivalence<E>(E a, E b, {TestStrategy strategy});
-
-/// Equality based equivalence function.
-bool equality(a, b) => a == b;
-
-/// Returns `true` if the elements in [a] and [b] are pair-wise equivalent
-/// according to [elementEquivalence].
-bool areListsEquivalent<T>(List<T> a, List<T> b,
-    [bool elementEquivalence(T a, T b) = equality]) {
-  if (a.length != b.length) return false;
-  for (int i = 0; i < a.length && i < b.length; i++) {
-    if (!elementEquivalence(a[i], b[i])) {
-      return false;
-    }
-  }
-  return true;
-}
-
-/// Returns `true` if the elements in [a] and [b] are equivalent as sets using
-/// [elementEquivalence] to determine element equivalence.
-bool areSetsEquivalent<E>(Iterable<E> set1, Iterable<E> set2,
-    [bool elementEquivalence(E a, E b) = equality]) {
-  Set<E> remaining = set2.toSet();
-  for (dynamic element1 in set1) {
-    bool found = false;
-    for (dynamic element2 in set2) {
-      if (elementEquivalence(element1, element2)) {
-        found = true;
-        remaining.remove(element2);
-        break;
-      }
-    }
-    if (!found) {
-      return false;
-    }
-  }
-  return remaining.isEmpty;
-}
-
-/// Returns `true` if the content of [map1] and [map2] is equivalent using
-/// [keyEquivalence] and [valueEquivalence] to determine key/value equivalence.
-bool areMapsEquivalent<K, V>(Map<K, V> map1, Map<K, V> map2,
-    [bool keyEquivalence(K a, K b) = equality,
-    bool valueEquivalence(V a, V b) = equality]) {
-  Set remaining = map2.keys.toSet();
-  for (dynamic key1 in map1.keys) {
-    bool found = false;
-    for (dynamic key2 in map2.keys) {
-      if (keyEquivalence(key1, key2)) {
-        found = true;
-        remaining.remove(key2);
-        if (!valueEquivalence(map1[key1], map2[key2])) {
-          return false;
-        }
-        break;
-      }
-    }
-    if (!found) {
-      return false;
-    }
-  }
-  return remaining.isEmpty;
-}
-
-/// Returns `true` if elements [a] and [b] are equivalent.
-bool areElementsEquivalent(Element a, Element b, {TestStrategy strategy}) {
-  if (identical(a, b)) return true;
-  if (a == null || b == null) return false;
-  return new ElementIdentityEquivalence(strategy ?? const TestStrategy())
-      .visit(a, b);
-}
-
-bool areEntitiesEquivalent(Entity a, Entity b, {TestStrategy strategy}) {
-  return areElementsEquivalent(a, b, strategy: strategy);
-}
-
-/// Returns `true` if types [a] and [b] are equivalent.
-bool areTypesEquivalent(DartType a, DartType b, {TestStrategy strategy}) {
-  if (identical(a, b)) return true;
-  if (a == null || b == null) return false;
-  return new TypeEquivalence(strategy ?? const TestStrategy()).visit(a, b);
-}
-
-/// Returns `true` if constants [exp1] and [exp2] are equivalent.
-bool areConstantsEquivalent(ConstantExpression exp1, ConstantExpression exp2,
-    {TestStrategy strategy}) {
-  if (identical(exp1, exp2)) return true;
-  if (exp1 == null || exp2 == null) return false;
-  return new ConstantEquivalence(strategy ?? const TestStrategy())
-      .visit(exp1, exp2);
-}
-
-/// Returns `true` if constant values [value1] and [value2] are equivalent.
-bool areConstantValuesEquivalent(ConstantValue value1, ConstantValue value2,
-    {TestStrategy strategy}) {
-  if (identical(value1, value2)) return true;
-  if (value1 == null || value2 == null) return false;
-  return new ConstantValueEquivalence(strategy ?? const TestStrategy())
-      .visit(value1, value2);
-}
-
-/// Returns `true` if the lists of elements, [a] and [b], are equivalent.
-bool areElementListsEquivalent(List<Element> a, List<Element> b) {
-  return areListsEquivalent(a, b, areElementsEquivalent);
-}
-
-/// Returns `true` if the lists of types, [a] and [b], are equivalent.
-bool areTypeListsEquivalent(
-    List<ResolutionDartType> a, List<ResolutionDartType> b) {
-  return areListsEquivalent(a, b, areTypesEquivalent);
-}
-
-/// Returns `true` if the lists of constants, [a] and [b], are equivalent.
-bool areConstantListsEquivalent(
-    List<ConstantExpression> a, List<ConstantExpression> b) {
-  return areListsEquivalent(a, b, areConstantsEquivalent);
-}
-
-/// Returns `true` if the lists of constant values, [a] and [b], are equivalent.
-bool areConstantValueListsEquivalent(
-    List<ConstantValue> a, List<ConstantValue> b) {
-  return areListsEquivalent(a, b, areConstantValuesEquivalent);
-}
-
-/// Returns `true` if the selectors [a] and [b] are equivalent.
-bool areSelectorsEquivalent(Selector a, Selector b,
-    {TestStrategy strategy: const TestStrategy()}) {
-  if (identical(a, b)) return true;
-  if (a == null || b == null) return false;
-  return a.kind == b.kind &&
-      a.callStructure == b.callStructure &&
-      areNamesEquivalent(a.memberName, b.memberName, strategy: strategy);
-}
-
-/// Returns `true` if the names [a] and [b] are equivalent.
-bool areNamesEquivalent(Name a, Name b,
-    {TestStrategy strategy: const TestStrategy()}) {
-  return a.text == b.text &&
-      a.isSetter == b.isSetter &&
-      strategy.testElements(a, b, 'library', a.library, b.library);
-}
-
-/// Returns `true` if the dynamic uses [a] and [b] are equivalent.
-bool areDynamicUsesEquivalent(DynamicUse a, DynamicUse b,
-    {TestStrategy strategy: const TestStrategy()}) {
-  return areSelectorsEquivalent(a.selector, b.selector, strategy: strategy);
-}
-
-/// Returns `true` if the static uses [a] and [b] are equivalent.
-bool areStaticUsesEquivalent(StaticUse a, StaticUse b,
-    {TestStrategy strategy: const TestStrategy()}) {
-  return a.kind == b.kind &&
-      strategy.testElements(a, b, 'element', a.element, b.element);
-}
-
-/// Returns `true` if the type uses [a] and [b] are equivalent.
-bool areTypeUsesEquivalent(TypeUse a, TypeUse b,
-    {TestStrategy strategy: const TestStrategy()}) {
-  return a.kind == b.kind && strategy.testTypes(a, b, 'type', a.type, b.type);
-}
-
-/// Returns `true` if the list literal uses [a] and [b] are equivalent.
-bool areListLiteralUsesEquivalent(ListLiteralUse a, ListLiteralUse b,
-    {TestStrategy strategy: const TestStrategy()}) {
-  return strategy.testTypes(a, b, 'type', a.type, b.type) &&
-      a.isConstant == b.isConstant &&
-      a.isEmpty == b.isEmpty;
-}
-
-/// Returns `true` if the map literal uses [a] and [b] are equivalent.
-bool areMapLiteralUsesEquivalent(MapLiteralUse a, MapLiteralUse b,
-    {TestStrategy strategy: const TestStrategy()}) {
-  return strategy.testTypes(a, b, 'type', a.type, b.type) &&
-      a.isConstant == b.isConstant &&
-      a.isEmpty == b.isEmpty;
-}
-
-/// Returns `true` if the access semantics [a] and [b] are equivalent.
-bool areAccessSemanticsEquivalent(AccessSemantics a, AccessSemantics b) {
-  if (a.kind != b.kind) return false;
-  switch (a.kind) {
-    case AccessKind.EXPRESSION:
-    case AccessKind.THIS:
-      // No additional properties.
-      return true;
-    case AccessKind.THIS_PROPERTY:
-    case AccessKind.DYNAMIC_PROPERTY:
-    case AccessKind.CONDITIONAL_DYNAMIC_PROPERTY:
-      return areNamesEquivalent(a.name, b.name);
-    case AccessKind.CLASS_TYPE_LITERAL:
-    case AccessKind.TYPEDEF_TYPE_LITERAL:
-    case AccessKind.DYNAMIC_TYPE_LITERAL:
-      return areConstantsEquivalent(a.constant, b.constant);
-    case AccessKind.LOCAL_FUNCTION:
-    case AccessKind.LOCAL_VARIABLE:
-    case AccessKind.FINAL_LOCAL_VARIABLE:
-    case AccessKind.PARAMETER:
-    case AccessKind.FINAL_PARAMETER:
-    case AccessKind.STATIC_FIELD:
-    case AccessKind.FINAL_STATIC_FIELD:
-    case AccessKind.STATIC_METHOD:
-    case AccessKind.STATIC_GETTER:
-    case AccessKind.STATIC_SETTER:
-    case AccessKind.TOPLEVEL_FIELD:
-    case AccessKind.FINAL_TOPLEVEL_FIELD:
-    case AccessKind.TOPLEVEL_METHOD:
-    case AccessKind.TOPLEVEL_GETTER:
-    case AccessKind.TOPLEVEL_SETTER:
-    case AccessKind.SUPER_FIELD:
-    case AccessKind.SUPER_FINAL_FIELD:
-    case AccessKind.SUPER_METHOD:
-    case AccessKind.SUPER_GETTER:
-    case AccessKind.SUPER_SETTER:
-    case AccessKind.TYPE_PARAMETER_TYPE_LITERAL:
-    case AccessKind.UNRESOLVED:
-    case AccessKind.UNRESOLVED_SUPER:
-    case AccessKind.INVALID:
-      return areElementsEquivalent(a.element, b.element);
-    case AccessKind.COMPOUND:
-      CompoundAccessSemantics compoundAccess1 = a;
-      CompoundAccessSemantics compoundAccess2 = b;
-      return compoundAccess1.compoundAccessKind ==
-              compoundAccess2.compoundAccessKind &&
-          areElementsEquivalent(
-              compoundAccess1.getter, compoundAccess2.getter) &&
-          areElementsEquivalent(compoundAccess1.setter, compoundAccess2.setter);
-    case AccessKind.CONSTANT:
-    default:
-      throw new UnsupportedError('Unsupported access kind: ${a.kind}');
-  }
-}
-
-/// Returns `true` if the send structures [a] and [b] are equivalent.
-bool areSendStructuresEquivalent(SendStructure a, SendStructure b) {
-  if (identical(a, b)) return true;
-  if (a == null || b == null) return false;
-  if (a.kind != b.kind) return false;
-
-  dynamic ad = a;
-  dynamic bd = b;
-  switch (a.kind) {
-    case SendStructureKind.IF_NULL:
-    case SendStructureKind.LOGICAL_AND:
-    case SendStructureKind.LOGICAL_OR:
-    case SendStructureKind.NOT:
-    case SendStructureKind.INVALID_UNARY:
-    case SendStructureKind.INVALID_BINARY:
-      // No additional properties.
-      return true;
-
-    case SendStructureKind.IS:
-    case SendStructureKind.IS_NOT:
-    case SendStructureKind.AS:
-      return areTypesEquivalent(ad.type, bd.type);
-
-    case SendStructureKind.INVOKE:
-    case SendStructureKind.INCOMPATIBLE_INVOKE:
-      if (!areSelectorsEquivalent(ad.selector, bd.selector)) return false;
-      continue semantics;
-
-    case SendStructureKind.UNARY:
-    case SendStructureKind.BINARY:
-    case SendStructureKind.PREFIX:
-    case SendStructureKind.POSTFIX:
-    case SendStructureKind.INDEX_PREFIX:
-    case SendStructureKind.INDEX_POSTFIX:
-    case SendStructureKind.COMPOUND:
-    case SendStructureKind.COMPOUND_INDEX_SET:
-      if (ad.operator != bd.operator) return false;
-      continue semantics;
-
-    case SendStructureKind.DEFERRED_PREFIX:
-      return areElementsEquivalent(ad.prefix, bd.prefix) &&
-          areSendStructuresEquivalent(ad.sendStructure, bd.sendStructure);
-
-    semantics:
-    case SendStructureKind.GET:
-    case SendStructureKind.SET:
-    case SendStructureKind.INDEX:
-    case SendStructureKind.INDEX_SET:
-    case SendStructureKind.EQUALS:
-    case SendStructureKind.NOT_EQUALS:
-    case SendStructureKind.SET_IF_NULL:
-    case SendStructureKind.INDEX_SET_IF_NULL:
-      return areAccessSemanticsEquivalent(ad.semantics, bd.semantics);
-  }
-  throw new UnsupportedError('Unexpected send structures $a vs $b');
-}
-
-/// Returns `true` if the new structures [a] and [b] are equivalent.
-bool areNewStructuresEquivalent(NewStructure a, NewStructure b) {
-  if (identical(a, b)) return true;
-  if (a == null || b == null) return false;
-  if (a.kind != b.kind) return false;
-
-  dynamic ad = a;
-  dynamic bd = b;
-  switch (a.kind) {
-    case NewStructureKind.NEW_INVOKE:
-      return ad.semantics.kind == bd.semantics.kind &&
-          areElementsEquivalent(ad.semantics.element, bd.semantics.element) &&
-          areTypesEquivalent(ad.semantics.type, bd.semantics.type) &&
-          areSelectorsEquivalent(ad.selector, bd.selector);
-    case NewStructureKind.CONST_INVOKE:
-      return ad.constantInvokeKind == bd.constantInvokeKind &&
-          areConstantsEquivalent(ad.constant, bd.constant);
-    case NewStructureKind.LATE_CONST:
-    default:
-      throw new UnsupportedError('Unsupported NewStructure kind ${a.kind}.');
-  }
-}
-
-/// Returns `true` if nodes [a] and [b] are equivalent.
-bool areNodesEquivalent(Node node1, Node node2) {
-  if (identical(node1, node2)) return true;
-  if (node1 == null || node2 == null) return false;
-  return node1.accept1(const NodeEquivalenceVisitor(), node2);
-}
-
-/// Strategy for testing equivalence.
-///
-/// Use this strategy to determine equivalence without failing on inequivalence.
-class TestStrategy {
-  final Equivalence<Entity> elementEquivalence;
-  final Equivalence<DartType> typeEquivalence;
-  final Equivalence<ConstantExpression> constantEquivalence;
-  final Equivalence<ConstantValue> constantValueEquivalence;
-
-  const TestStrategy(
-      {this.elementEquivalence: areEntitiesEquivalent,
-      this.typeEquivalence: areTypesEquivalent,
-      this.constantEquivalence: areConstantsEquivalent,
-      this.constantValueEquivalence: areConstantValuesEquivalent});
-
-  /// An equivalence [TestStrategy] that doesn't throw on inequivalence.
-  TestStrategy get testOnly => this;
-
-  bool test<T>(
-      dynamic object1, dynamic object2, String property, T value1, T value2,
-      [bool equivalence(T a, T b) = equality]) {
-    return equivalence(value1, value2);
-  }
-
-  bool testLists(
-      Object object1, Object object2, String property, List list1, List list2,
-      [bool elementEquivalence(a, b) = equality]) {
-    return areListsEquivalent(list1, list2, elementEquivalence);
-  }
-
-  bool testSets<E>(dynamic object1, dynamic object2, String property,
-      Iterable<E> set1, Iterable<E> set2,
-      [bool elementEquivalence(E a, E b) = equality]) {
-    return areSetsEquivalent(set1, set2, elementEquivalence);
-  }
-
-  bool testMaps<K, V>(dynamic object1, dynamic object2, String property,
-      Map<K, V> map1, Map<K, V> map2,
-      [bool keyEquivalence(K a, K b) = equality,
-      bool valueEquivalence(V a, V b) = equality]) {
-    return areMapsEquivalent(map1, map2, keyEquivalence, valueEquivalence);
-  }
-
-  bool testElements(Object object1, Object object2, String property,
-      Entity element1, Entity element2) {
-    return test(object1, object2, property, element1, element2,
-        (a, b) => elementEquivalence(a, b, strategy: this));
-  }
-
-  bool testTypes(Object object1, Object object2, String property,
-      DartType type1, DartType type2) {
-    return test(object1, object2, property, type1, type2,
-        (a, b) => typeEquivalence(a, b, strategy: this));
-  }
-
-  bool testConstants(Object object1, Object object2, String property,
-      ConstantExpression exp1, ConstantExpression exp2) {
-    return test(object1, object2, property, exp1, exp2,
-        (a, b) => constantEquivalence(a, b, strategy: this));
-  }
-
-  bool testConstantValues(Object object1, Object object2, String property,
-      ConstantValue value1, ConstantValue value2) {
-    return test(object1, object2, property, value1, value2,
-        (a, b) => constantValueEquivalence(a, b, strategy: this));
-  }
-
-  bool testTypeLists(Object object1, Object object2, String property,
-      List<DartType> list1, List<DartType> list2) {
-    return testLists(object1, object2, property, list1, list2,
-        (a, b) => typeEquivalence(a, b, strategy: this));
-  }
-
-  bool testConstantLists(Object object1, Object object2, String property,
-      List<ConstantExpression> list1, List<ConstantExpression> list2) {
-    return testLists(object1, object2, property, list1, list2,
-        (a, b) => constantEquivalence(a, b, strategy: this));
-  }
-
-  bool testConstantValueLists(Object object1, Object object2, String property,
-      List<ConstantValue> list1, List<ConstantValue> list2) {
-    return testLists(object1, object2, property, list1, list2,
-        (a, b) => constantValueEquivalence(a, b, strategy: this));
-  }
-
-  bool testNodes(
-      Object object1, Object object2, String property, Node node1, Node node2) {
-    return areNodesEquivalent(node1, node2);
-  }
-}
-
-/// Visitor that checks for equivalence of [Element]s.
-class ElementIdentityEquivalence extends BaseElementVisitor<bool, Element> {
-  final TestStrategy strategy;
-
-  const ElementIdentityEquivalence([this.strategy = const TestStrategy()]);
-
-  bool visit(Element element1, Element element2) {
-    if (element1 == null && element2 == null) {
-      return true;
-    } else if (element1 == null || element2 == null) {
-      return false;
-    }
-    element1 = element1.declaration;
-    element2 = element2.declaration;
-    if (element1 == element2) {
-      return true;
-    }
-    return strategy.test(
-            element1, element2, 'kind', element1.kind, element2.kind) &&
-        element1.accept(this, element2);
-  }
-
-  @override
-  bool visitElement(Element e, Element arg) {
-    throw new UnsupportedError("Unsupported element $e");
-  }
-
-  @override
-  bool visitLibraryElement(
-      LibraryElement element1, covariant LibraryElement element2) {
-    return strategy.test(element1, element2, 'canonicalUri',
-        element1.canonicalUri, element2.canonicalUri);
-  }
-
-  @override
-  bool visitCompilationUnitElement(CompilationUnitElement element1,
-      covariant CompilationUnitElement element2) {
-    return strategy.test(element1, element2, 'script.resourceUri',
-            element1.script.resourceUri, element2.script.resourceUri) &&
-        visit(element1.library, element2.library);
-  }
-
-  @override
-  bool visitClassElement(
-      ClassElement element1, covariant ClassElement element2) {
-    if (!strategy.test(
-        element1,
-        element2,
-        'isUnnamedMixinApplication',
-        element1.isUnnamedMixinApplication,
-        element2.isUnnamedMixinApplication)) {
-      return false;
-    }
-    if (element1.isUnnamedMixinApplication) {
-      MixinApplicationElement mixin1 = element1;
-      MixinApplicationElement mixin2 = element2;
-      return strategy.testElements(
-              mixin1, mixin2, 'subclass', mixin1.subclass, mixin2.subclass) &&
-          // Using the [mixinType] is more precise but requires the test to
-          // handle self references: The identity of a type variable is based on
-          // its type declaration and if [mixin1] is generic the [mixinType]
-          // will contain the type variables declared by [mixin1], i.e.
-          // `abstract class Mixin<T> implements MixinType<T> {}`
-          strategy.testElements(
-              mixin1, mixin2, 'mixin', mixin1.mixin, mixin2.mixin);
-    } else {
-      return strategy.test(
-              element1, element2, 'name', element1.name, element2.name) &&
-          visit(element1.library, element2.library);
-    }
-  }
-
-  bool checkMembers(Element element1, covariant Element element2) {
-    if (!strategy.test(
-        element1, element2, 'name', element1.name, element2.name)) {
-      return false;
-    }
-    if (element1.enclosingClass != null || element2.enclosingClass != null) {
-      return visit(element1.enclosingClass, element2.enclosingClass);
-    } else {
-      return visit(element1.library, element2.library);
-    }
-  }
-
-  @override
-  bool visitFieldElement(
-      FieldElement element1, covariant FieldElement element2) {
-    return checkMembers(element1, element2);
-  }
-
-  @override
-  bool visitBoxFieldElement(
-      BoxFieldElement element1, covariant BoxFieldElement element2) {
-    return element1.box.name == element2.box.name &&
-        visit(element1.box.executableContext, element2.box.executableContext) &&
-        visit(element1.variableElement, element2.variableElement);
-  }
-
-  @override
-  bool visitConstructorElement(
-      ConstructorElement element1, covariant ConstructorElement element2) {
-    return checkMembers(element1, element2);
-  }
-
-  @override
-  bool visitMethodElement(
-      covariant MethodElement element1, covariant MethodElement element2) {
-    return checkMembers(element1, element2);
-  }
-
-  @override
-  bool visitGetterElement(
-      GetterElement element1, covariant GetterElement element2) {
-    return checkMembers(element1, element2);
-  }
-
-  @override
-  bool visitSetterElement(
-      SetterElement element1, covariant SetterElement element2) {
-    return checkMembers(element1, element2);
-  }
-
-  @override
-  bool visitLocalFunctionElement(
-      LocalFunctionElement element1, covariant LocalFunctionElement element2) {
-    // TODO(johnniwinther): Define an equivalence on locals.
-    MemberElement member1 = element1.memberContext;
-    MemberElement member2 = element2.memberContext;
-    return strategy.test(
-            element1, element2, 'name', element1.name, element2.name) &&
-        checkMembers(member1, member2);
-  }
-
-  @override
-  bool visitLocalVariableElement(
-      LocalVariableElement element1, covariant LocalVariableElement element2) {
-    // TODO(johnniwinther): Define an equivalence on locals.
-    return strategy.test(
-            element1, element2, 'name', element1.name, element2.name) &&
-        checkMembers(element1.memberContext, element2.memberContext);
-  }
-
-  bool visitAbstractFieldElement(
-      AbstractFieldElement element1, covariant AbstractFieldElement element2) {
-    return checkMembers(element1, element2);
-  }
-
-  @override
-  bool visitTypeVariableElement(
-      TypeVariableElement element1, covariant TypeVariableElement element2) {
-    return strategy.test(
-            element1, element2, 'name', element1.name, element2.name) &&
-        visit(element1.typeDeclaration, element2.typeDeclaration);
-  }
-
-  @override
-  bool visitTypedefElement(
-      TypedefElement element1, covariant TypedefElement element2) {
-    return strategy.test(
-            element1, element2, 'name', element1.name, element2.name) &&
-        visit(element1.library, element2.library);
-  }
-
-  @override
-  bool visitParameterElement(
-      ParameterElement element1, covariant ParameterElement element2) {
-    return strategy.test(
-            element1, element2, 'name', element1.name, element2.name) &&
-        visit(element1.functionDeclaration, element2.functionDeclaration);
-  }
-
-  @override
-  bool visitImportElement(
-      ImportElement element1, covariant ImportElement element2) {
-    return visit(element1.importedLibrary, element2.importedLibrary) &&
-        visit(element1.library, element2.library);
-  }
-
-  @override
-  bool visitExportElement(
-      ExportElement element1, covariant ExportElement element2) {
-    return visit(element1.exportedLibrary, element2.exportedLibrary) &&
-        visit(element1.library, element2.library);
-  }
-
-  @override
-  bool visitPrefixElement(
-      PrefixElement element1, covariant PrefixElement element2) {
-    return strategy.test(
-            element1, element2, 'name', element1.name, element2.name) &&
-        visit(element1.library, element2.library);
-  }
-
-  @override
-  bool visitErroneousElement(
-      ErroneousElement element1, covariant ErroneousElement element2) {
-    return strategy.test(element1, element2, 'messageKind',
-        element1.messageKind, element2.messageKind);
-  }
-
-  @override
-  bool visitWarnOnUseElement(
-      WarnOnUseElement element1, covariant WarnOnUseElement element2) {
-    return strategy.testElements(element1, element2, 'wrappedElement',
-        element1.wrappedElement, element2.wrappedElement);
-  }
-}
-
-/// Visitor that checks for equivalence of [ResolutionDartType]s.
-class TypeEquivalence
-    implements ResolutionDartTypeVisitor<bool, ResolutionDartType> {
-  final TestStrategy strategy;
-
-  const TypeEquivalence([this.strategy = const TestStrategy()]);
-
-  bool visit(
-      covariant ResolutionDartType type1, covariant ResolutionDartType type2) {
-    return strategy.test(type1, type2, 'kind', type1.kind, type2.kind) &&
-        type1.accept(this, type2);
-  }
-
-  @override
-  bool visitDynamicType(covariant ResolutionDynamicType type,
-          covariant ResolutionDynamicType other) =>
-      true;
-
-  @override
-  bool visitFunctionType(covariant ResolutionFunctionType type,
-      covariant ResolutionFunctionType other) {
-    return strategy.testTypeLists(type, other, 'parameterTypes',
-            type.parameterTypes, other.parameterTypes) &&
-        strategy.testTypeLists(type, other, 'optionalParameterTypes',
-            type.optionalParameterTypes, other.optionalParameterTypes) &&
-        strategy.testTypeLists(type, other, 'namedParameterTypes',
-            type.namedParameterTypes, other.namedParameterTypes) &&
-        strategy.testLists(type, other, 'namedParameters', type.namedParameters,
-            other.namedParameters);
-  }
-
-  bool visitGenericType(GenericType type, GenericType other) {
-    return strategy.testElements(
-            type, other, 'element', type.element, other.element) &&
-        strategy.testTypeLists(type, other, 'typeArguments', type.typeArguments,
-            other.typeArguments);
-  }
-
-  @override
-  bool visitMalformedType(MalformedType type, covariant MalformedType other) =>
-      true;
-
-  @override
-  bool visitTypeVariableType(covariant ResolutionTypeVariableType type,
-      covariant ResolutionTypeVariableType other) {
-    return strategy.testElements(
-            type, other, 'element', type.element, other.element) &&
-        strategy.test(type, other, 'is MethodTypeVariableType',
-            type is MethodTypeVariableType, other is MethodTypeVariableType);
-  }
-
-  @override
-  bool visitVoidType(covariant ResolutionVoidType type,
-          covariant ResolutionVoidType argument) =>
-      true;
-
-  @override
-  bool visitInterfaceType(covariant ResolutionInterfaceType type,
-      covariant ResolutionInterfaceType other) {
-    return visitGenericType(type, other);
-  }
-
-  @override
-  bool visitTypedefType(covariant ResolutionTypedefType type,
-      covariant ResolutionTypedefType other) {
-    return visitGenericType(type, other);
-  }
-
-  @override
-  bool visitFunctionTypeVariable(
-      FunctionTypeVariable type, ResolutionDartType other) {
-    throw new UnsupportedError("Function type variables are not supported.");
-  }
-
-  @override
-  bool visitFutureOrType(
-      covariant FutureOrType type, covariant ResolutionDartType other) {
-    throw new UnsupportedError("FutureOr is not supported.");
-  }
-}
-
-/// Visitor that checks for structural equivalence of [ConstantExpression]s.
-class ConstantEquivalence
-    implements ConstantExpressionVisitor<bool, ConstantExpression> {
-  final TestStrategy strategy;
-
-  const ConstantEquivalence([this.strategy = const TestStrategy()]);
-
-  @override
-  bool visit(ConstantExpression exp1, covariant ConstantExpression exp2) {
-    if (identical(exp1, exp2)) return true;
-    return strategy.test(exp1, exp2, 'kind', exp1.kind, exp2.kind) &&
-        exp1.accept(this, exp2);
-  }
-
-  @override
-  bool visitAs(AsConstantExpression exp1, covariant AsConstantExpression exp2) {
-    return strategy.test(
-            exp1, exp2, 'expression', exp1.expression, exp2.expression) &&
-        strategy.testTypes(exp1, exp2, 'type', exp1.type, exp2.type);
-  }
-
-  @override
-  bool visitBinary(
-      BinaryConstantExpression exp1, covariant BinaryConstantExpression exp2) {
-    return strategy.test(
-            exp1, exp2, 'operator', exp1.operator, exp2.operator) &&
-        strategy.testConstants(exp1, exp2, 'left', exp1.left, exp2.left) &&
-        strategy.testConstants(exp1, exp2, 'right', exp1.right, exp2.right);
-  }
-
-  @override
-  bool visitConcatenate(ConcatenateConstantExpression exp1,
-      covariant ConcatenateConstantExpression exp2) {
-    return strategy.testConstantLists(
-        exp1, exp2, 'expressions', exp1.expressions, exp2.expressions);
-  }
-
-  @override
-  bool visitConditional(ConditionalConstantExpression exp1,
-      covariant ConditionalConstantExpression exp2) {
-    return strategy.testConstants(
-            exp1, exp2, 'condition', exp1.condition, exp2.condition) &&
-        strategy.testConstants(
-            exp1, exp2, 'trueExp', exp1.trueExp, exp2.trueExp) &&
-        strategy.testConstants(
-            exp1, exp2, 'falseExp', exp1.falseExp, exp2.falseExp);
-  }
-
-  @override
-  bool visitConstructed(ConstructedConstantExpression exp1,
-      covariant ConstructedConstantExpression exp2) {
-    return strategy.testTypes(exp1, exp2, 'type', exp1.type, exp2.type) &&
-        strategy.testElements(exp1, exp2, 'target', exp1.target, exp2.target) &&
-        strategy.testConstantLists(
-            exp1, exp2, 'arguments', exp1.arguments, exp2.arguments) &&
-        strategy.test(exp1, exp2, 'callStructure', exp1.callStructure,
-            exp2.callStructure);
-  }
-
-  @override
-  bool visitFunction(FunctionConstantExpression exp1,
-      covariant FunctionConstantExpression exp2) {
-    return strategy.testElements(
-        exp1, exp2, 'element', exp1.element, exp2.element);
-  }
-
-  @override
-  bool visitIdentical(IdenticalConstantExpression exp1,
-      covariant IdenticalConstantExpression exp2) {
-    return strategy.testConstants(exp1, exp2, 'left', exp1.left, exp2.left) &&
-        strategy.testConstants(exp1, exp2, 'right', exp1.right, exp2.right);
-  }
-
-  @override
-  bool visitList(
-      ListConstantExpression exp1, covariant ListConstantExpression exp2) {
-    return strategy.testTypes(exp1, exp2, 'type', exp1.type, exp2.type) &&
-        strategy.testConstantLists(
-            exp1, exp2, 'values', exp1.values, exp2.values);
-  }
-
-  @override
-  bool visitMap(
-      MapConstantExpression exp1, covariant MapConstantExpression exp2) {
-    return strategy.testTypes(exp1, exp2, 'type', exp1.type, exp2.type) &&
-        strategy.testConstantLists(exp1, exp2, 'keys', exp1.keys, exp2.keys) &&
-        strategy.testConstantLists(
-            exp1, exp2, 'values', exp1.values, exp2.values);
-  }
-
-  @override
-  bool visitNamed(
-      NamedArgumentReference exp1, covariant NamedArgumentReference exp2) {
-    return strategy.test(exp1, exp2, 'name', exp1.name, exp2.name);
-  }
-
-  @override
-  bool visitPositional(PositionalArgumentReference exp1,
-      covariant PositionalArgumentReference exp2) {
-    return strategy.test(exp1, exp2, 'index', exp1.index, exp2.index);
-  }
-
-  @override
-  bool visitSymbol(
-      SymbolConstantExpression exp1, covariant SymbolConstantExpression exp2) {
-    // TODO(johnniwinther): Handle private names. Currently not even supported
-    // in resolution.
-    return strategy.test(exp1, exp2, 'name', exp1.name, exp2.name);
-  }
-
-  @override
-  bool visitType(
-      TypeConstantExpression exp1, covariant TypeConstantExpression exp2) {
-    return strategy.testTypes(exp1, exp2, 'type', exp1.type, exp2.type);
-  }
-
-  @override
-  bool visitUnary(
-      UnaryConstantExpression exp1, covariant UnaryConstantExpression exp2) {
-    return strategy.test(
-            exp1, exp2, 'operator', exp1.operator, exp2.operator) &&
-        strategy.testConstants(
-            exp1, exp2, 'expression', exp1.expression, exp2.expression);
-  }
-
-  @override
-  bool visitField(
-      FieldConstantExpression exp1, covariant FieldConstantExpression exp2) {
-    return strategy.testElements(
-        exp1, exp2, 'element', exp1.element, exp2.element);
-  }
-
-  @override
-  bool visitLocalVariable(LocalVariableConstantExpression exp1,
-      covariant LocalVariableConstantExpression exp2) {
-    return strategy.testElements(
-        exp1, exp2, 'element', exp1.element, exp2.element);
-  }
-
-  @override
-  bool visitBool(
-      BoolConstantExpression exp1, covariant BoolConstantExpression exp2) {
-    return strategy.test(
-        exp1, exp2, 'boolValue', exp1.boolValue, exp2.boolValue);
-  }
-
-  @override
-  bool visitDouble(
-      DoubleConstantExpression exp1, covariant DoubleConstantExpression exp2) {
-    return strategy.test(
-        exp1, exp2, 'doubleValue', exp1.doubleValue, exp2.doubleValue);
-  }
-
-  @override
-  bool visitInt(
-      IntConstantExpression exp1, covariant IntConstantExpression exp2) {
-    return strategy.test(exp1, exp2, 'intValue', exp1.intValue, exp2.intValue);
-  }
-
-  @override
-  bool visitNull(
-      NullConstantExpression exp1, covariant NullConstantExpression exp2) {
-    return true;
-  }
-
-  @override
-  bool visitString(
-      StringConstantExpression exp1, covariant StringConstantExpression exp2) {
-    return strategy.test(
-        exp1, exp2, 'stringValue', exp1.stringValue, exp2.stringValue);
-  }
-
-  @override
-  bool visitBoolFromEnvironment(BoolFromEnvironmentConstantExpression exp1,
-      covariant BoolFromEnvironmentConstantExpression exp2) {
-    return strategy.testConstants(exp1, exp2, 'name', exp1.name, exp2.name) &&
-        strategy.testConstants(
-            exp1, exp2, 'defaultValue', exp1.defaultValue, exp2.defaultValue);
-  }
-
-  @override
-  bool visitIntFromEnvironment(IntFromEnvironmentConstantExpression exp1,
-      covariant IntFromEnvironmentConstantExpression exp2) {
-    return strategy.testConstants(exp1, exp2, 'name', exp1.name, exp2.name) &&
-        strategy.testConstants(
-            exp1, exp2, 'defaultValue', exp1.defaultValue, exp2.defaultValue);
-  }
-
-  @override
-  bool visitStringFromEnvironment(StringFromEnvironmentConstantExpression exp1,
-      covariant StringFromEnvironmentConstantExpression exp2) {
-    return strategy.testConstants(exp1, exp2, 'name', exp1.name, exp2.name) &&
-        strategy.testConstants(
-            exp1, exp2, 'defaultValue', exp1.defaultValue, exp2.defaultValue);
-  }
-
-  @override
-  bool visitStringLength(StringLengthConstantExpression exp1,
-      covariant StringLengthConstantExpression exp2) {
-    return strategy.testConstants(
-        exp1, exp2, 'expression', exp1.expression, exp2.expression);
-  }
-
-  @override
-  bool visitDeferred(DeferredConstantExpression exp1,
-      covariant DeferredConstantExpression exp2) {
-    return strategy.testElements(
-            exp1, exp2, 'import', exp1.import, exp2.import) &&
-        strategy.testConstants(
-            exp1, exp2, 'expression', exp1.expression, exp2.expression);
-  }
-
-  @override
-  bool visitAssert(
-      AssertConstantExpression exp1, covariant AssertConstantExpression exp2) {
-    return strategy.testConstants(
-            exp1, exp2, 'condition', exp1.condition, exp2.condition) &&
-        strategy.testConstants(
-            exp1, exp2, 'message', exp1.message, exp2.message);
-  }
-
-  @override
-  bool visitInstantiation(InstantiationConstantExpression exp1,
-      covariant InstantiationConstantExpression exp2) {
-    return strategy.testTypeLists(exp1, exp2, 'typeArguments',
-            exp1.typeArguments, exp2.typeArguments) &&
-        strategy.testConstants(
-            exp1, exp2, 'expression', exp1.expression, exp2.expression);
-  }
-}
-
-/// Visitor that checks for structural equivalence of [ConstantValue]s.
-class ConstantValueEquivalence
-    implements ConstantValueVisitor<bool, ConstantValue> {
-  final TestStrategy strategy;
-
-  const ConstantValueEquivalence([this.strategy = const TestStrategy()]);
-
-  bool visit(ConstantValue value1, covariant ConstantValue value2) {
-    if (identical(value1, value2)) return true;
-    return strategy.test(value1, value2, 'kind', value1.kind, value2.kind) &&
-        value1.accept(this, value2);
-  }
-
-  @override
-  bool visitConstructed(ConstructedConstantValue value1,
-      covariant ConstructedConstantValue value2) {
-    return strategy.testTypes(
-            value1, value2, 'type', value1.type, value2.type) &&
-        strategy.testMaps(
-            value1,
-            value2,
-            'fields',
-            value1.fields,
-            value2.fields,
-            strategy.elementEquivalence,
-            (a, b) => strategy.testConstantValues(
-                value1, value2, 'fields.values', a, b));
-  }
-
-  @override
-  bool visitFunction(
-      FunctionConstantValue value1, covariant FunctionConstantValue value2) {
-    return strategy.testElements(
-        value1, value2, 'element', value1.element, value2.element);
-  }
-
-  @override
-  bool visitList(ListConstantValue value1, covariant ListConstantValue value2) {
-    return strategy.testTypes(
-            value1, value2, 'type', value1.type, value2.type) &&
-        strategy.testConstantValueLists(
-            value1, value2, 'entries', value1.entries, value2.entries);
-  }
-
-  @override
-  bool visitMap(MapConstantValue value1, covariant MapConstantValue value2) {
-    return strategy.testTypes(
-            value1, value2, 'type', value1.type, value2.type) &&
-        strategy.testConstantValueLists(
-            value1, value2, 'keys', value1.keys, value2.keys) &&
-        strategy.testConstantValueLists(
-            value1, value2, 'values', value1.values, value2.values);
-  }
-
-  @override
-  bool visitType(TypeConstantValue value1, covariant TypeConstantValue value2) {
-    return strategy.testTypes(value1, value2, 'type', value1.type, value2.type);
-  }
-
-  @override
-  bool visitBool(BoolConstantValue value1, covariant BoolConstantValue value2) {
-    return strategy.test(
-        value1, value2, 'boolValue', value1.boolValue, value2.boolValue);
-  }
-
-  @override
-  bool visitDouble(
-      DoubleConstantValue value1, covariant DoubleConstantValue value2) {
-    return strategy.test(
-        value1, value2, 'doubleValue', value1.doubleValue, value2.doubleValue);
-  }
-
-  @override
-  bool visitInt(IntConstantValue value1, covariant IntConstantValue value2) {
-    return strategy.test(
-        value1, value2, 'intValue', value1.intValue, value2.intValue);
-  }
-
-  @override
-  bool visitNull(NullConstantValue value1, covariant NullConstantValue value2) {
-    return true;
-  }
-
-  @override
-  bool visitString(
-      StringConstantValue value1, covariant StringConstantValue value2) {
-    return strategy.test(
-        value1, value2, 'stringValue', value1.stringValue, value2.stringValue);
-  }
-
-  @override
-  bool visitDeferred(
-      DeferredConstantValue value1, covariant DeferredConstantValue value2) {
-    return strategy.testElements(
-            value1, value2, 'prefix', value1.import, value2.import) &&
-        strategy.testConstantValues(
-            value1, value2, 'referenced', value1.referenced, value2.referenced);
-  }
-
-  @override
-  bool visitDeferredGlobal(DeferredGlobalConstantValue value1,
-      covariant DeferredGlobalConstantValue value2) {
-    return strategy.testSets(
-            value1,
-            value2,
-            'imports',
-            value1.unit.importsForTesting,
-            value2.unit.importsForTesting,
-            strategy.elementEquivalence) &&
-        strategy.testConstantValues(
-            value1, value2, 'referenced', value1.referenced, value2.referenced);
-  }
-
-  @override
-  bool visitNonConstant(
-      NonConstantValue value1, covariant NonConstantValue value2) {
-    return true;
-  }
-
-  @override
-  bool visitSynthetic(
-      SyntheticConstantValue value1, covariant SyntheticConstantValue value2) {
-    return strategy.test(
-            value1, value2, 'payload', value1.payload, value2.payload) &&
-        strategy.test(
-            value1, value2, 'valueKind', value1.valueKind, value2.valueKind);
-  }
-
-  @override
-  bool visitInterceptor(InterceptorConstantValue value1,
-      covariant InterceptorConstantValue value2) {
-    return strategy.testElements(value1, value2, 'cls', value1.cls, value2.cls);
-  }
-
-  @override
-  bool visitInstantiation(InstantiationConstantValue value1,
-      covariant InstantiationConstantValue value2) {
-    return strategy.testTypeLists(value1, value2, 'typeArguments',
-            value1.typeArguments, value2.typeArguments) &&
-        strategy.testConstantValues(
-            value1, value2, 'function', value1.function, value2.function);
-  }
-}
-
-/// Tests the equivalence of [impact1] and [impact2] using [strategy].
-bool testResolutionImpactEquivalence(
-    ResolutionImpact impact1, ResolutionImpact impact2,
-    {TestStrategy strategy = const TestStrategy(),
-    Iterable<ConstantExpression> filterConstantLiterals(
-        Iterable<ConstantExpression> constants,
-        {bool fromFirstImpact})}) {
-  return strategy.testSets(impact1, impact2, 'constSymbolNames',
-          impact1.constSymbolNames, impact2.constSymbolNames) &&
-      strategy.testSets(
-          impact1,
-          impact2,
-          'constantLiterals',
-          filterConstantLiterals != null
-              ? filterConstantLiterals(impact1.constantLiterals,
-                  fromFirstImpact: true)
-              : impact1.constantLiterals,
-          filterConstantLiterals != null
-              ? filterConstantLiterals(impact2.constantLiterals,
-                  fromFirstImpact: false)
-              : impact2.constantLiterals,
-          areConstantsEquivalent) &&
-      strategy.testSets(
-          impact1,
-          impact2,
-          'dynamicUses',
-          impact1.dynamicUses,
-          impact2.dynamicUses,
-          (a, b) =>
-              areDynamicUsesEquivalent(a, b, strategy: strategy.testOnly)) &&
-      strategy.testSets(
-          impact1, impact2, 'features', impact1.features, impact2.features) &&
-      strategy.testSets(
-          impact1,
-          impact2,
-          'listLiterals',
-          impact1.listLiterals,
-          impact2.listLiterals,
-          (a, b) => areListLiteralUsesEquivalent(a, b,
-              strategy: strategy.testOnly)) &&
-      strategy.testSets(
-          impact1,
-          impact2,
-          'mapLiterals',
-          impact1.mapLiterals,
-          impact2.mapLiterals,
-          (a, b) =>
-              areMapLiteralUsesEquivalent(a, b, strategy: strategy.testOnly)) &&
-      strategy.testSets(
-          impact1,
-          impact2,
-          'staticUses',
-          impact1.staticUses,
-          impact2.staticUses,
-          (a, b) =>
-              areStaticUsesEquivalent(a, b, strategy: strategy.testOnly)) &&
-      strategy.testSets(
-          impact1,
-          impact2,
-          'typeUses',
-          impact1.typeUses,
-          impact2.typeUses,
-          (a, b) => areTypeUsesEquivalent(a, b, strategy: strategy.testOnly)) &&
-      strategy.testSets(
-          impact1,
-          impact2,
-          'nativeData',
-          impact1.nativeData,
-          impact2.nativeData,
-          (a, b) => testNativeBehavior(a, b, strategy: strategy));
-}
-
-/// Tests the equivalence of [resolvedAst1] and [resolvedAst2] using [strategy].
-bool testResolvedAstEquivalence(
-    ResolvedAst resolvedAst1, ResolvedAst resolvedAst2,
-    [TestStrategy strategy = const TestStrategy()]) {
-  if (!strategy.test(resolvedAst1, resolvedAst1, 'kind', resolvedAst1.kind,
-      resolvedAst2.kind)) {
-    return false;
-  }
-  if (resolvedAst1.kind != ResolvedAstKind.PARSED) {
-    // Nothing more to check.
-    return true;
-  }
-  bool result = strategy.testElements(resolvedAst1, resolvedAst2, 'element',
-          resolvedAst1.element, resolvedAst2.element) &&
-      strategy.testNodes(resolvedAst1, resolvedAst2, 'node', resolvedAst1.node,
-          resolvedAst2.node) &&
-      strategy.testNodes(resolvedAst1, resolvedAst2, 'body', resolvedAst1.body,
-          resolvedAst2.body) &&
-      testTreeElementsEquivalence(resolvedAst1, resolvedAst2, strategy) &&
-      strategy.test(resolvedAst1, resolvedAst2, 'sourceUri',
-          resolvedAst1.sourceUri, resolvedAst2.sourceUri);
-  if (resolvedAst1.element is FunctionElement) {
-    FunctionElement element1 = resolvedAst1.element;
-    FunctionElement element2 = resolvedAst2.element;
-    for (int index = 0; index < element1.parameters.length; index++) {
-      dynamic parameter1 = element1.parameters[index];
-      dynamic parameter2 = element2.parameters[index];
-      result = result &&
-          strategy.testNodes(parameter1, parameter2, 'node',
-              parameter1.implementation.node, parameter2.implementation.node) &&
-          strategy.testNodes(
-              parameter1,
-              parameter2,
-              'initializer',
-              parameter1.implementation.initializer,
-              parameter2.implementation.initializer);
-    }
-  }
-  return result;
-}
-
-/// Tests the equivalence of the data stored in the [TreeElements] of
-/// [resolvedAst1] and [resolvedAst2] using [strategy].
-bool testTreeElementsEquivalence(
-    ResolvedAst resolvedAst1, ResolvedAst resolvedAst2,
-    [TestStrategy strategy = const TestStrategy()]) {
-  AstIndexComputer indices1 = new AstIndexComputer();
-  resolvedAst1.node.accept(indices1);
-  AstIndexComputer indices2 = new AstIndexComputer();
-  resolvedAst2.node.accept(indices2);
-
-  TreeElements elements1 = resolvedAst1.elements;
-  TreeElements elements2 = resolvedAst2.elements;
-
-  TreeElementsEquivalenceVisitor visitor = new TreeElementsEquivalenceVisitor(
-      indices1, indices2, elements1, elements2, strategy);
-  resolvedAst1.node.accept(visitor);
-  if (visitor.success) {
-    return strategy.test(elements1, elements2, 'containsTryStatement',
-        elements1.containsTryStatement, elements2.containsTryStatement);
-  }
-  return false;
-}
-
-bool testNativeBehavior(NativeBehavior a, NativeBehavior b,
-    {TestStrategy strategy = const TestStrategy()}) {
-  if (identical(a, b)) return true;
-  if (a == null || b == null) return false;
-  return strategy.test(
-          a, b, 'codeTemplateText', a.codeTemplateText, b.codeTemplateText) &&
-      strategy.test(a, b, 'isAllocation', a.isAllocation, b.isAllocation) &&
-      strategy.test(a, b, 'sideEffects', a.sideEffects, b.sideEffects) &&
-      strategy.test(a, b, 'throwBehavior', a.throwBehavior, b.throwBehavior) &&
-      strategy.testTypeLists(
-          a,
-          b,
-          'dartTypesReturned',
-          NativeBehaviorFilters.filterDartTypes(a.typesReturned),
-          NativeBehaviorFilters.filterDartTypes(b.typesReturned)) &&
-      strategy.testLists(
-          a,
-          b,
-          'specialTypesReturned',
-          NativeBehaviorFilters.filterSpecialTypes(a.typesReturned),
-          NativeBehaviorFilters.filterSpecialTypes(b.typesReturned)) &&
-      strategy.testTypeLists(
-          a,
-          b,
-          'dartTypesInstantiated',
-          NativeBehaviorFilters.filterDartTypes(a.typesInstantiated),
-          NativeBehaviorFilters.filterDartTypes(b.typesInstantiated)) &&
-      strategy.testLists(
-          a,
-          b,
-          'specialTypesInstantiated',
-          NativeBehaviorFilters.filterSpecialTypes(a.typesInstantiated),
-          NativeBehaviorFilters.filterSpecialTypes(b.typesInstantiated)) &&
-      strategy.test(a, b, 'useGvn', a.useGvn, b.useGvn);
-}
-
-/// Visitor that checks the equivalence of [TreeElements] data.
-class TreeElementsEquivalenceVisitor extends Visitor {
-  final TestStrategy strategy;
-  final AstIndexComputer indices1;
-  final AstIndexComputer indices2;
-  final TreeElements elements1;
-  final TreeElements elements2;
-  bool success = true;
-
-  TreeElementsEquivalenceVisitor(
-      this.indices1, this.indices2, this.elements1, this.elements2,
-      [this.strategy = const TestStrategy()]);
-
-  bool testJumpTargets(
-      Node node1, Node node2, String property, JumpTarget a, JumpTarget b) {
-    if (identical(a, b)) return true;
-    if (a == null || b == null) return false;
-    return strategy.test(
-            a, b, 'nestingLevel', a.nestingLevel, b.nestingLevel) &&
-        strategy.test(a, b, 'statement', indices1.nodeIndices[a.statement],
-            indices2.nodeIndices[b.statement]) &&
-        strategy.test(
-            a, b, 'isBreakTarget', a.isBreakTarget, b.isBreakTarget) &&
-        strategy.test(
-            a, b, 'isContinueTarget', a.isContinueTarget, b.isContinueTarget) &&
-        strategy.testLists(a, b, 'labels', a.labels.toList(), b.labels.toList(),
-            (a, b) {
-          return indices1.nodeIndices[a.label] == indices2.nodeIndices[b.label];
-        });
-  }
-
-  bool testLabelDefinitions(Node node1, Node node2, String property,
-      LabelDefinitionX a, LabelDefinitionX b) {
-    if (identical(a, b)) return true;
-    if (a == null || b == null) return false;
-    return strategy.test(a, b, 'label', indices1.nodeIndices[a.label],
-            indices2.nodeIndices[b.label]) &&
-        strategy.test(a, b, 'labelName', a.labelName, b.labelName) &&
-        strategy.test(a, b, 'target', indices1.nodeIndices[a.target.statement],
-            indices2.nodeIndices[b.target.statement]) &&
-        strategy.test(
-            a, b, 'isBreakTarget', a.isBreakTarget, b.isBreakTarget) &&
-        strategy.test(
-            a, b, 'isContinueTarget', a.isContinueTarget, b.isContinueTarget);
-  }
-
-  bool testNativeData(Node node1, Node node2, String property, a, b) {
-    if (identical(a, b)) return true;
-    if (a == null || b == null) return false;
-    if (a is NativeBehavior && b is NativeBehavior) {
-      return testNativeBehavior(a, b, strategy: strategy);
-    }
-    return true;
-  }
-
-  visitNode(Node node1) {
-    if (!success) return;
-    int index = indices1.nodeIndices[node1];
-    Node node2 = indices2.nodeList[index];
-    success = strategy.testElements(
-            node1, node2, '[$index]', elements1[node1], elements2[node2]) &&
-        strategy.testTypes(node1, node2, 'getType($index)',
-            elements1.getType(node1), elements2.getType(node2)) &&
-        strategy.test(
-            node1,
-            node2,
-            'getSelector($index)',
-            elements1.getSelector(node1),
-            elements2.getSelector(node2),
-            areSelectorsEquivalent) &&
-        strategy.testConstants(node1, node2, 'getConstant($index)',
-            elements1.getConstant(node1), elements2.getConstant(node2)) &&
-        strategy.testTypes(node1, node2, 'typesCache[$index]',
-            elements1.typesCache[node1], elements2.typesCache[node2]) &&
-        testJumpTargets(
-            node1,
-            node2,
-            'getTargetDefinition($index)',
-            elements1.getTargetDefinition(node1),
-            elements2.getTargetDefinition(node2)) &&
-        testNativeData(node1, node2, 'getNativeData($index)',
-            elements1.getNativeData(node1), elements2.getNativeData(node2));
-
-    node1.visitChildren(this);
-  }
-
-  @override
-  visitSend(Send node1) {
-    visitExpression(node1);
-    if (!success) return;
-    int index = indices1.nodeIndices[node1];
-    Send node2 = indices2.nodeList[index];
-    success = strategy.test(node1, node2, 'isTypeLiteral($index)',
-            elements1.isTypeLiteral(node1), elements2.isTypeLiteral(node2)) &&
-        strategy.testTypes(
-            node1,
-            node2,
-            'getTypeLiteralType($index)',
-            elements1.getTypeLiteralType(node1),
-            elements2.getTypeLiteralType(node2)) &&
-        strategy.test(
-            node1,
-            node2,
-            'getSendStructure($index)',
-            elements1.getSendStructure(node1),
-            elements2.getSendStructure(node2),
-            areSendStructuresEquivalent);
-  }
-
-  @override
-  visitNewExpression(NewExpression node1) {
-    visitExpression(node1);
-    if (!success) return;
-    int index = indices1.nodeIndices[node1];
-    NewExpression node2 = indices2.nodeList[index];
-    success = strategy.test(
-        node1,
-        node2,
-        'getNewStructure($index)',
-        elements1.getNewStructure(node1),
-        elements2.getNewStructure(node2),
-        areNewStructuresEquivalent);
-  }
-
-  @override
-  visitSendSet(SendSet node1) {
-    visitSend(node1);
-    if (!success) return;
-    int index = indices1.nodeIndices[node1];
-    SendSet node2 = indices2.nodeList[index];
-    success = strategy.test(
-            node1,
-            node2,
-            'getGetterSelectorInComplexSendSet($index)',
-            elements1.getGetterSelectorInComplexSendSet(node1),
-            elements2.getGetterSelectorInComplexSendSet(node2),
-            areSelectorsEquivalent) &&
-        strategy.test(
-            node1,
-            node2,
-            'getOperatorSelectorInComplexSendSet($index)',
-            elements1.getOperatorSelectorInComplexSendSet(node1),
-            elements2.getOperatorSelectorInComplexSendSet(node2),
-            areSelectorsEquivalent);
-  }
-
-  @override
-  visitFunctionExpression(FunctionExpression node1) {
-    visitNode(node1);
-    if (!success) return;
-    int index = indices1.nodeIndices[node1];
-    FunctionExpression node2 = indices2.nodeList[index];
-    if (elements1[node1] is! FunctionElement) {
-      // [getFunctionDefinition] is currently stored in [] which doesn't always
-      // contain a [FunctionElement].
-      return;
-    }
-    success = strategy.testElements(
-        node1,
-        node2,
-        'getFunctionDefinition($index)',
-        elements1.getFunctionDefinition(node1),
-        elements2.getFunctionDefinition(node2));
-  }
-
-  @override
-  visitForIn(ForIn node1) {
-    visitLoop(node1);
-    if (!success) return;
-    int index = indices1.nodeIndices[node1];
-    ForIn node2 = indices2.nodeList[index];
-    success = strategy.testElements(node1, node2, 'getForInVariable($index)',
-        elements1.getForInVariable(node1), elements2.getForInVariable(node2));
-  }
-
-  @override
-  visitRedirectingFactoryBody(RedirectingFactoryBody node1) {
-    visitStatement(node1);
-    if (!success) return;
-    int index = indices1.nodeIndices[node1];
-    RedirectingFactoryBody node2 = indices2.nodeList[index];
-    success = strategy.testElements(
-        node1,
-        node2,
-        'getRedirectingTargetConstructor($index)',
-        elements1.getRedirectingTargetConstructor(node1),
-        elements2.getRedirectingTargetConstructor(node2));
-  }
-
-  @override
-  visitGotoStatement(GotoStatement node1) {
-    visitStatement(node1);
-    if (!success) return;
-    int index = indices1.nodeIndices[node1];
-    GotoStatement node2 = indices2.nodeList[index];
-    success = testJumpTargets(node1, node2, 'getTargetOf($index)',
-        elements1.getTargetOf(node1), elements2.getTargetOf(node2));
-    if (!success) return;
-    if (node1.target == null && node2.target == null) {
-      return;
-    }
-    success = testLabelDefinitions(node1, node2, 'getTarget($index)',
-        elements1.getTargetLabel(node1), elements2.getTargetLabel(node2));
-  }
-
-  @override
-  visitLabel(Label node1) {
-    visitNode(node1);
-    if (!success) return;
-    int index = indices1.nodeIndices[node1];
-    Label node2 = indices2.nodeList[index];
-    success = testLabelDefinitions(
-        node1,
-        node2,
-        'getLabelDefinition($index)',
-        elements1.getLabelDefinition(node1),
-        elements2.getLabelDefinition(node2));
-  }
-}
-
-class NodeEquivalenceVisitor implements Visitor1<bool, Node> {
-  final TestStrategy strategy;
-
-  const NodeEquivalenceVisitor([this.strategy = const TestStrategy()]);
-
-  bool testNodes(dynamic object1, dynamic object2, String property, Node node1,
-      Node node2) {
-    return strategy.test(object1, object2, property, node1, node2,
-        (Node n1, Node n2) {
-      if (n1 == n2) return true;
-      if (n1 == null || n2 == null) return false;
-      return n1.accept1(this, n2);
-    });
-  }
-
-  bool testNodeLists(dynamic object1, dynamic object2, String property,
-      Link<Node> list1, Link<Node> list2) {
-    return strategy.test(object1, object2, property, list1, list2,
-        (Link<Node> l1, Link<Node> l2) {
-      if (l1 == l2) return true;
-      if (l1 == null || l2 == null) return false;
-      while (l1.isNotEmpty && l2.isNotEmpty) {
-        if (!l1.head.accept1(this, l2.head)) {
-          return false;
-        }
-        l1 = l1.tail;
-        l2 = l2.tail;
-      }
-      return l1.isEmpty && l2.isEmpty;
-    });
-  }
-
-  bool testTokens(dynamic object1, dynamic object2, String property,
-      Token token1, Token token2) {
-    return strategy.test(object1, object2, property, token1, token2,
-        (Token t1, Token t2) {
-      if (t1 == t2) return true;
-      if (t1 == null || t2 == null) return false;
-      return strategy.test(
-              t1, t2, 'charOffset', t1.charOffset, t2.charOffset) &&
-          strategy.test(t1, t2, 'info', t1.type, t2.type) &&
-          strategy.test(t1, t2, 'value', t1.lexeme, t2.lexeme);
-    });
-  }
-
-  @override
-  bool visitAssert(Assert node1, covariant Assert node2) {
-    return testTokens(node1, node2, 'assertToken', node1.assertToken,
-            node2.assertToken) &&
-        testNodes(
-            node1, node2, 'condition', node1.condition, node2.condition) &&
-        testNodes(node1, node2, 'message', node1.message, node2.message);
-  }
-
-  @override
-  bool visitAsyncForIn(AsyncForIn node1, covariant AsyncForIn node2) {
-    return visitForIn(node1, node2) &&
-        testTokens(
-            node1, node2, 'awaitToken', node1.awaitToken, node2.awaitToken);
-  }
-
-  @override
-  bool visitAsyncModifier(AsyncModifier node1, covariant AsyncModifier node2) {
-    return testTokens(
-            node1, node2, 'asyncToken', node1.asyncToken, node2.asyncToken) &&
-        testTokens(node1, node2, 'starToken', node1.starToken, node2.starToken);
-  }
-
-  @override
-  bool visitAwait(Await node1, covariant Await node2) {
-    return testTokens(
-            node1, node2, 'awaitToken', node1.awaitToken, node2.awaitToken) &&
-        testNodes(
-            node1, node2, 'expression', node1.expression, node2.expression);
-  }
-
-  @override
-  bool visitBlock(Block node1, covariant Block node2) {
-    return testNodes(
-        node1, node2, 'statements', node1.statements, node2.statements);
-  }
-
-  @override
-  bool visitBreakStatement(
-      BreakStatement node1, covariant BreakStatement node2) {
-    return testTokens(node1, node2, 'keywordToken', node1.keywordToken,
-            node2.keywordToken) &&
-        testNodes(node1, node2, 'target', node1.target, node2.target);
-  }
-
-  @override
-  bool visitCascade(Cascade node1, covariant Cascade node2) {
-    return testNodes(
-        node1, node2, 'expression', node1.expression, node2.expression);
-  }
-
-  @override
-  bool visitCascadeReceiver(
-      CascadeReceiver node1, covariant CascadeReceiver node2) {
-    return testTokens(node1, node2, 'cascadeOperator', node1.cascadeOperator,
-            node2.cascadeOperator) &&
-        testNodes(
-            node1, node2, 'expression', node1.expression, node2.expression);
-  }
-
-  @override
-  bool visitCaseMatch(CaseMatch node1, covariant CaseMatch node2) {
-    return testTokens(node1, node2, 'caseKeyword', node1.caseKeyword,
-            node2.caseKeyword) &&
-        testNodes(
-            node1, node2, 'expression', node1.expression, node2.expression);
-  }
-
-  @override
-  bool visitCatchBlock(CatchBlock node1, covariant CatchBlock node2) {
-    return testTokens(node1, node2, 'catchKeyword', node1.catchKeyword,
-            node2.catchKeyword) &&
-        testTokens(
-            node1, node2, 'onKeyword', node1.onKeyword, node2.onKeyword) &&
-        testNodes(node1, node2, 'type', node1.type, node2.type) &&
-        testNodes(node1, node2, 'formals', node1.formals, node2.formals) &&
-        testNodes(node1, node2, 'block', node1.block, node2.block);
-  }
-
-  @override
-  bool visitClassNode(ClassNode node1, covariant ClassNode node2) {
-    return testTokens(
-            node1, node2, 'beginToken', node1.beginToken, node2.beginToken) &&
-        testTokens(node1, node2, 'extendsKeyword', node1.extendsKeyword,
-            node2.extendsKeyword) &&
-        testTokens(node1, node2, 'endToken', node1.endToken, node2.endToken) &&
-        testNodes(
-            node1, node2, 'modifiers', node1.modifiers, node2.modifiers) &&
-        testNodes(node1, node2, 'name', node1.name, node2.name) &&
-        testNodes(
-            node1, node2, 'superclass', node1.superclass, node2.superclass) &&
-        testNodes(
-            node1, node2, 'interfaces', node1.interfaces, node2.interfaces) &&
-        testNodes(node1, node2, 'typeParameters', node1.typeParameters,
-            node2.typeParameters) &&
-        testNodes(node1, node2, 'body', node1.body, node2.body);
-  }
-
-  @override
-  bool visitCombinator(Combinator node1, covariant Combinator node2) {
-    return testTokens(node1, node2, 'keywordToken', node1.keywordToken,
-            node2.keywordToken) &&
-        testNodes(
-            node1, node2, 'identifiers', node1.identifiers, node2.identifiers);
-  }
-
-  @override
-  bool visitConditional(Conditional node1, covariant Conditional node2) {
-    return testTokens(node1, node2, 'questionToken', node1.questionToken,
-            node2.questionToken) &&
-        testTokens(
-            node1, node2, 'colonToken', node1.colonToken, node2.colonToken) &&
-        testNodes(
-            node1, node2, 'condition', node1.condition, node2.condition) &&
-        testNodes(node1, node2, 'thenExpression', node1.thenExpression,
-            node2.thenExpression) &&
-        testNodes(node1, node2, 'elseExpression', node1.elseExpression,
-            node2.elseExpression);
-  }
-
-  @override
-  bool visitConditionalUri(
-      ConditionalUri node1, covariant ConditionalUri node2) {
-    return testTokens(node1, node2, 'ifToken', node1.ifToken, node2.ifToken) &&
-        testNodes(node1, node2, 'key', node1.key, node2.key) &&
-        testNodes(node1, node2, 'value', node1.value, node2.value) &&
-        testNodes(node1, node2, 'uri', node1.uri, node2.uri);
-  }
-
-  @override
-  bool visitContinueStatement(
-      ContinueStatement node1, covariant ContinueStatement node2) {
-    return testTokens(node1, node2, 'keywordToken', node1.keywordToken,
-            node2.keywordToken) &&
-        testNodes(node1, node2, 'target', node1.target, node2.target);
-  }
-
-  @override
-  bool visitDoWhile(DoWhile node1, covariant DoWhile node2) {
-    return testTokens(
-            node1, node2, 'doKeyword', node1.doKeyword, node2.doKeyword) &&
-        testTokens(node1, node2, 'whileKeyword', node1.whileKeyword,
-            node2.whileKeyword) &&
-        testTokens(node1, node2, 'endToken', node1.endToken, node2.endToken) &&
-        testNodes(
-            node1, node2, 'condition', node1.condition, node2.condition) &&
-        testNodes(node1, node2, 'body', node1.body, node2.body);
-  }
-
-  @override
-  bool visitDottedName(DottedName node1, covariant DottedName node2) {
-    return testTokens(node1, node2, 'token', node1.token, node2.token) &&
-        testNodes(
-            node1, node2, 'identifiers', node1.identifiers, node2.identifiers);
-  }
-
-  @override
-  bool visitEmptyStatement(
-      EmptyStatement node1, covariant EmptyStatement node2) {
-    return testTokens(node1, node2, 'semicolonToken', node1.semicolonToken,
-        node2.semicolonToken);
-  }
-
-  @override
-  bool visitEnum(Enum node1, covariant Enum node2) {
-    return testTokens(
-            node1, node2, 'enumToken', node1.enumToken, node2.enumToken) &&
-        testNodes(node1, node2, 'name', node1.name, node2.name) &&
-        testNodes(node1, node2, 'names', node1.names, node2.names);
-  }
-
-  @override
-  bool visitExport(Export node1, covariant Export node2) {
-    return visitLibraryDependency(node1, node2) &&
-        testTokens(node1, node2, 'exportKeyword', node1.exportKeyword,
-            node2.exportKeyword);
-  }
-
-  @override
-  bool visitExpressionStatement(
-      ExpressionStatement node1, covariant ExpressionStatement node2) {
-    return testTokens(
-            node1, node2, 'endToken', node1.endToken, node2.endToken) &&
-        testNodes(
-            node1, node2, 'expression', node1.expression, node2.expression);
-  }
-
-  @override
-  bool visitFor(For node1, covariant For node2) {
-    return testTokens(
-            node1, node2, 'forToken', node1.forToken, node2.forToken) &&
-        testNodes(node1, node2, 'initializer', node1.initializer,
-            node2.initializer) &&
-        testNodes(node1, node2, 'conditionStatement', node1.conditionStatement,
-            node2.conditionStatement) &&
-        testNodes(node1, node2, 'update', node1.update, node2.update) &&
-        testNodes(node1, node2, 'body', node1.body, node2.body);
-  }
-
-  @override
-  bool visitForIn(ForIn node1, covariant ForIn node2) {
-    return testNodes(
-            node1, node2, 'condition', node1.condition, node2.condition) &&
-        testNodes(
-            node1, node2, 'expression', node1.expression, node2.expression) &&
-        testNodes(node1, node2, 'body', node1.body, node2.body) &&
-        testNodes(node1, node2, 'declaredIdentifier', node1.declaredIdentifier,
-            node2.declaredIdentifier);
-  }
-
-  @override
-  bool visitFunctionDeclaration(
-      FunctionDeclaration node1, covariant FunctionDeclaration node2) {
-    return testNodes(node1, node2, 'function', node1.function, node2.function);
-  }
-
-  @override
-  bool visitFunctionExpression(
-      FunctionExpression node1, covariant FunctionExpression node2) {
-    return testTokens(
-            node1, node2, 'getOrSet', node1.getOrSet, node2.getOrSet) &&
-        testNodes(node1, node2, 'name', node1.name, node2.name) &&
-        testNodes(
-            node1, node2, 'parameters', node1.parameters, node2.parameters) &&
-        testNodes(node1, node2, 'body', node1.body, node2.body) &&
-        testNodes(
-            node1, node2, 'returnType', node1.returnType, node2.returnType) &&
-        testNodes(
-            node1, node2, 'modifiers', node1.modifiers, node2.modifiers) &&
-        testNodes(node1, node2, 'initializers', node1.initializers,
-            node2.initializers) &&
-        testNodes(node1, node2, 'asyncModifier', node1.asyncModifier,
-            node2.asyncModifier);
-  }
-
-  @override
-  bool visitGotoStatement(GotoStatement node1, covariant GotoStatement node2) {
-    return testTokens(node1, node2, 'keywordToken', node1.keywordToken,
-            node2.keywordToken) &&
-        testTokens(node1, node2, 'semicolonToken', node1.semicolonToken,
-            node2.semicolonToken) &&
-        testNodes(node1, node2, 'target', node1.target, node2.target);
-  }
-
-  @override
-  bool visitIdentifier(Identifier node1, covariant Identifier node2) {
-    return testTokens(node1, node2, 'token', node1.token, node2.token);
-  }
-
-  @override
-  bool visitIf(If node1, covariant If node2) {
-    return testTokens(node1, node2, 'ifToken', node1.ifToken, node2.ifToken) &&
-        testTokens(
-            node1, node2, 'elseToken', node1.elseToken, node2.elseToken) &&
-        testNodes(
-            node1, node2, 'condition', node1.condition, node2.condition) &&
-        testNodes(node1, node2, 'thenPart', node1.thenPart, node2.thenPart) &&
-        testNodes(node1, node2, 'elsePart', node1.elsePart, node2.elsePart);
-  }
-
-  @override
-  bool visitImport(Import node1, covariant Import node2) {
-    return visitLibraryDependency(node1, node2) &&
-        testTokens(node1, node2, 'importKeyword', node1.importKeyword,
-            node2.importKeyword) &&
-        testNodes(node1, node2, 'prefix', node1.prefix, node2.prefix) &&
-        strategy.test(
-            node1, node2, 'isDeferred', node1.isDeferred, node2.isDeferred);
-  }
-
-  @override
-  bool visitLabel(Label node1, covariant Label node2) {
-    return testTokens(
-            node1, node2, 'colonToken', node1.colonToken, node2.colonToken) &&
-        testNodes(
-            node1, node2, 'identifier', node1.identifier, node2.identifier);
-  }
-
-  @override
-  bool visitLabeledStatement(
-      LabeledStatement node1, covariant LabeledStatement node2) {
-    return testNodes(node1, node2, 'labels', node1.labels, node2.labels) &&
-        testNodes(node1, node2, 'statement', node1.statement, node2.statement);
-  }
-
-  @override
-  bool visitLibraryDependency(
-      LibraryDependency node1, covariant LibraryDependency node2) {
-    return visitLibraryTag(node1, node2) &&
-        testNodes(node1, node2, 'uri', node1.uri, node2.uri) &&
-        testNodes(node1, node2, 'conditionalUris', node1.conditionalUris,
-            node2.conditionalUris) &&
-        testNodes(
-            node1, node2, 'combinators', node1.combinators, node2.combinators);
-  }
-
-  @override
-  bool visitLibraryName(LibraryName node1, covariant LibraryName node2) {
-    return visitLibraryTag(node1, node2) &&
-        testTokens(node1, node2, 'libraryKeyword', node1.libraryKeyword,
-            node2.libraryKeyword) &&
-        testNodes(node1, node2, 'name', node1.name, node2.name);
-  }
-
-  @override
-  bool visitLibraryTag(LibraryTag node1, covariant LibraryTag node2) {
-    // TODO(johnniwinther): Check metadata?
-    return true;
-  }
-
-  @override
-  bool visitLiteral(Literal node1, covariant Literal node2) {
-    return testTokens(node1, node2, 'token', node1.token, node2.token);
-  }
-
-  @override
-  bool visitLiteralBool(LiteralBool node1, covariant LiteralBool node2) {
-    return visitLiteral(node1, node2);
-  }
-
-  @override
-  bool visitLiteralDouble(LiteralDouble node1, covariant LiteralDouble node2) {
-    return visitLiteral(node1, node2);
-  }
-
-  @override
-  bool visitLiteralInt(LiteralInt node1, covariant LiteralInt node2) {
-    return visitLiteral(node1, node2);
-  }
-
-  @override
-  bool visitLiteralList(LiteralList node1, covariant LiteralList node2) {
-    return testTokens(node1, node2, 'constKeyword', node1.constKeyword,
-            node2.constKeyword) &&
-        testNodes(node1, node2, 'typeArguments', node1.typeArguments,
-            node2.typeArguments) &&
-        testNodes(node1, node2, 'elements', node1.elements, node2.elements);
-  }
-
-  @override
-  bool visitLiteralMap(LiteralMap node1, covariant LiteralMap node2) {
-    return testTokens(node1, node2, 'constKeyword', node1.constKeyword,
-            node2.constKeyword) &&
-        testNodes(node1, node2, 'typeArguments', node1.typeArguments,
-            node2.typeArguments) &&
-        testNodes(node1, node2, 'entries', node1.entries, node2.entries);
-  }
-
-  @override
-  bool visitLiteralMapEntry(
-      LiteralMapEntry node1, covariant LiteralMapEntry node2) {
-    return testTokens(
-            node1, node2, 'colonToken', node1.colonToken, node2.colonToken) &&
-        testNodes(node1, node2, 'key', node1.key, node2.key) &&
-        testNodes(node1, node2, 'value', node1.value, node2.value);
-  }
-
-  @override
-  bool visitLiteralNull(LiteralNull node1, covariant LiteralNull node2) {
-    return visitLiteral(node1, node2);
-  }
-
-  @override
-  bool visitLiteralString(LiteralString node1, covariant LiteralString node2) {
-    return testTokens(node1, node2, 'token', node1.token, node2.token) &&
-        strategy.test(
-            node1, node2, 'dartString', node1.dartString, node2.dartString);
-  }
-
-  @override
-  bool visitLiteralSymbol(LiteralSymbol node1, covariant LiteralSymbol node2) {
-    return testTokens(
-            node1, node2, 'hashToken', node1.hashToken, node2.hashToken) &&
-        testNodes(
-            node1, node2, 'identifiers', node1.identifiers, node2.identifiers);
-  }
-
-  @override
-  bool visitLoop(Loop node1, covariant Loop node2) {
-    return testNodes(
-            node1, node2, 'condition', node1.condition, node2.condition) &&
-        testNodes(node1, node2, 'body', node1.body, node2.body);
-  }
-
-  @override
-  bool visitMetadata(Metadata node1, covariant Metadata node2) {
-    return testTokens(node1, node2, 'token', node1.token, node2.token) &&
-        testNodes(
-            node1, node2, 'expression', node1.expression, node2.expression);
-  }
-
-  @override
-  bool visitMixinApplication(
-      MixinApplication node1, covariant MixinApplication node2) {
-    return testNodes(
-            node1, node2, 'superclass', node1.superclass, node2.superclass) &&
-        testNodes(node1, node2, 'mixins', node1.mixins, node2.mixins);
-  }
-
-  @override
-  bool visitModifiers(Modifiers node1, covariant Modifiers node2) {
-    return strategy.test(node1, node2, 'flags', node1.flags, node2.flags) &&
-        testNodes(node1, node2, 'nodes', node1.nodes, node2.nodes);
-  }
-
-  @override
-  bool visitNamedArgument(NamedArgument node1, covariant NamedArgument node2) {
-    return testTokens(
-            node1, node2, 'colonToken', node1.colonToken, node2.colonToken) &&
-        testNodes(node1, node2, 'name', node1.name, node2.name) &&
-        testNodes(
-            node1, node2, 'expression', node1.expression, node2.expression);
-  }
-
-  @override
-  bool visitNamedMixinApplication(
-      NamedMixinApplication node1, covariant NamedMixinApplication node2) {
-    return testTokens(node1, node2, 'classKeyword', node1.classKeyword,
-            node2.classKeyword) &&
-        testTokens(node1, node2, 'endToken', node1.endToken, node2.endToken) &&
-        testNodes(node1, node2, 'name', node1.name, node2.name) &&
-        testNodes(node1, node2, 'typeParameters', node1.typeParameters,
-            node2.typeParameters) &&
-        testNodes(
-            node1, node2, 'modifiers', node1.modifiers, node2.modifiers) &&
-        testNodes(node1, node2, 'mixinApplication', node1.mixinApplication,
-            node2.mixinApplication) &&
-        testNodes(
-            node1, node2, 'interfaces', node1.interfaces, node2.interfaces);
-  }
-
-  @override
-  bool visitNewExpression(NewExpression node1, covariant NewExpression node2) {
-    return testTokens(
-            node1, node2, 'newToken', node1.newToken, node2.newToken) &&
-        testNodes(node1, node2, 'send', node1.send, node2.send);
-  }
-
-  @override
-  bool visitNodeList(NodeList node1, covariant NodeList node2) {
-    return testTokens(
-            node1, node2, 'beginToken', node1.beginToken, node2.beginToken) &&
-        testTokens(node1, node2, 'endToken', node1.endToken, node2.endToken) &&
-        strategy.test(
-            node1, node2, 'delimiter', node1.delimiter, node2.delimiter) &&
-        testNodeLists(node1, node2, 'nodes', node1.nodes, node2.nodes);
-  }
-
-  @override
-  bool visitOperator(Operator node1, covariant Operator node2) {
-    return visitIdentifier(node1, node2);
-  }
-
-  @override
-  bool visitParenthesizedExpression(
-      ParenthesizedExpression node1, covariant ParenthesizedExpression node2) {
-    return testTokens(
-            node1, node2, 'beginToken', node1.beginToken, node2.beginToken) &&
-        testNodes(
-            node1, node2, 'expression', node1.expression, node2.expression);
-  }
-
-  @override
-  bool visitPart(Part node1, covariant Part node2) {
-    return visitLibraryTag(node1, node2) &&
-        testTokens(node1, node2, 'partKeyword', node1.partKeyword,
-            node2.partKeyword) &&
-        testNodes(node1, node2, 'uri', node1.uri, node2.uri);
-  }
-
-  @override
-  bool visitPartOf(PartOf node1, covariant PartOf node2) {
-    // TODO(johnniwinther): Check metadata?
-    return testTokens(node1, node2, 'partKeyword', node1.partKeyword,
-            node2.partKeyword) &&
-        testNodes(node1, node2, 'name', node1.name, node2.name);
-  }
-
-  @override
-  bool visitPostfix(Postfix node1, covariant Postfix node2) {
-    return visitNodeList(node1, node2);
-  }
-
-  @override
-  bool visitPrefix(Prefix node1, covariant Prefix node2) {
-    return visitNodeList(node1, node2);
-  }
-
-  @override
-  bool visitRedirectingFactoryBody(
-      RedirectingFactoryBody node1, covariant RedirectingFactoryBody node2) {
-    return testTokens(
-            node1, node2, 'beginToken', node1.beginToken, node2.beginToken) &&
-        testTokens(node1, node2, 'endToken', node1.endToken, node2.endToken) &&
-        testNodes(node1, node2, 'constructorReference',
-            node1.constructorReference, node2.constructorReference);
-  }
-
-  @override
-  bool visitRethrow(Rethrow node1, covariant Rethrow node2) {
-    return testTokens(
-            node1, node2, 'throwToken', node1.throwToken, node2.throwToken) &&
-        testTokens(node1, node2, 'endToken', node1.endToken, node2.endToken);
-  }
-
-  @override
-  bool visitReturn(Return node1, covariant Return node2) {
-    return testTokens(
-            node1, node2, 'beginToken', node1.beginToken, node2.beginToken) &&
-        testTokens(node1, node2, 'endToken', node1.endToken, node2.endToken) &&
-        testNodes(
-            node1, node2, 'expression', node1.expression, node2.expression);
-  }
-
-  @override
-  bool visitSend(Send node1, covariant Send node2) {
-    return strategy.test(node1, node2, 'isConditional', node1.isConditional,
-            node2.isConditional) &&
-        testNodes(node1, node2, 'receiver', node1.receiver, node2.receiver) &&
-        testNodes(node1, node2, 'selector', node1.selector, node2.selector) &&
-        testNodes(node1, node2, 'argumentsNode', node1.argumentsNode,
-            node2.argumentsNode);
-  }
-
-  @override
-  bool visitSendSet(SendSet node1, covariant SendSet node2) {
-    return visitSend(node1, node2) &&
-        testNodes(node1, node2, 'assignmentOperator', node1.assignmentOperator,
-            node2.assignmentOperator);
-  }
-
-  @override
-  bool visitStringInterpolation(
-      StringInterpolation node1, covariant StringInterpolation node2) {
-    return testNodes(node1, node2, 'string', node1.string, node2.string) &&
-        testNodes(node1, node2, 'parts', node1.parts, node2.parts);
-  }
-
-  @override
-  bool visitStringInterpolationPart(
-      StringInterpolationPart node1, covariant StringInterpolationPart node2) {
-    return testNodes(
-        node1, node2, 'expression', node1.expression, node2.expression);
-  }
-
-  @override
-  bool visitStringJuxtaposition(
-      StringJuxtaposition node1, covariant StringJuxtaposition node2) {
-    return testNodes(node1, node2, 'first', node1.first, node2.first) &&
-        testNodes(node1, node2, 'second', node1.second, node2.second);
-  }
-
-  @override
-  bool visitSwitchCase(SwitchCase node1, covariant SwitchCase node2) {
-    return testTokens(node1, node2, 'defaultKeyword', node1.defaultKeyword,
-            node2.defaultKeyword) &&
-        testTokens(
-            node1, node2, 'startToken', node1.startToken, node2.startToken) &&
-        testNodes(node1, node2, 'labelsAndCases', node1.labelsAndCases,
-            node2.labelsAndCases) &&
-        testNodes(
-            node1, node2, 'statements', node1.statements, node2.statements);
-  }
-
-  @override
-  bool visitSwitchStatement(
-      SwitchStatement node1, covariant SwitchStatement node2) {
-    return testTokens(node1, node2, 'switchKeyword', node1.switchKeyword,
-            node2.switchKeyword) &&
-        testNodes(node1, node2, 'parenthesizedExpression',
-            node1.parenthesizedExpression, node2.parenthesizedExpression) &&
-        testNodes(node1, node2, 'cases', node1.cases, node2.cases);
-  }
-
-  @override
-  bool visitSyncForIn(SyncForIn node1, covariant SyncForIn node2) {
-    return visitForIn(node1, node2);
-  }
-
-  @override
-  bool visitThrow(Throw node1, covariant Throw node2) {
-    return testTokens(
-            node1, node2, 'throwToken', node1.throwToken, node2.throwToken) &&
-        testTokens(node1, node2, 'endToken', node1.endToken, node2.endToken) &&
-        testNodes(
-            node1, node2, 'expression', node1.expression, node2.expression);
-  }
-
-  @override
-  bool visitTryStatement(TryStatement node1, covariant TryStatement node2) {
-    return testTokens(
-            node1, node2, 'tryKeyword', node1.tryKeyword, node2.tryKeyword) &&
-        testTokens(node1, node2, 'finallyKeyword', node1.finallyKeyword,
-            node2.finallyKeyword) &&
-        testNodes(node1, node2, 'tryBlock', node1.tryBlock, node2.tryBlock) &&
-        testNodes(node1, node2, 'catchBlocks', node1.catchBlocks,
-            node2.catchBlocks) &&
-        testNodes(node1, node2, 'finallyBlock', node1.finallyBlock,
-            node2.finallyBlock);
-  }
-
-  @override
-  bool visitNominalTypeAnnotation(
-      NominalTypeAnnotation node1, covariant NominalTypeAnnotation node2) {
-    return testNodes(
-            node1, node2, 'typeName', node1.typeName, node2.typeName) &&
-        testNodes(node1, node2, 'typeArguments', node1.typeArguments,
-            node2.typeArguments);
-  }
-
-  @override
-  bool visitFunctionTypeAnnotation(
-      FunctionTypeAnnotation node1, covariant FunctionTypeAnnotation node2) {
-    return testNodes(
-            node1, node2, 'returnType', node1.returnType, node2.returnType) &&
-        testNodes(node1, node2, 'formals', node1.formals, node2.formals) &&
-        testNodes(node1, node2, 'typeParameters', node1.typeParameters,
-            node2.typeParameters);
-  }
-
-  @override
-  bool visitTypeVariable(TypeVariable node1, covariant TypeVariable node2) {
-    return testNodes(node1, node2, 'name', node1.name, node2.name) &&
-        testNodes(node1, node2, 'bound', node1.bound, node2.bound);
-  }
-
-  @override
-  bool visitTypedef(Typedef node1, covariant Typedef node2) {
-    return testTokens(node1, node2, 'typedefKeyword', node1.typedefKeyword,
-            node2.typedefKeyword) &&
-        testTokens(node1, node2, 'endToken', node1.endToken, node2.endToken) &&
-        testNodes(
-            node1, node2, 'returnType', node1.returnType, node2.returnType) &&
-        testNodes(node1, node2, 'name', node1.name, node2.name) &&
-        testNodes(node1, node2, 'typeParameters', node1.templateParameters,
-            node2.templateParameters) &&
-        testNodes(node1, node2, 'formals', node1.formals, node2.formals);
-  }
-
-  @override
-  bool visitVariableDefinitions(
-      VariableDefinitions node1, covariant VariableDefinitions node2) {
-    return testNodes(
-            node1, node2, 'metadata', node1.metadata, node2.metadata) &&
-        testNodes(node1, node2, 'type', node1.type, node2.type) &&
-        testNodes(
-            node1, node2, 'modifiers', node1.modifiers, node2.modifiers) &&
-        testNodes(
-            node1, node2, 'definitions', node1.definitions, node2.definitions);
-  }
-
-  @override
-  bool visitWhile(While node1, covariant While node2) {
-    return testTokens(node1, node2, 'whileKeyword', node1.whileKeyword,
-            node2.whileKeyword) &&
-        testNodes(
-            node1, node2, 'condition', node1.condition, node2.condition) &&
-        testNodes(node1, node2, 'body', node1.body, node2.body);
-  }
-
-  @override
-  bool visitYield(Yield node1, covariant Yield node2) {
-    return testTokens(
-            node1, node2, 'yieldToken', node1.yieldToken, node2.yieldToken) &&
-        testTokens(
-            node1, node2, 'starToken', node1.starToken, node2.starToken) &&
-        testTokens(node1, node2, 'endToken', node1.endToken, node2.endToken) &&
-        testNodes(
-            node1, node2, 'expression', node1.expression, node2.expression);
-  }
-
-  @override
-  bool visitNode(Node node1, covariant Node node2) {
-    throw new UnsupportedError('Unexpected nodes: $node1 <> $node2');
-  }
-
-  @override
-  bool visitExpression(Expression node1, covariant Expression node2) {
-    throw new UnsupportedError('Unexpected nodes: $node1 <> $node2');
-  }
-
-  @override
-  bool visitStatement(Statement node1, covariant Statement node2) {
-    throw new UnsupportedError('Unexpected nodes: $node1 <> $node2');
-  }
-
-  @override
-  bool visitStringNode(StringNode node1, covariant StringNode node2) {
-    throw new UnsupportedError('Unexpected nodes: $node1 <> $node2');
-  }
-
-  @override
-  bool visitTypeAnnotation(
-      TypeAnnotation node1, covariant TypeAnnotation node2) {
-    throw new UnsupportedError('Unexpected nodes: $node1 <> $node2');
-  }
-}
-
-bool areMetadataAnnotationsEquivalent(
-    MetadataAnnotation metadata1, MetadataAnnotation metadata2) {
-  if (metadata1 == metadata2) return true;
-  if (metadata1 == null || metadata2 == null) return false;
-  return areElementsEquivalent(
-          metadata1.annotatedElement, metadata2.annotatedElement) &&
-      areConstantsEquivalent(metadata1.constant, metadata2.constant);
-}
-
-class NativeBehaviorFilters {
-  static const int NORMAL_TYPE = 0;
-  static const int THIS_TYPE = 1;
-  static const int SPECIAL_TYPE = 2;
-
-  static int getTypeKind(var type) {
-    if (type is DartType) {
-      // TODO(johnniwinther): Remove this when annotation are no longer resolved
-      // to this-types.
-      if (type is InterfaceType &&
-          type.typeArguments.isNotEmpty &&
-          type.typeArguments.first is TypeVariableType) {
-        return THIS_TYPE;
-      }
-      return NORMAL_TYPE;
-    }
-    return SPECIAL_TYPE;
-  }
-
-  /// Returns a list of the non-this-type [ResolutionDartType]s in [types].
-  static List<ResolutionDartType> filterDartTypes(List types) {
-    return types.where((type) => getTypeKind(type) == NORMAL_TYPE).toList();
-  }
-
-  // TODO(johnniwinther): Remove this when annotation are no longer resolved
-  // to this-types.
-  /// Returns a list of the classes of this-types in [types].
-  static List<Element> filterThisTypes(List types) {
-    return types
-        .where((type) => getTypeKind(type) == THIS_TYPE)
-        .map((type) => type.element)
-        .toList();
-  }
-
-  /// Returns a list of the names of the [SpecialType]s in [types].
-  static List<String> filterSpecialTypes(List types) {
-    return types.where((type) => getTypeKind(type) == SPECIAL_TYPE).map((t) {
-      SpecialType type = t;
-      return type.name;
-    }).toList();
-  }
-}
-
-/// Visitor that computes a node-index mapping.
-class AstIndexComputer extends Visitor {
-  final Map<Node, int> nodeIndices = <Node, int>{};
-  final List<Node> nodeList = <Node>[];
-
-  @override
-  visitNode(Node node) {
-    nodeIndices.putIfAbsent(node, () {
-      // Some nodes (like Modifier and empty NodeList) can be reused.
-      nodeList.add(node);
-      return nodeIndices.length;
-    });
-    node.visitChildren(this);
-  }
-}
diff --git a/tests/compiler/dart2js/equivalence/id_equivalence.dart b/tests/compiler/dart2js/equivalence/id_equivalence.dart
index c2828f6..6564b65 100644
--- a/tests/compiler/dart2js/equivalence/id_equivalence.dart
+++ b/tests/compiler/dart2js/equivalence/id_equivalence.dart
@@ -119,6 +119,8 @@
       id = new NodeId(offset, IdKind.node);
       expected = text;
     }
+    // Remove newlines.
+    expected = expected.replaceAll(new RegExp(r'\s*(\n\s*)+\s*'), '');
     return new IdValue(id, expected);
   }
 }
diff --git a/tests/compiler/dart2js/equivalence/id_equivalence_helper.dart b/tests/compiler/dart2js/equivalence/id_equivalence_helper.dart
index 6c824ed..58f7e1d 100644
--- a/tests/compiler/dart2js/equivalence/id_equivalence_helper.dart
+++ b/tests/compiler/dart2js/equivalence/id_equivalence_helper.dart
@@ -95,6 +95,26 @@
     Compiler compiler, ClassEntity cls, Map<Id, ActualData> actualMap,
     {bool verbose});
 
+abstract class DataComputer {
+  void setup();
+
+  /// Function that computes a data mapping for [member].
+  ///
+  /// Fills [actualMap] with the data and [sourceSpanMap] with the source spans
+  /// for the data origin.
+  void computeMemberData(
+      Compiler compiler, MemberEntity member, Map<Id, ActualData> actualMap,
+      {bool verbose});
+
+  /// Function that computes a data mapping for [cls].
+  ///
+  /// Fills [actualMap] with the data and [sourceSpanMap] with the source spans
+  /// for the data origin.
+  void computeClassData(
+      Compiler compiler, ClassEntity cls, Map<Id, ActualData> actualMap,
+      {bool verbose});
+}
+
 const String stopAfterTypeInference = 'stopAfterTypeInference';
 
 /// Reports [message] as an error using [spannable] as error location.
@@ -124,6 +144,7 @@
     ComputeMemberDataFunction computeMemberData,
     {List<String> options: const <String>[],
     bool verbose: false,
+    bool testFrontend: false,
     bool forUserLibrariesOnly: true,
     bool skipUnprocessedMembers: false,
     bool skipFailedCompilations: false,
@@ -142,7 +163,9 @@
     Expect.isTrue(result.isSuccess, "Unexpected compilation error.");
   }
   Compiler compiler = result.compiler;
-  ClosedWorld closedWorld = compiler.backendClosedWorldForTesting;
+  ClosedWorld closedWorld = testFrontend
+      ? compiler.resolutionWorldBuilder.closedWorldForTesting
+      : compiler.backendClosedWorldForTesting;
   ElementEnvironment elementEnvironment = closedWorld.elementEnvironment;
   CommonElements commonElements = closedWorld.commonElements;
 
@@ -456,6 +479,7 @@
     List<String> options: const <String>[],
     List<String> args: const <String>[],
     Directory libDirectory: null,
+    bool testFrontend: false,
     bool forUserLibrariesOnly: true,
     Callback setUpFunction,
     ComputeClassDataFunction computeClassDataFromKernel,
@@ -560,6 +584,7 @@
           computeClassData: computeClassDataFromKernel,
           options: options,
           verbose: verbose,
+          testFrontend: testFrontend,
           forUserLibrariesOnly: forUserLibrariesOnly,
           globalIds: annotations.globalData.keys);
       if (await checkCode(
@@ -584,6 +609,7 @@
             computeClassData: computeClassDataFromKernel,
             options: options,
             verbose: verbose,
+            testFrontend: testFrontend,
             forUserLibrariesOnly: forUserLibrariesOnly,
             globalIds: annotations.globalData.keys);
         if (await checkCode(
@@ -607,6 +633,7 @@
             computeClassData: computeClassDataFromKernel,
             options: options,
             verbose: verbose,
+            testFrontend: testFrontend,
             forUserLibrariesOnly: forUserLibrariesOnly,
             globalIds: annotations.globalData.keys);
         if (await checkCode(
diff --git a/tests/compiler/dart2js/equivalence/show_helper.dart b/tests/compiler/dart2js/equivalence/show_helper.dart
index fa2eb40..0cdad7d 100644
--- a/tests/compiler/dart2js/equivalence/show_helper.dart
+++ b/tests/compiler/dart2js/equivalence/show_helper.dart
@@ -27,6 +27,7 @@
 
 show(ArgResults argResults, ComputeMemberDataFunction computeKernelData,
     {ComputeClassDataFunction computeKernelClassData,
+    bool testFrontend: false,
     List<String> options: const <String>[]}) async {
   if (argResults.wasParsed('colors')) {
     useColors = argResults['colors'];
@@ -60,6 +61,7 @@
   CompiledData data = await computeData(entryPoint, const {}, computeKernelData,
       computeClassData: computeKernelClassData,
       options: options,
+      testFrontend: testFrontend,
       forUserLibrariesOnly: false,
       skipUnprocessedMembers: true,
       skipFailedCompilations: true,
diff --git a/tests/compiler/dart2js/impact/data/async.dart b/tests/compiler/dart2js/impact/data/async.dart
new file mode 100644
index 0000000..8f67a76
--- /dev/null
+++ b/tests/compiler/dart2js/impact/data/async.dart
@@ -0,0 +1,371 @@
+// 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.
+
+/*element: main:
+ static=[
+  testAnonymousAsync(0),
+  testAnonymousAsyncStar(0),
+  testAnonymousSyncStar(0),
+  testAsync(0),
+  testAsyncForIn(1),
+  testAsyncForInTyped(1),
+  testAsyncStar(0),
+  testLocalAsync(0),
+  testLocalAsyncStar(0),
+  testLocalSyncStar(0),
+  testSyncStar(0)],
+  type=[inst:JSNull]
+*/
+main() {
+  testSyncStar();
+  testAsync();
+  testAsyncStar();
+  testLocalSyncStar();
+  testLocalAsync();
+  testLocalAsyncStar();
+  testAnonymousSyncStar();
+  testAnonymousAsync();
+  testAnonymousAsyncStar();
+  testAsyncForIn(null);
+  testAsyncForInTyped(null);
+}
+
+/*element: testSyncStar:
+ static=[
+  _IterationMarker.endOfIteration,
+  _IterationMarker.uncaughtError,
+  _IterationMarker.yieldStar,
+  _makeSyncStarIterable<dynamic>(1)]
+*/
+testSyncStar() sync* {}
+
+/*element: testAsync:
+ static=[
+  StreamIterator.,
+  _asyncAwait,
+  _asyncRethrow,
+  _asyncReturn,
+  _asyncStartSync,
+  _makeAsyncAwaitCompleter<dynamic>(0),
+  _wrapJsFunctionForAsync]
+*/
+testAsync() async {}
+
+/*element: testAsyncStar:static=[StreamIterator.,
+  _IterationMarker.yieldSingle,
+  _IterationMarker.yieldStar,
+  _asyncStarHelper,
+  _makeAsyncStarStreamController<dynamic>(1),
+  _streamOfController,
+  _wrapJsFunctionForAsync]*/
+testAsyncStar() async* {}
+
+/*kernel.element: testLocalSyncStar:
+ static=[
+  _IterationMarker.endOfIteration,
+  _IterationMarker.uncaughtError,
+  _IterationMarker.yieldStar,
+  _makeSyncStarIterable<dynamic>(1),
+  def:local],
+ type=[inst:Function]
+*/
+/*strong.element: testLocalSyncStar:
+ static=[
+  _IterationMarker.endOfIteration,
+  _IterationMarker.uncaughtError,
+  _IterationMarker.yieldStar,
+  _makeSyncStarIterable<Null>(1),
+  computeSignature,
+  def:local,
+  getRuntimeTypeArguments,
+  getRuntimeTypeInfo,
+  setRuntimeTypeInfo],
+ type=[
+  inst:Function,
+  inst:JSArray<dynamic>,
+  inst:JSExtendableArray<dynamic>,
+  inst:JSFixedArray<dynamic>,
+  inst:JSMutableArray<dynamic>,
+  inst:JSUnmodifiableArray<dynamic>]
+*/
+testLocalSyncStar() {
+  local() sync* {}
+  return local;
+}
+
+/*kernel.element: testLocalAsync:
+ static=[
+  StreamIterator.,
+  _asyncAwait,
+  _asyncRethrow,
+  _asyncReturn,
+  _asyncStartSync,
+  _makeAsyncAwaitCompleter<dynamic>(0),
+  _wrapJsFunctionForAsync,
+  def:local],
+ type=[inst:Function]
+*/
+/*strong.element: testLocalAsync:
+ static=[
+  StreamIterator.,
+  _asyncAwait,
+  _asyncRethrow,
+  _asyncReturn,
+  _asyncStartSync,
+  _makeAsyncAwaitCompleter<Null>(0),
+  _wrapJsFunctionForAsync,
+  computeSignature,
+  def:local,
+  getRuntimeTypeArguments,
+  getRuntimeTypeInfo,
+  setRuntimeTypeInfo],
+ type=[
+  inst:Function,
+  inst:JSArray<dynamic>,
+  inst:JSExtendableArray<dynamic>,
+  inst:JSFixedArray<dynamic>,
+  inst:JSMutableArray<dynamic>,
+  inst:JSUnmodifiableArray<dynamic>]
+*/
+testLocalAsync() {
+  local() async {}
+  return local;
+}
+
+/*kernel.element: testLocalAsyncStar:
+ static=[
+ StreamIterator.,
+  _IterationMarker.yieldSingle,
+  _IterationMarker.yieldStar,
+  _asyncStarHelper,
+  _makeAsyncStarStreamController<dynamic>(1),
+  _streamOfController,
+  _wrapJsFunctionForAsync,
+  def:local],
+ type=[inst:Function]
+*/
+/*strong.element: testLocalAsyncStar:
+ static=[
+  StreamIterator.,
+  _IterationMarker.yieldSingle,
+  _IterationMarker.yieldStar,
+  _asyncStarHelper,
+  _makeAsyncStarStreamController<Null>(1),
+  _streamOfController,
+  _wrapJsFunctionForAsync,
+  computeSignature,
+  def:local,
+  getRuntimeTypeArguments,
+  getRuntimeTypeInfo,
+  setRuntimeTypeInfo],
+ type=[
+  inst:Function,
+  inst:JSArray<dynamic>,
+  inst:JSExtendableArray<dynamic>,
+  inst:JSFixedArray<dynamic>,
+  inst:JSMutableArray<dynamic>,
+  inst:JSUnmodifiableArray<dynamic>]
+*/
+testLocalAsyncStar() {
+  local() async* {}
+  return local;
+}
+
+/*kernel.element: testAnonymousSyncStar:
+ static=[
+  _IterationMarker.endOfIteration,
+  _IterationMarker.uncaughtError,
+  _IterationMarker.yieldStar,
+  _makeSyncStarIterable<dynamic>(1),
+  def:<anonymous>],
+ type=[
+  check:Iterable<dynamic>,
+  inst:Function]
+*/
+/*strong.element: testAnonymousSyncStar:
+ static=[
+  _IterationMarker.endOfIteration,
+  _IterationMarker.uncaughtError,
+  _IterationMarker.yieldStar,
+  _makeSyncStarIterable<Null>(1),
+  computeSignature,
+  def:<anonymous>,
+  getRuntimeTypeArguments,
+  getRuntimeTypeInfo,
+  setRuntimeTypeInfo],
+ type=[
+  inst:Function,
+  inst:JSArray<dynamic>,
+  inst:JSExtendableArray<dynamic>,
+  inst:JSFixedArray<dynamic>,
+  inst:JSMutableArray<dynamic>,
+  inst:JSUnmodifiableArray<dynamic>]
+*/
+testAnonymousSyncStar() {
+  return () sync* {};
+}
+
+/*kernel.element: testAnonymousAsync:
+ static=[
+  StreamIterator.,
+  _asyncAwait,
+  _asyncRethrow,
+  _asyncReturn,
+  _asyncStartSync,
+  _makeAsyncAwaitCompleter<dynamic>(0),
+  _wrapJsFunctionForAsync,
+  def:<anonymous>],
+ type=[
+  check:Future<dynamic>,
+  inst:Function]
+*/
+/*strong.element: testAnonymousAsync:
+ static=[
+  StreamIterator.,
+  _asyncAwait,
+  _asyncRethrow,
+  _asyncReturn,
+  _asyncStartSync,
+  _makeAsyncAwaitCompleter<Null>(0),
+  _wrapJsFunctionForAsync,
+  computeSignature,
+  def:<anonymous>,
+  getRuntimeTypeArguments,
+  getRuntimeTypeInfo,
+  setRuntimeTypeInfo],
+ type=[
+  inst:Function,
+  inst:JSArray<dynamic>,
+  inst:JSExtendableArray<dynamic>,
+  inst:JSFixedArray<dynamic>,
+  inst:JSMutableArray<dynamic>,
+  inst:JSUnmodifiableArray<dynamic>]
+*/
+testAnonymousAsync() {
+  return () async {};
+}
+
+/*kernel.element: testAnonymousAsyncStar:
+ static=[
+  StreamIterator.,
+  _IterationMarker.yieldSingle,
+  _IterationMarker.yieldStar,
+  _asyncStarHelper,
+  _makeAsyncStarStreamController<dynamic>(1),
+  _streamOfController,
+  _wrapJsFunctionForAsync,
+  def:<anonymous>],
+ type=[
+  check:Stream<dynamic>,
+  inst:Function]
+*/
+/*strong.element: testAnonymousAsyncStar:
+ static=[
+  StreamIterator.,
+  _IterationMarker.yieldSingle,
+  _IterationMarker.yieldStar,
+  _asyncStarHelper,
+  _makeAsyncStarStreamController<Null>(1),
+  _streamOfController,
+  _wrapJsFunctionForAsync,
+  computeSignature,
+  def:<anonymous>,
+  getRuntimeTypeArguments,
+  getRuntimeTypeInfo,
+  setRuntimeTypeInfo],
+ type=[
+  inst:Function,
+  inst:JSArray<dynamic>,
+  inst:JSExtendableArray<dynamic>,
+  inst:JSFixedArray<dynamic>,
+  inst:JSMutableArray<dynamic>,
+  inst:JSUnmodifiableArray<dynamic>]
+*/
+testAnonymousAsyncStar() {
+  return () async* {};
+}
+
+/*kernel.element: testAsyncForIn:
+ dynamic=[
+  cancel(0),
+  current,
+  moveNext(0)],
+ static=[
+  StreamIterator.,
+  _asyncAwait,
+  _asyncRethrow,
+  _asyncReturn,
+  _asyncStartSync,
+  _makeAsyncAwaitCompleter<dynamic>(0),
+  _wrapJsFunctionForAsync],
+ type=[
+  inst:JSNull,
+  inst:Null]
+*/
+/*strong.element: testAsyncForIn:
+ dynamic=[
+  cancel(0),
+  current,
+  moveNext(0)],
+ static=[
+  StreamIterator.,
+  _asyncAwait,
+  _asyncRethrow,
+  _asyncReturn,
+  _asyncStartSync,
+  _makeAsyncAwaitCompleter<dynamic>(0),
+  _wrapJsFunctionForAsync],
+ type=[
+  impl:Stream<dynamic>,
+  inst:JSBool,
+  inst:JSNull,
+  inst:Null]
+*/
+testAsyncForIn(o) async {
+  // ignore: UNUSED_LOCAL_VARIABLE
+  await for (var e in o) {}
+}
+
+/*kernel.element: testAsyncForInTyped:
+ dynamic=[
+  cancel(0),
+  current,
+  moveNext(0)],
+ static=[
+  StreamIterator.,
+  _asyncAwait,
+  _asyncRethrow,
+  _asyncReturn,
+  _asyncStartSync,
+  _makeAsyncAwaitCompleter<dynamic>(0),
+  _wrapJsFunctionForAsync],
+ type=[
+  check:int,
+  inst:JSNull,
+  inst:Null]
+*/
+/*strong.element: testAsyncForInTyped:
+ dynamic=[
+  cancel(0),
+  current,
+  moveNext(0)],
+ static=[
+  StreamIterator.,
+  _asyncAwait,
+  _asyncRethrow,
+  _asyncReturn,
+  _asyncStartSync,
+  _makeAsyncAwaitCompleter<dynamic>(0),
+  _wrapJsFunctionForAsync],
+ type=[
+  impl:Stream<dynamic>,
+  impl:int,
+  inst:JSBool,
+  inst:JSNull,
+  inst:Null]
+*/
+testAsyncForInTyped(o) async {
+  // ignore: UNUSED_LOCAL_VARIABLE
+  await for (int e in o) {}
+}
diff --git a/tests/compiler/dart2js/impact/data/classes.dart b/tests/compiler/dart2js/impact/data/classes.dart
new file mode 100644
index 0000000..6b3c008
--- /dev/null
+++ b/tests/compiler/dart2js/impact/data/classes.dart
@@ -0,0 +1,390 @@
+// 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.
+
+/*element: main:
+ static=[
+  testAbstractClassWithField(0),
+  testEnum(0),
+  testForwardingConstructor(0),
+  testForwardingConstructorGeneric(0),
+  testForwardingConstructorTyped(0),
+  testGenericMixinInstantiation(0),
+  testGenericNamedMixinInstantiation(0),
+  testInstanceGenericMethod(0),
+  testMixinInstantiation(0),
+  testNamedMixinInstantiation(0),
+  testStaticGenericMethod(0),
+  testSuperCall(0),
+  testSuperClosurization(0),
+  testSuperFieldSet(0),
+  testSuperGet(0),
+  testSuperSetterSet(0)]
+*/
+main() {
+  testSuperCall();
+  testSuperGet();
+  testSuperFieldSet();
+  testSuperSetterSet();
+  testSuperClosurization();
+  testForwardingConstructor();
+  testForwardingConstructorTyped();
+  testForwardingConstructorGeneric();
+  testEnum();
+  testStaticGenericMethod();
+  testInstanceGenericMethod();
+  testAbstractClassWithField();
+  testMixinInstantiation();
+  testNamedMixinInstantiation();
+  testGenericMixinInstantiation();
+  testGenericNamedMixinInstantiation();
+}
+
+/*element: Super1.:static=[Object.(0)]*/
+class Super1 {
+  /*element: Super1.foo:*/
+  foo() {}
+}
+
+class Sub1 extends Super1 {
+  /*element: Sub1.:static=[Super1.(0),Super1.foo(0)]*/
+  Sub1() {
+    super.foo();
+  }
+}
+
+/*element: testSuperCall:static=[Sub1.(0)]*/
+testSuperCall() => new Sub1();
+
+/*element: Super2.:static=[Object.(0)]*/
+class Super2 {
+  /*element: Super2.foo:type=[inst:JSNull]*/
+  var foo;
+}
+
+class Sub2 extends Super2 {
+  /*element: Sub2.:static=[Super2.(0),Super2.foo]*/
+  Sub2() {
+    super.foo;
+  }
+}
+
+/*element: testSuperGet:static=[Sub2.(0)]*/
+testSuperGet() => new Sub2();
+
+/*element: Super3.:static=[Object.(0)]*/
+class Super3 {
+  /*element: Super3.foo:type=[inst:JSNull]*/
+  var foo;
+}
+
+class Sub3 extends Super3 {
+  /*element: Sub3.:static=[Super3.(0),set:Super3.foo],type=[inst:JSBool]*/
+  Sub3() {
+    super.foo = true;
+  }
+}
+
+/*element: testSuperFieldSet:static=[Sub3.(0)]*/
+testSuperFieldSet() => new Sub3();
+
+/*element: Super4.:static=[Object.(0)]*/
+class Super4 {
+  /*element: Super4.foo=:*/
+  set foo(_) {}
+}
+
+class Sub4 extends Super4 {
+  /*element: Sub4.:static=[Super4.(0),set:Super4.foo],type=[inst:JSBool]*/
+  Sub4() {
+    super.foo = true;
+  }
+}
+
+/*element: testSuperSetterSet:static=[Sub4.(0)]*/
+testSuperSetterSet() => new Sub4();
+
+/*element: Super5.:static=[Object.(0)]*/
+class Super5 {
+  /*element: Super5.foo:*/
+  foo() {}
+}
+
+/*element: Sub5.:static=[Super5.(0),Super5.foo]*/
+class Sub5 extends Super5 {
+  Sub5() {
+    super.foo;
+  }
+}
+
+/*element: testSuperClosurization:static=[Sub5.(0)]*/
+testSuperClosurization() => new Sub5();
+
+class EmptyMixin {}
+
+class ForwardingConstructorSuperClass {
+  /*element: ForwardingConstructorSuperClass.:static=[Object.(0)]*/
+  ForwardingConstructorSuperClass(arg);
+}
+
+class ForwardingConstructorClass = ForwardingConstructorSuperClass
+    with EmptyMixin;
+
+/*element: testForwardingConstructor:
+ static=[ForwardingConstructorClass.(1)],
+ type=[inst:JSNull]
+*/
+testForwardingConstructor() => new ForwardingConstructorClass(null);
+
+class ForwardingConstructorTypedSuperClass {
+  /*kernel.element: ForwardingConstructorTypedSuperClass.:
+   static=[Object.(0)],
+   type=[check:int]
+  */
+  /*strong.element: ForwardingConstructorTypedSuperClass.:
+   static=[Object.(0)],
+   type=[inst:JSBool,param:int]
+  */
+  ForwardingConstructorTypedSuperClass(int arg);
+}
+
+class ForwardingConstructorTypedClass = ForwardingConstructorTypedSuperClass
+    with EmptyMixin;
+
+/*element: testForwardingConstructorTyped:
+ static=[ForwardingConstructorTypedClass.(1)],
+ type=[inst:JSNull]
+*/
+testForwardingConstructorTyped() => new ForwardingConstructorTypedClass(null);
+
+class ForwardingConstructorGenericSuperClass<T> {
+  /*kernel.element: ForwardingConstructorGenericSuperClass.:
+   static=[Object.(0)],
+   type=[check:ForwardingConstructorGenericSuperClass.T]
+  */
+  /*strong.element: ForwardingConstructorGenericSuperClass.:
+   static=[
+    Object.(0),
+    checkSubtype,
+    checkSubtypeOfRuntimeType,
+    getRuntimeTypeArgument,
+    getRuntimeTypeArgumentIntercepted,
+    getRuntimeTypeInfo,
+    getTypeArgumentByIndex,
+    setRuntimeTypeInfo],
+   type=[
+    inst:JSArray<dynamic>,
+    inst:JSBool,
+    inst:JSExtendableArray<dynamic>,
+    inst:JSFixedArray<dynamic>,
+    inst:JSMutableArray<dynamic>,
+    inst:JSUnmodifiableArray<dynamic>,
+    param:ForwardingConstructorGenericSuperClass.T]
+  */
+  ForwardingConstructorGenericSuperClass(T arg);
+}
+
+class ForwardingConstructorGenericClass<
+    S> = ForwardingConstructorGenericSuperClass<S> with EmptyMixin;
+
+/*element: testForwardingConstructorGeneric:
+ static=[
+  ForwardingConstructorGenericClass.(1),
+  assertIsSubtype,
+  throwTypeError],
+ type=[inst:JSNull]
+*/
+testForwardingConstructorGeneric() {
+  new ForwardingConstructorGenericClass<int>(null);
+}
+
+enum Enum {
+  /*kernel.element: Enum.A:static=[Enum.(2)],
+   type=[
+    check:Enum,
+    inst:JSDouble,
+    inst:JSInt,
+    inst:JSNumber,
+    inst:JSPositiveInt,
+    inst:JSString,
+    inst:JSUInt31,
+    inst:JSUInt32]
+  */
+  /*strong.element: Enum.A:static=[Enum.(2)],
+   type=[
+    inst:JSBool,
+    inst:JSDouble,
+    inst:JSInt,
+    inst:JSNumber,
+    inst:JSPositiveInt,
+    inst:JSString,
+    inst:JSUInt31,
+    inst:JSUInt32,
+    param:Enum]
+  */
+  A
+}
+
+/*element: testEnum:static=[Enum.A]*/
+testEnum() => Enum.A;
+
+/*kernel.element: staticGenericMethod:
+ type=[
+  check:List<staticGenericMethod.T>,
+  check:staticGenericMethod.T,
+  inst:List<dynamic>]
+ */
+/*strong.element: staticGenericMethod:
+ static=[
+  checkSubtype,
+  checkSubtypeOfRuntimeType,
+  getRuntimeTypeArgument,
+  getRuntimeTypeArgumentIntercepted,
+  getRuntimeTypeInfo,
+  getTypeArgumentByIndex,
+  setRuntimeTypeInfo],
+ type=[
+  inst:JSArray<dynamic>,
+  inst:JSBool,
+  inst:JSExtendableArray<dynamic>,
+  inst:JSFixedArray<dynamic>,
+  inst:JSMutableArray<dynamic>,
+  inst:JSUnmodifiableArray<dynamic>,
+  inst:List<staticGenericMethod.T>,
+  param:Object,
+  param:staticGenericMethod.T]
+*/
+List<T> staticGenericMethod<T>(T arg) => [arg];
+
+/*kernel.element: testStaticGenericMethod:
+  static=[staticGenericMethod(1)],
+  type=[inst:JSBool]
+*/
+/*strong.element: testStaticGenericMethod:
+  static=[staticGenericMethod<bool>(1)],
+  type=[inst:JSBool]
+*/
+testStaticGenericMethod() {
+  staticGenericMethod<bool>(true);
+}
+
+/*kernel.element: testInstanceGenericMethod:
+ dynamic=[genericMethod(1)],
+ static=[
+  GenericClass.generative(0),
+  assertIsSubtype,
+  throwTypeError],
+ type=[inst:JSBool]
+*/
+/*strong.element: testInstanceGenericMethod:
+ dynamic=[genericMethod<bool>(1)],
+ static=[
+  GenericClass.generative(0),
+  assertIsSubtype,
+  throwTypeError],
+ type=[inst:JSBool]
+*/
+testInstanceGenericMethod() {
+  new GenericClass<int, String>.generative().genericMethod<bool>(false);
+}
+
+abstract class AbstractClass {
+  // ignore: UNUSED_FIELD
+  final _field;
+
+  /*kernel.element: AbstractClass.:type=[check:AbstractClass,inst:JSNull]*/
+  /*strong.element: AbstractClass.:type=[inst:JSNull]*/
+  factory AbstractClass() => null;
+}
+
+/*element: testAbstractClassWithField:static=[AbstractClass.(0)]*/
+testAbstractClassWithField() => new AbstractClass();
+
+/*element: testMixinInstantiation:static=[Sub.(0)]*/
+testMixinInstantiation() => new Sub();
+
+/*element: testNamedMixinInstantiation:static=[NamedMixin.(0)]*/
+testNamedMixinInstantiation() => new NamedMixin();
+
+/*element: testGenericMixinInstantiation:
+ static=[
+  GenericSub.(0),
+  assertIsSubtype,
+  throwTypeError]
+*/
+testGenericMixinInstantiation() => new GenericSub<int, String>();
+
+/*element: testGenericNamedMixinInstantiation:
+ static=[
+  GenericNamedMixin.(0),
+  assertIsSubtype,
+  throwTypeError]
+*/
+testGenericNamedMixinInstantiation() => new GenericNamedMixin<int, String>();
+
+class Class {
+  /*element: GenericClass.generative:static=[Object.(0)]*/
+  const Class.generative();
+}
+
+class GenericClass<X, Y> {
+  const GenericClass.generative();
+
+  /*kernel.element: GenericClass.genericMethod:
+   type=[
+    check:Map<GenericClass.X,genericMethod.T>,
+    check:genericMethod.T,
+    inst:JSNull,
+    inst:Map<dynamic,dynamic>]
+  */
+  /*strong.element: GenericClass.genericMethod:
+   static=[
+    checkSubtype,
+    checkSubtypeOfRuntimeType,
+    getRuntimeTypeArgument,
+    getRuntimeTypeArgumentIntercepted,
+    getRuntimeTypeInfo,
+    getTypeArgumentByIndex,
+    setRuntimeTypeInfo],
+   type=[
+    inst:JSArray<dynamic>,
+    inst:JSBool,
+    inst:JSExtendableArray<dynamic>,
+    inst:JSFixedArray<dynamic>,
+    inst:JSMutableArray<dynamic>,
+    inst:JSNull,
+    inst:JSUnmodifiableArray<dynamic>,
+    inst:Map<GenericClass.X,genericMethod.T>,
+    param:Object,
+    param:genericMethod.T]
+   */
+  Map<X, T> genericMethod<T>(T arg) => {null: arg};
+}
+
+/*element: Super.:static=[Object.(0)]*/
+class Super {}
+
+class Mixin1 {}
+
+class Mixin2 {}
+
+/*element: Sub.:static=[_Sub&Super&Mixin1&Mixin2.(0)]*/
+class Sub extends Super with Mixin1, Mixin2 {}
+
+class NamedMixin = Super with Mixin1, Mixin2;
+
+/*element: GenericSuper.:static=[Object.(0)]*/
+class GenericSuper<X1, Y1> {}
+
+class GenericMixin1<X2, Y2> {}
+
+class GenericMixin2<X3, Y3> {}
+
+/*element: GenericSub.:
+  static=[_GenericSub&GenericSuper&GenericMixin1&GenericMixin2.(0)]
+*/
+class GenericSub<X4, Y4> extends GenericSuper<X4, Y4>
+    with GenericMixin1<X4, Y4>, GenericMixin2<X4, Y4> {}
+
+class GenericNamedMixin<X5, Y5> = GenericSuper<X5, Y5>
+    with GenericMixin1<X5, Y5>, GenericMixin2<X5, Y5>;
diff --git a/tests/compiler/dart2js/impact/data/constructors.dart b/tests/compiler/dart2js/impact/data/constructors.dart
new file mode 100644
index 0000000..440aded
--- /dev/null
+++ b/tests/compiler/dart2js/impact/data/constructors.dart
@@ -0,0 +1,162 @@
+// 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.
+
+/*element: main:
+ static=[
+  testConstRedirectingFactoryInvoke(0),
+  testConstRedirectingFactoryInvokeGeneric(0),
+  testConstRedirectingFactoryInvokeGenericDynamic(0),
+  testConstRedirectingFactoryInvokeGenericRaw(0),
+  testConstructorInvoke(0),
+  testConstructorInvokeGeneric(0),
+  testConstructorInvokeGenericDynamic(0),
+  testConstructorInvokeGenericRaw(0),
+  testFactoryConstructor(0),
+  testFactoryInvoke(0),
+  testFactoryInvokeGeneric(0),
+  testFactoryInvokeGenericDynamic(0),
+  testFactoryInvokeGenericRaw(0),
+  testImplicitConstructor(0),
+  testRedirectingFactoryInvoke(0),
+  testRedirectingFactoryInvokeGeneric(0),
+  testRedirectingFactoryInvokeGenericDynamic(0),
+  testRedirectingFactoryInvokeGenericRaw(0)]
+*/
+main() {
+  testConstructorInvoke();
+  testConstructorInvokeGeneric();
+  testConstructorInvokeGenericRaw();
+  testConstructorInvokeGenericDynamic();
+  testFactoryInvoke();
+  testFactoryInvokeGeneric();
+  testFactoryInvokeGenericRaw();
+  testFactoryInvokeGenericDynamic();
+  testRedirectingFactoryInvoke();
+  testRedirectingFactoryInvokeGeneric();
+  testRedirectingFactoryInvokeGenericRaw();
+  testRedirectingFactoryInvokeGenericDynamic();
+  testConstRedirectingFactoryInvoke();
+  testConstRedirectingFactoryInvokeGeneric();
+  testConstRedirectingFactoryInvokeGenericRaw();
+  testConstRedirectingFactoryInvokeGenericDynamic();
+  testImplicitConstructor();
+  testFactoryConstructor();
+}
+
+/*element: testConstructorInvoke:static=[Class.generative(0)]*/
+testConstructorInvoke() {
+  new Class.generative();
+}
+
+/*element: testConstructorInvokeGeneric:static=[GenericClass.generative(0),assertIsSubtype,throwTypeError]*/
+testConstructorInvokeGeneric() {
+  new GenericClass<int, String>.generative();
+}
+
+/*element: testConstructorInvokeGenericRaw:static=[GenericClass.generative(0)]*/
+testConstructorInvokeGenericRaw() {
+  new GenericClass.generative();
+}
+
+/*element: testConstructorInvokeGenericDynamic:static=[GenericClass.generative(0)]*/
+testConstructorInvokeGenericDynamic() {
+  new GenericClass<dynamic, dynamic>.generative();
+}
+
+/*element: testFactoryInvoke:static=[Class.fact(0)]*/
+testFactoryInvoke() {
+  new Class.fact();
+}
+
+/*element: testFactoryInvokeGeneric:static=[GenericClass.fact(0),assertIsSubtype,throwTypeError]*/
+testFactoryInvokeGeneric() {
+  new GenericClass<int, String>.fact();
+}
+
+/*element: testFactoryInvokeGenericRaw:static=[GenericClass.fact(0)]*/
+testFactoryInvokeGenericRaw() {
+  new GenericClass.fact();
+}
+
+/*element: testFactoryInvokeGenericDynamic:static=[GenericClass.fact(0)]*/
+testFactoryInvokeGenericDynamic() {
+  new GenericClass<dynamic, dynamic>.fact();
+}
+
+/*element: testRedirectingFactoryInvoke:static=[Class.generative(0)]*/
+testRedirectingFactoryInvoke() {
+  new Class.redirect();
+}
+
+/*element: testRedirectingFactoryInvokeGeneric:static=[GenericClass.generative(0),assertIsSubtype,throwTypeError]*/
+testRedirectingFactoryInvokeGeneric() {
+  new GenericClass<int, String>.redirect();
+}
+
+/*element: testRedirectingFactoryInvokeGenericRaw:static=[GenericClass.generative(0)]*/
+testRedirectingFactoryInvokeGenericRaw() {
+  new GenericClass.redirect();
+}
+
+/*element: testRedirectingFactoryInvokeGenericDynamic:static=[GenericClass.generative(0)]*/
+testRedirectingFactoryInvokeGenericDynamic() {
+  new GenericClass<dynamic, dynamic>.redirect();
+}
+
+/*element: testConstRedirectingFactoryInvoke:static=[Class.generative(0)]*/
+testConstRedirectingFactoryInvoke() {
+  const Class.redirect();
+}
+
+/*element: testConstRedirectingFactoryInvokeGeneric:static=[GenericClass.generative(0),assertIsSubtype,throwTypeError]*/
+testConstRedirectingFactoryInvokeGeneric() {
+  const GenericClass<int, String>.redirect();
+}
+
+/*element: testConstRedirectingFactoryInvokeGenericRaw:static=[GenericClass.generative(0)]*/
+testConstRedirectingFactoryInvokeGenericRaw() {
+  const GenericClass.redirect();
+}
+
+/*element: testConstRedirectingFactoryInvokeGenericDynamic:static=[GenericClass.generative(0)]*/
+testConstRedirectingFactoryInvokeGenericDynamic() {
+  const GenericClass<dynamic, dynamic>.redirect();
+}
+
+/*element: ClassImplicitConstructor.:static=[Object.(0)]*/
+class ClassImplicitConstructor {}
+
+/*element: testImplicitConstructor:static=[ClassImplicitConstructor.(0)]*/
+testImplicitConstructor() => new ClassImplicitConstructor();
+
+class ClassFactoryConstructor {
+  /*kernel.element: ClassFactoryConstructor.:type=[check:ClassFactoryConstructor,inst:JSNull]*/
+  /*strong.element: ClassFactoryConstructor.:type=[inst:JSNull]*/
+  factory ClassFactoryConstructor() => null;
+}
+
+/*element: testFactoryConstructor:static=[ClassFactoryConstructor.(0)]*/
+testFactoryConstructor() => new ClassFactoryConstructor();
+
+class Class {
+  /*element: Class.generative:static=[Object.(0)]*/
+  const Class.generative();
+
+  /*kernel.element: Class.fact:type=[check:Class,inst:JSNull]*/
+  /*strong.element: Class.fact:type=[inst:JSNull]*/
+  factory Class.fact() => null;
+
+  const factory Class.redirect() = Class.generative;
+}
+
+class GenericClass<X, Y> {
+  /*element: GenericClass.generative:static=[Object.(0)]*/
+  const GenericClass.generative();
+
+  /*kernel.element: GenericClass.fact:type=[check:GenericClass<GenericClass.X,GenericClass.Y>,inst:JSNull]*/
+  /*strong.element: GenericClass.fact:type=[inst:JSBool,inst:JSNull,param:Object]*/
+  factory GenericClass.fact() => null;
+
+  const factory GenericClass.redirect() = GenericClass<X, Y>.generative;
+}
diff --git a/tests/compiler/dart2js/impact/data/expressions.dart b/tests/compiler/dart2js/impact/data/expressions.dart
new file mode 100644
index 0000000..ed4ea6d
--- /dev/null
+++ b/tests/compiler/dart2js/impact/data/expressions.dart
@@ -0,0 +1,331 @@
+// 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.
+
+/*element: main:static=[
+  testAs(0),
+  testAsGeneric(0),
+  testAsGenericDynamic(0),
+  testAsGenericRaw(0),
+  testConditional(0),
+  testIfNotNull(1),
+  testIfNotNullSet(1),
+  testIfNull(1),
+  testIs(0),
+  testIsGeneric(0),
+  testIsGenericDynamic(0),
+  testIsGenericRaw(0),
+  testIsNot(0),
+  testIsNotGeneric(0),
+  testIsNotGenericDynamic(0),
+  testIsNotGenericRaw(0),
+  testIsTypedef(0),
+  testIsTypedefDeep(0),
+  testIsTypedefGeneric(0),
+  testIsTypedefGenericDynamic(0),
+  testIsTypedefGenericRaw(0),
+  testNot(0),
+  testPostDec(1),
+  testPostInc(1),
+  testPreDec(1),
+  testPreInc(1),
+  testSetIfNull(1),
+  testThrow(0),
+  testUnaryMinus(0)
+],type=[inst:JSNull]
+ */
+main() {
+  testNot();
+  testUnaryMinus();
+  testConditional();
+  testPostInc(null);
+  testPostDec(null);
+  testPreInc(null);
+  testPreDec(null);
+  testIs();
+  testIsGeneric();
+  testIsGenericRaw();
+  testIsGenericDynamic();
+  testIsNot();
+  testIsNotGeneric();
+  testIsNotGenericRaw();
+  testIsNotGenericDynamic();
+  testIsTypedef();
+  testIsTypedefGeneric();
+  testIsTypedefGenericRaw();
+  testIsTypedefGenericDynamic();
+  testIsTypedefDeep();
+  testAs();
+  testAsGeneric();
+  testAsGenericRaw();
+  testAsGenericDynamic();
+  testThrow();
+  testIfNotNull(null);
+  testIfNotNullSet(null);
+  testIfNull(null);
+  testSetIfNull(null);
+}
+
+/*element: testNot:type=[inst:JSBool]*/
+testNot() => !false;
+
+/*element: testUnaryMinus:
+ dynamic=[unary-],
+ type=[inst:JSDouble,inst:JSInt,inst:JSNumber,inst:JSPositiveInt,inst:JSUInt31,inst:JSUInt32]
+*/
+testUnaryMinus() => -1;
+
+/*element: testConditional:type=[inst:JSBool,inst:JSNull,inst:JSString]*/
+// ignore: DEAD_CODE
+testConditional() => true ? null : '';
+
+/*element: testPostInc:
+ dynamic=[+],
+ type=[inst:JSDouble,inst:JSInt,inst:JSNumber,inst:JSPositiveInt,inst:JSUInt31,inst:JSUInt32]
+*/
+testPostInc(o) => o++;
+
+/*element: testPostDec:
+ dynamic=[-],
+ type=[inst:JSDouble,inst:JSInt,inst:JSNumber,inst:JSPositiveInt,inst:JSUInt31,inst:JSUInt32]
+*/
+testPostDec(o) => o--;
+
+/*element: testPreInc:
+ dynamic=[+],
+ type=[inst:JSDouble,inst:JSInt,inst:JSNumber,inst:JSPositiveInt,inst:JSUInt31,inst:JSUInt32]
+*/
+testPreInc(o) => ++o;
+
+/*element: testPreDec:
+ dynamic=[-],
+ type=[inst:JSDouble,inst:JSInt,inst:JSNumber,inst:JSPositiveInt,inst:JSUInt31,inst:JSUInt32]
+*/
+testPreDec(o) => --o;
+
+/*element: testIs:type=[inst:JSBool,inst:JSNull,is:Class]*/
+testIs() => null is Class;
+
+/*element: testIsGeneric:
+ static=[
+  checkSubtype,
+  getRuntimeTypeArgument,
+  getRuntimeTypeArgumentIntercepted,
+  getRuntimeTypeInfo,
+  getTypeArgumentByIndex,
+  setRuntimeTypeInfo],
+ type=[
+  inst:JSArray<dynamic>,
+  inst:JSBool,
+  inst:JSExtendableArray<dynamic>,
+  inst:JSFixedArray<dynamic>,
+  inst:JSMutableArray<dynamic>,
+  inst:JSNull,
+  inst:JSUnmodifiableArray<dynamic>,
+  is:GenericClass<int,String>]
+ */
+testIsGeneric() => null is GenericClass<int, String>;
+
+/*element: testIsGenericRaw:
+ type=[inst:JSBool,inst:JSNull,is:GenericClass<dynamic,dynamic>]
+*/
+testIsGenericRaw() => null is GenericClass;
+
+/*element: testIsGenericDynamic:
+ type=[inst:JSBool,inst:JSNull,is:GenericClass<dynamic,dynamic>]
+*/
+testIsGenericDynamic() => null is GenericClass<dynamic, dynamic>;
+
+/*element: testIsNot:type=[inst:JSBool,inst:JSNull,is:Class]*/
+testIsNot() => null is! Class;
+
+/*element: testIsNotGeneric:
+ static=[
+  checkSubtype,
+  getRuntimeTypeArgument,
+  getRuntimeTypeArgumentIntercepted,
+  getRuntimeTypeInfo,
+  getTypeArgumentByIndex,
+  setRuntimeTypeInfo],
+ type=[
+  inst:JSArray<dynamic>,
+  inst:JSBool,
+  inst:JSExtendableArray<dynamic>,
+  inst:JSFixedArray<dynamic>,
+  inst:JSMutableArray<dynamic>,
+  inst:JSNull,
+  inst:JSUnmodifiableArray<dynamic>,
+  is:GenericClass<int,String>]
+*/
+testIsNotGeneric() => null is! GenericClass<int, String>;
+
+/*element: testIsNotGenericRaw:
+ type=[inst:JSBool,inst:JSNull,is:GenericClass<dynamic,dynamic>]
+*/
+testIsNotGenericRaw() => null is! GenericClass;
+
+/*element: testIsNotGenericDynamic:
+ type=[inst:JSBool,inst:JSNull,is:GenericClass<dynamic,dynamic>]
+*/
+testIsNotGenericDynamic() => null is! GenericClass<dynamic, dynamic>;
+
+/*element: testIsTypedef:
+ static=[
+  checkSubtype,
+  getRuntimeTypeArgument,
+  getRuntimeTypeArgumentIntercepted,
+  getRuntimeTypeInfo,
+  getTypeArgumentByIndex,
+  setRuntimeTypeInfo],
+ type=[
+  inst:JSArray<dynamic>,
+  inst:JSBool,
+  inst:JSExtendableArray<dynamic>,
+  inst:JSFixedArray<dynamic>,
+  inst:JSMutableArray<dynamic>,
+  inst:JSNull,
+  inst:JSUnmodifiableArray<dynamic>,
+  is:dynamic Function()]
+*/
+testIsTypedef() => null is Typedef;
+
+/*element: testIsTypedefGeneric:
+ static=[
+ checkSubtype,
+  getRuntimeTypeArgument,
+  getRuntimeTypeArgumentIntercepted,
+  getRuntimeTypeInfo,
+  getTypeArgumentByIndex,
+  setRuntimeTypeInfo],
+ type=[
+  inst:JSArray<dynamic>,
+  inst:JSBool,
+  inst:JSExtendableArray<dynamic>,
+  inst:JSFixedArray<dynamic>,
+  inst:JSMutableArray<dynamic>,
+  inst:JSNull,
+  inst:JSUnmodifiableArray<dynamic>,
+  is:int Function(String)]*/
+testIsTypedefGeneric() => null is GenericTypedef<int, String>;
+
+/*element: testIsTypedefGenericRaw:
+ static=[
+  checkSubtype,
+  getRuntimeTypeArgument,
+  getRuntimeTypeArgumentIntercepted,
+  getRuntimeTypeInfo,
+  getTypeArgumentByIndex,
+  setRuntimeTypeInfo],
+ type=[
+  inst:JSArray<dynamic>,
+  inst:JSBool,
+  inst:JSExtendableArray<dynamic>,
+  inst:JSFixedArray<dynamic>,
+  inst:JSMutableArray<dynamic>,
+  inst:JSNull,
+  inst:JSUnmodifiableArray<dynamic>,
+  is:dynamic Function(dynamic)]*/
+testIsTypedefGenericRaw() => null is GenericTypedef;
+
+/*element: testIsTypedefGenericDynamic:
+ static=[
+  checkSubtype,
+  getRuntimeTypeArgument,
+  getRuntimeTypeArgumentIntercepted,
+  getRuntimeTypeInfo,
+  getTypeArgumentByIndex,
+  setRuntimeTypeInfo],
+ type=[
+  inst:JSArray<dynamic>,
+  inst:JSBool,
+  inst:JSExtendableArray<dynamic>,
+  inst:JSFixedArray<dynamic>,
+  inst:JSMutableArray<dynamic>,
+  inst:JSNull,
+  inst:JSUnmodifiableArray<dynamic>,
+  is:dynamic Function(dynamic)]*/
+testIsTypedefGenericDynamic() => null is GenericTypedef<dynamic, dynamic>;
+
+/*element: testIsTypedefDeep:
+ static=[
+  checkSubtype,
+  getRuntimeTypeArgument,
+  getRuntimeTypeArgumentIntercepted,
+  getRuntimeTypeInfo,
+  getTypeArgumentByIndex,
+  setRuntimeTypeInfo],
+ type=[
+  inst:JSArray<dynamic>,
+  inst:JSBool,
+  inst:JSExtendableArray<dynamic>,
+  inst:JSFixedArray<dynamic>,
+  inst:JSMutableArray<dynamic>,
+  inst:JSNull,
+  inst:JSUnmodifiableArray<dynamic>,
+  is:List<int Function(dynamic Function(dynamic))>]*/
+testIsTypedefDeep() => null is List<GenericTypedef<int, GenericTypedef>>;
+
+/*element: testAs:
+ static=[throwRuntimeError],
+ type=[as:Class,inst:JSBool,inst:JSNull]
+*/
+// ignore: UNNECESSARY_CAST
+testAs() => null as Class;
+
+/*element: testAsGeneric:static=[checkSubtype,
+  getRuntimeTypeArgument,
+  getRuntimeTypeArgumentIntercepted,
+  getRuntimeTypeInfo,
+  getTypeArgumentByIndex,
+  setRuntimeTypeInfo,
+  throwRuntimeError],
+  type=[as:GenericClass<int,
+  String>,
+  inst:JSArray<dynamic>,
+  inst:JSBool,
+  inst:JSExtendableArray<dynamic>,
+  inst:JSFixedArray<dynamic>,
+  inst:JSMutableArray<dynamic>,
+  inst:JSNull,
+  inst:JSUnmodifiableArray<dynamic>]*/
+// ignore: UNNECESSARY_CAST
+testAsGeneric() => null as GenericClass<int, String>;
+
+/*element: testAsGenericRaw:
+ static=[throwRuntimeError],
+ type=[as:GenericClass<dynamic,dynamic>,inst:JSBool,inst:JSNull]
+*/
+// ignore: UNNECESSARY_CAST
+testAsGenericRaw() => null as GenericClass;
+
+/*element: testAsGenericDynamic:
+ static=[throwRuntimeError],
+ type=[as:GenericClass<dynamic,dynamic>,inst:JSBool,inst:JSNull]
+*/
+// ignore: UNNECESSARY_CAST
+testAsGenericDynamic() => null as GenericClass<dynamic, dynamic>;
+
+/*element: testThrow:
+ static=[throwExpression,wrapException],
+ type=[inst:JSString]*/
+testThrow() => throw '';
+
+/*element: testIfNotNull:dynamic=[==,foo],type=[inst:JSNull]*/
+testIfNotNull(o) => o?.foo;
+
+/*element: testIfNotNullSet:dynamic=[==,foo=],type=[inst:JSBool,inst:JSNull]*/
+testIfNotNullSet(o) => o?.foo = true;
+
+/*element: testIfNull:dynamic=[==],type=[inst:JSBool,inst:JSNull]*/
+testIfNull(o) => o ?? true;
+
+/*element: testSetIfNull:dynamic=[==],type=[inst:JSBool,inst:JSNull]*/
+testSetIfNull(o) => o ??= true;
+
+class Class {}
+
+class GenericClass<X, Y> {}
+
+typedef Typedef();
+
+typedef X GenericTypedef<X, Y>(Y y);
diff --git a/tests/compiler/dart2js/impact/data/extract_type_arguments_strong.dart b/tests/compiler/dart2js/impact/data/extract_type_arguments_strong.dart
new file mode 100644
index 0000000..defa672
--- /dev/null
+++ b/tests/compiler/dart2js/impact/data/extract_type_arguments_strong.dart
@@ -0,0 +1,65 @@
+// 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.
+
+/// ignore: IMPORT_INTERNAL_LIBRARY
+import 'dart:_internal';
+
+class A<T> {}
+
+class B<S, U> {}
+
+/*element: C.:static=[Object.(0)]*/
+class C implements A<int>, B<String, bool> {}
+
+/*element: testA:
+ dynamic=[call<A.T>(0)],
+ static=[
+  checkSubtype,
+  extractTypeArguments<A<dynamic>>(2),
+  getRuntimeTypeArgument,
+  getRuntimeTypeArgumentIntercepted,
+  getRuntimeTypeInfo,
+  getTypeArgumentByIndex,
+  setRuntimeTypeInfo],
+ type=[
+  impl:A<dynamic>,
+  impl:Function,
+  inst:JSArray<dynamic>,
+  inst:JSBool,
+  inst:JSExtendableArray<dynamic>,
+  inst:JSFixedArray<dynamic>,
+  inst:JSMutableArray<dynamic>,
+  inst:JSUnmodifiableArray<dynamic>,is:A<A.T>]
+*/
+testA(c, f) => extractTypeArguments<A>(c, f);
+
+/*element: testB:
+ dynamic=[call<B.S,B.U>(0)],
+ static=[
+  checkSubtype,
+  extractTypeArguments<B<dynamic,dynamic>>(2),
+  getRuntimeTypeArgument,
+  getRuntimeTypeArgumentIntercepted,
+  getRuntimeTypeInfo,
+  getTypeArgumentByIndex,
+  setRuntimeTypeInfo],
+ type=[
+  impl:B<dynamic,dynamic>,
+  impl:Function,
+  inst:JSArray<dynamic>,
+  inst:JSBool,
+  inst:JSExtendableArray<dynamic>,
+  inst:JSFixedArray<dynamic>,
+  inst:JSMutableArray<dynamic>,
+  inst:JSUnmodifiableArray<dynamic>,
+  is:B<B.S,B.U>]
+*/
+testB(c, f) => extractTypeArguments<B>(c, f);
+
+/*element: main:static=[C.(0),testA(2),testB(2)],type=[inst:JSNull]*/
+main() {
+  var c = new C();
+  testA(c, null);
+  testB(c, null);
+}
diff --git a/tests/compiler/dart2js/impact/data/fallthrough.dart b/tests/compiler/dart2js/impact/data/fallthrough.dart
new file mode 100644
index 0000000..a49177a
--- /dev/null
+++ b/tests/compiler/dart2js/impact/data/fallthrough.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.
+
+/*element: main:
+ static=[testSwitchWithFallthrough(1)],
+ type=[inst:JSNull]
+*/
+main() {
+  testSwitchWithFallthrough(null);
+}
+
+/*element: testSwitchWithFallthrough:
+ static=[
+  FallThroughError._create(2),
+  throwExpression,
+  wrapException],
+ type=[inst:JSDouble,
+  inst:JSInt,
+  inst:JSNumber,
+  inst:JSPositiveInt,
+  inst:JSString,
+  inst:JSUInt31,
+  inst:JSUInt32]
+*/
+testSwitchWithFallthrough(o) {
+  switch (o) {
+    case 0:
+    // ignore: CASE_BLOCK_NOT_TERMINATED
+    case 1:
+      o = 2;
+    case 2:
+      o = 3;
+      return;
+    case 3:
+    default:
+  }
+}
diff --git a/tests/compiler/dart2js/impact/data/initializers.dart b/tests/compiler/dart2js/impact/data/initializers.dart
new file mode 100644
index 0000000..a262272
--- /dev/null
+++ b/tests/compiler/dart2js/impact/data/initializers.dart
@@ -0,0 +1,151 @@
+// 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.
+
+/*element: main:
+ static=[
+  testDefaultValuesNamed(0),
+  testDefaultValuesPositional(0),
+  testFieldInitializer1(0),
+  testFieldInitializer2(0),
+  testFieldInitializer3(0),
+  testGenericClass(0),
+  testInstanceFieldTyped(0),
+  testInstanceFieldWithInitializer(0),
+  testSuperInitializer(0),
+  testThisInitializer(0)]
+*/
+main() {
+  testDefaultValuesPositional();
+  testDefaultValuesNamed();
+  testFieldInitializer1();
+  testFieldInitializer2();
+  testFieldInitializer3();
+  testInstanceFieldWithInitializer();
+  testInstanceFieldTyped();
+  testThisInitializer();
+  testSuperInitializer();
+  testGenericClass();
+}
+
+/*kernel.element: testDefaultValuesPositional:type=[check:bool,inst:JSBool]*/
+/*strong.element: testDefaultValuesPositional:type=[inst:JSBool,param:bool]*/
+testDefaultValuesPositional([bool value = false]) {}
+
+/*kernel.element: testDefaultValuesNamed:type=[check:bool,inst:JSBool]*/
+/*strong.element: testDefaultValuesNamed:type=[inst:JSBool,param:bool]*/
+testDefaultValuesNamed({bool value: false}) {}
+
+class ClassFieldInitializer1 {
+  /*element: ClassFieldInitializer1.field:type=[inst:JSNull]*/
+  var field;
+
+  /*element: ClassFieldInitializer1.:static=[Object.(0),init:ClassFieldInitializer1.field]*/
+  ClassFieldInitializer1(this.field);
+}
+
+/*element: testFieldInitializer1:
+ static=[ClassFieldInitializer1.(1)],
+ type=[inst:JSDouble,inst:JSInt,inst:JSNumber,inst:JSPositiveInt,inst:JSUInt31,inst:JSUInt32]
+*/
+testFieldInitializer1() => new ClassFieldInitializer1(42);
+
+class ClassFieldInitializer2 {
+  /*element: ClassFieldInitializer2.field:type=[inst:JSNull]*/
+  var field;
+
+  /*element: ClassFieldInitializer2.:static=[Object.(0),init:ClassFieldInitializer2.field]*/
+  ClassFieldInitializer2(value) : field = value;
+}
+
+/*element: testFieldInitializer2:
+ static=[ClassFieldInitializer2.(1)],
+ type=[inst:JSDouble,inst:JSInt,inst:JSNumber,inst:JSPositiveInt,inst:JSUInt31,inst:JSUInt32]
+*/
+testFieldInitializer2() => new ClassFieldInitializer2(42);
+
+class ClassFieldInitializer3 {
+  /*element: ClassFieldInitializer3.field:type=[inst:JSNull]*/
+  var field;
+
+  /*element: ClassFieldInitializer3.a:static=[Object.(0),init:ClassFieldInitializer3.field],type=[inst:JSNull]*/
+  ClassFieldInitializer3.a();
+
+  /*element: ClassFieldInitializer3.b:static=[Object.(0),init:ClassFieldInitializer3.field]*/
+  ClassFieldInitializer3.b(value) : field = value;
+}
+
+/*element: testFieldInitializer3:
+ static=[ClassFieldInitializer3.a(0),ClassFieldInitializer3.b(1)],
+ type=[inst:JSDouble,inst:JSInt,inst:JSNumber,inst:JSPositiveInt,inst:JSUInt31,inst:JSUInt32]
+*/
+testFieldInitializer3() {
+  new ClassFieldInitializer3.a();
+  new ClassFieldInitializer3.b(42);
+}
+
+/*element: ClassInstanceFieldWithInitializer.:static=[Object.(0)]*/
+class ClassInstanceFieldWithInitializer {
+  /*kernel.element: ClassInstanceFieldWithInitializer.field:type=[inst:JSBool]*/
+  /*strong.element: ClassInstanceFieldWithInitializer.field:type=[inst:JSBool,param:bool]*/
+  var field = false;
+}
+
+/*element: testInstanceFieldWithInitializer:static=[ClassInstanceFieldWithInitializer.(0)]*/
+testInstanceFieldWithInitializer() => new ClassInstanceFieldWithInitializer();
+
+/*element: ClassInstanceFieldTyped.:static=[Object.(0)]*/
+class ClassInstanceFieldTyped {
+  /*kernel.element: ClassInstanceFieldTyped.field:type=[check:int,inst:JSNull]*/
+  /*strong.element: ClassInstanceFieldTyped.field:type=[inst:JSBool,inst:JSNull,param:int]*/
+  int field;
+}
+
+/*element: testInstanceFieldTyped:static=[ClassInstanceFieldTyped.(0)]*/
+testInstanceFieldTyped() => new ClassInstanceFieldTyped();
+
+class ClassThisInitializer {
+  /*element: ClassThisInitializer.:static=[ClassThisInitializer.internal(0)]*/
+  ClassThisInitializer() : this.internal();
+
+  /*element: ClassThisInitializer.internal:static=[Object.(0)]*/
+  ClassThisInitializer.internal();
+}
+
+/*element: testThisInitializer:static=[ClassThisInitializer.(0)]*/
+testThisInitializer() => new ClassThisInitializer();
+
+class ClassSuperInitializer extends ClassThisInitializer {
+  /*element: ClassSuperInitializer.:static=[ClassThisInitializer.internal(0)]*/
+  ClassSuperInitializer() : super.internal();
+}
+
+/*element: testSuperInitializer:static=[ClassSuperInitializer.(0)]*/
+testSuperInitializer() => new ClassSuperInitializer();
+
+class ClassGeneric<T> {
+  /*kernel.element: ClassGeneric.:static=[Object.(0)],type=[check:ClassGeneric.T]*/
+  /*strong.element: ClassGeneric.:
+   static=[
+    Object.(0),
+    checkSubtype,
+    checkSubtypeOfRuntimeType,
+    getRuntimeTypeArgument,
+    getRuntimeTypeArgumentIntercepted,
+    getRuntimeTypeInfo,
+    getTypeArgumentByIndex,
+    setRuntimeTypeInfo],
+   type=[
+    inst:JSArray<dynamic>,
+    inst:JSBool,
+    inst:JSExtendableArray<dynamic>,
+    inst:JSFixedArray<dynamic>,
+    inst:JSMutableArray<dynamic>,
+    inst:JSUnmodifiableArray<dynamic>,
+    param:ClassGeneric.T]
+  */
+  ClassGeneric(T arg);
+}
+
+/*element: testGenericClass:static=[ClassGeneric.(1),assertIsSubtype,throwTypeError],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
new file mode 100644
index 0000000..6de7f52
--- /dev/null
+++ b/tests/compiler/dart2js/impact/data/invokes.dart
@@ -0,0 +1,672 @@
+// 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.
+
+/*element: main:
+ static=[
+  testClosure(0),
+  testClosureInvoke(0),
+  testDynamicGet(1),
+  testDynamicInvoke(1),
+  testDynamicPrivateMethodInvoke(0),
+  testDynamicSet(1),
+  testInvokeIndex(1),
+  testInvokeIndexSet(1),
+  testLocalFunction(0),
+  testLocalFunctionGet(0),
+  testLocalFunctionInvoke(0),
+  testLocalFunctionTyped(0),
+  testLocalWithInitializer(0),
+  testLocalWithInitializerTyped(0),
+  testLocalWithoutInitializer(0),
+  testStaticFunctionGet(0),
+  testTopLevelField(0),
+  testTopLevelFieldConst(0),
+  testTopLevelFieldFinal(0),
+  testTopLevelFieldGeneric1(0),
+  testTopLevelFieldGeneric2(0),
+  testTopLevelFieldGeneric3(0),
+  testTopLevelFieldLazy(0),
+  testTopLevelFieldTyped(0),
+  testTopLevelFieldWrite(0),
+  testTopLevelFunctionGet(0),
+  testTopLevelFunctionTyped(0),
+  testTopLevelGetterGet(0),
+  testTopLevelGetterGetTyped(0),
+  testTopLevelInvoke(0),
+  testTopLevelInvokeTyped(0),
+  testTopLevelSetterSet(0),
+  testTopLevelSetterSetTyped(0)],
+ type=[inst:JSNull]
+*/
+main() {
+  testTopLevelInvoke();
+  testTopLevelInvokeTyped();
+  testTopLevelFunctionTyped();
+  testTopLevelFunctionGet();
+  testTopLevelGetterGet();
+  testTopLevelGetterGetTyped();
+  testTopLevelSetterSet();
+  testTopLevelSetterSetTyped();
+  testTopLevelField();
+  testTopLevelFieldLazy();
+  testTopLevelFieldConst();
+  testTopLevelFieldFinal();
+  testTopLevelFieldTyped();
+  testTopLevelFieldGeneric1();
+  testTopLevelFieldGeneric2();
+  testTopLevelFieldGeneric3();
+  testTopLevelFieldWrite();
+  testStaticFunctionGet();
+  testDynamicInvoke(null);
+  testDynamicGet(null);
+  testDynamicSet(null);
+  testLocalWithoutInitializer();
+  testLocalWithInitializer();
+  testLocalWithInitializerTyped();
+  testLocalFunction();
+  testLocalFunctionTyped();
+  testLocalFunctionInvoke();
+  testLocalFunctionGet();
+  testClosure();
+  testClosureInvoke();
+  testInvokeIndex(null);
+  testInvokeIndexSet(null);
+  testDynamicPrivateMethodInvoke();
+}
+
+/*element: topLevelFunction1:*/
+topLevelFunction1(a) {}
+
+/*element: topLevelFunction2:type=[inst:JSNull]*/
+topLevelFunction2(a, [b, c]) {}
+
+/*element: topLevelFunction3:type=[inst:JSNull]*/
+topLevelFunction3(a, {b, c}) {}
+
+/*element: testTopLevelInvoke:
+ static=[
+  topLevelFunction1(1),
+  topLevelFunction2(1),
+  topLevelFunction2(2),
+  topLevelFunction2(3),
+  topLevelFunction3(1),
+  topLevelFunction3(1,b),
+  topLevelFunction3(1,b,c),
+  topLevelFunction3(1,b,c),
+  topLevelFunction3(1,c)],
+ type=[
+  inst:JSDouble,
+  inst:JSInt,
+  inst:JSNumber,
+  inst:JSPositiveInt,
+  inst:JSUInt31,
+  inst:JSUInt32]
+*/
+testTopLevelInvoke() {
+  topLevelFunction1(0);
+  topLevelFunction2(1);
+  topLevelFunction2(2, 3);
+  topLevelFunction2(4, 5, 6);
+  topLevelFunction3(7);
+  topLevelFunction3(8, b: 9);
+  topLevelFunction3(10, c: 11);
+  topLevelFunction3(12, b: 13, c: 14);
+  topLevelFunction3(15, c: 16, b: 17);
+}
+
+/*kernel.element: topLevelFunction1Typed:type=[check:int,check:void]*/
+/*strong.element: topLevelFunction1Typed:type=[inst:JSBool,param:int]*/
+void topLevelFunction1Typed(int a) {}
+
+/*kernel.element: topLevelFunction2Typed:
+ type=[
+  check:String,
+  check:double,
+  check:int,
+  check:num,
+  inst:JSNull]
+*/
+/*strong.element: topLevelFunction2Typed:
+ type=[
+  inst:JSBool,
+  inst:JSNull,
+  param:String,
+  param:double,
+  param:num]
+*/
+int topLevelFunction2Typed(String a, [num b, double c]) => null;
+
+/*kernel.element: topLevelFunction3Typed:
+ type=[
+  check:List<int>,
+  check:Map<String,bool>,
+  check:bool,
+  check:double,
+  inst:JSNull]
+*/
+/*strong.element: topLevelFunction3Typed:
+ static=[
+  checkSubtype,
+  getRuntimeTypeArgument,
+  getRuntimeTypeArgumentIntercepted,
+  getRuntimeTypeInfo,
+  getTypeArgumentByIndex,
+  setRuntimeTypeInfo],
+ type=[
+  inst:JSArray<dynamic>,
+  inst:JSBool,
+  inst:JSExtendableArray<dynamic>,
+  inst:JSFixedArray<dynamic>,
+  inst:JSMutableArray<dynamic>,
+  inst:JSNull,
+  inst:JSUnmodifiableArray<dynamic>,
+  param:List<int>,
+  param:Map<String,bool>,
+  param:bool]
+*/
+double topLevelFunction3Typed(bool a, {List<int> b, Map<String, bool> c}) {
+  return null;
+}
+
+/*kernel.element: testTopLevelInvokeTyped:
+ static=[
+  topLevelFunction1Typed(1),
+  topLevelFunction2Typed(1),
+  topLevelFunction2Typed(2),
+  topLevelFunction2Typed(3),
+  topLevelFunction3Typed(1),
+  topLevelFunction3Typed(1,b),
+  topLevelFunction3Typed(1,b,c),
+  topLevelFunction3Typed(1,b,c),
+  topLevelFunction3Typed(1,c)],
+ type=[
+  inst:JSBool,
+  inst:JSDouble,
+  inst:JSInt,
+  inst:JSNull,
+  inst:JSNumber,
+  inst:JSPositiveInt,
+  inst:JSString,
+  inst:JSUInt31,
+  inst:JSUInt32,
+  inst:List<dynamic>,
+  inst:Map<dynamic,dynamic>]
+*/
+/*strong.element: testTopLevelInvokeTyped:
+ static=[
+  topLevelFunction1Typed(1),
+  topLevelFunction2Typed(1),
+  topLevelFunction2Typed(2),
+  topLevelFunction2Typed(3),
+  topLevelFunction3Typed(1),
+  topLevelFunction3Typed(1,b),
+  topLevelFunction3Typed(1,b,c),
+  topLevelFunction3Typed(1,b,c),
+  topLevelFunction3Typed(1,c)],
+ type=[
+  inst:JSBool,
+  inst:JSDouble,
+  inst:JSInt,
+  inst:JSNull,
+  inst:JSNumber,
+  inst:JSPositiveInt,
+  inst:JSString,
+  inst:JSUInt31,
+  inst:JSUInt32,
+  inst:List<int>,
+  inst:Map<String,bool>]
+*/
+testTopLevelInvokeTyped() {
+  topLevelFunction1Typed(0);
+  topLevelFunction2Typed('1');
+  topLevelFunction2Typed('2', 3);
+  topLevelFunction2Typed('3', 5, 6.0);
+  topLevelFunction3Typed(true);
+  topLevelFunction3Typed(false, b: []);
+  topLevelFunction3Typed(null, c: {});
+  topLevelFunction3Typed(true, b: [13], c: {'14': true});
+  topLevelFunction3Typed(false, c: {'16': false}, b: [17]);
+}
+
+/*kernel.element: topLevelFunctionTyped1:type=[check:void Function(num)]*/
+/*strong.element: topLevelFunctionTyped1:
+ static=[
+  checkSubtype,
+  getRuntimeTypeArgument,
+  getRuntimeTypeArgumentIntercepted,
+  getRuntimeTypeInfo,
+  getTypeArgumentByIndex,
+  setRuntimeTypeInfo],
+ type=[
+  inst:JSArray<dynamic>,
+  inst:JSBool,
+  inst:JSExtendableArray<dynamic>,
+  inst:JSFixedArray<dynamic>,
+  inst:JSMutableArray<dynamic>,
+  inst:JSUnmodifiableArray<dynamic>,
+  param:void Function(num)]
+*/
+topLevelFunctionTyped1(void a(num b)) {}
+
+/*kernel.element: topLevelFunctionTyped2:type=[check:void Function(num,[String])]*/
+/*strong.element: topLevelFunctionTyped2:
+ static=[
+  checkSubtype,
+  getRuntimeTypeArgument,
+  getRuntimeTypeArgumentIntercepted,
+  getRuntimeTypeInfo,
+  getTypeArgumentByIndex,
+  setRuntimeTypeInfo],
+ type=[
+  inst:JSArray<dynamic>,
+  inst:JSBool,
+  inst:JSExtendableArray<dynamic>,
+  inst:JSFixedArray<dynamic>,
+  inst:JSMutableArray<dynamic>,
+  inst:JSUnmodifiableArray<dynamic>,
+  param:void Function(num,[String])]
+*/
+topLevelFunctionTyped2(void a(num b, [String c])) {}
+
+/*kernel.element: topLevelFunctionTyped3:
+ type=[check:void Function(num,{String c,int d})]
+*/
+/*strong.element: topLevelFunctionTyped3:
+ static=[
+  checkSubtype,
+  getRuntimeTypeArgument,
+  getRuntimeTypeArgumentIntercepted,
+  getRuntimeTypeInfo,
+  getTypeArgumentByIndex,
+  setRuntimeTypeInfo],
+ type=[
+  inst:JSArray<dynamic>,
+  inst:JSBool,
+  inst:JSExtendableArray<dynamic>,
+  inst:JSFixedArray<dynamic>,
+  inst:JSMutableArray<dynamic>,
+  inst:JSUnmodifiableArray<dynamic>,
+  param:void Function(num,{String c,int d})]
+*/
+topLevelFunctionTyped3(void a(num b, {String c, int d})) {}
+
+/*kernel.element: topLevelFunctionTyped4:
+ type=[check:void Function(num,{int c,String d})]
+*/
+/*strong.element: topLevelFunctionTyped4:
+ static=[
+  checkSubtype,
+  getRuntimeTypeArgument,
+  getRuntimeTypeArgumentIntercepted,
+  getRuntimeTypeInfo,
+  getTypeArgumentByIndex,
+  setRuntimeTypeInfo],
+ type=[
+  inst:JSArray<dynamic>,
+  inst:JSBool,
+  inst:JSExtendableArray<dynamic>,
+  inst:JSFixedArray<dynamic>,
+  inst:JSMutableArray<dynamic>,
+  inst:JSUnmodifiableArray<dynamic>,
+  param:void Function(num,{int c,String d})]
+*/
+topLevelFunctionTyped4(void a(num b, {String d, int c})) {}
+
+/*element: testTopLevelFunctionTyped:
+ static=[
+  topLevelFunctionTyped1(1),
+  topLevelFunctionTyped2(1),
+  topLevelFunctionTyped3(1),
+  topLevelFunctionTyped4(1)],
+ type=[inst:JSNull]
+*/
+testTopLevelFunctionTyped() {
+  topLevelFunctionTyped1(null);
+  topLevelFunctionTyped2(null);
+  topLevelFunctionTyped3(null);
+  topLevelFunctionTyped4(null);
+}
+
+/*element: testTopLevelFunctionGet:static=[topLevelFunction1]*/
+testTopLevelFunctionGet() => topLevelFunction1;
+
+/*element: topLevelGetter:type=[inst:JSNull]*/
+get topLevelGetter => null;
+
+/*element: testTopLevelGetterGet:static=[topLevelGetter]*/
+testTopLevelGetterGet() => topLevelGetter;
+
+/*kernel.element: topLevelGetterTyped:type=[check:int,inst:JSNull]*/
+/*strong.element: topLevelGetterTyped:type=[inst:JSNull]*/
+int get topLevelGetterTyped => null;
+
+/*element: testTopLevelGetterGetTyped:static=[topLevelGetterTyped]*/
+testTopLevelGetterGetTyped() => topLevelGetterTyped;
+
+/*element: topLevelSetter=:*/
+set topLevelSetter(_) {}
+
+/*element: testTopLevelSetterSet:static=[set:topLevelSetter],type=[inst:JSNull]*/
+testTopLevelSetterSet() => topLevelSetter = null;
+
+/*kernel.element: topLevelSetterTyped=:type=[check:int,check:void]*/
+/*strong.element: topLevelSetterTyped=:type=[inst:JSBool,param:int]*/
+void set topLevelSetterTyped(int value) {}
+
+/*element: testTopLevelSetterSetTyped:static=[set:topLevelSetterTyped],type=[inst:JSNull]*/
+testTopLevelSetterSetTyped() => topLevelSetterTyped = null;
+
+/*element: topLevelField:type=[inst:JSNull]*/
+var topLevelField;
+
+/*element: testTopLevelField:static=[topLevelField]*/
+testTopLevelField() => topLevelField;
+
+/*element: topLevelFieldLazy:static=[throwCyclicInit,topLevelFunction1(1)],type=[inst:JSNull]*/
+var topLevelFieldLazy = topLevelFunction1(null);
+
+/*element: testTopLevelFieldLazy:static=[topLevelFieldLazy]*/
+testTopLevelFieldLazy() => topLevelFieldLazy;
+
+/*element: topLevelFieldConst:type=[inst:JSNull]*/
+const topLevelFieldConst = null;
+
+/*element: testTopLevelFieldConst:static=[topLevelFieldConst]*/
+testTopLevelFieldConst() => topLevelFieldConst;
+
+/*element: topLevelFieldFinal:static=[throwCyclicInit,topLevelFunction1(1)],type=[inst:JSNull]*/
+final topLevelFieldFinal = topLevelFunction1(null);
+
+/*element: testTopLevelFieldFinal:static=[topLevelFieldFinal]*/
+testTopLevelFieldFinal() => topLevelFieldFinal;
+
+/*kernel.element: topLevelFieldTyped:type=[check:int,inst:JSNull]*/
+/*strong.element: topLevelFieldTyped:type=[inst:JSBool,inst:JSNull,param:int]*/
+int topLevelFieldTyped;
+
+/*element: testTopLevelFieldTyped:static=[topLevelFieldTyped]*/
+testTopLevelFieldTyped() => topLevelFieldTyped;
+
+/*kernel.element: topLevelFieldGeneric1:type=[check:GenericClass<dynamic,dynamic>,inst:JSNull]*/
+/*strong.element: topLevelFieldGeneric1:type=[inst:JSBool,inst:JSNull,param:GenericClass<dynamic,dynamic>]*/
+GenericClass topLevelFieldGeneric1;
+
+/*element: testTopLevelFieldGeneric1:static=[topLevelFieldGeneric1]*/
+testTopLevelFieldGeneric1() => topLevelFieldGeneric1;
+
+/*kernel.element: topLevelFieldGeneric2:type=[check:GenericClass<dynamic,dynamic>,inst:JSNull]*/
+/*strong.element: topLevelFieldGeneric2:type=[inst:JSBool,inst:JSNull,param:GenericClass<dynamic,dynamic>]*/
+GenericClass<dynamic, dynamic> topLevelFieldGeneric2;
+
+/*element: testTopLevelFieldGeneric2:static=[topLevelFieldGeneric2]*/
+testTopLevelFieldGeneric2() => topLevelFieldGeneric2;
+
+/*kernel.element: topLevelFieldGeneric3:type=[check:GenericClass<int,String>,inst:JSNull]*/
+/*strong.element: topLevelFieldGeneric3:
+ static=[
+  checkSubtype,
+  getRuntimeTypeArgument,
+  getRuntimeTypeArgumentIntercepted,
+  getRuntimeTypeInfo,
+  getTypeArgumentByIndex,
+  setRuntimeTypeInfo],
+ type=[
+  inst:JSArray<dynamic>,
+  inst:JSBool,
+  inst:JSExtendableArray<dynamic>,
+  inst:JSFixedArray<dynamic>,
+  inst:JSMutableArray<dynamic>,
+  inst:JSNull,
+  inst:JSUnmodifiableArray<dynamic>,
+  param:GenericClass<int,String>]
+*/
+GenericClass<int, String> topLevelFieldGeneric3;
+
+/*element: testTopLevelFieldGeneric3:static=[topLevelFieldGeneric3]*/
+testTopLevelFieldGeneric3() => topLevelFieldGeneric3;
+
+/*element: testTopLevelFieldWrite:static=[set:topLevelField],type=[inst:JSNull]*/
+testTopLevelFieldWrite() => topLevelField = null;
+
+class StaticFunctionGetClass {
+  /*element: StaticFunctionGetClass.foo:*/
+  static foo() {}
+}
+
+/*element: testStaticFunctionGet:static=[StaticFunctionGetClass.foo]*/
+testStaticFunctionGet() => StaticFunctionGetClass.foo;
+
+/*element: testDynamicInvoke:
+ dynamic=[
+  f1(1),
+  f2(1),
+  f3(2),
+  f4(3),
+  f5(1),
+  f6(1,b),
+  f7(1,c),
+  f8(1,b,c),
+  f9(1,b,c)],
+ type=[
+  inst:JSDouble,
+  inst:JSInt,
+  inst:JSNumber,
+  inst:JSPositiveInt,
+  inst:JSUInt31,
+  inst:JSUInt32]
+*/
+testDynamicInvoke(o) {
+  o.f1(0);
+  o.f2(1);
+  o.f3(2, 3);
+  o.f4(4, 5, 6);
+  o.f5(7);
+  o.f6(8, b: 9);
+  o.f7(10, c: 11);
+  o.f8(12, b: 13, c: 14);
+  o.f9(15, c: 16, b: 17);
+}
+
+/*element: testDynamicGet:dynamic=[foo]*/
+testDynamicGet(o) => o.foo;
+
+/*element: testDynamicSet:
+ dynamic=[foo=],
+ type=[
+  inst:JSDouble,
+  inst:JSInt,
+  inst:JSNumber,
+  inst:JSPositiveInt,
+  inst:JSUInt31,
+  inst:JSUInt32]
+*/
+testDynamicSet(o) => o.foo = 42;
+
+// TODO(johnniwinther): Remove 'inst:Null'.
+/*element: testLocalWithoutInitializer:type=[inst:JSNull,inst:Null]*/
+testLocalWithoutInitializer() {
+  // ignore: UNUSED_LOCAL_VARIABLE
+  var l;
+}
+
+/*element: testLocalWithInitializer:
+ type=[
+  inst:JSDouble,
+  inst:JSInt,
+  inst:JSNumber,
+  inst:JSPositiveInt,
+  inst:JSUInt31,
+  inst:JSUInt32]
+*/
+testLocalWithInitializer() {
+  // ignore: UNUSED_LOCAL_VARIABLE
+  var l = 42;
+}
+
+/*kernel.element: testLocalWithInitializerTyped:
+ type=[
+  check:int,
+  inst:JSDouble,
+  inst:JSInt,
+  inst:JSNumber,
+  inst:JSPositiveInt,
+  inst:JSUInt31,
+  inst:JSUInt32]
+*/
+/*strong.element: testLocalWithInitializerTyped:
+ type=[
+  inst:JSDouble,
+  inst:JSInt,
+  inst:JSNumber,
+  inst:JSPositiveInt,
+  inst:JSUInt31,
+  inst:JSUInt32]
+*/
+testLocalWithInitializerTyped() {
+  // ignore: UNUSED_LOCAL_VARIABLE
+  int l = 42;
+}
+
+/*kernel.element: testLocalFunction:static=[def:localFunction],type=[inst:Function]*/
+/*strong.element: testLocalFunction:
+ static=[
+  computeSignature,
+  def:localFunction,
+  getRuntimeTypeArguments,
+  getRuntimeTypeInfo,
+  setRuntimeTypeInfo],
+ type=[
+  inst:Function,
+  inst:JSArray<dynamic>,
+  inst:JSExtendableArray<dynamic>,
+  inst:JSFixedArray<dynamic>,
+  inst:JSMutableArray<dynamic>,
+  inst:JSUnmodifiableArray<dynamic>]
+*/
+testLocalFunction() {
+  // ignore: UNUSED_ELEMENT
+  localFunction() {}
+}
+
+/*kernel.element: testLocalFunctionTyped:
+ static=[def:localFunction],
+ type=[check:String,check:int,inst:Function,inst:JSNull]
+*/
+/*strong.element: testLocalFunctionTyped:
+ static=[
+  computeSignature,
+  def:localFunction,
+  getRuntimeTypeArguments,
+  getRuntimeTypeInfo,
+  setRuntimeTypeInfo],
+  type=[inst:Function,
+  inst:JSArray<dynamic>,
+  inst:JSBool,
+  inst:JSExtendableArray<dynamic>,
+  inst:JSFixedArray<dynamic>,
+  inst:JSMutableArray<dynamic>,
+  inst:JSNull,
+  inst:JSUnmodifiableArray<dynamic>,
+  param:String]*/
+testLocalFunctionTyped() {
+  // ignore: UNUSED_ELEMENT
+  int localFunction(String a) => null;
+}
+
+/*kernel.element: testLocalFunctionInvoke:static=[def:localFunction],
+  type=[inst:Function]*/
+/*strong.element: testLocalFunctionInvoke:static=[computeSignature,
+  def:localFunction,
+  getRuntimeTypeArguments,
+  getRuntimeTypeInfo,
+  localFunction(0),
+  setRuntimeTypeInfo],
+  type=[inst:Function,
+  inst:JSArray<dynamic>,
+  inst:JSExtendableArray<dynamic>,
+  inst:JSFixedArray<dynamic>,
+  inst:JSMutableArray<dynamic>,
+  inst:JSUnmodifiableArray<dynamic>]*/
+testLocalFunctionInvoke() {
+  localFunction() {}
+  localFunction();
+}
+
+/*kernel.element: testLocalFunctionGet:static=[def:localFunction],
+  type=[inst:Function]*/
+/*strong.element: testLocalFunctionGet:static=[computeSignature,
+  def:localFunction,
+  getRuntimeTypeArguments,
+  getRuntimeTypeInfo,
+  setRuntimeTypeInfo],
+  type=[inst:Function,
+  inst:JSArray<dynamic>,
+  inst:JSExtendableArray<dynamic>,
+  inst:JSFixedArray<dynamic>,
+  inst:JSMutableArray<dynamic>,
+  inst:JSUnmodifiableArray<dynamic>]*/
+testLocalFunctionGet() {
+  localFunction() {}
+  localFunction;
+}
+
+/*kernel.element: testClosure:static=[def:<anonymous>],
+  type=[inst:Function]*/
+/*strong.element: testClosure:static=[computeSignature,
+  def:<anonymous>,
+  getRuntimeTypeArguments,
+  getRuntimeTypeInfo,
+  setRuntimeTypeInfo],
+  type=[inst:Function,
+  inst:JSArray<dynamic>,
+  inst:JSExtendableArray<dynamic>,
+  inst:JSFixedArray<dynamic>,
+  inst:JSMutableArray<dynamic>,
+  inst:JSUnmodifiableArray<dynamic>]*/
+testClosure() {
+  () {};
+}
+
+/*kernel.element: testClosureInvoke:dynamic=[call(0)],
+  static=[def:<anonymous>],
+  type=[inst:Function]*/
+/*strong.element: testClosureInvoke:dynamic=[call(0)],
+  static=[computeSignature,
+  def:<anonymous>,
+  getRuntimeTypeArguments,
+  getRuntimeTypeInfo,
+  setRuntimeTypeInfo],
+  type=[inst:Function,
+  inst:JSArray<dynamic>,
+  inst:JSExtendableArray<dynamic>,
+  inst:JSFixedArray<dynamic>,
+  inst:JSMutableArray<dynamic>,
+  inst:JSUnmodifiableArray<dynamic>]*/
+testClosureInvoke() {
+  () {}();
+}
+
+/*element: testInvokeIndex:dynamic=[[]],
+  type=[inst:JSDouble,
+  inst:JSInt,
+  inst:JSNumber,
+  inst:JSPositiveInt,
+  inst:JSUInt31,
+  inst:JSUInt32]*/
+testInvokeIndex(o) => o[42];
+
+/*element: testInvokeIndexSet:dynamic=[[]=],
+  type=[inst:JSDouble,
+  inst:JSInt,
+  inst:JSNull,
+  inst:JSNumber,
+  inst:JSPositiveInt,
+  inst:JSUInt31,
+  inst:JSUInt32]*/
+testInvokeIndexSet(o) => o[42] = null;
+
+/*element: testDynamicPrivateMethodInvoke:dynamic=[_privateMethod(0)],type=[inst:JSNull]*/
+testDynamicPrivateMethodInvoke([o]) => o._privateMethod();
+
+class GenericClass<X, Y> {}
diff --git a/tests/compiler/dart2js/impact/data/jsinterop.dart b/tests/compiler/dart2js/impact/data/jsinterop.dart
new file mode 100644
index 0000000..b063cee
--- /dev/null
+++ b/tests/compiler/dart2js/impact/data/jsinterop.dart
@@ -0,0 +1,62 @@
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@JS()
+library jsinterop;
+
+import 'package:js/js.dart';
+
+/*element: main:static=[testJsInteropClass(0),testJsInteropMethod(0)]*/
+main() {
+  testJsInteropMethod();
+  testJsInteropClass();
+}
+
+/*kernel.element: testJsInteropMethod:type=[check:int]*/
+/*strong.element: testJsInteropMethod:*/
+@JS()
+external int testJsInteropMethod();
+
+@JS()
+class JsInteropClass {
+  /*element: JsInteropClass.:static=[JavaScriptObject.(0)]*/
+  external JsInteropClass();
+
+  /*kernel.element: JsInteropClass.method:
+   type=[
+    check:double,
+    native:ApplicationCacheErrorEvent,
+    native:DomError,
+    native:DomException,
+    native:ErrorEvent,
+    native:JsInteropClass,
+    native:MediaError,
+    native:NavigatorUserMediaError,
+    native:OverconstrainedError,
+    native:PositionError,
+    native:SensorErrorEvent,
+    native:SpeechRecognitionError,
+    native:SqlError]
+  */
+  /*strong.element: JsInteropClass.method:
+   type=[
+    native:ApplicationCacheErrorEvent,
+    native:DomError,
+    native:DomException,
+    native:ErrorEvent,
+    native:JsInteropClass,
+    native:MediaError,
+    native:NavigatorUserMediaError,
+    native:OverconstrainedError,
+    native:PositionError,
+    native:SensorErrorEvent,
+    native:SpeechRecognitionError,
+    native:SqlError]
+  */
+  @JS()
+  external double method();
+}
+
+/*element: testJsInteropClass:dynamic=[method(0)],static=[JsInteropClass.(0)]*/
+testJsInteropClass() => new JsInteropClass().method();
diff --git a/tests/compiler/dart2js/impact/data/literals.dart b/tests/compiler/dart2js/impact/data/literals.dart
new file mode 100644
index 0000000..65a8ea5
--- /dev/null
+++ b/tests/compiler/dart2js/impact/data/literals.dart
@@ -0,0 +1,216 @@
+// 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.
+
+/*element: main:static=[
+ testBoolFromEnvironment(0),
+ testComplexConstSymbol(0),
+ testConstSymbol(0),
+ testDouble(0),
+ testEmpty(0),
+ testEmptyListLiteral(0),
+ testEmptyListLiteralConstant(0),
+ testEmptyListLiteralDynamic(0),
+ testEmptyListLiteralTyped(0),
+ testEmptyMapLiteral(0),
+ testEmptyMapLiteralConstant(0),
+ testEmptyMapLiteralDynamic(0),
+ testEmptyMapLiteralTyped(0),
+ testFalse(0),
+ testIfNullConstSymbol(0),
+ testInt(0),
+ testNonEmptyListLiteral(0),
+ testNonEmptyMapLiteral(0),
+ testNull(0),
+ testString(0),
+ testStringInterpolation(0),
+ testStringInterpolationConst(0),
+ testStringJuxtaposition(0),
+ testSymbol(0),
+ testTrue(0),
+ testTypeLiteral(0)]
+*/
+main() {
+  testEmpty();
+  testNull();
+  testTrue();
+  testFalse();
+  testInt();
+  testDouble();
+  testString();
+  testStringInterpolation();
+  testStringInterpolationConst();
+  testStringJuxtaposition();
+  testSymbol();
+  testConstSymbol();
+  testComplexConstSymbol();
+  testIfNullConstSymbol();
+  testTypeLiteral();
+  testBoolFromEnvironment();
+  testEmptyListLiteral();
+  testEmptyListLiteralDynamic();
+  testEmptyListLiteralTyped();
+  testEmptyListLiteralConstant();
+  testNonEmptyListLiteral();
+  testEmptyMapLiteral();
+  testEmptyMapLiteralDynamic();
+  testEmptyMapLiteralTyped();
+  testEmptyMapLiteralConstant();
+  testNonEmptyMapLiteral();
+}
+
+/*element: testEmpty:*/
+testEmpty() {}
+
+/*element: testNull:type=[inst:JSNull]*/
+testNull() => null;
+
+/*element: testTrue:type=[inst:JSBool]*/
+testTrue() => true;
+
+/*element: testFalse:type=[inst:JSBool]*/
+testFalse() => false;
+
+/*element: testInt:type=[inst:JSDouble,inst:JSInt,inst:JSNumber,inst:JSPositiveInt,inst:JSUInt31,inst:JSUInt32]*/
+testInt() => 42;
+
+/*element: testDouble:type=[inst:JSDouble,inst:JSInt,inst:JSNumber,inst:JSPositiveInt,inst:JSUInt31,inst:JSUInt32]*/
+testDouble() => 37.5;
+
+/*element: testString:type=[inst:JSString]*/
+testString() => 'foo';
+
+/*element: testStringInterpolation:dynamic=[toString(0)],static=[S],type=[inst:JSBool,inst:JSString]*/
+testStringInterpolation() => '${true}';
+
+/*element: testStringInterpolationConst:dynamic=[toString(0)],static=[S],type=[inst:JSBool,inst:JSString]*/
+testStringInterpolationConst() {
+  const b = '${true}';
+  return b;
+}
+
+/*element: testStringJuxtaposition:dynamic=[toString(0)],static=[S],type=[inst:JSString]*/
+testStringJuxtaposition() => 'a' 'b';
+
+/*element: testSymbol:static=[Symbol.],type=[inst:Symbol]*/
+testSymbol() => #main;
+
+/*element: testConstSymbol:static=[Symbol.,Symbol.(1),Symbol.validated],type=[inst:JSString,inst:Symbol]*/
+testConstSymbol() => const Symbol('main');
+
+/*kernel.element: complexSymbolField1:
+ dynamic=[==,length],
+ type=[inst:JSDouble,inst:JSInt,inst:JSNumber,inst:JSPositiveInt,inst:JSString,inst:JSUInt31,inst:JSUInt32]
+*/
+/*strong.element: complexSymbolField1:
+ dynamic=[==,length],
+ type=[inst:JSBool,inst:JSDouble,inst:JSInt,inst:JSNumber,inst:JSPositiveInt,inst:JSString,inst:JSUInt31,inst:JSUInt32,param:bool]
+*/
+const complexSymbolField1 = "true".length == 4;
+
+/*kernel.element: complexSymbolField2:dynamic=[toString(0)],static=[S],type=[inst:JSBool,inst:JSNull,inst:JSString]*/
+/*strong.element: complexSymbolField2:dynamic=[toString(0)],static=[S],type=[inst:JSBool,inst:JSNull,inst:JSString,param:String]*/
+const complexSymbolField2 = "true" "false" "${true}${null}";
+
+/*kernel.element: complexSymbolField3:
+dynamic=[+,unary-],
+static=[
+ GenericClass.generative(0),
+ String.fromEnvironment(1),
+ Symbol.,assertIsSubtype,
+ bool.fromEnvironment(1,defaultValue),
+ identical(2),
+ int.fromEnvironment(1,defaultValue),
+ override,
+ testComplexConstSymbol,
+ throwTypeError],
+type=[
+ check:int,
+ inst:ConstantMap<dynamic,dynamic>,
+ inst:ConstantProtoMap<dynamic,dynamic>,
+ inst:ConstantStringMap<dynamic,dynamic>,
+ inst:GeneralConstantMap<dynamic,dynamic>,
+ inst:JSBool,
+ inst:JSDouble,
+ inst:JSInt,
+ inst:JSNumber,
+ inst:JSPositiveInt,
+ inst:JSString,
+ inst:JSUInt31,
+ inst:JSUInt32,
+ inst:List<int>,
+ inst:Symbol]
+*/
+/*strong.element: complexSymbolField3:dynamic=[+,unary-],static=[GenericClass.generative(0),String.fromEnvironment(1),Symbol.,assertIsSubtype,bool.fromEnvironment(1,defaultValue),checkSubtype,getRuntimeTypeArgument,getRuntimeTypeArgumentIntercepted,getRuntimeTypeInfo,getTypeArgumentByIndex,identical(2),int.fromEnvironment(1,defaultValue),override,setRuntimeTypeInfo,testComplexConstSymbol,throwTypeError],type=[inst:ConstantMap<dynamic,dynamic>,inst:ConstantProtoMap<dynamic,dynamic>,inst:ConstantStringMap<dynamic,dynamic>,inst:GeneralConstantMap<dynamic,dynamic>,inst:JSArray<dynamic>,inst:JSBool,inst:JSDouble,inst:JSExtendableArray<dynamic>,inst:JSFixedArray<dynamic>,inst:JSInt,inst:JSMutableArray<dynamic>,inst:JSNumber,inst:JSPositiveInt,inst:JSString,inst:JSUInt31,inst:JSUInt32,inst:JSUnmodifiableArray<dynamic>,inst:List<int>,inst:Symbol,param:Map<Object,Object>]*/
+const complexSymbolField3 = const {
+  0: const bool.fromEnvironment('a', defaultValue: true),
+  false: const int.fromEnvironment('b', defaultValue: 42),
+  const <int>[]: const String.fromEnvironment('c'),
+  testComplexConstSymbol: #testComplexConstSymbol,
+  1 + 2: identical(0, -0),
+  // ignore: dead_code
+  true || false: false && true,
+  override: const GenericClass<int, String>.generative(),
+};
+
+/*kernel.element: complexSymbolField:static=[complexSymbolField1,complexSymbolField2,complexSymbolField3]*/
+/*strong.element: complexSymbolField:static=[complexSymbolField1,complexSymbolField2,complexSymbolField3],type=[inst:JSBool,param:Object]*/
+const complexSymbolField =
+    complexSymbolField1 ? complexSymbolField2 : complexSymbolField3;
+
+/*kernel.element: testComplexConstSymbol:static=[Symbol.,Symbol.(1),Symbol.validated,complexSymbolField],type=[inst:Symbol]*/
+/*strong.element: testComplexConstSymbol:static=[Symbol.,Symbol.(1),Symbol.validated,complexSymbolField],type=[impl:String,inst:JSBool,inst:Symbol]*/
+testComplexConstSymbol() => const Symbol(complexSymbolField);
+
+/*element: testIfNullConstSymbol:dynamic=[==],static=[Symbol.,Symbol.(1),Symbol.validated],type=[inst:JSNull,inst:JSString,inst:Symbol]*/
+testIfNullConstSymbol() => const Symbol(null ?? 'foo');
+
+/*element: testTypeLiteral:static=[createRuntimeType],type=[inst:Type,inst:TypeImpl,lit:Object]*/
+testTypeLiteral() => Object;
+
+/*element: testBoolFromEnvironment:static=[bool.fromEnvironment(1)],type=[inst:JSString]*/
+testBoolFromEnvironment() => const bool.fromEnvironment('FOO');
+
+/*element: testEmptyListLiteral:type=[inst:List<dynamic>]*/
+testEmptyListLiteral() => [];
+
+/*element: testEmptyListLiteralDynamic:type=[inst:List<dynamic>]*/
+testEmptyListLiteralDynamic() => <dynamic>[];
+
+/*kernel.element: testEmptyListLiteralTyped:type=[check:String,inst:List<String>]*/
+/*strong.element: testEmptyListLiteralTyped:type=[inst:List<String>]*/
+testEmptyListLiteralTyped() => <String>[];
+
+/*element: testEmptyListLiteralConstant:type=[inst:List<dynamic>]*/
+testEmptyListLiteralConstant() => const [];
+
+/*kernel.element: testNonEmptyListLiteral:type=[inst:JSBool,inst:List<dynamic>]*/
+/*strong.element: testNonEmptyListLiteral:type=[inst:JSBool,inst:List<bool>]*/
+testNonEmptyListLiteral() => [true];
+
+/*element: testEmptyMapLiteral:type=[inst:Map<dynamic,dynamic>]*/
+testEmptyMapLiteral() => {};
+
+/*element: testEmptyMapLiteralDynamic:type=[inst:Map<dynamic,dynamic>]*/
+testEmptyMapLiteralDynamic() => <dynamic, dynamic>{};
+
+/*kernel.element: testEmptyMapLiteralTyped:type=[check:String,check:int,inst:Map<String,int>]*/
+/*strong.element: testEmptyMapLiteralTyped:type=[inst:Map<String,int>]*/
+testEmptyMapLiteralTyped() => <String, int>{};
+
+/*element: testEmptyMapLiteralConstant:
+type=[
+ inst:ConstantMap<dynamic,dynamic>,
+ inst:ConstantProtoMap<dynamic,dynamic>,
+ inst:ConstantStringMap<dynamic,dynamic>,
+ inst:GeneralConstantMap<dynamic,dynamic>]*/
+testEmptyMapLiteralConstant() => const {};
+
+/*kernel.element: testNonEmptyMapLiteral:type=[inst:JSBool,inst:JSNull,inst:Map<dynamic,dynamic>]*/
+/*strong.element: testNonEmptyMapLiteral:type=[inst:JSBool,inst:JSNull,inst:Map<Null,bool>]*/
+testNonEmptyMapLiteral() => {null: true};
+
+class GenericClass<X, Y> {
+  /*element: GenericClass.generative:static=[Object.(0)]*/
+  const GenericClass.generative();
+}
diff --git a/tests/compiler/dart2js/impact/data/native.dart b/tests/compiler/dart2js/impact/data/native.dart
new file mode 100644
index 0000000..f396310a
--- /dev/null
+++ b/tests/compiler/dart2js/impact/data/native.dart
@@ -0,0 +1,103 @@
+// 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.
+
+// ignore: IMPORT_INTERNAL_LIBRARY
+import 'dart:_foreign_helper' as foreign show JS;
+// ignore: IMPORT_INTERNAL_LIBRARY
+import 'dart:_js_helper';
+import 'dart:html_common';
+
+/*element: main:static=[testJSCall(0),
+  testNativeField(1),
+  testNativeMethod(0),
+  testNativeMethodCreates(0),
+  testNativeMethodReturns(0)],
+  type=[inst:JSNull]*/
+main() {
+  testJSCall();
+  testNativeMethod();
+  testNativeField(null);
+  testNativeMethodCreates();
+  testNativeMethodReturns();
+}
+
+/*kernel.element: testJSCall:
+ static=[JS(3)],
+ type=[inst:JSNull,inst:JSString,native:bool,native:int]
+*/
+/*strong.element: testJSCall:
+ static=[JS<dynamic>(3)],
+ type=[inst:JSNull,inst:JSString,native:bool,native:int]
+*/
+testJSCall() => foreign.JS(
+    'int|bool|NativeUint8List|Rectangle|IdbFactory|SqlDatabase|TypedData|ContextAttributes',
+    '#',
+    null);
+
+/*element: testNativeMethod:*/
+@JSName('foo')
+@SupportedBrowser(SupportedBrowser.CHROME)
+// ignore: NATIVE_FUNCTION_BODY_IN_NON_SDK_CODE
+testNativeMethod() native;
+
+/*element: testNativeMethodCreates:
+ type=[native:JSArray<JSArray.E>,native:Null,native:int]
+*/
+@Creates('int|Null|JSArray')
+// ignore: NATIVE_FUNCTION_BODY_IN_NON_SDK_CODE
+testNativeMethodCreates() native;
+
+// This will trigger native instantiation and therefore include type use
+// `native:X` for all native types. This is truncated to `type=[*]` to avoid
+// dependency on the particular types. If `testNativeMethodReturns` was not
+// called `testNativeMethodCreates` would instead trigger the native
+// instantiations, so the blame is a bit arbitrary.
+/*element: testNativeMethodReturns:type=[*]*/
+@Returns('String|Null|JSArray')
+// ignore: NATIVE_FUNCTION_BODY_IN_NON_SDK_CODE
+testNativeMethodReturns() native;
+
+@Native("NativeClass")
+class NativeClass {
+  /*kernel.element: NativeClass.field:
+   type=[
+    check:Object,
+    inst:JSNull,
+    native:JSExtendableArray<JSExtendableArray.E>,
+    native:Object,
+    native:String,
+    native:bool,
+    native:double,
+    native:int]
+  */
+  /*strong.element: NativeClass.field:
+   type=[
+    inst:JSBool,
+    inst:JSNull,
+    native:JSExtendableArray<JSExtendableArray.E>,
+    native:Object,
+    native:String,
+    native:bool,
+    native:double,
+    native:int,
+    param:Object]
+  */
+  @annotation_Creates_SerializedScriptValue
+  final Object field;
+
+  factory NativeClass._() {
+    throw new UnsupportedError("Not supported");
+  }
+}
+
+/*kernel.element: testNativeField:
+ dynamic=[field],
+ type=[check:NativeClass]
+*/
+/*strong.element: testNativeField:
+ dynamic=[field],
+ static=[defineProperty],
+ type=[inst:JSBool,param:NativeClass]
+*/
+testNativeField(NativeClass c) => c.field;
diff --git a/tests/compiler/dart2js/impact/data/statements.dart b/tests/compiler/dart2js/impact/data/statements.dart
new file mode 100644
index 0000000..9ab5130
--- /dev/null
+++ b/tests/compiler/dart2js/impact/data/statements.dart
@@ -0,0 +1,205 @@
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/*element: main:
+ static=[
+  testAssert(0),
+  testAssertWithMessage(0),
+  testForIn(1),
+  testForInTyped(1),
+  testIfThen(0),
+  testIfThenElse(0),
+  testSwitchWithoutFallthrough(1),
+  testTryCatch(0),
+  testTryCatchOn(0),
+  testTryCatchStackTrace(0),
+  testTryFinally(0)],
+  type=[inst:JSNull]
+*/
+main() {
+  testIfThen();
+  testIfThenElse();
+  testForIn(null);
+  testForInTyped(null);
+  testTryCatch();
+  testTryCatchOn();
+  testTryCatchStackTrace();
+  testTryFinally();
+  testSwitchWithoutFallthrough(null);
+  testAssert();
+  testAssertWithMessage();
+}
+
+/*element: testIfThen:
+ type=[
+  inst:JSBool,
+  inst:JSDouble,
+  inst:JSInt,
+  inst:JSNumber,
+  inst:JSPositiveInt,
+  inst:JSUInt31,
+  inst:JSUInt32]
+*/
+testIfThen() {
+  // ignore: DEAD_CODE
+  if (false) return 42;
+  return 1;
+}
+
+/*element: testIfThenElse:
+ type=[
+  inst:JSBool,
+  inst:JSDouble,
+  inst:JSInt,
+  inst:JSNumber,
+  inst:JSPositiveInt,
+  inst:JSUInt31,
+  inst:JSUInt32]
+*/
+testIfThenElse() {
+  if (true)
+    return 42;
+  else
+    // ignore: DEAD_CODE
+    return 1;
+}
+
+/*kernel.element: testForIn:
+ dynamic=[
+  current,
+  iterator,
+  moveNext(0)],
+ static=[
+  checkConcurrentModificationError],
+ type=[
+  inst:JSNull,
+  inst:Null]
+*/
+/*strong.element: testForIn:
+ dynamic=[
+  current,
+  iterator,
+  moveNext(0)],
+ static=[checkConcurrentModificationError],
+ type=[
+  impl:Iterable<dynamic>,
+  inst:JSBool,
+  inst:JSNull,
+  inst:Null]
+*/
+testForIn(o) {
+  // ignore: UNUSED_LOCAL_VARIABLE
+  for (var e in o) {}
+}
+
+/*kernel.element: testForInTyped:
+ dynamic=[
+  current,
+  iterator,
+  moveNext(0)],
+ static=[
+  checkConcurrentModificationError],
+ type=[
+  check:int,
+  inst:JSNull,
+  inst:Null]
+*/
+/*strong.element: testForInTyped:
+ dynamic=[
+  current,
+  iterator,
+  moveNext(0)],
+ static=[checkConcurrentModificationError],
+ type=[
+  impl:Iterable<dynamic>,
+  impl:int,
+  inst:JSBool,
+  inst:JSNull,
+  inst:Null]
+*/
+testForInTyped(o) {
+  // ignore: UNUSED_LOCAL_VARIABLE
+  for (int e in o) {}
+}
+
+/*element: testTryCatch:
+ static=[unwrapException],
+ type=[
+  inst:PlainJavaScriptObject,
+  inst:UnknownJavaScriptObject]
+*/
+testTryCatch() {
+  try {} catch (e) {}
+}
+
+/*element: testTryCatchOn:
+ static=[unwrapException],
+ type=[
+  catch:String,
+  inst:JSBool,
+  inst:PlainJavaScriptObject,
+  inst:UnknownJavaScriptObject]
+*/
+testTryCatchOn() {
+  // ignore: UNUSED_CATCH_CLAUSE
+  try {} on String catch (e) {}
+}
+
+/*element: testTryCatchStackTrace:
+ static=[
+  getTraceFromException,
+  unwrapException],
+ type=[
+  inst:PlainJavaScriptObject,
+  inst:UnknownJavaScriptObject,
+  inst:_StackTrace]
+*/
+testTryCatchStackTrace() {
+  // ignore: UNUSED_CATCH_STACK
+  try {} catch (e, s) {}
+}
+
+/*element: testTryFinally:*/
+testTryFinally() {
+  try {} finally {}
+}
+
+/*element: testSwitchWithoutFallthrough:
+ static=[
+  throwExpression,
+  wrapException],
+ type=[
+  inst:JSDouble,
+  inst:JSInt,
+  inst:JSNumber,
+  inst:JSPositiveInt,
+  inst:JSString,
+  inst:JSUInt31,
+  inst:JSUInt32]
+*/
+testSwitchWithoutFallthrough(o) {
+  switch (o) {
+    case 0:
+    case 1:
+      o = 2;
+      break;
+    case 2:
+      o = 3;
+      return;
+    case 3:
+      throw '';
+    case 4:
+    default:
+  }
+}
+
+/*element: testAssert:static=[assertHelper],type=[inst:JSBool]*/
+testAssert() {
+  assert(true);
+}
+
+/*element: testAssertWithMessage:static=[assertTest,assertThrow],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
new file mode 100644
index 0000000..7dd7401
--- /dev/null
+++ b/tests/compiler/dart2js/impact/impact_test.dart
@@ -0,0 +1,67 @@
+// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:io';
+import 'package:async_helper/async_helper.dart';
+import 'package:compiler/src/compiler.dart';
+import 'package:compiler/src/elements/entities.dart';
+import 'package:compiler/src/frontend_strategy.dart';
+import 'package:compiler/src/kernel/element_map.dart';
+import 'package:compiler/src/kernel/kernel_strategy.dart';
+import 'package:compiler/src/universe/world_impact.dart';
+import 'package:compiler/src/universe/use.dart';
+import '../equivalence/id_equivalence.dart';
+import '../equivalence/id_equivalence_helper.dart';
+
+main(List<String> args) {
+  ImpactCacheDeleter.retainCachesForTesting = true;
+  asyncTest(() async {
+    Directory dataDir = new Directory.fromUri(Platform.script.resolve('data'));
+    await checkTests(dataDir, computeMemberImpact,
+        args: args, skipForStrong: ['fallthrough.dart'], testFrontend: true);
+  });
+}
+
+class Tags {
+  static const String typeUse = 'type';
+  static const String staticUse = 'static';
+  static const String dynamicUse = 'dynamic';
+  static const String constantUse = 'constant';
+}
+
+/// Compute type inference data for [member] from kernel based inference.
+///
+/// Fills [actualMap] with the data.
+void computeMemberImpact(
+    Compiler compiler, MemberEntity member, Map<Id, ActualData> actualMap,
+    {bool verbose: false}) {
+  KernelFrontEndStrategy frontendStrategy = compiler.frontendStrategy;
+  WorldImpact impact = compiler.impactCache[member];
+  MemberDefinition definition =
+      frontendStrategy.elementMap.getMemberDefinition(member);
+  Features features = new Features();
+  if (impact.typeUses.length > 50) {
+    features.addElement(Tags.typeUse, '*');
+  } else {
+    for (TypeUse use in impact.typeUses) {
+      features.addElement(Tags.typeUse, use.shortText);
+    }
+  }
+  if (impact.staticUses.length > 50) {
+    features.addElement(Tags.staticUse, '*');
+  } else {
+    for (StaticUse use in impact.staticUses) {
+      features.addElement(Tags.staticUse, use.shortText);
+    }
+  }
+  for (DynamicUse use in impact.dynamicUses) {
+    features.addElement(Tags.dynamicUse, use.shortText);
+  }
+  for (ConstantUse use in impact.constantUses) {
+    features.addElement(Tags.constantUse, use.shortText);
+  }
+  Id id = computeEntityId(definition.node);
+  actualMap[id] = new ActualData(new IdValue(id, features.getText()),
+      computeSourceSpanFromTreeNode(definition.node), member);
+}
diff --git a/tests/compiler/dart2js/inference/inference_test_helper.dart b/tests/compiler/dart2js/inference/inference_test_helper.dart
index 7796132..4094778 100644
--- a/tests/compiler/dart2js/inference/inference_test_helper.dart
+++ b/tests/compiler/dart2js/inference/inference_test_helper.dart
@@ -9,6 +9,7 @@
 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/types/masks.dart';
 import 'package:compiler/src/types/types.dart';
 import 'package:compiler/src/js_model/locals.dart';
 import 'package:compiler/src/kernel/element_map.dart';
@@ -105,7 +106,7 @@
       .run(definition.node);
 }
 
-/// AST visitor for computing inference data for a member.
+/// IR visitor for computing inference data for a member.
 class TypeMaskIrComputer extends IrDataExtractor
     with ComputeValueMixin<ir.Node> {
   final GlobalTypeInferenceResults<ir.Node> results;
diff --git a/tests/compiler/dart2js/inference/list_tracer_test.dart b/tests/compiler/dart2js/inference/list_tracer_test.dart
index 4e3b241..e7713ce 100644
--- a/tests/compiler/dart2js/inference/list_tracer_test.dart
+++ b/tests/compiler/dart2js/inference/list_tracer_test.dart
@@ -3,7 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'package:async_helper/async_helper.dart';
-import 'package:compiler/src/types/types.dart' show ContainerTypeMask, TypeMask;
+import 'package:compiler/src/types/masks.dart' show ContainerTypeMask, TypeMask;
 import 'package:expect/expect.dart';
 
 import 'type_mask_test_helper.dart';
diff --git a/tests/compiler/dart2js/inference/load_deferred_library_test.dart b/tests/compiler/dart2js/inference/load_deferred_library_test.dart
index 78a0ea5..62d1b4a 100644
--- a/tests/compiler/dart2js/inference/load_deferred_library_test.dart
+++ b/tests/compiler/dart2js/inference/load_deferred_library_test.dart
@@ -11,7 +11,7 @@
 import 'package:compiler/src/js_model/js_strategy.dart';
 import 'package:compiler/src/kernel/element_map.dart';
 import 'package:compiler/src/types/abstract_value_domain.dart';
-import 'package:compiler/src/types/types.dart';
+import 'package:compiler/src/types/masks.dart';
 import 'package:compiler/src/world.dart';
 import 'package:expect/expect.dart';
 import 'package:kernel/ast.dart' as ir;
diff --git a/tests/compiler/dart2js/inference/map_tracer_test.dart b/tests/compiler/dart2js/inference/map_tracer_test.dart
index c450698..4336589 100644
--- a/tests/compiler/dart2js/inference/map_tracer_test.dart
+++ b/tests/compiler/dart2js/inference/map_tracer_test.dart
@@ -6,7 +6,8 @@
 import 'package:compiler/src/compiler.dart';
 import 'package:compiler/src/elements/entities.dart';
 import 'package:compiler/src/inferrer/type_graph_inferrer.dart';
-import 'package:compiler/src/types/types.dart' show MapTypeMask, TypeMask;
+import 'package:compiler/src/types/abstract_value_domain.dart';
+import 'package:compiler/src/types/masks.dart' show MapTypeMask, TypeMask;
 import 'package:compiler/src/world.dart';
 import 'package:expect/expect.dart';
 
@@ -233,7 +234,7 @@
   TypeGraphInferrer typesInferrer =
       compiler.globalInference.typesInferrerInternal;
   ClosedWorld closedWorld = typesInferrer.closedWorld;
-  CommonMasks commonMasks = closedWorld.abstractValueDomain;
+  AbstractValueDomain commonMasks = closedWorld.abstractValueDomain;
   TypeMask emptyType = new TypeMask.nonNullEmpty();
   MemberEntity aKey = findMember(closedWorld, 'aKey');
   TypeMask aKeyType = typesInferrer.getTypeOfMember(aKey);
diff --git a/tests/compiler/dart2js/inference/type_combination_test.dart b/tests/compiler/dart2js/inference/type_combination_test.dart
index 2d84f97..64216dc 100644
--- a/tests/compiler/dart2js/inference/type_combination_test.dart
+++ b/tests/compiler/dart2js/inference/type_combination_test.dart
@@ -7,10 +7,9 @@
 import 'package:compiler/src/common_elements.dart';
 import 'package:compiler/src/compiler.dart';
 import 'package:compiler/src/elements/entities.dart';
-import 'package:compiler/src/types/types.dart';
+import 'package:compiler/src/types/masks.dart';
 import 'package:compiler/src/world.dart';
 import 'type_mask_test_helper.dart';
-import '../compiler_helper.dart';
 import '../memory_compiler.dart';
 
 TypeMask nullType;
diff --git a/tests/compiler/dart2js/inference/type_mask2_test.dart b/tests/compiler/dart2js/inference/type_mask2_test.dart
index 3cd3137..c5e075a 100644
--- a/tests/compiler/dart2js/inference/type_mask2_test.dart
+++ b/tests/compiler/dart2js/inference/type_mask2_test.dart
@@ -8,7 +8,7 @@
 import 'package:expect/expect.dart';
 import 'package:async_helper/async_helper.dart';
 import 'package:compiler/src/elements/entities.dart';
-import 'package:compiler/src/types/types.dart';
+import 'package:compiler/src/types/masks.dart';
 import 'package:compiler/src/world.dart' show ClosedWorld;
 import '../type_test_helper.dart';
 
diff --git a/tests/compiler/dart2js/inference/type_mask_disjoint_test.dart b/tests/compiler/dart2js/inference/type_mask_disjoint_test.dart
index b520387..a680f5b 100644
--- a/tests/compiler/dart2js/inference/type_mask_disjoint_test.dart
+++ b/tests/compiler/dart2js/inference/type_mask_disjoint_test.dart
@@ -7,7 +7,7 @@
 import 'package:compiler/src/common_elements.dart';
 import 'package:compiler/src/compiler.dart';
 import 'package:compiler/src/elements/entities.dart';
-import 'package:compiler/src/types/types.dart';
+import 'package:compiler/src/types/masks.dart';
 import 'package:compiler/src/world.dart';
 
 import '../memory_compiler.dart';
diff --git a/tests/compiler/dart2js/inference/type_mask_test.dart b/tests/compiler/dart2js/inference/type_mask_test.dart
index 91b1968..4561962 100644
--- a/tests/compiler/dart2js/inference/type_mask_test.dart
+++ b/tests/compiler/dart2js/inference/type_mask_test.dart
@@ -4,7 +4,7 @@
 
 import 'package:async_helper/async_helper.dart';
 import 'package:expect/expect.dart';
-import 'package:compiler/src/types/types.dart';
+import 'package:compiler/src/types/masks.dart';
 
 import 'package:compiler/src/common_elements.dart';
 import 'package:compiler/src/compiler.dart';
diff --git a/tests/compiler/dart2js/inference/type_mask_test_helper.dart b/tests/compiler/dart2js/inference/type_mask_test_helper.dart
index a3b661b..f979741 100644
--- a/tests/compiler/dart2js/inference/type_mask_test_helper.dart
+++ b/tests/compiler/dart2js/inference/type_mask_test_helper.dart
@@ -4,7 +4,7 @@
 
 library type_mask_test_helper;
 
-import 'package:compiler/src/types/types.dart';
+import 'package:compiler/src/types/masks.dart';
 import 'package:compiler/src/world.dart' show ClosedWorld;
 
 export 'package:compiler/src/types/types.dart';
diff --git a/tests/compiler/dart2js/inference/union_type_test.dart b/tests/compiler/dart2js/inference/union_type_test.dart
index 1890622..37f4e29 100644
--- a/tests/compiler/dart2js/inference/union_type_test.dart
+++ b/tests/compiler/dart2js/inference/union_type_test.dart
@@ -4,7 +4,7 @@
 
 import "package:async_helper/async_helper.dart";
 import "package:expect/expect.dart";
-import "package:compiler/src/types/types.dart";
+import "package:compiler/src/types/masks.dart";
 import "package:compiler/src/world.dart";
 import '../type_test_helper.dart';
 
diff --git a/tests/compiler/dart2js/memory_compiler.dart b/tests/compiler/dart2js/memory_compiler.dart
index 3f92e4c..6564b2b 100644
--- a/tests/compiler/dart2js/memory_compiler.dart
+++ b/tests/compiler/dart2js/memory_compiler.dart
@@ -204,9 +204,6 @@
     compiler.processLoadedLibraries(new MemoryLoadedLibraries(copiedLibraries));
     ResolutionEnqueuer resolutionEnqueuer = compiler.startResolution();
 
-    compiler.backend.constantCompilerTask
-        .copyConstantValues(cachedCompiler.backend.constantCompilerTask);
-
     Iterable<MemberEntity> cachedTreeElements =
         cachedCompiler.enqueuer.resolution.processedEntities;
     cachedTreeElements.forEach((MemberEntity element) {
@@ -221,19 +218,12 @@
     // One potential problem that can occur when reusing elements is that there
     // is a stale reference to an old compiler object.  By nulling out the old
     // compiler's fields, such stale references are easier to identify.
-    cachedCompiler.scanner = null;
-    cachedCompiler.dietParser = null;
-    cachedCompiler.parser = null;
-    cachedCompiler.patchParser = null;
     cachedCompiler.libraryLoader = null;
-    cachedCompiler.resolver = null;
-    cachedCompiler.checker = null;
     cachedCompiler.globalInference = null;
     cachedCompiler.backend = null;
     // Don't null out the enqueuer as it prevents us from using cachedCompiler
     // more than once.
     cachedCompiler.deferredLoadTask = null;
-    cachedCompiler.mirrorUsageAnalyzerTask = null;
     cachedCompiler.dumpInfoTask = null;
   }
   return compiler;
diff --git a/tests/compiler/dart2js/model/enqueuer_test.dart b/tests/compiler/dart2js/model/enqueuer_test.dart
index 567a11f..1912168 100644
--- a/tests/compiler/dart2js/model/enqueuer_test.dart
+++ b/tests/compiler/dart2js/model/enqueuer_test.dart
@@ -13,7 +13,7 @@
 import 'package:compiler/src/elements/names.dart';
 import 'package:compiler/src/elements/types.dart';
 import 'package:compiler/src/enqueue.dart';
-import 'package:compiler/src/types/types.dart';
+import 'package:compiler/src/types/masks.dart';
 import 'package:compiler/src/universe/call_structure.dart';
 import 'package:compiler/src/universe/selector.dart';
 import 'package:compiler/src/universe/world_impact.dart';
diff --git a/tests/compiler/dart2js/model/strong_mode_impact_test.dart b/tests/compiler/dart2js/model/strong_mode_impact_test.dart
index 188bd2e..907a0cc 100644
--- a/tests/compiler/dart2js/model/strong_mode_impact_test.dart
+++ b/tests/compiler/dart2js/model/strong_mode_impact_test.dart
@@ -8,6 +8,7 @@
 import 'package:compiler/src/compiler.dart';
 import 'package:compiler/src/common_elements.dart';
 import 'package:compiler/src/elements/entities.dart';
+import 'package:compiler/src/frontend_strategy.dart';
 import 'package:compiler/src/world.dart';
 import 'package:compiler/src/universe/use.dart';
 import 'package:compiler/src/universe/world_impact.dart';
@@ -89,12 +90,10 @@
         : new Impact(checkedModeChecks: ['int', 'String']),
   };
 
+  ImpactCacheDeleter.retainCachesForTesting = true;
   CompilationResult result = await runCompiler(
       memorySourceFiles: {'main.dart': source},
-      options: strongMode ? [Flags.strongMode] : [],
-      beforeRun: (compiler) {
-        compiler.impactCacheDeleter.retainCachesForTesting = true;
-      });
+      options: strongMode ? [Flags.strongMode] : []);
   Expect.isTrue(result.isSuccess);
   Compiler compiler = result.compiler;
 
diff --git a/tests/compiler/dart2js/model/subtype_test.dart b/tests/compiler/dart2js/model/subtype_test.dart
index 63eaa41..7a44b77 100644
--- a/tests/compiler/dart2js/model/subtype_test.dart
+++ b/tests/compiler/dart2js/model/subtype_test.dart
@@ -9,7 +9,6 @@
 import 'package:compiler/src/commandline_options.dart';
 import 'package:compiler/src/elements/entities.dart' show ClassEntity;
 import 'package:compiler/src/elements/types.dart';
-import 'package:compiler/src/elements/resolution_types.dart';
 import 'package:expect/expect.dart';
 import '../type_test_helper.dart';
 
@@ -44,10 +43,6 @@
     Expect.isTrue(env.isPotentialSubtype(subtype, supertype),
         '$subtype <: $supertype (potential)');
   }
-  if (env.types is Types) {
-    Expect.equals(expectMoreSpecific, env.isMoreSpecific(subtype, supertype),
-        '$subtype << $supertype');
-  }
 }
 
 void testElementTypes(TypeEnvironment env, String subname, String supername,
diff --git a/tests/compiler/dart2js/receiver_type_test.dart b/tests/compiler/dart2js/receiver_type_test.dart
index da0a7a2..ac1c71f 100644
--- a/tests/compiler/dart2js/receiver_type_test.dart
+++ b/tests/compiler/dart2js/receiver_type_test.dart
@@ -5,7 +5,7 @@
 import 'dart:async';
 import 'package:async_helper/async_helper.dart';
 import 'package:compiler/src/elements/entities.dart';
-import 'package:compiler/src/types/types.dart';
+import 'package:compiler/src/types/masks.dart';
 import 'package:compiler/src/universe/selector.dart';
 import 'package:compiler/src/world.dart';
 import 'package:expect/expect.dart';
diff --git a/tests/compiler/dart2js/rti/rti_need_test_helper.dart b/tests/compiler/dart2js/rti/rti_need_test_helper.dart
index d13dae2..d7a44f5 100644
--- a/tests/compiler/dart2js/rti/rti_need_test_helper.dart
+++ b/tests/compiler/dart2js/rti/rti_need_test_helper.dart
@@ -9,9 +9,7 @@
 import 'package:compiler/src/common_elements.dart';
 import 'package:compiler/src/compiler.dart';
 import 'package:compiler/src/diagnostics/diagnostic_listener.dart';
-import 'package:compiler/src/elements/elements.dart';
 import 'package:compiler/src/elements/entities.dart';
-import 'package:compiler/src/elements/resolution_types.dart';
 import 'package:compiler/src/elements/types.dart';
 import 'package:compiler/src/js_backend/runtime_types.dart';
 import 'package:compiler/src/kernel/element_map.dart';
@@ -165,10 +163,6 @@
       }
 
       if (frontendClosure != null) {
-        if (frontendClosure is LocalFunctionElement &&
-            rtiNeed.localFunctionNeedsSignature(frontendClosure)) {
-          features.add(Tags.needsSignature);
-        }
         addFrontendData(frontendClosure);
         if (rtiNeedBuilder.localFunctionsUsingTypeVariableLiterals
             .contains(frontendClosure)) {
@@ -187,7 +181,7 @@
 }
 
 /// Visitor that determines whether a type refers to [entity].
-class FindTypeVisitor extends BaseResolutionDartTypeVisitor<bool, Null> {
+class FindTypeVisitor extends BaseDartTypeVisitor<bool, Null> {
   final Entity entity;
 
   FindTypeVisitor(this.entity);
diff --git a/tests/compiler/dart2js/sourcemaps/helpers/source_map_validator_helper.dart b/tests/compiler/dart2js/sourcemaps/helpers/source_map_validator_helper.dart
index 75c211b..cc49c33 100644
--- a/tests/compiler/dart2js/sourcemaps/helpers/source_map_validator_helper.dart
+++ b/tests/compiler/dart2js/sourcemaps/helpers/source_map_validator_helper.dart
@@ -10,19 +10,6 @@
 import 'package:expect/expect.dart';
 import 'package:source_maps/source_maps.dart';
 import 'package:compiler/src/apiimpl.dart';
-import 'package:compiler/src/elements/elements.dart'
-    show
-        AstElement,
-        ClassElement,
-        CompilationUnitElement,
-        Element,
-        FunctionElement,
-        LibraryElement,
-        MemberElement;
-import 'package:compiler/src/io/source_file.dart' show SourceFile;
-import 'package:compiler/src/io/source_information.dart'
-    show computeElementNameForSourceMaps;
-import 'package:kernel/ast.dart' show Location;
 
 validateSourceMap(Uri targetUri,
     {Uri mainUri, Position mainPosition, CompilerImpl compiler}) {
@@ -102,6 +89,8 @@
 
 checkNames(
     Uri targetUri, Uri mapUri, SingleMapping sourceMap, CompilerImpl compiler) {
+  // TODO(johnniwinther): Port this to work on kernel based elements.
+  /*
   Map<Uri, CompilationUnitElement> compilationUnitMap = {};
 
   void mapCompilationUnits(LibraryElement library) {
@@ -142,9 +131,8 @@
         Interval intervalFromElement(AstElement element) {
           if (!element.hasNode) return null;
 
-          var begin = element.node.getBeginToken().charOffset;
-          var endToken = element.node.getEndToken();
-          int end = endToken.charOffset + endToken.charCount;
+          var begin = 0;
+          int end = 0;
           return new Interval(
               positionFromOffset(begin), positionFromOffset(end));
         }
@@ -224,7 +212,7 @@
         });
       }
     }
-  });
+  });*/
 }
 
 RegExp mainSignaturePrefix = new RegExp(r'main: \[?function\(');
diff --git a/tests/compiler/dart2js/sourcemaps/helpers/sourcemap_helper.dart b/tests/compiler/dart2js/sourcemaps/helpers/sourcemap_helper.dart
index 70a70c1..88372a5 100644
--- a/tests/compiler/dart2js/sourcemaps/helpers/sourcemap_helper.dart
+++ b/tests/compiler/dart2js/sourcemaps/helpers/sourcemap_helper.dart
@@ -9,7 +9,6 @@
 import 'package:compiler/compiler_new.dart';
 import 'package:compiler/src/apiimpl.dart' as api;
 import 'package:compiler/src/commandline_options.dart';
-import 'package:compiler/src/elements/elements.dart';
 import 'package:compiler/src/elements/entities.dart';
 import 'package:compiler/src/io/code_output.dart';
 import 'package:compiler/src/io/source_file.dart';
diff --git a/tests/compiler/dart2js/sourcemaps/tools/diff_view.dart b/tests/compiler/dart2js/sourcemaps/tools/diff_view.dart
index 194dfed..ead452a 100644
--- a/tests/compiler/dart2js/sourcemaps/tools/diff_view.dart
+++ b/tests/compiler/dart2js/sourcemaps/tools/diff_view.dart
@@ -8,9 +8,9 @@
 import 'dart:convert';
 import 'dart:io';
 
+import 'package:compiler/src/common_elements.dart';
 import 'package:compiler/src/commandline_options.dart';
 import 'package:compiler/src/diagnostics/invariant.dart';
-import 'package:compiler/src/elements/elements.dart';
 import 'package:compiler/src/elements/entities.dart';
 import 'package:compiler/src/filenames.dart';
 import 'package:compiler/src/io/position_information.dart';
@@ -615,12 +615,15 @@
 }
 
 class CodeSources {
-  Map<Element, CodeSource> codeSourceMap = <Element, CodeSource>{};
+  Map<Entity, CodeSource> codeSourceMap = <Entity, CodeSource>{};
   Map<Uri, Map<Interval, CodeSource>> uriCodeSourceMap =
       <Uri, Map<Interval, CodeSource>>{};
 
   CodeSources(SourceMapProcessor processor, SourceMaps sourceMaps) {
-    CodeSource computeCodeSource(Element element) {
+    ElementEnvironment elementEnvironment =
+        sourceMaps.compiler.backendClosedWorldForTesting.elementEnvironment;
+
+    CodeSource computeCodeSource(Entity element) {
       return codeSourceMap.putIfAbsent(element, () {
         CodeSource codeSource = codeSourceFromElement(element);
         if (codeSource.begin != null) {
@@ -650,26 +653,18 @@
           }
           intervals[interval] = codeSource;
         }
-        if (element is ClassElement) {
-          element.forEachLocalMember((Element member) {
-            codeSource.members.add(computeCodeSource(member));
-          });
-          element.implementation.forEachLocalMember((Element member) {
-            codeSource.members.add(computeCodeSource(member));
-          });
-        } else if (element is MemberElement) {
-          element.nestedClosures.forEach((Element closure) {
-            codeSource.members.add(computeCodeSource(closure));
-          });
+        if (element is ClassEntity) {
+          elementEnvironment.forEachConstructor(element, computeCodeSource);
+          elementEnvironment.forEachLocalClassMember(
+              element, computeCodeSource);
         }
         return codeSource;
       });
     }
 
-    for (LibraryElement library
-        in sourceMaps.compiler.libraryLoader.libraries) {
-      library.forEachLocalMember(computeCodeSource);
-      library.implementation.forEachLocalMember(computeCodeSource);
+    for (LibraryEntity library in elementEnvironment.libraries) {
+      elementEnvironment.forEachClass(library, computeCodeSource);
+      elementEnvironment.forEachLibraryMember(library, computeCodeSource);
     }
 
     uriCodeSourceMap.forEach((Uri uri, Map<Interval, CodeSource> intervals) {
@@ -882,32 +877,25 @@
 }
 
 /// Compute a [CodeSource] for source span of [element].
-CodeSource codeSourceFromElement(Entity _element) {
+CodeSource codeSourceFromElement(Entity element) {
   // TODO(johnniwinther): Handle kernel based elements.
-  Element element = _element;
   CodeKind kind;
   Uri uri;
   String name;
   int begin;
   int end;
-  if (element.isLibrary) {
-    LibraryElement library = element;
+  if (element is LibraryEntity) {
     kind = CodeKind.LIBRARY;
-    name = library.name;
-    uri = library.entryCompilationUnit.script.resourceUri;
-  } else if (element.isClass) {
+    name = element.name;
+    uri = element.canonicalUri;
+  } else if (element is ClassEntity) {
     kind = CodeKind.CLASS;
     name = element.name;
-    uri = element.compilationUnit.script.resourceUri;
-  } else {
-    AstElement astElement = element.implementation;
+    uri = element.library.canonicalUri;
+  } else if (element is MemberEntity) {
     kind = CodeKind.MEMBER;
-    uri = astElement.compilationUnit.script.resourceUri;
-    name = computeElementNameForSourceMaps(astElement);
-    if (astElement.hasNode) {
-      begin = astElement.node.getBeginToken().charOffset;
-      end = astElement.node.getEndToken().charEnd;
-    }
+    uri = element.library.canonicalUri;
+    name = computeElementNameForSourceMaps(element);
   }
   return new CodeSource(kind, uri, name, begin, end);
 }
diff --git a/tests/compiler/dart2js/type_test_helper.dart b/tests/compiler/dart2js/type_test_helper.dart
index 36496c2..51e1680 100644
--- a/tests/compiler/dart2js/type_test_helper.dart
+++ b/tests/compiler/dart2js/type_test_helper.dart
@@ -6,37 +6,24 @@
 
 import 'dart:async';
 import 'package:expect/expect.dart';
-import 'package:compiler/src/common/resolution.dart';
 import 'package:compiler/src/common_elements.dart';
 import 'package:compiler/src/commandline_options.dart';
-import 'package:compiler/src/elements/resolution_types.dart';
 import 'package:compiler/src/elements/types.dart';
 import 'package:compiler/src/compiler.dart' show Compiler;
 import 'package:compiler/src/elements/entities.dart';
-import 'package:compiler/src/elements/elements.dart'
-    show ClassElement, LibraryElement, TypedefElement;
+import 'package:compiler/src/frontend_strategy.dart';
 import 'package:compiler/src/kernel/kernel_strategy.dart';
-import 'package:compiler/src/universe/world_builder.dart';
 import 'package:compiler/src/world.dart' show ClosedWorld;
 import 'memory_compiler.dart' as memory;
 
-DartType instantiate(Entity element, List<DartType> arguments) {
-  if (element is ClassElement) {
-    return new ResolutionInterfaceType(element, arguments);
-  } else if (element is ClassEntity) {
-    return new InterfaceType(element, arguments);
-  } else {
-    assert(element is TypedefElement);
-    return new ResolutionTypedefType(element, arguments);
-  }
+DartType instantiate(ClassEntity element, List<DartType> arguments) {
+  return new InterfaceType(element, arguments);
 }
 
 class TypeEnvironment {
   final Compiler compiler;
   final bool testBackendWorld;
 
-  Resolution get resolution => compiler.resolution;
-
   static Future<TypeEnvironment> create(String source,
       {bool expectNoErrors: false,
       bool expectNoWarningsOrErrors: false,
@@ -73,8 +60,7 @@
               ..addAll(options)),
         diagnosticHandler: collector,
         beforeRun: (compiler) {
-          ElementResolutionWorldBuilder.useInstantiationMap = true;
-          compiler.impactCacheDeleter.retainCachesForTesting = true;
+          ImpactCacheDeleter.retainCachesForTesting = true;
           compiler.stopAfterTypeInference = stopAfterTypeInference;
         });
     compiler = result.compiler;
@@ -108,15 +94,11 @@
   }
 
   DartTypes get types {
-    if (resolution != null) {
-      return resolution.types;
+    if (testBackendWorld) {
+      return compiler.backendClosedWorldForTesting.dartTypes;
     } else {
-      if (testBackendWorld) {
-        return compiler.backendClosedWorldForTesting.dartTypes;
-      } else {
-        KernelFrontEndStrategy frontendStrategy = compiler.frontendStrategy;
-        return frontendStrategy.elementMap.types;
-      }
+      KernelFrontEndStrategy frontendStrategy = compiler.frontendStrategy;
+      return frontendStrategy.elementMap.types;
     }
   }
 
@@ -126,15 +108,7 @@
     element ??= elementEnvironment.lookupClass(mainLibrary, name);
     element ??=
         elementEnvironment.lookupClass(commonElements.coreLibrary, name);
-    if (element == null && mainLibrary is LibraryElement) {
-      element = mainLibrary.find(name);
-    }
     Expect.isNotNull(element, "No element named '$name' found.");
-    if (element is ClassElement) {
-      element.ensureResolved(compiler.resolution);
-    } else if (element is TypedefElement) {
-      element.computeType(compiler.resolution);
-    }
     return element;
   }
 
@@ -142,9 +116,6 @@
     LibraryEntity mainLibrary = elementEnvironment.mainLibrary;
     ClassEntity element = elementEnvironment.lookupClass(mainLibrary, name);
     Expect.isNotNull(element, "No class named '$name' found.");
-    if (element is ClassElement) {
-      element.ensureResolved(compiler.resolution);
-    }
     return element;
   }
 
@@ -157,25 +128,16 @@
     } else if (element is ClassEntity) {
       return elementEnvironment.getThisType(element);
     } else {
-      /// ignore: undefined_method
-      return element.computeType(compiler.resolution);
+      throw 'Unexpected element $element';
     }
   }
 
   DartType operator [](String name) {
     if (name == 'dynamic') {
-      if (resolution != null) {
-        return const ResolutionDynamicType();
-      } else {
-        return const DynamicType();
-      }
+      return const DynamicType();
     }
     if (name == 'void') {
-      if (resolution != null) {
-        return const ResolutionVoidType();
-      } else {
-        return const VoidType();
-      }
+      return const VoidType();
     }
     return getElementType(name);
   }
@@ -231,36 +193,6 @@
     return types.isPotentialSubtype(T, S);
   }
 
-  bool isMoreSpecific(ResolutionDartType T, ResolutionDartType S) {
-    return (types as Types).isMoreSpecific(T, S);
-  }
-
-  ResolutionDartType computeLeastUpperBound(
-      ResolutionDartType T, ResolutionDartType S) {
-    return (types as Types).computeLeastUpperBound(T, S);
-  }
-
-  ResolutionDartType flatten(ResolutionDartType T) {
-    return (types as Types).flatten(T);
-  }
-
-  ResolutionFunctionType functionType(
-      ResolutionDartType returnType, List<ResolutionDartType> parameters,
-      {List<ResolutionDartType> optionalParameters:
-          const <ResolutionDartType>[],
-      Map<String, ResolutionDartType> namedParameters}) {
-    List<String> namedParameterNames = <String>[];
-    List<ResolutionDartType> namedParameterTypes = <ResolutionDartType>[];
-    if (namedParameters != null) {
-      namedParameters.forEach((String name, ResolutionDartType type) {
-        namedParameterNames.add(name);
-        namedParameterTypes.add(type);
-      });
-    }
-    return new ResolutionFunctionType.synthesized(returnType, parameters,
-        optionalParameters, namedParameterNames, namedParameterTypes);
-  }
-
   ClosedWorld get closedWorld {
     if (testBackendWorld) {
       return compiler.backendClosedWorldForTesting;
diff --git a/tests/compiler/dart2js_extra/dummy_compiler_test.dart b/tests/compiler/dart2js_extra/dummy_compiler_test.dart
index 3e3a64f..0c13dbb 100644
--- a/tests/compiler/dart2js_extra/dummy_compiler_test.dart
+++ b/tests/compiler/dart2js_extra/dummy_compiler_test.dart
@@ -27,8 +27,6 @@
     return buildLibrarySource(DEFAULT_INTERCEPTORS_LIBRARY);
   } else if (uri.path.endsWith('js_helper.dart')) {
     return buildLibrarySource(DEFAULT_JS_HELPER_LIBRARY);
-  } else if (uri.path.endsWith('isolate_helper.dart')) {
-    return buildLibrarySource(DEFAULT_ISOLATE_HELPER_LIBRARY);
   } else if (uri.path.endsWith('/async.dart')) {
     return buildLibrarySource(DEFAULT_ASYNC_LIBRARY);
   } else {
diff --git a/tests/compiler/dart2js_extra/instantiation_stub_2_test.dart b/tests/compiler/dart2js_extra/instantiation_stub_2_test.dart
new file mode 100644
index 0000000..49dfcaf
--- /dev/null
+++ b/tests/compiler/dart2js_extra/instantiation_stub_2_test.dart
@@ -0,0 +1,27 @@
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// dart2jsOptions=--strong
+
+import 'package:expect/expect.dart';
+
+List<T> foo<T>([T a1, T a2, T a3, T a4, T a5, T a6, T a7]) =>
+    <T>[a1, a2, a3, a4, a5, a6, a7];
+
+class CC {
+  List<T> bar<T, U, V>([T a1, T a2, T a3, T a4, T a5, T a6]) =>
+      <T>[a1, a2, a3, a4, a5, a6];
+}
+
+main() {
+  // We expect a call$1$5 entry for foo, accessed nowhere else in the program
+  // except via the call$5 entry on the instantiation.
+  List<int> Function(int, int, int, int, int) f = foo;
+  Expect.equals(4, f(1, 2, 3, 4, 5)[3]);
+
+  // We expect a bar$3$4 entry for bar, accessed nowhere else in the program
+  // except via the call$4 entry on the instantiation.
+  var o = new CC();
+  List<String> Function(String, String, String, String) g = o.bar;
+  Expect.equals('abcdnullnull', g('a', 'b', 'c', 'd').join(''));
+}
diff --git a/tests/compiler/dart2js_extra/mock_libraries.dart b/tests/compiler/dart2js_extra/mock_libraries.dart
index f5f6e63..025f221 100644
--- a/tests/compiler/dart2js_extra/mock_libraries.dart
+++ b/tests/compiler/dart2js_extra/mock_libraries.dart
@@ -13,7 +13,6 @@
 _js_helper:_internal/js_runtime/lib/js_helper.dart
 _interceptors:_internal/js_runtime/lib/interceptors.dart
 _internal:internal/internal.dart
-_isolate_helper:_internal/js_runtime/lib/isolate_helper.dart
 """;
 
 String buildLibrarySource(Map<String, String> elementMap,
@@ -130,7 +129,6 @@
 const String DEFAULT_PATCH_CORE_SOURCE = r'''
 import 'dart:_js_helper';
 import 'dart:_interceptors';
-import 'dart:_isolate_helper';
 import 'dart:async';
 
 @patch
@@ -436,14 +434,6 @@
   'JavaScriptFunction': 'class JavaScriptFunction {}',
 };
 
-const Map<String, String> DEFAULT_ISOLATE_HELPER_LIBRARY =
-    const <String, String>{
-  'startRootIsolate': 'void startRootIsolate(entry, args) {}',
-  '_currentIsolate': 'var _currentIsolate;',
-  '_callInIsolate': 'var _callInIsolate;',
-  '_WorkerBase': 'class _WorkerBase {}',
-};
-
 const Map<String, String> DEFAULT_ASYNC_LIBRARY = const <String, String>{
   'DeferredLibrary': 'class DeferredLibrary {}',
   'Future': '''
diff --git a/tests/compiler/dart2js_native/compute_this_script_test.dart b/tests/compiler/dart2js_native/compute_this_script_test.dart
index 2cdfb52..fcf4539 100644
--- a/tests/compiler/dart2js_native/compute_this_script_test.dart
+++ b/tests/compiler/dart2js_native/compute_this_script_test.dart
@@ -2,17 +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.
 
-// Test of IsolateNatives.computeThisScript().
+// Test of _computeThisScript().
 
-import 'dart:_isolate_helper';
+import 'dart:_js_helper' show thisScript;
 
 main() {
-  String script = computeThisScript();
-
   // This is somewhat brittle and relies on an implementation detail
   // of our test runner, but I can think of no other way to test this.
   // -- ahe
-  if (!script.endsWith('/out.js')) {
-    throw 'Unexpected script: "$script"';
+  if (!thisScript.endsWith('/out.js')) {
+    throw 'Unexpected script: "$thiscript"';
   }
 }
diff --git a/tests/corelib_2/corelib_2.status b/tests/corelib_2/corelib_2.status
index 87b316b..6aac957 100644
--- a/tests/corelib_2/corelib_2.status
+++ b/tests/corelib_2/corelib_2.status
@@ -306,7 +306,6 @@
 
 # ===== dartk + vm status lines =====
 [ $compiler == dartk && $runtime == vm && $strong ]
-apply_generic_function_test: RuntimeError
 iterable_fold_test/02: RuntimeError
 iterable_reduce_test/01: CompileTimeError # Issue 31533
 iterable_reduce_test/none: RuntimeError
@@ -321,7 +320,6 @@
 apply_test/01: RuntimeError
 
 [ $compiler == dartkp && $runtime == dart_precompiled && $strong ]
-apply_generic_function_test: RuntimeError
 iterable_fold_test/02: RuntimeError
 iterable_reduce_test/01: CompileTimeError # Issue 31533
 iterable_reduce_test/none: RuntimeError
diff --git a/tests/corelib_2/map_unmodifiable_cast_test.dart b/tests/corelib_2/map_unmodifiable_cast_test.dart
index 3091337..ec5b419 100644
--- a/tests/corelib_2/map_unmodifiable_cast_test.dart
+++ b/tests/corelib_2/map_unmodifiable_cast_test.dart
@@ -49,9 +49,9 @@
   testNum(m2.cast<int, int>(), "Map<num>.unmod.cast<int>");
 
   Map<Symbol, dynamic> nsm = new NsmMap().foo(a: 0);
-  test(nsm, #a, 0, "nsm");
-  test(nsm.cast<Object, int>(), #a, 0, "nsm.cast");
-  test(nsm.retype<Object, int>(), #a, 0, "nsm.retype");
+  test(nsm, #a, 0, "nsm", noSuchMethodMap: true);
+  test(nsm.cast<Object, int>(), #a, 0, "nsm.cast", noSuchMethodMap: true);
+  test(nsm.retype<Object, int>(), #a, 0, "nsm.retype", noSuchMethodMap: true);
 }
 
 void testNum(Map<Object, Object> map, String name) {
@@ -59,11 +59,14 @@
 }
 
 void test(
-    Map<Object, Object> map, Object firstKey, Object firstValue, String name) {
-  Expect.isTrue(map.containsKey(firstKey), "$name.containsKey");
-  Expect.equals(1, map.length, "$name.length");
-  Expect.equals(firstKey, map.keys.first, "$name.keys.first");
-  Expect.equals(firstValue, map.values.first, "$name.values.first");
+    Map<Object, Object> map, Object firstKey, Object firstValue, String name,
+    {bool noSuchMethodMap: false}) {
+  if (!noSuchMethodMap) {
+    Expect.isTrue(map.containsKey(firstKey), "$name.containsKey");
+    Expect.equals(1, map.length, "$name.length");
+    Expect.equals(firstKey, map.keys.first, "$name.keys.first");
+    Expect.equals(firstValue, map.values.first, "$name.values.first");
+  }
 
   Expect.throwsUnsupportedError(map.clear, "$name.clear");
   Expect.throwsUnsupportedError(() {
diff --git a/tests/language/language.status b/tests/language/language.status
index 33b2122..a228688 100644
--- a/tests/language/language.status
+++ b/tests/language/language.status
@@ -359,6 +359,14 @@
 assertion_initializer_const_error_test/01: MissingCompileTimeError
 assertion_initializer_const_function_error_test/01: MissingCompileTimeError
 
+[ $mode == debug && $hot_reload_rollback ]
+enum_duplicate_test/02: Pass, Crash # http://dartbug.com/33156
+enum_duplicate_test/none: Pass, Crash # http://dartbug.com/33156
+enum_private_test/01: Pass, Crash # http://dartbug.com/33156
+
+[ $mode == debug && ($hot_reload || $hot_reload_rollback) ]
+enum_duplicate_test/01: Pass, Crash # http://dartbug.com/33156
+
 [ $runtime == dart_precompiled && $minified ]
 cyclic_type_test/*: Skip # Tests below rely on Type.toString()
 enum_duplicate_test/*: Skip # Uses Enum.toString()
diff --git a/tests/language/language_dart2js.status b/tests/language/language_dart2js.status
index 1f1f0d4..b9f01fd 100644
--- a/tests/language/language_dart2js.status
+++ b/tests/language/language_dart2js.status
@@ -289,7 +289,7 @@
 bit_operations_test/04: RuntimeError
 bit_operations_test/none: RuntimeError
 branch_canonicalization_test: RuntimeError
-call_function_apply_test: RuntimeError
+call_function_apply_test: RuntimeError # Issue 23873
 call_nonexistent_constructor_test/01: RuntimeError
 call_type_literal_test/01: RuntimeError
 canonical_const2_test: RuntimeError
@@ -554,7 +554,6 @@
 [ $compiler == dart2js && $fasta && $host_checked ]
 async_test/setter1: Crash # 'file:*/pkg/compiler/lib/src/kernel/element_map_impl.dart': Failed assertion: line 939 pos 18: 'asyncMarker == AsyncMarker.SYNC': is not true.
 closure_self_reference_test: Crash # 'file:*/pkg/compiler/lib/src/ssa/nodes.dart': Failed assertion: line 641 pos 12: 'isClosed()': is not true.
-generic_methods_generic_function_parameter_test: Crash # 'file:*/pkg/compiler/lib/src/ssa/builder_kernel.dart': Failed assertion: line 1728 pos 16: 'type is MethodTypeVariableType': is not true.
 generic_methods_type_expression_test/01: Crash # 'file:*/pkg/compiler/lib/src/ssa/builder_kernel.dart': Failed assertion: line 1728 pos 16: 'type is MethodTypeVariableType': is not true.
 generic_methods_type_expression_test/03: Crash # 'file:*/pkg/compiler/lib/src/ssa/builder_kernel.dart': Failed assertion: line 1728 pos 16: 'type is MethodTypeVariableType': is not true.
 generic_methods_type_expression_test/none: Crash # 'file:*/pkg/compiler/lib/src/ssa/builder_kernel.dart': Failed assertion: line 1728 pos 16: 'type is MethodTypeVariableType': is not true.
diff --git a/tests/language_2/built_in_identifier_illegal_test.dart b/tests/language_2/built_in_identifier_illegal_test.dart
index d3bb320..030aa76 100644
--- a/tests/language_2/built_in_identifier_illegal_test.dart
+++ b/tests/language_2/built_in_identifier_illegal_test.dart
@@ -4,20 +4,22 @@
 // Check that we cannot use a pseudo keyword at the class level code.
 
 // Pseudo keywords are not allowed to be used as class names.
-class abstract { } //   //# 01: syntax error
-class as { } //         //# 19: syntax error
-class dynamic { } //    //# 04: compile-time error
-class export { } //     //# 17: syntax error
-class external { } //   //# 20: syntax error
-class factory { } //    //# 05: syntax error
-class get { } //        //# 06: syntax error
-class implements { } // //# 07: syntax error
-class import { } //     //# 08: syntax error
-class library { } //    //# 10: syntax error
-class operator { } //   //# 12: syntax error
-class part { } //       //# 18: syntax error
-class set { } //        //# 13: syntax error
-class static { } //     //# 15: syntax error
-class typedef { } //    //# 16: syntax error
+class abstract { } //   //# abstract: syntax error
+class as { } //         //# as: syntax error
+class dynamic { } //    //# dynamic: compile-time error
+class export { } //     //# export: syntax error
+class external { } //   //# external: syntax error
+class factory { } //    //# factory: syntax error
+class get { } //        //# get: syntax error
+class interface { } //  //# interface: syntax error
+class implements { } // //# implements: syntax error
+class import { } //     //# import: syntax error
+class mixin { } //      //# mixin: syntax error
+class library { } //    //# library: syntax error
+class operator { } //   //# operator: syntax error
+class part { } //       //# part: syntax error
+class set { } //        //# set: syntax error
+class static { } //     //# static: syntax error
+class typedef { } //    //# typedef: syntax error
 
 main() {}
diff --git a/tests/language_2/built_in_identifier_not_prefix_test.dart b/tests/language_2/built_in_identifier_not_prefix_test.dart
index 7666032..db1e856 100644
--- a/tests/language_2/built_in_identifier_not_prefix_test.dart
+++ b/tests/language_2/built_in_identifier_not_prefix_test.dart
@@ -17,75 +17,46 @@
 
 // Dart test for using a built-in identifier as a library prefix.
 
-import 'dart:core' deferred as abstract; //    //# 01: compile-time error
-import 'dart:core' deferred as as; //          //# 02: compile-time error
-import 'dart:core' deferred as covariant; //   //# 03: compile-time error
-import 'dart:core' deferred as deferred; //    //# 04: compile-time error
-import 'dart:core' deferred as dynamic; //     //# 05: compile-time error
-import 'dart:core' deferred as export; //      //# 06: compile-time error
-import 'dart:core' deferred as external; //    //# 07: compile-time error
-import 'dart:core' deferred as factory; //     //# 08: compile-time error
-import 'dart:core' deferred as get; //         //# 09: compile-time error
-import 'dart:core' deferred as implements; //  //# 10: compile-time error
-import 'dart:core' deferred as import; //      //# 11: compile-time error
-import 'dart:core' deferred as library; //     //# 12: compile-time error
-import 'dart:core' deferred as operator; //    //# 13: compile-time error
-import 'dart:core' deferred as part; //        //# 14: compile-time error
-import 'dart:core' deferred as set; //         //# 15: compile-time error
-import 'dart:core' deferred as static; //      //# 16: compile-time error
-import 'dart:core' deferred as typedef; //     //# 17: compile-time error
-import 'dart:core' as abstract; //             //# 18: syntax error
-import 'dart:core' as as; //                   //# 19: syntax error
-import 'dart:core' as covariant; //            //# 20: syntax error
-import 'dart:core' as deferred; //             //# 21: syntax error
-import 'dart:core' as dynamic; //              //# 22: compile-time error
-import 'dart:core' as export; //               //# 23: syntax error
-import 'dart:core' as external; //             //# 24: syntax error
-import 'dart:core' as factory; //              //# 25: syntax error
-import 'dart:core' as get; //                  //# 26: syntax error
-import 'dart:core' as implements; //           //# 27: syntax error
-import 'dart:core' as import; //               //# 28: syntax error
-import 'dart:core' as library; //              //# 29: syntax error
-import 'dart:core' as operator; //             //# 30: syntax error
-import 'dart:core' as part; //                 //# 31: syntax error
-import 'dart:core' as set; //                  //# 32: syntax error
-import 'dart:core' as static; //               //# 33: syntax error
-import 'dart:core' as typedef; //              //# 34: syntax error
+import "dart:core" // Fine unless imported with a built-in identifier as prefix.
+deferred as abstract //    //# deferred-abstract: compile-time error
+deferred as as //          //# deferred-as: compile-time error
+deferred as covariant //   //# deferred-covariant: compile-time error
+deferred as deferred //    //# deferred-deferred: compile-time error
+deferred as dynamic //     //# deferred-dynamic: compile-time error
+deferred as export //      //# deferred-export: compile-time error
+deferred as external //    //# deferred-external: compile-time error
+deferred as factory //     //# deferred-factory: compile-time error
+deferred as get //         //# deferred-get: compile-time error
+deferred as implements //  //# deferred-implements: compile-time error
+deferred as import //      //# deferred-import: compile-time error
+deferred as interface //   //# deferred-interface: compile-time error
+deferred as library //     //# deferred-library: compile-time error
+deferred as mixin //       //# deferred-mixin: compile-time error
+deferred as operator //    //# deferred-operator: compile-time error
+deferred as part //        //# deferred-part: compile-time error
+deferred as set //         //# deferred-set: compile-time error
+deferred as static //      //# deferred-static: compile-time error
+deferred as typedef //     //# deferred-typedef: compile-time error
+as abstract //             //# abstract: compile-time error
+as as //                   //# as: compile-time error
+as covariant //            //# covariant: compile-time error
+as deferred //             //# deferred: compile-time error
+as dynamic //              //# dynamic: compile-time error
+as export //               //# export: compile-time error
+as external //             //# external: compile-time error
+as factory //              //# factory: compile-time error
+as get //                  //# get: compile-time error
+as implements //           //# implements: compile-time error
+as import //               //# import: compile-time error
+as interface //            //# interface: compile-time error
+as library //              //# library: compile-time error
+as mixin //                //# mixin: compile-time error
+as operator //             //# operator: compile-time error
+as part //                 //# part: compile-time error
+as set //                  //# set: compile-time error
+as static //               //# static: compile-time error
+as typedef //              //# typedef: compile-time error
+;
 
 main() {
-  abstract.loadLibrary(); //   //# 01: continued
-  as.loadLibrary(); //         //# 02: continued
-  covariant.loadLibrary(); //  //# 03: continued
-  deferred.loadLibrary(); //   //# 04: continued
-  dynamic.loadLibrary(); //    //# 05: continued
-  export.loadLibrary(); //     //# 06: continued
-  external.loadLibrary(); //   //# 07: continued
-  factory.loadLibrary(); //    //# 08: continued
-  get.loadLibrary(); //        //# 09: continued
-  implements.loadLibrary(); // //# 10: continued
-  import.loadLibrary(); //     //# 11: continued
-  library.loadLibrary(); //    //# 12: continued
-  operator.loadLibrary(); //   //# 13: continued
-  part.loadLibrary(); //       //# 14: continued
-  set.loadLibrary(); //        //# 15: continued
-  static.loadLibrary(); //     //# 16: continued
-  typedef.loadLibrary(); //    //# 17: continued
-
-  abstract.int x = 42; //      //# 18: continued
-  as.int x = 42; //            //# 19: continued
-  covariant.int x = 42; //     //# 20: continued
-  deferred.int x = 42; //      //# 21: continued
-  dynamic.int x = 42; //       //# 22: continued
-  export.int x = 42; //        //# 23: continued
-  external.int x = 42; //      //# 24: continued
-  factory.int x = 42; //       //# 25: continued
-  get.int x = 42; //           //# 26: continued
-  implements.int x = 42; //    //# 27: continued
-  import.int x = 42; //        //# 28: continued
-  library.int x = 42; //       //# 29: continued
-  operator.int x = 42; //      //# 30: continued
-  part.int x = 42; //          //# 31: continued
-  set.int x = 42; //           //# 32: continued
-  static.int x = 42; //        //# 33: continued
-  typedef.int x = 42; //       //# 34: continued
 }
diff --git a/tests/language_2/built_in_identifier_test.dart b/tests/language_2/built_in_identifier_test.dart
index 46a02cc..50cc344 100644
--- a/tests/language_2/built_in_identifier_test.dart
+++ b/tests/language_2/built_in_identifier_test.dart
@@ -17,9 +17,11 @@
     var external = 0; //# 01: ok
     var factory = 0;
     var get = 0;
+    var interface = 0;
     var implements = 0;
     var import = 0;
     var library = 0;
+    var mixin = 0;
     var operator = 0;
     var part = 0;
     var set = 0;
diff --git a/tests/language_2/built_in_identifier_type_annotation_test.dart b/tests/language_2/built_in_identifier_type_annotation_test.dart
index 2fbd24e..5225709 100644
--- a/tests/language_2/built_in_identifier_type_annotation_test.dart
+++ b/tests/language_2/built_in_identifier_type_annotation_test.dart
@@ -21,97 +21,109 @@
 // Note that we have several ways to use built-in identifiers other than
 // `dynamic` in other locations in a type, e.g., `Function(int set)`.
 
-abstract x = null; //              //# 01: syntax error
-as x = null; //                    //# 02: syntax error
-covariant x = null; //             //# 03: syntax error
-deferred x = null; //              //# 04: syntax error
-dynamic x = null; //               //# 05: ok
-export x = null; //                //# 06: syntax error
-external x = null; //              //# 07: syntax error
-factory x = null; //               //# 08: syntax error
-get x = null; //                   //# 09: syntax error
-implements x = null; //            //# 10: syntax error
-import x = null; //                //# 11: syntax error
-library x = null; //               //# 12: syntax error
-operator x = null; //              //# 13: syntax error
-part x = null; //                  //# 14: syntax error
-set x = null; //                   //# 15: syntax error
-static x = null; //                //# 16: syntax error
-typedef x = null; //               //# 17: syntax error
+final // optional type before variable must not be a built-in identifier.
+abstract //              //# abstract: syntax error
+as //                    //# as: syntax error
+covariant //             //# covariant: syntax error
+deferred //              //# deferred: syntax error
+dynamic //               //# dynamic: ok
+export //                //# export: syntax error
+external //              //# external: syntax error
+factory //               //# factory: syntax error
+get //                   //# get: syntax error
+implements //            //# implements: syntax error
+import //                //# import: syntax error
+interface //             //# interface: syntax error
+library //               //# library: syntax error
+mixin //                 //# mixin: syntax error
+operator //              //# operator: syntax error
+part //                  //# part: syntax error
+set //                   //# set: syntax error
+static //                //# static: syntax error
+typedef //               //# typedef: syntax error
 
-abstract<int> x = null; //         //# 18: syntax error
-as<int> x = null; //               //# 19: syntax error
-covariant<int> x = null; //        //# 20: syntax error
-deferred<int> x = null; //         //# 21: syntax error
-dynamic<int> x = null; //          //# 22: compile-time error
-export<int> x = null; //           //# 23: syntax error
-external<int> x = null; //         //# 24: syntax error
-factory<int> x = null; //          //# 25: syntax error
-get<int> x = null; //              //# 26: syntax error
-implements<int> x = null; //       //# 27: syntax error
-import<int> x = null; //           //# 28: syntax error
-library<int> x = null; //          //# 29: syntax error
-operator<int> x = null; //         //# 30: syntax error
-part<int> x = null; //             //# 31: syntax error
-set<int> x = null; //              //# 32: syntax error
-static<int> x = null; //           //# 33: syntax error
-typedef<int> x = null; //          //# 34: syntax error
+abstract<int> //         //# abstract-gen: syntax error
+as<int> //               //# as-gen: syntax error
+covariant<int> //        //# covariant-gen: syntax error
+deferred<int> //         //# deferred-gen: syntax error
+dynamic<int> //          //# dynamic-gen: compile-time error
+export<int> //           //# export-gen: syntax error
+external<int> //         //# external-gen: syntax error
+factory<int> //          //# factory-gen: syntax error
+get<int> //              //# get-gen: syntax error
+implements<int> //       //# implements-gen: syntax error
+import<int> //           //# import-gen: syntax error
+interface<int> //        //# interface-gen: syntax error
+library<int> //          //# library-gen: syntax error
+mixin<int> //            //# mixin-gen: syntax error
+operator<int> //         //# operator-gen: syntax error
+part<int> //             //# part-gen: syntax error
+set<int> //              //# set-gen: syntax error
+static<int> //           //# static-gen: syntax error
+typedef<int> //          //# typedef-gen: syntax error
 
-List<abstract> x = null; //        //# 35: syntax error
-List<as> x = null; //              //# 36: syntax error
-List<covariant> x = null; //       //# 37: syntax error
-List<deferred> x = null; //        //# 38: syntax error
-List<dynamic> x = null; //         //# 39: ok
-List<export> x = null; //          //# 40: syntax error
-List<external> x = null; //        //# 41: syntax error
-List<factory> x = null; //         //# 42: syntax error
-List<get> x = null; //             //# 43: syntax error
-List<implements> x = null; //      //# 44: syntax error
-List<import> x = null; //          //# 45: syntax error
-List<library> x = null; //         //# 46: syntax error
-List<operator> x = null; //        //# 47: syntax error
-List<part> x = null; //            //# 48: syntax error
-List<set> x = null; //             //# 49: syntax error
-List<static> x = null; //          //# 50: syntax error
-List<typedef> x = null; //         //# 51: syntax error
+List<abstract> //        //# abstract-list: syntax error
+List<as> //              //# as-list: syntax error
+List<covariant> //       //# covariant-list: syntax error
+List<deferred> //        //# deferred-list: syntax error
+List<dynamic> //         //# dynamic-list: ok
+List<export> //          //# export-list: syntax error
+List<external> //        //# external-list: syntax error
+List<factory> //         //# factory-list: syntax error
+List<get> //             //# get-list: syntax error
+List<implements> //      //# implements-list: syntax error
+List<import> //          //# import-list: syntax error
+List<interface> //       //# interface-list: syntax error
+List<library> //         //# library-list: syntax error
+List<mixin> //           //# mixin-list: syntax error
+List<operator> //        //# operator-list: syntax error
+List<part> //            //# part-list: syntax error
+List<set> //             //# set-list: syntax error
+List<static> //          //# static-list: syntax error
+List<typedef> //         //# typedef-list: syntax error
 
-Function(abstract) x = null; //    //# 52: syntax error
-Function(as) x = null; //          //# 53: syntax error
-Function(covariant) x = null; //   //# 54: syntax error
-Function(deferred) x = null; //    //# 55: syntax error
-Function(dynamic) x = null; //     //# 56: ok
-Function(export) x = null; //      //# 57: syntax error
-Function(external) x = null; //    //# 58: syntax error
-Function(factory) x = null; //     //# 59: syntax error
-Function(get) x = null; //         //# 60: syntax error
-Function(implements) x = null; //  //# 61: syntax error
-Function(import) x = null; //      //# 62: syntax error
-Function(library) x = null; //     //# 63: syntax error
-Function(operator) x = null; //    //# 64: syntax error
-Function(part) x = null; //        //# 65: syntax error
-Function(set) x = null; //         //# 66: syntax error
-Function(static) x = null; //      //# 67: syntax error
-Function(typedef) x = null; //     //# 68: syntax error
+Function(abstract) //    //# abstract-funarg: syntax error
+Function(as) //          //# as-funarg: syntax error
+Function(covariant) //   //# covariant-funarg: syntax error
+Function(deferred) //    //# deferred-funarg: syntax error
+Function(dynamic) //     //# dynamic-funarg: ok
+Function(export) //      //# export-funarg: syntax error
+Function(external) //    //# external-funarg: syntax error
+Function(factory) //     //# factory-funarg: syntax error
+Function(get) //         //# get-funarg: syntax error
+Function(implements) //  //# implements-funarg: syntax error
+Function(import) //      //# import-funarg: syntax error
+Function(interface) //   //# interface-funarg: syntax error
+Function(library) //     //# library-funarg: syntax error
+Function(mixin) //       //# mixin-funarg: syntax error
+Function(operator) //    //# operator-funarg: syntax error
+Function(part) //        //# part-funarg: syntax error
+Function(set) //         //# set-funarg: syntax error
+Function(static) //      //# static-funarg: syntax error
+Function(typedef) //     //# typedef-funarg: syntax error
 
-abstract Function() x = null; //   //# 69: syntax error
-as Function() x = null; //         //# 70: syntax error
-covariant Function() x = null; //  //# 71: syntax error
-deferred Function() x = null; //   //# 72: syntax error
-dynamic Function() x = null; //    //# 73: ok
-export Function() x = null; //     //# 74: syntax error
-external Function() x = null; //   //# 75: syntax error
-factory Function() x = null; //    //# 76: syntax error
-get Function() x = null; //        //# 77: syntax error
-implements Function() x = null; // //# 78: syntax error
-import Function() x = null; //     //# 79: syntax error
-library Function() x = null; //    //# 80: syntax error
-operator Function() x = null; //   //# 81: syntax error
-part Function() x = null; //       //# 82: syntax error
-set Function() x = null; //        //# 83: syntax error
-static Function() x = null; //     //# 84: syntax error
-typedef Function() x = null; //    //# 85: syntax error
+abstract Function() //   //# abstract-funret: syntax error
+as Function() //         //# as-funret: syntax error
+covariant Function() //  //# covariant-funret: syntax error
+deferred Function() //   //# deferred-funret: syntax error
+dynamic Function() //    //# dynamic-funret: ok
+export Function() //     //# export-funret: syntax error
+external Function() //   //# external-funret: syntax error
+factory Function() //    //# factory-funret: syntax error
+get Function() //        //# get-funret: syntax error
+implements Function() // //# implements-funret: syntax error
+import Function() //     //# import-funret: syntax error
+interface Function() //  //# interface-funret: syntax error
+library Function() //    //# library-funret: syntax error
+mixin Function() //      //# mixin-funret: syntax error
+operator Function() //   //# operator-funret: syntax error
+part Function() //       //# part-funret: syntax error
+set Function() //        //# set-funret: syntax error
+static Function() //     //# static-funret: syntax error
+typedef Function() //    //# typedef-funret: syntax error
+
+x = null;
 
 main() {
-  var x = null; //                 //# none: ok
   x.toString();
 }
diff --git a/tests/language_2/constructor_type_parameter_test.dart b/tests/language_2/constructor_type_parameter_test.dart
new file mode 100644
index 0000000..d038361
--- /dev/null
+++ b/tests/language_2/constructor_type_parameter_test.dart
@@ -0,0 +1,11 @@
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+class Foo {
+  Foo<A>() {} // //# 00: compile-time error
+}
+
+main() {
+  new Foo();
+}
diff --git a/tests/language_2/f_bounded_quantification_test.dart b/tests/language_2/f_bounded_quantification_test.dart
index b1abcb0..433df64 100644
--- a/tests/language_2/f_bounded_quantification_test.dart
+++ b/tests/language_2/f_bounded_quantification_test.dart
@@ -19,5 +19,5 @@
   FBound<SubBar> fsb = new FBound<SubBar>(); // //# 01: compile-time error
 
   FBound<Baz<Bar>> fbb = new FBound<Baz<Bar>>();
-  FBound<SubBaz<Bar>> fsb = new FBound<SubBaz<Bar>>(); // //# 02: compile-time error
+  FBound<SubBaz<Bar>> fsbb = new FBound<SubBaz<Bar>>(); // //# 02: compile-time error
 }
diff --git a/tests/language_2/field3_test.dart b/tests/language_2/field3_test.dart
index 2f4b8ba..901dd06 100644
--- a/tests/language_2/field3_test.dart
+++ b/tests/language_2/field3_test.dart
@@ -9,11 +9,22 @@
   // illegal: var cannot follow final
   final var a = 0;// //# 00: syntax error
   // illegal: final field declaration, must be initialized
-  final a; // //# 01: compile-time error
-  final a = 0; // //# none: ok
+  final b; // //# 01: compile-time error
+  final c; // //# 02: compile-time error
+  final d; // //# 03: ok
+  final e; // //# 04: ok
+  final f = 0; // //# 05: ok
+
+  C() {} //# 02: continued
+  C(this.d) {} //# 03: continued
+  C(x) : e = x {} //# 04: continued
 }
 
 main() {
-  var val = new C();
-  Expect.equals(val.a, 0);
+  var val = new C(); //# 00: continued
+  var val = new C(); //# 01: continued
+  var val = new C(); //# 02: continued
+  var val = new C(0); //# 03: continued
+  var val = new C(0); //# 04: continued
+  var val = new C(); //# 05: continued
 }
diff --git a/tests/language_2/language_2.status b/tests/language_2/language_2.status
index bdfe9cd..23cf368 100644
--- a/tests/language_2/language_2.status
+++ b/tests/language_2/language_2.status
@@ -46,9 +46,6 @@
 initializer_super_last_test/cc31: MissingCompileTimeError
 initializer_super_last_test/cc32: MissingCompileTimeError
 
-[ $compiler == dart2js && !$strong ]
-initializer_super_last_test: Crash, CompileTimeError # Issue 31321
-
 [ $compiler != dart2js && $compiler != dartdevc && !$fasta && $strong ]
 type_promotion_functions_test: CompileTimeError # Issue 30895: This test requires a complete rewrite for 2.0.
 
@@ -121,7 +118,7 @@
 function_type/*: Skip # Needs checked mode.
 
 [ $compiler != dartk && $compiler != dartkp && $mode == debug && $runtime == vm ]
-built_in_identifier_type_annotation_test/15: Crash # Not supported by legacy VM front-end.
+built_in_identifier_type_annotation_test/set: Crash # Not supported by legacy VM front-end.
 
 [ $compiler == none && $runtime == drt && !$checked ]
 assertion_initializer_const_error_test/01: Fail
@@ -253,12 +250,6 @@
 [ $checked && !$strong ]
 type_parameter_test/05: Pass
 
-# We no longer expect Dart2 tests to run with the standalone VM without the new
-# common front end, but for now we get better coverage by still running them in
-# checked mode, which is mostly Dart2-compatible.
-[ !$checked && ($compiler == app_jit || $compiler == none || $compiler == precompiler) && ($runtime == dart_precompiled || $runtime == vm) ]
-*: SkipByDesign
-
 [ !$fasta && !$strong ]
 implicit_creation/implicit_const_context_constructor_generic_named_test: Fail # No support for implicit creation.
 implicit_creation/implicit_const_context_constructor_generic_test: Fail # No support for implicit creation.
diff --git a/tests/language_2/language_2_analyzer.status b/tests/language_2/language_2_analyzer.status
index c9ddf1c..74be6be 100644
--- a/tests/language_2/language_2_analyzer.status
+++ b/tests/language_2/language_2_analyzer.status
@@ -9,7 +9,7 @@
 abstract_override_adds_optional_args_supercall_test: MissingCompileTimeError # Issue #30568
 bad_initializer2_negative_test: Fail # Issue 14880
 built_in_identifier_prefix_test: CompileTimeError
-built_in_identifier_type_annotation_test/22: MissingCompileTimeError # Issue 28813
+built_in_identifier_type_annotation_test/dynamic-gen: MissingCompileTimeError # Issue 28813
 cascade_test/none: Fail # Issue 11577
 config_import_corelib_test: StaticWarning, OK
 conflicting_type_variable_and_setter_test: CompileTimeError # Issue 25525
@@ -17,6 +17,7 @@
 const_cast2_test/none: CompileTimeError
 const_for_in_variable_test/01: MissingCompileTimeError # Issue 25161
 constructor_call_wrong_argument_count_negative_test: Fail # Issue 11585
+constructor_type_parameter_test/00: MissingCompileTimeError # Issue 33110
 deep_nesting1_negative_test: CompileTimeError # Issue 25558
 deep_nesting2_negative_test: CompileTimeError # Issue 25558
 duplicate_export_negative_test: CompileTimeError
@@ -24,7 +25,8 @@
 emit_const_fields_test: CompileTimeError
 enum_syntax_test/05: Fail # Issue 21649
 enum_syntax_test/06: Fail # Issue 21649
-field3_test/01: MissingCompileTimeError
+field3_test/01: MissingCompileTimeError # Issue 33022
+field3_test/02: MissingCompileTimeError # Issue 33022
 final_syntax_test/01: Fail # Issue 11124
 final_syntax_test/02: Fail # Issue 11124
 final_syntax_test/03: Fail # Issue 11124
@@ -1101,6 +1103,7 @@
 constant_type_literal_test/01: MissingCompileTimeError # Issue 28823
 default_implementation2_test: CompileTimeError # Issue 30855
 error_stacktrace_test/00: Pass
+field3_test/02: MissingCompileTimeError # Issue 33022
 field3a_negative_test: StaticWarning # Issue 28823
 forwarding_stub_tearoff_test: CompileTimeError
 generic_methods_generic_function_result_test/none: CompileTimeError # Issue #30207
@@ -1206,26 +1209,34 @@
 async_congruence_unnamed_test/02: MissingCompileTimeError
 black_listed_test/none: Fail # Issue 14228
 bug32305_test: MissingCompileTimeError
-built_in_identifier_type_annotation_test/35: MissingCompileTimeError # Issue 28813
-built_in_identifier_type_annotation_test/36: MissingCompileTimeError # Issue 28813
-built_in_identifier_type_annotation_test/37: MissingCompileTimeError # Issue 28813
-built_in_identifier_type_annotation_test/38: MissingCompileTimeError # Issue 28813
-built_in_identifier_type_annotation_test/40: MissingCompileTimeError # Issue 28813
-built_in_identifier_type_annotation_test/41: MissingCompileTimeError # Issue 28813
-built_in_identifier_type_annotation_test/42: MissingCompileTimeError # Issue 28813
-built_in_identifier_type_annotation_test/43: MissingCompileTimeError # Issue 28813
-built_in_identifier_type_annotation_test/44: MissingCompileTimeError # Issue 28813
-built_in_identifier_type_annotation_test/45: MissingCompileTimeError # Issue 28813
-built_in_identifier_type_annotation_test/46: MissingCompileTimeError # Issue 28813
-built_in_identifier_type_annotation_test/47: MissingCompileTimeError # Issue 28813
-built_in_identifier_type_annotation_test/48: MissingCompileTimeError # Issue 28813
-built_in_identifier_type_annotation_test/49: MissingCompileTimeError # Issue 28813
-built_in_identifier_type_annotation_test/50: MissingCompileTimeError # Issue 28813
-built_in_identifier_type_annotation_test/51: MissingCompileTimeError # Issue 28813
-built_in_identifier_type_annotation_test/70: MissingCompileTimeError # Issue 28813
-built_in_identifier_type_annotation_test/72: MissingCompileTimeError # Issue 28813
-built_in_identifier_type_annotation_test/78: MissingCompileTimeError # Issue 28813
-built_in_identifier_type_annotation_test/81: MissingCompileTimeError # Issue 28813
+built_in_identifier_type_annotation_test/abstract-list: MissingCompileTimeError # Issue 28813
+built_in_identifier_type_annotation_test/as-funret: MissingCompileTimeError # Issue 28813
+built_in_identifier_type_annotation_test/as-list: MissingCompileTimeError # Issue 28813
+built_in_identifier_type_annotation_test/covariant-list: MissingCompileTimeError # Issue 28813
+built_in_identifier_type_annotation_test/deferred-funret: MissingCompileTimeError # Issue 28813
+built_in_identifier_type_annotation_test/deferred-list: MissingCompileTimeError # Issue 28813
+built_in_identifier_type_annotation_test/export-funret: MissingCompileTimeError # Issue 28813
+built_in_identifier_type_annotation_test/export-list: MissingCompileTimeError # Issue 28813
+built_in_identifier_type_annotation_test/external-list: MissingCompileTimeError # Issue 28813
+built_in_identifier_type_annotation_test/factory-list: MissingCompileTimeError # Issue 28813
+built_in_identifier_type_annotation_test/get-list: MissingCompileTimeError # Issue 28813
+built_in_identifier_type_annotation_test/implements-funret: MissingCompileTimeError # Issue 28813
+built_in_identifier_type_annotation_test/implements-list: MissingCompileTimeError # Issue 28813
+built_in_identifier_type_annotation_test/import-funret: MissingCompileTimeError # Issue 28813
+built_in_identifier_type_annotation_test/import-list: MissingCompileTimeError # Issue 28813
+built_in_identifier_type_annotation_test/interface-funret: MissingCompileTimeError # Issue 28813
+built_in_identifier_type_annotation_test/interface-list: MissingCompileTimeError # Issue 28813
+built_in_identifier_type_annotation_test/library-funret: MissingCompileTimeError # Issue 28813
+built_in_identifier_type_annotation_test/library-list: MissingCompileTimeError # Issue 28813
+built_in_identifier_type_annotation_test/mixin-funret: MissingCompileTimeError # Issue 28813
+built_in_identifier_type_annotation_test/mixin-list: MissingCompileTimeError # Issue 28813
+built_in_identifier_type_annotation_test/operator-funret: MissingCompileTimeError # Issue 28813
+built_in_identifier_type_annotation_test/operator-list: MissingCompileTimeError # Issue 28813
+built_in_identifier_type_annotation_test/part-funret: MissingCompileTimeError # Issue 28813
+built_in_identifier_type_annotation_test/part-list: MissingCompileTimeError # Issue 28813
+built_in_identifier_type_annotation_test/set-list: MissingCompileTimeError # Issue 28813
+built_in_identifier_type_annotation_test/static-list: MissingCompileTimeError # Issue 28813
+built_in_identifier_type_annotation_test/typedef-list: MissingCompileTimeError # Issue 28813
 call_method_implicit_invoke_local_test/05: MissingCompileTimeError
 call_method_implicit_tear_off_assignable_test: StaticWarning
 call_method_implicit_tear_off_implements_function_test/03: StaticWarning
diff --git a/tests/language_2/language_2_dart2js.status b/tests/language_2/language_2_dart2js.status
index 66550b4..4579ab6 100644
--- a/tests/language_2/language_2_dart2js.status
+++ b/tests/language_2/language_2_dart2js.status
@@ -8,6 +8,7 @@
 bit_operations_test: RuntimeError, OK # non JS number semantics
 config_import_corelib_test: CompileTimeError # we need a special platform.dill file for categories=all. Once we fix that, all dart:* are supported when using '--categories=all' so this will become a RuntimeError, OK.
 config_import_test: RuntimeError # Test flag is not passed to the compiler.
+constructor_type_parameter_test/00: Crash # Issue 33110
 double_identical_test: RuntimeError # Negative and positive zero are distinct, but not in dart2js; bug #11551.
 issue23244_test: RuntimeError # Isolates - enum canonicalization - Issue 23244
 library_env_test/has_mirror_support: RuntimeError, OK
@@ -31,9 +32,6 @@
 field_override_optimization_test: RuntimeError
 field_type_check2_test/01: MissingRuntimeError
 
-[ $compiler == dart2js && $runtime == d8 && !$checked && !$strong ]
-generic_list_checked_test: RuntimeError
-
 [ $compiler == dart2js && $runtime == d8 && $fasta ]
 assertion_test: RuntimeError
 bug32372_test: CompileTimeError
@@ -551,10 +549,6 @@
 bad_override_test/03: MissingCompileTimeError
 bit_operations_test: RuntimeError
 branch_canonicalization_test: RuntimeError
-call_method_implicit_tear_off_implements_function_test/02: RuntimeError
-call_method_implicit_tear_off_implements_function_test/04: RuntimeError
-call_method_implicit_tear_off_test/02: RuntimeError
-call_method_implicit_tear_off_test/04: RuntimeError
 canonical_const2_test: RuntimeError, OK # non JS number semantics
 check_member_static_test/02: MissingCompileTimeError
 class_cycle_test/02: MissingCompileTimeError
@@ -585,7 +579,6 @@
 constructor_redirect1_negative_test/01: Crash # Stack Overflow
 constructor_redirect2_negative_test: Crash # Stack Overflow
 constructor_redirect_test/01: Crash # Assertion failure: Cannot find value Instance of 'ThisLocal' in (local(A.named2#x), local(A.named2#y), local(A.named2#z)) for j:constructor(A.named2).
-covariance_type_parameter_test/02: RuntimeError
 covariant_override/tear_off_type_test: RuntimeError
 covariant_subtyping_test: Crash # Unsupported operation: Unsupported type parameter type node E.
 cyclic_constructor_test/01: Crash # Stack Overflow
@@ -615,7 +608,6 @@
 external_test/20: MissingRuntimeError
 external_test/21: CompileTimeError
 external_test/24: CompileTimeError
-extract_type_arguments_test: RuntimeError
 f_bounded_quantification4_test: RuntimeError
 fauxverride_test/03: MissingCompileTimeError
 fauxverride_test/05: MissingCompileTimeError
@@ -657,8 +649,6 @@
 generic_methods_dynamic_test/04: MissingRuntimeError
 generic_methods_generic_class_tearoff_test: RuntimeError
 generic_methods_generic_function_result_test/01: MissingCompileTimeError
-generic_methods_simple_as_expression_test/02: MissingRuntimeError
-generic_methods_type_expression_test: RuntimeError
 generic_methods_unused_parameter_test: RuntimeError
 generic_no_such_method_dispatcher_simple_test: CompileTimeError
 generic_no_such_method_dispatcher_test: CompileTimeError
@@ -683,7 +673,6 @@
 int64_literal_test/none: RuntimeError
 integer_division_by_zero_test: RuntimeError # Issue 8301
 internal_library_test/02: Crash # NoSuchMethodError: Class 'DillLibraryBuilder' has no instance getter 'mixinApplicationClasses'.
-invocation_mirror2_test: RuntimeError # mirrors not supported
 invocation_mirror_invoke_on2_test: RuntimeError
 invocation_mirror_invoke_on_test: RuntimeError
 issue21079_test: RuntimeError
@@ -695,7 +684,6 @@
 local_function2_test/none: RuntimeError
 local_function3_test/none: RuntimeError
 local_function_test/none: RuntimeError
-many_overridden_no_such_method_test: RuntimeError
 method_override7_test/00: MissingCompileTimeError
 method_override7_test/01: MissingCompileTimeError
 method_override7_test/02: MissingCompileTimeError
@@ -783,14 +771,12 @@
 nested_generic_closure_test: RuntimeError
 no_main_test/01: CompileTimeError
 no_such_method_mock_test: RuntimeError
-no_such_method_test: RuntimeError
 nosuchmethod_forwarding/nosuchmethod_forwarding_arguments_test: RuntimeError
 nosuchmethod_forwarding/nosuchmethod_forwarding_test/05: RuntimeError
 nosuchmethod_forwarding/nosuchmethod_forwarding_test/06: RuntimeError
 null_no_such_method_test: CompileTimeError
 number_identity2_test: RuntimeError
 numbers_test: RuntimeError, OK # non JS number semantics
-overridden_no_such_method_test: RuntimeError
 override_field_test/01: MissingCompileTimeError
 override_inheritance_field_test/04: CompileTimeError
 override_inheritance_field_test/06: CompileTimeError
@@ -879,7 +865,6 @@
 function_propagation_test: RuntimeError
 generic_test/01: MissingCompileTimeError # front end does not validate `extends`
 instantiate_tearoff_of_call_test: RuntimeError
-instantiate_tearoff_test: RuntimeError
 mixin_type_parameter_inference_error_test/none: CompileTimeError
 mixin_type_parameter_inference_previous_mixin_test/01: CompileTimeError
 mixin_type_parameter_inference_previous_mixin_test/02: CompileTimeError
@@ -931,10 +916,6 @@
 bad_override_test/03: MissingCompileTimeError
 bit_operations_test: RuntimeError
 branch_canonicalization_test: RuntimeError
-call_method_implicit_tear_off_implements_function_test/02: RuntimeError
-call_method_implicit_tear_off_implements_function_test/04: RuntimeError
-call_method_implicit_tear_off_test/02: RuntimeError
-call_method_implicit_tear_off_test/04: RuntimeError
 call_non_method_field_test/01: MissingCompileTimeError
 call_non_method_field_test/02: MissingCompileTimeError
 canonical_const2_test: RuntimeError, OK # non JS number semantics
@@ -1065,8 +1046,6 @@
 generic_methods_generic_function_result_test/01: MissingCompileTimeError
 generic_methods_overriding_test/01: MissingCompileTimeError
 generic_methods_recursive_bound_test/02: MissingCompileTimeError
-generic_methods_simple_as_expression_test/02: MissingRuntimeError
-generic_methods_type_expression_test: RuntimeError
 generic_methods_unused_parameter_test: Crash # Assertion failure: kind=special,memberName=instantiate,callStructure:CallStructure(arity=0, types=1)
 generic_no_such_method_dispatcher_simple_test: CompileTimeError
 generic_no_such_method_dispatcher_test: CompileTimeError
@@ -1086,7 +1065,6 @@
 initializing_formal_type_annotation_test/02: MissingCompileTimeError
 instance_creation_in_function_annotation_test: RuntimeError
 instantiate_tearoff_of_call_test: CompileTimeError
-instantiate_tearoff_test: Crash # Assertion failure: kind=special,memberName=instantiate,callStructure:CallStructure(arity=0, types=1)
 int64_literal_test/01: RuntimeError
 int64_literal_test/02: RuntimeError
 int64_literal_test/03: MissingCompileTimeError
@@ -1485,10 +1463,6 @@
 bad_override_test/03: MissingCompileTimeError
 bit_operations_test: RuntimeError
 branch_canonicalization_test: RuntimeError
-call_method_implicit_tear_off_implements_function_test/02: RuntimeError
-call_method_implicit_tear_off_implements_function_test/04: RuntimeError
-call_method_implicit_tear_off_test/02: RuntimeError
-call_method_implicit_tear_off_test/04: RuntimeError
 call_non_method_field_test/01: MissingCompileTimeError
 call_non_method_field_test/02: MissingCompileTimeError
 call_with_no_such_method_test: RuntimeError
@@ -1613,8 +1587,6 @@
 generic_methods_generic_function_result_test/01: MissingCompileTimeError
 generic_methods_overriding_test/01: MissingCompileTimeError
 generic_methods_recursive_bound_test/02: MissingCompileTimeError
-generic_methods_simple_as_expression_test/02: MissingRuntimeError
-generic_methods_type_expression_test: RuntimeError
 generic_methods_unused_parameter_test: RuntimeError
 generic_no_such_method_dispatcher_simple_test: CompileTimeError
 generic_no_such_method_dispatcher_test: CompileTimeError
@@ -1957,6 +1929,7 @@
 const_constructor3_test/04: MissingCompileTimeError # OK - Subtype check uses JS number semantics.
 covariant_subtyping_test: Crash
 ct_const_test: RuntimeError
+nosuchmethod_forwarding/nosuchmethod_forwarding_partial_instantiation_test: RuntimeError
 
 [ $compiler == dart2js && $fasta && !$strong ]
 *: SkipByDesign
diff --git a/tests/language_2/language_2_dartdevc.status b/tests/language_2/language_2_dartdevc.status
index 96bed6a..2bfb404 100644
--- a/tests/language_2/language_2_dartdevc.status
+++ b/tests/language_2/language_2_dartdevc.status
@@ -22,7 +22,10 @@
 bit_operations_test: RuntimeError # No bigints on web.
 bug32372_test: RuntimeError
 built_in_identifier_prefix_test: CompileTimeError
-built_in_identifier_type_annotation_test/22: MissingCompileTimeError # Issue 28816
+built_in_identifier_type_annotation_test/dynamic-funarg: RuntimeError # Issue 28816
+built_in_identifier_type_annotation_test/dynamic-funret: RuntimeError # Issue 28816
+built_in_identifier_type_annotation_test/dynamic-gen: MissingCompileTimeError # Issue 28816
+built_in_identifier_type_annotation_test/dynamic-list: RuntimeError # Issue 28816
 cascaded_forwarding_stubs_generic_test: RuntimeError
 cascaded_forwarding_stubs_test: CompileTimeError
 conflicting_generic_interfaces_hierarchy_loop_infinite_test: Skip # Crashes or times out
@@ -36,6 +39,7 @@
 const_types_test/14: MissingCompileTimeError
 const_types_test/15: MissingCompileTimeError
 constant_type_literal_test/01: MissingCompileTimeError # DDC allows type parameter type literals in const expressions.
+constructor_type_parameter_test/00: MissingCompileTimeError # Issue 33110
 covariance_field_test/03: RuntimeError
 covariant_override/tear_off_type_test: RuntimeError # Issue 28395
 default_implementation2_test: CompileTimeError # Issue 30855
@@ -295,7 +299,10 @@
 bad_override_test/01: MissingCompileTimeError
 bad_override_test/02: MissingCompileTimeError
 bad_override_test/03: MissingCompileTimeError
-built_in_identifier_type_annotation_test/05: RuntimeError # Issue 32194
+built_in_identifier_type_annotation_test/dynamic: RuntimeError # Issue 32194
+built_in_identifier_type_annotation_test/dynamic-funarg: RuntimeError # Issue 32194
+built_in_identifier_type_annotation_test/dynamic-funret: RuntimeError # Issue 32194
+built_in_identifier_type_annotation_test/dynamic-list: RuntimeError # Issue 32194
 built_in_identifier_type_annotation_test/none: RuntimeError # Issue 32194
 call_method_as_cast_test/06: RuntimeError # Kernel allows classes to subtype `Function` so DDK elides the explicit cast.
 call_method_implicit_tear_off_implements_function_test/05: RuntimeError # Kernel is missing the implicit `call` tearoff for assignment `Function`
@@ -514,11 +521,13 @@
 mixin_supertype_subclass_test/05: MissingCompileTimeError
 mixin_type_parameters_errors_test/03: MissingCompileTimeError
 mixin_type_parameters_errors_test/04: MissingCompileTimeError
+mock_writable_final_field_test: RuntimeError # Issue 30847
 mock_writable_final_private_field_test: RuntimeError
 multiline_newline_test/06: MissingCompileTimeError
 multiline_newline_test/06r: MissingCompileTimeError
 named_constructor_test/01: MissingCompileTimeError
 named_parameters_default_eq_test/02: MissingCompileTimeError
+no_such_method_mock_test: RuntimeError # Issue 31426 - Kernel does not introduce nSM for implemented fields.
 null2_test: RuntimeError # Issue 32194
 null_method_test: RuntimeError # Issue 32194
 null_no_such_method_test: CompileTimeError # Issue 31533
@@ -663,7 +672,8 @@
 exception_test: RuntimeError # DDC doesn't implement NullThrownError?; Expect.isTrue(false) fails.
 expect_test: RuntimeError # Issue 29920; Expect.identical did not fail
 f_bounded_quantification3_test: RuntimeError # Issue 29920; Uncaught Error: type arguments should not be null: (F1, F2) => {
-field3_test/01: MissingCompileTimeError
+field3_test/01: MissingCompileTimeError # Issue 33022
+field3_test/02: MissingCompileTimeError # Issue 33022
 field_initialization_order_test/none: RuntimeError # Expect.equals(expected: <b.a.ai.bi.>, actual: <b.bi.a.ai.>) fails.
 flatten_test/05: MissingRuntimeError # Issue 29920
 flatten_test/08: MissingRuntimeError # Issue 29920
diff --git a/tests/language_2/language_2_kernel.status b/tests/language_2/language_2_kernel.status
index 6c07860..4a738cc 100644
--- a/tests/language_2/language_2_kernel.status
+++ b/tests/language_2/language_2_kernel.status
@@ -65,70 +65,65 @@
 async_return_types_test/wrongReturnType: MissingCompileTimeError # Issue 33068
 bad_override_test/01: MissingCompileTimeError # Issue 32984
 bad_override_test/02: MissingCompileTimeError # Issue 32984
-call_non_method_field_test/01: MissingCompileTimeError
-call_non_method_field_test/02: MissingCompileTimeError
-check_member_static_test/01: MissingCompileTimeError
-compile_time_constant_o_test/01: MissingCompileTimeError
-compile_time_constant_o_test/02: MissingCompileTimeError
-const_cast2_test/01: CompileTimeError
-const_cast2_test/none: CompileTimeError
-const_dynamic_type_literal_test/02: MissingCompileTimeError
+call_non_method_field_test/01: MissingCompileTimeError # Issue 32975
+call_non_method_field_test/02: MissingCompileTimeError # Issue 32975
+check_member_static_test/01: MissingCompileTimeError # Issue 32613
+const_cast2_test/01: CompileTimeError # Issue 32517
+const_cast2_test/none: CompileTimeError # Issue 32517
 const_instance_field_test/01: MissingCompileTimeError # Fasta bug: Const instance field. Issue 32326.
 const_map2_test/00: MissingCompileTimeError # KernelVM bug: Constant evaluation.
 const_map3_test/00: MissingCompileTimeError # KernelVM bug: Constant evaluation.
 const_switch2_test/01: MissingCompileTimeError # KernelVM bug: Constant evaluation.
-const_types_test/34: MissingCompileTimeError
-const_types_test/39: MissingCompileTimeError
-constructor_redirect1_negative_test/01: MissingCompileTimeError
-constructor_redirect2_negative_test: MissingCompileTimeError
+const_types_test/34: MissingCompileTimeError # Issue 32988
+const_types_test/39: MissingCompileTimeError # Issue 32988
+constructor_redirect1_negative_test/01: MissingCompileTimeError # Issue 30856
+constructor_redirect2_negative_test: MissingCompileTimeError # Issue 30856
 constructor_redirect_test/01: MissingCompileTimeError # Fasta bug: Initializer refers to this.
-cyclic_constructor_test/01: MissingCompileTimeError # Fasta bug: Cyclic constructor redirection.
+constructor_type_parameter_test/00: MissingCompileTimeError # Issue 33110
+cyclic_constructor_test/01: MissingCompileTimeError # Issue 30856 (cyclic constructor redirection)
 cyclic_type_variable_test/01: MissingCompileTimeError # Issue 32989 (missing cycle check in bounds)
 cyclic_type_variable_test/02: MissingCompileTimeError # Issue 32989 (missing cycle check in bounds)
 cyclic_type_variable_test/03: MissingCompileTimeError # Issue 32989 (missing cycle check in bounds)
 cyclic_type_variable_test/04: MissingCompileTimeError # Issue 32989 (missing cycle check in bounds)
-default_factory2_test/01: MissingCompileTimeError
-default_factory_test/01: MissingCompileTimeError
+default_factory2_test/01: MissingCompileTimeError # Issue 32988
+default_factory_test/01: MissingCompileTimeError # Issue 32988
 deferred_inheritance_constraints_test/extends: MissingCompileTimeError # Fasta/KernelVM bug: Deferred loading kernel issue 30273.
 deferred_inheritance_constraints_test/implements: MissingCompileTimeError # Fasta/KernelVM bug: Deferred loading kernel issue 30273.
 deferred_inheritance_constraints_test/mixin: MissingCompileTimeError # Fasta/KernelVM bug: Deferred loading kernel issue 30273.
 deferred_inheritance_constraints_test/redirecting_constructor: MissingCompileTimeError # Fasta/KernelVM bug: Deferred loading kernel issue 30273.
-duplicate_export_negative_test: Fail # Issue 6134
-f_bounded_quantification_test/01: MissingCompileTimeError
-f_bounded_quantification_test/02: MissingCompileTimeError
-factory4_test/00: MissingCompileTimeError
-field3_test/01: MissingCompileTimeError
-field_override_test/00: MissingCompileTimeError
-field_override_test/01: MissingCompileTimeError
-generic_methods_bounds_test/01: MissingCompileTimeError
-generic_methods_overriding_test/01: MissingCompileTimeError
-generic_methods_recursive_bound_test/02: MissingCompileTimeError
-getter_override_test/03: MissingCompileTimeError
-identical_const_test/01: MissingCompileTimeError
-identical_const_test/02: MissingCompileTimeError
-identical_const_test/03: MissingCompileTimeError
-identical_const_test/04: MissingCompileTimeError
+duplicate_export_negative_test: Fail # Issue 12916
+f_bounded_quantification_test/01: MissingCompileTimeError # Issue 33018
+f_bounded_quantification_test/02: MissingCompileTimeError # Issue 33018
+factory4_test/00: MissingCompileTimeError # Issue 32988
+field3_test/01: MissingCompileTimeError # Issue 33022
+field3_test/02: MissingCompileTimeError # Issue 33022
+field_override_test/00: MissingCompileTimeError # Issue 32613
+field_override_test/01: MissingCompileTimeError # Issue 32613
+generic_methods_bounds_test/01: MissingCompileTimeError # Issue 33018
+generic_methods_overriding_test/01: MissingCompileTimeError # Issue 32613
+generic_methods_recursive_bound_test/02: MissingCompileTimeError # Issue 33018
+getter_override_test/03: MissingCompileTimeError # Issue 32984
 issue31596_override_test/07: MissingCompileTimeError
 issue31596_override_test/08: MissingCompileTimeError
 issue31596_super_test/02: MissingCompileTimeError
 issue31596_super_test/04: MissingCompileTimeError
-malbounded_instantiation_test/01: MissingCompileTimeError
-malbounded_instantiation_test/02: MissingCompileTimeError
-malbounded_instantiation_test/03: MissingCompileTimeError
-malbounded_redirecting_factory_test/02: MissingCompileTimeError
-malbounded_redirecting_factory_test/03: MissingCompileTimeError
-malbounded_redirecting_factory_test/04: MissingCompileTimeError
-malbounded_redirecting_factory_test/05: MissingCompileTimeError
-malbounded_type_cast2_test: MissingCompileTimeError
-malbounded_type_cast_test/00: MissingCompileTimeError
-malbounded_type_cast_test/01: MissingCompileTimeError
-malbounded_type_cast_test/02: MissingCompileTimeError
-malbounded_type_literal_test/00: MissingCompileTimeError
-malbounded_type_test2_test/00: MissingCompileTimeError
-malbounded_type_test_test/00: MissingCompileTimeError
-malbounded_type_test_test/01: MissingCompileTimeError
-malbounded_type_test_test/02: MissingCompileTimeError
-method_override7_test/03: MissingCompileTimeError
+malbounded_instantiation_test/01: MissingCompileTimeError # Issue 33018
+malbounded_instantiation_test/02: MissingCompileTimeError # Issue 33018
+malbounded_instantiation_test/03: MissingCompileTimeError # Issue 33018
+malbounded_redirecting_factory_test/02: MissingCompileTimeError # Issue 33018
+malbounded_redirecting_factory_test/03: MissingCompileTimeError # Issue 33018
+malbounded_redirecting_factory_test/04: MissingCompileTimeError # Issue 33018
+malbounded_redirecting_factory_test/05: MissingCompileTimeError # Issue 33018
+malbounded_type_cast2_test: MissingCompileTimeError # Issue 33018
+malbounded_type_cast_test/00: MissingCompileTimeError # Issue 33018
+malbounded_type_cast_test/01: MissingCompileTimeError # Issue 33018
+malbounded_type_cast_test/02: MissingCompileTimeError # Issue 33018
+malbounded_type_literal_test/00: MissingCompileTimeError # Issue 33018
+malbounded_type_test2_test/00: MissingCompileTimeError # Issue 33018
+malbounded_type_test_test/00: MissingCompileTimeError # Issue 33018
+malbounded_type_test_test/01: MissingCompileTimeError # Issue 33018
+malbounded_type_test_test/02: MissingCompileTimeError # Issue 33018
+method_override7_test/03: MissingCompileTimeError # Issue 32984
 mixin_forwarding_constructor4_test/01: MissingCompileTimeError # KernelVM bug: Issue 15101
 mixin_forwarding_constructor4_test/02: MissingCompileTimeError # KernelVM bug: Issue 15101
 mixin_forwarding_constructor4_test/03: MissingCompileTimeError # KernelVM bug: Issue 15101
@@ -439,19 +434,21 @@
 void_type_usage_test/paren_void_init: MissingCompileTimeError # Issue 32804
 void_type_usage_test/paren_while: MissingCompileTimeError # Issue 32804
 
-[ $arch == simarm && $compiler == dartkp && $strong ]
-await_test: RuntimeError
-
-[ $arch != simarm && $arch != simarm64 && $arch != simdbc64 && $compiler == dartk ]
-export_ambiguous_main_test: MissingCompileTimeError
+[ $arch != simarm && $arch != simarm64 && $arch != simdbc64 && $compiler == dartk && $runtime == vm && $strong ]
+export_ambiguous_main_test: Crash # Issue 32618
 
 [ $compiler != dart2js && $compiler != dartk && $compiler != dartkp && $fasta ]
 const_optional_args_test/01: MissingCompileTimeError
 
-[ $compiler != dart2js && $fasta ]
+# The precomilation configuration uses a kernel2kernel constants evaluator
+# which is is more correct than fasta/vm in JIT mode (i.e. it catches more
+# compile-time errors).
+[ $compiler != dart2js && $compiler != dartkp && $fasta ]
 compile_time_constant_c_test/02: MissingCompileTimeError
 const_constructor_nonconst_field_test/01: MissingCompileTimeError
 const_syntax_test/05: MissingCompileTimeError
+
+[ $compiler != dart2js && $fasta ]
 mixin_super_2_test/01: MissingCompileTimeError
 mixin_super_2_test/03: MissingCompileTimeError
 mixin_supertype_subclass_test/02: MissingCompileTimeError
@@ -857,11 +854,6 @@
 checked_setter3_test/01: MissingCompileTimeError
 checked_setter3_test/02: MissingCompileTimeError
 checked_setter3_test/03: MissingCompileTimeError
-compile_time_constant_k_test/01: MissingCompileTimeError
-compile_time_constant_k_test/02: MissingCompileTimeError
-compile_time_constant_k_test/03: MissingCompileTimeError
-compile_time_constant_o_test/01: RuntimeError # KernelVM bug: Constant map duplicated key.
-compile_time_constant_o_test/02: RuntimeError # KernelVM bug: Constant map duplicated key.
 compile_time_constant_static5_test/11: CompileTimeError # Issue 31537
 compile_time_constant_static5_test/16: CompileTimeError # Issue 31537
 compile_time_constant_static5_test/21: CompileTimeError # Issue 31537
@@ -870,11 +862,9 @@
 conditional_import_test: CompileTimeError # KernelVM bug: Deferred loading kernel issue 30273.
 config_import_corelib_test: CompileTimeError # Issue 31533
 config_import_test: RuntimeError # KernelVM bug: Configurable imports.
-const_dynamic_type_literal_test/02: RuntimeError # KernelVM bug: Constant map duplicated key.
 const_evaluation_test: SkipByDesign
 const_list_test: RuntimeError
 const_map4_test: RuntimeError
-const_nested_test: RuntimeError # KernelVM bug: Constant evaluation.
 constructor12_test: RuntimeError
 constructor3_test: Fail, OK, Pass
 ct_const2_test: Skip # Incompatible flag: --compile_all
@@ -974,8 +964,6 @@
 main_not_a_function_test: Skip
 main_test/03: RuntimeError
 many_overridden_no_such_method_test: SkipByDesign
-map_literal3_test/01: MissingCompileTimeError
-map_literal3_test/02: MissingCompileTimeError
 map_literal3_test/03: MissingCompileTimeError
 method_override4_test/01: MissingCompileTimeError
 method_override4_test/02: MissingCompileTimeError
@@ -1103,6 +1091,28 @@
 tearoff_dynamic_test: RuntimeError # Compares call to "foo" (noSuchMethod) with string "foo"
 type_variable_promotion_test: RuntimeError # Compares runtime type to the string "List<B>"
 
+# The precomilation configuration uses a kernel2kernel constants evaluator
+# which is is more correct than fasta/vm in JIT mode (i.e. it catches more
+# compile-time errors).
+[ $compiler != dartkp && $fasta ]
+compile_time_constant_o_test/01: MissingCompileTimeError # Issue 32983
+compile_time_constant_o_test/02: MissingCompileTimeError # Issue 32983
+const_dynamic_type_literal_test/02: MissingCompileTimeError # Issue 32983
+identical_const_test/01: MissingCompileTimeError # Issue 32983
+identical_const_test/02: MissingCompileTimeError # Issue 32983
+identical_const_test/03: MissingCompileTimeError # Issue 32983
+identical_const_test/04: MissingCompileTimeError # Issue 32983
+
+# The precomilation configuration uses a kernel2kernel constants evaluator
+# which is is more correct than fasta/vm in JIT mode (i.e. it catches more
+# compile-time errors).
+[ $compiler != dartkp && $fasta && $strong ]
+compile_time_constant_k_test/01: MissingCompileTimeError
+compile_time_constant_k_test/02: MissingCompileTimeError
+compile_time_constant_k_test/03: MissingCompileTimeError
+map_literal3_test/01: MissingCompileTimeError
+map_literal3_test/02: MissingCompileTimeError
+
 [ $compiler == fasta && $strong ]
 bad_override_test/03: MissingCompileTimeError
 check_member_static_test/02: MissingCompileTimeError
@@ -1296,16 +1306,11 @@
 variable_shadow_class_test/01: MissingCompileTimeError
 
 [ $fasta && $strong ]
-compile_time_constant_k_test/01: MissingCompileTimeError
-compile_time_constant_k_test/02: MissingCompileTimeError
-compile_time_constant_k_test/03: MissingCompileTimeError
 compile_time_constant_static2_test/04: MissingCompileTimeError
 compile_time_constant_static3_test/04: MissingCompileTimeError
 initializing_formal_type_annotation_test/01: MissingCompileTimeError
 initializing_formal_type_annotation_test/02: MissingCompileTimeError
 issue18628_2_test/01: MissingCompileTimeError
-map_literal3_test/01: MissingCompileTimeError
-map_literal3_test/02: MissingCompileTimeError
 map_literal3_test/03: MissingCompileTimeError
 redirecting_factory_infinite_steps_test/01: MissingCompileTimeError
 redirecting_factory_malbounded_test/01: MissingCompileTimeError
@@ -1355,7 +1360,7 @@
 bad_named_parameters_test/05: MissingCompileTimeError
 bad_override_test/03: MissingCompileTimeError
 bad_override_test/06: MissingCompileTimeError
-built_in_identifier_type_annotation_test/22: MissingCompileTimeError
+built_in_identifier_type_annotation_test/dynamic-gen: MissingCompileTimeError
 call_constructor_on_unresolvable_class_test/01: MissingCompileTimeError
 call_constructor_on_unresolvable_class_test/02: MissingCompileTimeError
 call_constructor_on_unresolvable_class_test/03: MissingCompileTimeError
diff --git a/tests/language_2/language_2_precompiled.status b/tests/language_2/language_2_precompiled.status
index 58fc4e0..33d21dd 100644
--- a/tests/language_2/language_2_precompiled.status
+++ b/tests/language_2/language_2_precompiled.status
@@ -3,9 +3,6 @@
 # BSD-style license that can be found in the LICENSE file.
 # Sections in this file should start with "$runtime == dart_precompiled".
 
-[ $arch != arm && $arch != simarm64 && $arch != x64 && $compiler == precompiler && $runtime == dart_precompiled ]
-built_in_identifier_type_annotation_test/15: Crash
-
 [ $arch == arm64 && $runtime == dart_precompiled ]
 large_class_declaration_test: SkipSlow # Uses too much memory.
 setter4_test: MissingCompileTimeError
@@ -13,9 +10,6 @@
 [ $arch == ia32 && $runtime == dart_precompiled ]
 vm/regress_24517_test: Pass, Fail # Issue 24517.
 
-[ $arch == x64 && $compiler == precompiler && $mode == debug && $runtime == dart_precompiled ]
-built_in_identifier_type_annotation_test/15: Crash
-
 [ $compiler == precompiler && $mode == debug && $runtime == dart_precompiled ]
 regress_29025_test: Crash # Issue dartbug.com/29331
 
diff --git a/tests/language_2/language_2_vm.status b/tests/language_2/language_2_vm.status
index fcd9492..3674357 100644
--- a/tests/language_2/language_2_vm.status
+++ b/tests/language_2/language_2_vm.status
@@ -20,1360 +20,8 @@
 closure_cycles_test: Pass, Slow
 large_class_declaration_test: SkipSlow # Uses too much memory.
 
-[ $arch == ia32 && $compiler == app_jit && $runtime == vm ]
-vm/regress_24517_test: Pass, Fail # Issue 24517.
-
-[ $arch == ia32 && $compiler == none && $runtime == vm ]
-vm/regress_24517_test: Pass, Fail # Issue 24517.
-
-[ $arch == ia32 && $compiler == none && $runtime == vm && $system == windows ]
-vm/optimized_stacktrace_test: Pass, Crash # Issue 28276
-
 [ $arch == ia32 && $mode == release && $runtime == vm ]
 deep_nesting1_negative_test: Crash, Pass # Issue 31496
 
-[ $compiler == app_jit && $mode != product && $runtime == vm ]
-vm/type_vm_test/none: RuntimeError
-
-[ $compiler == app_jit && $runtime == vm ]
-async_star_cancel_while_paused_test: RuntimeError
-async_star_pause_test: Fail, OK
-async_star_regression_2238_test: CompileTimeError, RuntimeError
-class_keyword_test/02: MissingCompileTimeError # Issue 13627
-constructor3_test: Fail, OK, Pass
-ct_const2_test: Skip # Incompatible flag: --compile_all
-cyclic_type2_test: Fail, OK
-cyclic_type_test/02: Fail, OK
-cyclic_type_test/04: Fail, OK
-deferred_load_constants_test/02: Fail
-deferred_load_constants_test/03: Fail
-deferred_load_constants_test/05: Fail
-deferred_not_loaded_check_test: RuntimeError
-deferred_redirecting_factory_test: Fail, Crash # Issue 23408
-duplicate_export_negative_test: Fail # Issue 6134
-dynamic_prefix_core_test/01: RuntimeError # Issue 12478
-example_constructor_test: Fail, OK
-export_ambiguous_main_negative_test: Fail # Issue 14763
-field_initialization_order_test: Fail, OK
-hello_dart_test: Skip # Incompatible flag: --compile_all
-library_env_test/has_html_support: RuntimeError, OK
-library_env_test/has_no_io_support: RuntimeError, OK
-main_not_a_function_test: Skip
-mixin_illegal_super_use_test: Skip # Issues 24478 and 23773
-mixin_illegal_superclass_test: Skip # Issues 24478 and 23773
-multiline_strings_test: Fail # Issue 23020
-no_main_test/01: Skip
-regress_21793_test/01: MissingCompileTimeError
-regress_23408_test: Crash
-super_test: Fail, OK
-type_parameter_test/05: MissingCompileTimeError
-type_variable_scope_test/03: MissingCompileTimeError
-unicode_bom_test: Fail # Issue 16067
-vm/debug_break_enabled_vm_test/01: Crash, OK # Expected to hit breakpoint.
-vm/regress_27201_test: Fail
-vm/regress_29145_test: Skip # Issue 29145
-vm/type_cast_vm_test: RuntimeError # Expects line and column numbers
-
-[ $compiler == app_jit && $runtime == vm && $checked ]
-dynamic_test: RuntimeError
-generic_functions_test: Pass # Issue 25869
-generic_local_functions_test: Pass # Issue 25869
-generic_methods_function_type_test: Pass # Issue 25869
-generic_methods_generic_function_parameter_test: Pass # Issue 25869
-generic_methods_new_test: Pass # Issue 25869
-generic_methods_test: Pass # Issue 25869
-
-[ $compiler == app_jit && $runtime == vm && !$checked ]
-assertion_initializer_const_error_test/01: MissingCompileTimeError
-generic_methods_bounds_test/02: MissingRuntimeError
-generic_methods_dynamic_test/02: MissingRuntimeError
-generic_methods_dynamic_test/04: MissingRuntimeError
-
-[ $compiler != dartk && $mode == product && $runtime == vm ]
-deferred_load_constants_test/02: Fail
-deferred_load_constants_test/03: Fail
-deferred_load_constants_test/05: Fail
-deferred_not_loaded_check_test: RuntimeError
-vm/causal_async_exception_stack2_test: SkipByDesign
-vm/causal_async_exception_stack_test: SkipByDesign
-vm/regress_27201_test: Fail
-vm/type_vm_test/28: MissingRuntimeError
-vm/type_vm_test/29: MissingRuntimeError
-vm/type_vm_test/30: MissingRuntimeError
-vm/type_vm_test/31: MissingRuntimeError
-vm/type_vm_test/32: MissingRuntimeError
-vm/type_vm_test/33: MissingRuntimeError
-vm/type_vm_test/34: MissingRuntimeError
-vm/type_vm_test/35: MissingRuntimeError
-vm/type_vm_test/36: MissingRuntimeError
-
-# The VM does not implement the Dart 2.0 static type errors yet.
-[ $compiler != dartk && $runtime == vm ]
-abstract_beats_arguments_test: MissingCompileTimeError
-abstract_exact_selector_test/01: MissingCompileTimeError
-abstract_factory_constructor_test/00: MissingCompileTimeError
-abstract_getter_test/01: MissingCompileTimeError
-abstract_override_adds_optional_args_concrete_subclass_test: MissingCompileTimeError
-abstract_override_adds_optional_args_concrete_test: MissingCompileTimeError
-abstract_override_adds_optional_args_supercall_test: MissingCompileTimeError
-abstract_syntax_test/00: MissingCompileTimeError
-additional_interface_adds_optional_args_concrete_subclass_test: MissingCompileTimeError
-additional_interface_adds_optional_args_concrete_test: MissingCompileTimeError
-additional_interface_adds_optional_args_supercall_test: MissingCompileTimeError
-argument_assignability_function_typed_test/01: MissingCompileTimeError
-argument_assignability_function_typed_test/02: MissingCompileTimeError
-argument_assignability_function_typed_test/03: RuntimeError
-argument_assignability_function_typed_test/04: RuntimeError
-argument_assignability_function_typed_test/05: RuntimeError
-assertion_initializer_const_function_test/01: MissingCompileTimeError
-assertion_test: RuntimeError # Issue 30326
-assign_static_type_test/01: MissingCompileTimeError
-assign_static_type_test/02: MissingCompileTimeError
-assign_static_type_test/03: MissingCompileTimeError
-assign_static_type_test/04: MissingCompileTimeError
-assign_static_type_test/05: MissingCompileTimeError
-assign_static_type_test/06: MissingCompileTimeError
-assign_to_type_test/01: MissingCompileTimeError
-assign_to_type_test/02: MissingCompileTimeError
-assign_to_type_test/03: MissingCompileTimeError
-assign_to_type_test/04: MissingCompileTimeError
-assign_top_method_test: MissingCompileTimeError
-async_await_syntax_test/a10a: MissingCompileTimeError
-async_await_syntax_test/b10a: MissingCompileTimeError
-async_await_syntax_test/c10a: MissingCompileTimeError
-async_await_syntax_test/d08b: MissingCompileTimeError
-async_await_syntax_test/d10a: MissingCompileTimeError
-async_congruence_local_test/01: MissingCompileTimeError
-async_congruence_local_test/02: MissingCompileTimeError
-async_congruence_local_test/none: RuntimeError
-async_congruence_method_test/01: MissingCompileTimeError
-async_congruence_method_test/none: RuntimeError
-async_congruence_top_level_test: RuntimeError
-async_congruence_unnamed_test/01: MissingCompileTimeError
-async_congruence_unnamed_test/02: MissingCompileTimeError
-async_congruence_unnamed_test/none: RuntimeError
-async_or_generator_return_type_stacktrace_test/01: MissingCompileTimeError
-async_or_generator_return_type_stacktrace_test/02: MissingCompileTimeError
-async_or_generator_return_type_stacktrace_test/03: MissingCompileTimeError
-async_return_types_test/nestedFuture: MissingCompileTimeError
-async_return_types_test/tooManyTypeParameters: MissingCompileTimeError
-async_return_types_test/wrongReturnType: MissingCompileTimeError
-async_return_types_test/wrongTypeParameter: MissingCompileTimeError
-async_star_test/01: CompileTimeError # Issue 2238.
-async_star_test/02: RuntimeError
-bad_named_parameters2_test/01: MissingCompileTimeError
-bad_named_parameters_test/01: MissingCompileTimeError
-bad_named_parameters_test/02: MissingCompileTimeError
-bad_named_parameters_test/03: MissingCompileTimeError
-bad_named_parameters_test/04: MissingCompileTimeError
-bad_named_parameters_test/05: MissingCompileTimeError
-bad_override_test/01: MissingCompileTimeError
-bad_override_test/02: MissingCompileTimeError
-bad_override_test/06: MissingCompileTimeError
-bug31436_test: RuntimeError
-bug32305_test: MissingCompileTimeError
-bug32372_test: RuntimeError
-built_in_identifier_prefix_test: CompileTimeError
-call_constructor_on_unresolvable_class_test/01: MissingCompileTimeError
-call_constructor_on_unresolvable_class_test/02: MissingCompileTimeError
-call_constructor_on_unresolvable_class_test/03: MissingCompileTimeError
-call_method_as_cast_test/01: RuntimeError
-call_method_as_cast_test/02: RuntimeError
-call_method_as_cast_test/03: RuntimeError
-call_method_as_cast_test/04: RuntimeError
-call_method_as_cast_test/05: RuntimeError
-call_method_implicit_tear_off_assignable_test: RuntimeError
-call_method_implicit_tear_off_implements_function_test/01: RuntimeError
-call_method_implicit_tear_off_implements_function_test/02: RuntimeError
-call_method_implicit_tear_off_implements_function_test/03: RuntimeError
-call_method_implicit_tear_off_implements_function_test/04: RuntimeError
-call_method_implicit_tear_off_test/01: RuntimeError
-call_method_implicit_tear_off_test/02: RuntimeError
-call_method_implicit_tear_off_test/03: RuntimeError
-call_method_implicit_tear_off_test/04: RuntimeError
-call_method_implicit_tear_off_test/05: RuntimeError
-call_method_implicit_tear_off_test/06: RuntimeError
-call_method_is_check_test/01: RuntimeError
-call_method_is_check_test/02: RuntimeError
-call_method_is_check_test/03: RuntimeError
-call_method_is_check_test/04: RuntimeError
-call_method_is_check_test/05: RuntimeError
-call_method_must_not_be_field_test/01: MissingCompileTimeError
-call_method_must_not_be_field_test/02: MissingCompileTimeError
-call_method_must_not_be_field_test/03: RuntimeError
-call_method_must_not_be_getter_test/01: MissingCompileTimeError
-call_method_must_not_be_getter_test/02: MissingCompileTimeError
-call_method_must_not_be_getter_test/03: RuntimeError
-call_method_override_test/01: MissingCompileTimeError
-call_method_override_test/02: MissingCompileTimeError
-call_non_method_field_test/01: MissingCompileTimeError
-call_non_method_field_test/02: MissingCompileTimeError
-call_nonexistent_constructor_test/01: MissingCompileTimeError
-call_nonexistent_constructor_test/02: MissingCompileTimeError
-call_nonexistent_static_test/01: MissingCompileTimeError
-call_nonexistent_static_test/02: MissingCompileTimeError
-call_nonexistent_static_test/03: MissingCompileTimeError
-call_nonexistent_static_test/04: MissingCompileTimeError
-call_nonexistent_static_test/05: MissingCompileTimeError
-call_nonexistent_static_test/06: MissingCompileTimeError
-call_nonexistent_static_test/07: MissingCompileTimeError
-call_nonexistent_static_test/08: MissingCompileTimeError
-call_nonexistent_static_test/09: MissingCompileTimeError
-call_nonexistent_static_test/10: MissingCompileTimeError
-call_through_getter_test/01: MissingCompileTimeError
-call_through_getter_test/02: MissingCompileTimeError
-call_type_literal_test/01: MissingCompileTimeError
-callable_test/00: MissingCompileTimeError
-callable_test/01: MissingCompileTimeError
-cast_test/04: MissingCompileTimeError
-cast_test/05: MissingCompileTimeError
-check_member_static_test/01: MissingCompileTimeError
-check_method_override_test/01: MissingCompileTimeError
-check_method_override_test/02: MissingCompileTimeError
-checked_null_test/01: MissingCompileTimeError
-class_literal_test/01: MissingCompileTimeError
-class_literal_test/02: MissingCompileTimeError
-class_literal_test/03: MissingCompileTimeError
-class_literal_test/04: MissingCompileTimeError
-class_literal_test/05: MissingCompileTimeError
-class_literal_test/06: MissingCompileTimeError
-class_literal_test/07: MissingCompileTimeError
-class_literal_test/08: MissingCompileTimeError
-class_literal_test/09: MissingCompileTimeError
-class_literal_test/10: MissingCompileTimeError
-class_literal_test/11: MissingCompileTimeError
-class_literal_test/12: MissingCompileTimeError
-class_literal_test/13: MissingCompileTimeError
-class_literal_test/14: MissingCompileTimeError
-class_literal_test/15: MissingCompileTimeError
-class_literal_test/16: MissingCompileTimeError
-class_literal_test/17: MissingCompileTimeError
-class_literal_test/18: MissingCompileTimeError
-class_literal_test/19: MissingCompileTimeError
-class_literal_test/20: MissingCompileTimeError
-class_literal_test/21: MissingCompileTimeError
-class_literal_test/22: MissingCompileTimeError
-class_literal_test/23: MissingCompileTimeError
-class_literal_test/24: MissingCompileTimeError
-class_literal_test/25: MissingCompileTimeError
-closure_invoked_through_interface_target_field_test: MissingCompileTimeError
-closure_invoked_through_interface_target_getter_test: MissingCompileTimeError
-closure_param_null_to_object_test: RuntimeError
-compile_time_constant_o_test/01: MissingCompileTimeError
-compile_time_constant_o_test/02: MissingCompileTimeError
-conditional_method_invocation_test/05: MissingCompileTimeError
-conditional_method_invocation_test/06: MissingCompileTimeError
-conditional_method_invocation_test/07: MissingCompileTimeError
-conditional_method_invocation_test/08: MissingCompileTimeError
-conditional_method_invocation_test/12: MissingCompileTimeError
-conditional_method_invocation_test/13: MissingCompileTimeError
-conditional_method_invocation_test/18: MissingCompileTimeError
-conditional_method_invocation_test/19: MissingCompileTimeError
-conditional_property_access_test/04: MissingCompileTimeError
-conditional_property_access_test/05: MissingCompileTimeError
-conditional_property_access_test/06: MissingCompileTimeError
-conditional_property_access_test/10: MissingCompileTimeError
-conditional_property_access_test/11: MissingCompileTimeError
-conditional_property_access_test/16: MissingCompileTimeError
-conditional_property_access_test/17: MissingCompileTimeError
-conditional_property_assignment_test/04: MissingCompileTimeError
-conditional_property_assignment_test/05: MissingCompileTimeError
-conditional_property_assignment_test/06: MissingCompileTimeError
-conditional_property_assignment_test/10: MissingCompileTimeError
-conditional_property_assignment_test/11: MissingCompileTimeError
-conditional_property_assignment_test/12: MissingCompileTimeError
-conditional_property_assignment_test/13: MissingCompileTimeError
-conditional_property_assignment_test/27: MissingCompileTimeError
-conditional_property_assignment_test/28: MissingCompileTimeError
-conditional_property_assignment_test/32: MissingCompileTimeError
-conditional_property_assignment_test/33: MissingCompileTimeError
-conditional_property_assignment_test/34: MissingCompileTimeError
-conditional_property_assignment_test/35: MissingCompileTimeError
-conditional_property_increment_decrement_test/04: MissingCompileTimeError
-conditional_property_increment_decrement_test/08: MissingCompileTimeError
-conditional_property_increment_decrement_test/12: MissingCompileTimeError
-conditional_property_increment_decrement_test/16: MissingCompileTimeError
-conditional_property_increment_decrement_test/21: MissingCompileTimeError
-conditional_property_increment_decrement_test/22: MissingCompileTimeError
-conditional_property_increment_decrement_test/27: MissingCompileTimeError
-conditional_property_increment_decrement_test/28: MissingCompileTimeError
-conditional_property_increment_decrement_test/33: MissingCompileTimeError
-conditional_property_increment_decrement_test/34: MissingCompileTimeError
-conditional_property_increment_decrement_test/39: MissingCompileTimeError
-conditional_property_increment_decrement_test/40: MissingCompileTimeError
-conflicting_generic_interfaces_simple_test: MissingCompileTimeError
-const_constructor2_test/05: MissingCompileTimeError
-const_constructor2_test/06: MissingCompileTimeError
-const_dynamic_type_literal_test/02: MissingCompileTimeError
-const_types_test/01: MissingCompileTimeError
-const_types_test/02: MissingCompileTimeError
-const_types_test/03: MissingCompileTimeError
-const_types_test/04: MissingCompileTimeError
-const_types_test/05: MissingCompileTimeError
-const_types_test/06: MissingCompileTimeError
-const_types_test/13: MissingCompileTimeError
-const_types_test/34: MissingCompileTimeError
-const_types_test/35: MissingCompileTimeError
-const_types_test/39: MissingCompileTimeError
-const_types_test/40: MissingCompileTimeError
-constructor13_test/01: MissingCompileTimeError
-constructor13_test/02: MissingCompileTimeError
-constructor_call_as_function_test/01: MissingCompileTimeError
-covariant_override/runtime_check_test: RuntimeError
-covariant_tear_off_type_test: RuntimeError
-create_unresolved_type_test/01: MissingCompileTimeError
-cyclic_type_variable_test/01: MissingCompileTimeError
-cyclic_type_variable_test/02: MissingCompileTimeError
-cyclic_type_variable_test/03: MissingCompileTimeError
-cyclic_type_variable_test/04: MissingCompileTimeError
-cyclic_typedef_test/13: MissingCompileTimeError
-default_factory2_test/01: MissingCompileTimeError
-default_factory_test/01: MissingCompileTimeError
-deferred_constraints_type_annotation_test/as_operation: MissingCompileTimeError
-deferred_constraints_type_annotation_test/catch_check: MissingCompileTimeError
-deferred_constraints_type_annotation_test/is_check: MissingCompileTimeError
-deferred_constraints_type_annotation_test/new_before_load: MissingCompileTimeError
-deferred_constraints_type_annotation_test/new_generic2: MissingCompileTimeError
-deferred_constraints_type_annotation_test/new_generic3: MissingCompileTimeError
-deferred_constraints_type_annotation_test/type_annotation1: MissingCompileTimeError
-deferred_constraints_type_annotation_test/type_annotation_generic1: MissingCompileTimeError
-deferred_constraints_type_annotation_test/type_annotation_generic2: MissingCompileTimeError
-deferred_constraints_type_annotation_test/type_annotation_generic3: MissingCompileTimeError
-deferred_constraints_type_annotation_test/type_annotation_generic4: MissingCompileTimeError
-deferred_constraints_type_annotation_test/type_annotation_null: MissingCompileTimeError
-deferred_constraints_type_annotation_test/type_annotation_top_level: MissingCompileTimeError
-deferred_inheritance_constraints_test/redirecting_constructor: MissingCompileTimeError
-dynamic_field_test/01: MissingCompileTimeError
-dynamic_field_test/02: MissingCompileTimeError
-dynamic_prefix_core_test/01: MissingCompileTimeError
-dynamic_prefix_core_test/none: RuntimeError
-empty_block_case_test: MissingCompileTimeError
-enum_private_test/02: MissingCompileTimeError
-error_stacktrace_test/00: MissingCompileTimeError
-export_ambiguous_main_test: MissingCompileTimeError
-f_bounded_quantification_test/01: MissingCompileTimeError
-f_bounded_quantification_test/02: MissingCompileTimeError
-factory1_test/00: MissingCompileTimeError
-factory1_test/01: MissingCompileTimeError
-factory2_test/03: MissingCompileTimeError
-factory2_test/none: MissingCompileTimeError
-factory3_test/none: MissingCompileTimeError
-factory4_test/00: MissingCompileTimeError
-factory5_test/00: MissingCompileTimeError
-factory6_test/00: MissingCompileTimeError
-factory_redirection_test/01: MissingCompileTimeError
-factory_redirection_test/02: MissingCompileTimeError
-factory_redirection_test/03: MissingCompileTimeError
-factory_redirection_test/05: MissingCompileTimeError
-factory_redirection_test/06: MissingCompileTimeError
-factory_redirection_test/08: MissingCompileTimeError
-factory_redirection_test/09: MissingCompileTimeError
-factory_redirection_test/10: MissingCompileTimeError
-factory_redirection_test/11: MissingCompileTimeError
-factory_redirection_test/12: MissingCompileTimeError
-factory_redirection_test/13: MissingCompileTimeError
-factory_redirection_test/14: MissingCompileTimeError
-factory_redirection_test/none: MissingCompileTimeError
-factory_return_type_checked_test/00: MissingCompileTimeError
-field3_test/01: MissingCompileTimeError
-field_method4_test: MissingCompileTimeError
-field_override2_test: MissingCompileTimeError
-field_override_test/00: MissingCompileTimeError
-field_override_test/01: MissingCompileTimeError
-field_override_test/02: MissingCompileTimeError
-field_override_test/none: MissingCompileTimeError
-field_type_check_test/01: MissingCompileTimeError
-final_for_in_variable_test: MissingCompileTimeError
-final_param_test: MissingCompileTimeError
-final_super_field_set_test: MissingCompileTimeError
-final_syntax_test/10: MissingCompileTimeError
-final_variable_assignment_test/01: MissingCompileTimeError
-final_variable_assignment_test/02: MissingCompileTimeError
-final_variable_assignment_test/03: MissingCompileTimeError
-final_variable_assignment_test/04: MissingCompileTimeError
-first_class_types_literals_test/03: MissingCompileTimeError
-first_class_types_literals_test/04: MissingCompileTimeError
-first_class_types_literals_test/05: MissingCompileTimeError
-first_class_types_literals_test/06: MissingCompileTimeError
-first_class_types_literals_test/07: MissingCompileTimeError
-first_class_types_literals_test/08: MissingCompileTimeError
-first_class_types_literals_test/09: MissingCompileTimeError
-first_class_types_literals_test/10: MissingCompileTimeError
-first_class_types_literals_test/11: MissingCompileTimeError
-first_class_types_literals_test/12: MissingCompileTimeError
-flatten_test/05: MissingRuntimeError
-flatten_test/08: MissingRuntimeError
-flatten_test/09: MissingRuntimeError
-flatten_test/12: MissingRuntimeError
-for_in3_test: MissingCompileTimeError
-for_in_side_effects_test/01: MissingCompileTimeError
-function_malformed_result_type_test/00: MissingCompileTimeError
-function_propagation_test: RuntimeError
-function_subtype3_test: RuntimeError
-function_subtype_bound_closure1_test: RuntimeError
-function_subtype_bound_closure2_test: RuntimeError
-function_subtype_bound_closure3_test: RuntimeError
-function_subtype_bound_closure4_test: RuntimeError
-function_subtype_bound_closure5_test: RuntimeError
-function_subtype_bound_closure5a_test: RuntimeError
-function_subtype_bound_closure6_test: RuntimeError
-function_subtype_bound_closure7_test: RuntimeError
-function_subtype_call0_test: RuntimeError
-function_subtype_call1_test: RuntimeError
-function_subtype_call2_test: RuntimeError
-function_subtype_cast0_test: RuntimeError
-function_subtype_cast1_test: RuntimeError
-function_subtype_cast2_test: RuntimeError
-function_subtype_cast3_test: RuntimeError
-function_subtype_checked0_test: RuntimeError
-function_subtype_local1_test: RuntimeError
-function_subtype_local2_test: RuntimeError
-function_subtype_local5_test: RuntimeError
-function_subtype_not0_test: RuntimeError
-function_subtype_not1_test: RuntimeError
-function_subtype_not2_test: RuntimeError
-function_subtype_not3_test: RuntimeError
-function_subtype_top_level1_test: RuntimeError
-function_subtype_typearg5_test: RuntimeError
-function_type_alias3_test: RuntimeError
-function_type_alias4_test: RuntimeError
-function_type_alias_test: RuntimeError
-function_type_call_getter2_test/00: MissingCompileTimeError
-function_type_call_getter2_test/01: MissingCompileTimeError
-function_type_call_getter2_test/02: MissingCompileTimeError
-function_type_call_getter2_test/03: MissingCompileTimeError
-function_type_call_getter2_test/04: MissingCompileTimeError
-function_type_call_getter2_test/05: MissingCompileTimeError
-fuzzy_arrows_test/01: MissingCompileTimeError
-fuzzy_arrows_test/03: RuntimeError
-generic_closure_test: RuntimeError
-generic_constructor_mixin2_test/01: MissingCompileTimeError
-generic_constructor_mixin3_test/01: MissingCompileTimeError
-generic_constructor_mixin_test/01: MissingCompileTimeError
-generic_field_mixin6_test/01: MissingCompileTimeError
-generic_function_bounds_test: RuntimeError
-generic_function_dcall_test: RuntimeError
-generic_function_type_as_type_argument_test/02: MissingCompileTimeError, OK # No type inference
-generic_function_typedef2_test/04: MissingCompileTimeError
-generic_instanceof_test: RuntimeError
-generic_method_types_test/02: RuntimeError, OK # No support for covariant tear-off in VM.
-generic_methods_bounds_test/01: MissingCompileTimeError
-generic_methods_dynamic_test/01: MissingCompileTimeError
-generic_methods_dynamic_test/03: MissingCompileTimeError
-generic_methods_generic_class_tearoff_test: RuntimeError
-generic_methods_overriding_test/01: MissingCompileTimeError
-generic_methods_overriding_test/03: MissingCompileTimeError
-generic_methods_recursive_bound_test/02: MissingCompileTimeError
-generic_methods_tearoff_specialization_test: RuntimeError
-generic_methods_unused_parameter_test: RuntimeError
-generic_no_such_method_dispatcher_simple_test: Skip # This test is only for kernel.
-generic_tearoff_test: RuntimeError
-generic_test/01: MissingCompileTimeError
-generic_test/none: RuntimeError # test requires Dart 2 subtyping for `is`
-getter_no_setter2_test/00: MissingCompileTimeError
-getter_no_setter2_test/01: MissingCompileTimeError
-getter_no_setter2_test/03: MissingCompileTimeError
-getter_no_setter_test/00: MissingCompileTimeError
-getter_no_setter_test/01: MissingCompileTimeError
-getter_no_setter_test/03: MissingCompileTimeError
-getter_override_test/03: MissingCompileTimeError
-getters_setters2_test/02: MissingCompileTimeError
-identical_const_test/01: MissingCompileTimeError
-identical_const_test/02: MissingCompileTimeError
-identical_const_test/03: MissingCompileTimeError
-identical_const_test/04: MissingCompileTimeError
-if_null_assignment_behavior_test/03: MissingCompileTimeError
-if_null_assignment_behavior_test/13: MissingCompileTimeError
-if_null_assignment_behavior_test/15: MissingCompileTimeError
-if_null_assignment_static_test/02: MissingCompileTimeError
-if_null_assignment_static_test/04: MissingCompileTimeError
-if_null_assignment_static_test/06: MissingCompileTimeError
-if_null_assignment_static_test/07: MissingCompileTimeError
-if_null_assignment_static_test/09: MissingCompileTimeError
-if_null_assignment_static_test/11: MissingCompileTimeError
-if_null_assignment_static_test/13: MissingCompileTimeError
-if_null_assignment_static_test/14: MissingCompileTimeError
-if_null_assignment_static_test/16: MissingCompileTimeError
-if_null_assignment_static_test/18: MissingCompileTimeError
-if_null_assignment_static_test/20: MissingCompileTimeError
-if_null_assignment_static_test/21: MissingCompileTimeError
-if_null_assignment_static_test/23: MissingCompileTimeError
-if_null_assignment_static_test/25: MissingCompileTimeError
-if_null_assignment_static_test/27: MissingCompileTimeError
-if_null_assignment_static_test/28: MissingCompileTimeError
-if_null_assignment_static_test/30: MissingCompileTimeError
-if_null_assignment_static_test/32: MissingCompileTimeError
-if_null_assignment_static_test/34: MissingCompileTimeError
-if_null_assignment_static_test/35: MissingCompileTimeError
-if_null_assignment_static_test/37: MissingCompileTimeError
-if_null_assignment_static_test/39: MissingCompileTimeError
-if_null_assignment_static_test/41: MissingCompileTimeError
-if_null_assignment_static_test/42: MissingCompileTimeError
-if_null_precedence_test/06: MissingCompileTimeError
-if_null_precedence_test/07: MissingCompileTimeError
-implicit_downcast_during_for_in_iterable_test: RuntimeError
-implicit_downcast_during_function_literal_arrow_test: RuntimeError
-implicit_downcast_during_function_literal_return_test: RuntimeError
-implicit_downcast_during_yield_star_test: RuntimeError
-implicit_downcast_during_yield_test: RuntimeError
-implicit_this_test/01: MissingCompileTimeError
-implicit_this_test/02: MissingCompileTimeError
-implicit_this_test/04: MissingCompileTimeError
-import_combinators2_test/00: MissingCompileTimeError
-import_self_test/01: MissingCompileTimeError
-inferrer_constructor5_test/01: MissingCompileTimeError
-initializing_formal_final_test: MissingCompileTimeError
-initializing_formal_type_test: MissingCompileTimeError
-instanceof2_test: RuntimeError
-instantiate_tearoff_after_contravariance_check_test: RuntimeError
-instantiate_tearoff_of_call_test: RuntimeError
-instantiate_tearoff_test: RuntimeError
-instantiate_type_variable_test/01: MissingCompileTimeError
-interface_test/00: MissingCompileTimeError
-invalid_cast_test/01: MissingCompileTimeError
-invalid_cast_test/02: MissingCompileTimeError
-invalid_cast_test/03: MissingCompileTimeError
-invalid_cast_test/04: MissingCompileTimeError
-invalid_cast_test/07: MissingCompileTimeError
-invalid_cast_test/08: MissingCompileTimeError
-invalid_cast_test/09: MissingCompileTimeError
-invalid_cast_test/10: MissingCompileTimeError
-invalid_cast_test/11: MissingCompileTimeError
-issue31596_override_test/05: MissingCompileTimeError
-issue31596_override_test/06: MissingCompileTimeError
-issue31596_override_test/07: MissingCompileTimeError
-issue31596_override_test/08: MissingCompileTimeError
-issue31596_super_test/02: MissingCompileTimeError
-issue31596_super_test/04: MissingCompileTimeError
-issue31596_super_test/05: RuntimeError
-issue31596_tearoff_test: RuntimeError
-issue32353_2_test: MissingCompileTimeError # Issue 32353
-issue32353_test: RuntimeError
-least_upper_bound_expansive_test/none: CompileTimeError
-least_upper_bound_test/03: MissingCompileTimeError
-least_upper_bound_test/04: MissingCompileTimeError
-least_upper_bound_test/10: MissingCompileTimeError
-least_upper_bound_test/19: MissingCompileTimeError
-least_upper_bound_test/20: MissingCompileTimeError
-least_upper_bound_test/23: MissingCompileTimeError
-least_upper_bound_test/24: MissingCompileTimeError
-least_upper_bound_test/29: MissingCompileTimeError
-least_upper_bound_test/30: MissingCompileTimeError
-least_upper_bound_test/32: MissingCompileTimeError
-library_ambiguous_test/00: MissingCompileTimeError
-library_ambiguous_test/01: MissingCompileTimeError
-library_ambiguous_test/02: MissingCompileTimeError
-library_ambiguous_test/03: MissingCompileTimeError
-library_ambiguous_test/04: MissingCompileTimeError
-list_literal4_test/00: MissingCompileTimeError
-list_literal4_test/01: MissingCompileTimeError
-list_literal4_test/03: MissingCompileTimeError
-list_literal4_test/04: MissingCompileTimeError
-list_literal4_test/05: MissingCompileTimeError
-list_literal_syntax_test/01: MissingCompileTimeError
-list_literal_syntax_test/02: MissingCompileTimeError
-list_literal_syntax_test/03: MissingCompileTimeError
-local_function2_test/01: MissingCompileTimeError
-local_function2_test/02: MissingCompileTimeError
-local_function2_test/none: RuntimeError
-local_function3_test/01: MissingCompileTimeError
-local_function3_test/none: RuntimeError
-local_function_test/01: MissingCompileTimeError
-local_function_test/02: MissingCompileTimeError
-local_function_test/03: MissingCompileTimeError
-local_function_test/04: MissingCompileTimeError
-local_function_test/none: RuntimeError
-logical_expression3_test: MissingCompileTimeError
-main_test/03: RuntimeError
-malbounded_instantiation_test/01: MissingCompileTimeError
-malbounded_instantiation_test/02: MissingCompileTimeError
-malbounded_instantiation_test/03: MissingCompileTimeError
-malbounded_redirecting_factory_test/02: MissingCompileTimeError
-malbounded_redirecting_factory_test/03: MissingCompileTimeError
-malbounded_redirecting_factory_test/04: MissingCompileTimeError
-malbounded_redirecting_factory_test/05: MissingCompileTimeError
-malbounded_type_cast2_test: MissingCompileTimeError
-malbounded_type_cast_test/00: MissingCompileTimeError
-malbounded_type_cast_test/01: MissingCompileTimeError
-malbounded_type_cast_test/02: MissingCompileTimeError
-malbounded_type_literal_test/00: MissingCompileTimeError
-malbounded_type_test2_test/00: MissingCompileTimeError
-malbounded_type_test_test/00: MissingCompileTimeError
-malbounded_type_test_test/01: MissingCompileTimeError
-malbounded_type_test_test/02: MissingCompileTimeError
-malformed2_test/01: MissingCompileTimeError
-malformed2_test/02: MissingCompileTimeError
-malformed2_test/03: MissingCompileTimeError
-malformed2_test/04: MissingCompileTimeError
-malformed2_test/05: MissingCompileTimeError
-malformed2_test/06: MissingCompileTimeError
-malformed2_test/07: MissingCompileTimeError
-malformed2_test/08: MissingCompileTimeError
-malformed2_test/09: MissingCompileTimeError
-malformed2_test/10: MissingCompileTimeError
-malformed2_test/11: MissingCompileTimeError
-malformed2_test/12: MissingCompileTimeError
-malformed2_test/13: MissingCompileTimeError
-malformed_bound_test/00: MissingCompileTimeError
-malformed_bound_test/01: MissingCompileTimeError
-malformed_inheritance_test/01: MissingCompileTimeError
-malformed_inheritance_test/03: MissingCompileTimeError
-malformed_inheritance_test/05: MissingCompileTimeError
-malformed_test/00: MissingCompileTimeError
-malformed_test/01: MissingCompileTimeError
-malformed_test/02: MissingCompileTimeError
-malformed_test/03: MissingCompileTimeError
-malformed_test/04: MissingCompileTimeError
-malformed_test/05: MissingCompileTimeError
-malformed_test/06: MissingCompileTimeError
-malformed_test/07: MissingCompileTimeError
-malformed_test/08: MissingCompileTimeError
-malformed_test/09: MissingCompileTimeError
-malformed_test/10: MissingCompileTimeError
-malformed_test/11: MissingCompileTimeError
-malformed_test/12: MissingCompileTimeError
-malformed_test/13: MissingCompileTimeError
-malformed_test/14: MissingCompileTimeError
-malformed_test/15: MissingCompileTimeError
-malformed_test/16: MissingCompileTimeError
-malformed_test/17: MissingCompileTimeError
-malformed_test/18: MissingCompileTimeError
-malformed_test/19: MissingCompileTimeError
-malformed_test/20: MissingCompileTimeError
-malformed_test/21: MissingCompileTimeError
-malformed_test/22: MissingCompileTimeError
-malformed_test/23: MissingCompileTimeError
-malformed_test/24: MissingCompileTimeError
-malformed_type_test: MissingCompileTimeError
-many_generic_instanceof_test: RuntimeError
-method_override2_test/00: MissingCompileTimeError
-method_override2_test/01: MissingCompileTimeError
-method_override2_test/02: MissingCompileTimeError
-method_override2_test/03: MissingCompileTimeError
-method_override3_test/00: MissingCompileTimeError
-method_override3_test/01: MissingCompileTimeError
-method_override3_test/02: MissingCompileTimeError
-method_override4_test/01: MissingCompileTimeError
-method_override4_test/02: MissingCompileTimeError
-method_override4_test/03: MissingCompileTimeError
-method_override5_test/01: MissingCompileTimeError
-method_override5_test/02: MissingCompileTimeError
-method_override5_test/03: MissingCompileTimeError
-method_override6_test/01: MissingCompileTimeError
-method_override6_test/02: MissingCompileTimeError
-method_override6_test/03: MissingCompileTimeError
-method_override7_test/03: MissingCompileTimeError
-method_override8_test/03: MissingCompileTimeError
-method_override_test: RuntimeError, OK # No support for covariant tear-off in VM.
-mixin_illegal_constructor_test/13: MissingCompileTimeError
-mixin_illegal_constructor_test/14: MissingCompileTimeError
-mixin_illegal_constructor_test/15: MissingCompileTimeError
-mixin_illegal_constructor_test/16: MissingCompileTimeError
-mixin_illegal_static_access_test/01: MissingCompileTimeError
-mixin_illegal_static_access_test/02: MissingCompileTimeError
-mixin_illegal_syntax_test/13: MissingCompileTimeError
-mixin_invalid_bound2_test/02: MissingCompileTimeError
-mixin_invalid_bound2_test/03: MissingCompileTimeError
-mixin_invalid_bound2_test/04: MissingCompileTimeError
-mixin_invalid_bound2_test/05: MissingCompileTimeError
-mixin_invalid_bound2_test/06: MissingCompileTimeError
-mixin_invalid_bound2_test/07: MissingCompileTimeError
-mixin_invalid_bound2_test/08: MissingCompileTimeError
-mixin_invalid_bound2_test/09: MissingCompileTimeError
-mixin_invalid_bound2_test/10: MissingCompileTimeError
-mixin_invalid_bound2_test/11: MissingCompileTimeError
-mixin_invalid_bound2_test/12: MissingCompileTimeError
-mixin_invalid_bound2_test/13: MissingCompileTimeError
-mixin_invalid_bound2_test/14: MissingCompileTimeError
-mixin_invalid_bound2_test/15: MissingCompileTimeError
-mixin_invalid_bound_test/02: MissingCompileTimeError
-mixin_invalid_bound_test/03: MissingCompileTimeError
-mixin_invalid_bound_test/04: MissingCompileTimeError
-mixin_invalid_bound_test/05: MissingCompileTimeError
-mixin_invalid_bound_test/06: MissingCompileTimeError
-mixin_invalid_bound_test/07: MissingCompileTimeError
-mixin_invalid_bound_test/08: MissingCompileTimeError
-mixin_invalid_bound_test/09: MissingCompileTimeError
-mixin_invalid_bound_test/10: MissingCompileTimeError
-mixin_of_mixin_test/01: MissingCompileTimeError
-mixin_of_mixin_test/02: MissingCompileTimeError
-mixin_of_mixin_test/03: MissingCompileTimeError
-mixin_of_mixin_test/04: MissingCompileTimeError
-mixin_of_mixin_test/05: MissingCompileTimeError
-mixin_of_mixin_test/06: MissingCompileTimeError
-mixin_super_2_test/01: MissingCompileTimeError
-mixin_super_2_test/03: MissingCompileTimeError
-mixin_super_bound_test/01: MissingCompileTimeError
-mixin_super_bound_test/02: MissingCompileTimeError
-mixin_supertype_subclass_test/02: MissingCompileTimeError
-mixin_supertype_subclass_test/05: MissingCompileTimeError
-mixin_type_parameter_inference_error_test/01: MissingCompileTimeError
-mixin_type_parameter_inference_error_test/02: MissingCompileTimeError
-mixin_type_parameter_inference_error_test/03: MissingCompileTimeError
-mixin_type_parameter_inference_error_test/04: MissingCompileTimeError
-mixin_type_parameter_inference_previous_mixin_test/03: MissingCompileTimeError
-mixin_type_parameter_inference_previous_mixin_test/04: MissingCompileTimeError
-mixin_type_parameter_inference_previous_mixin_test/05: RuntimeError
-mixin_type_parameter_inference_test/04: MissingCompileTimeError
-mixin_type_parameter_inference_test/05: MissingCompileTimeError
-mixin_type_parameter_inference_test/06: MissingCompileTimeError
-mixin_type_parameter_inference_test/07: MissingCompileTimeError
-mixin_type_parameter_inference_test/08: RuntimeError
-mixin_type_parameter_inference_test/09: RuntimeError
-mixin_type_parameter_inference_test/11: MissingCompileTimeError
-mixin_type_parameter_inference_test/14: MissingCompileTimeError
-mixin_type_parameter_inference_test/15: MissingCompileTimeError
-mixin_type_parameters_errors_test/01: MissingCompileTimeError
-mixin_type_parameters_errors_test/02: MissingCompileTimeError
-mixin_type_parameters_errors_test/03: MissingCompileTimeError
-mixin_type_parameters_errors_test/04: MissingCompileTimeError
-mixin_type_parameters_errors_test/05: MissingCompileTimeError
-mixin_with_two_implicit_constructors_test: MissingCompileTimeError
-mock_writable_final_private_field_test: RuntimeError # Issue 30849
-named_constructor_test/01: MissingCompileTimeError
-named_constructor_test/03: MissingCompileTimeError
-named_parameters2_test: MissingCompileTimeError
-named_parameters3_test: MissingCompileTimeError
-named_parameters4_test: MissingCompileTimeError
-named_parameters_aggregated_test/05: MissingCompileTimeError
-named_parameters_test/01: MissingCompileTimeError
-named_parameters_test/02: MissingCompileTimeError
-named_parameters_test/03: MissingCompileTimeError
-named_parameters_test/04: MissingCompileTimeError
-named_parameters_test/05: MissingCompileTimeError
-named_parameters_test/06: MissingCompileTimeError
-named_parameters_test/07: MissingCompileTimeError
-named_parameters_test/08: MissingCompileTimeError
-named_parameters_test/09: MissingCompileTimeError
-named_parameters_test/10: MissingCompileTimeError
-named_parameters_type_test/01: MissingCompileTimeError
-named_parameters_type_test/02: MissingCompileTimeError
-named_parameters_type_test/03: MissingCompileTimeError
-new_expression_type_args_test/00: MissingCompileTimeError
-new_expression_type_args_test/01: MissingCompileTimeError
-new_expression_type_args_test/02: MissingCompileTimeError
-new_prefix_test/01: MissingCompileTimeError
-no_such_constructor_test/01: MissingCompileTimeError
-not_enough_positional_arguments_test/00: MissingCompileTimeError
-not_enough_positional_arguments_test/03: MissingCompileTimeError
-not_enough_positional_arguments_test/06: MissingCompileTimeError
-not_enough_positional_arguments_test/07: MissingCompileTimeError
-object_has_no_call_method_test/02: MissingCompileTimeError
-object_has_no_call_method_test/05: MissingCompileTimeError
-object_has_no_call_method_test/08: MissingCompileTimeError
-optional_named_parameters_test/01: MissingCompileTimeError
-optional_named_parameters_test/02: MissingCompileTimeError
-optional_named_parameters_test/03: MissingCompileTimeError
-optional_named_parameters_test/04: MissingCompileTimeError
-optional_named_parameters_test/05: MissingCompileTimeError
-optional_named_parameters_test/06: MissingCompileTimeError
-optional_named_parameters_test/07: MissingCompileTimeError
-optional_named_parameters_test/08: MissingCompileTimeError
-optional_named_parameters_test/09: MissingCompileTimeError
-override_field_test/02: MissingCompileTimeError
-override_field_test/03: MissingCompileTimeError
-override_inheritance_abstract_test/02: MissingCompileTimeError
-override_inheritance_abstract_test/03: MissingCompileTimeError
-override_inheritance_abstract_test/04: MissingCompileTimeError
-override_inheritance_abstract_test/07: MissingCompileTimeError
-override_inheritance_abstract_test/08: MissingCompileTimeError
-override_inheritance_abstract_test/09: MissingCompileTimeError
-override_inheritance_abstract_test/10: MissingCompileTimeError
-override_inheritance_abstract_test/11: MissingCompileTimeError
-override_inheritance_abstract_test/12: MissingCompileTimeError
-override_inheritance_abstract_test/13: MissingCompileTimeError
-override_inheritance_abstract_test/14: MissingCompileTimeError
-override_inheritance_abstract_test/17: MissingCompileTimeError
-override_inheritance_abstract_test/19: MissingCompileTimeError
-override_inheritance_abstract_test/20: MissingCompileTimeError
-override_inheritance_abstract_test/21: MissingCompileTimeError
-override_inheritance_abstract_test/22: MissingCompileTimeError
-override_inheritance_abstract_test/23: MissingCompileTimeError
-override_inheritance_abstract_test/24: MissingCompileTimeError
-override_inheritance_abstract_test/25: MissingCompileTimeError
-override_inheritance_abstract_test/26: MissingCompileTimeError
-override_inheritance_field_test/05: MissingCompileTimeError
-override_inheritance_field_test/07: MissingCompileTimeError
-override_inheritance_field_test/08: MissingCompileTimeError
-override_inheritance_field_test/09: MissingCompileTimeError
-override_inheritance_field_test/10: MissingCompileTimeError
-override_inheritance_field_test/11: MissingCompileTimeError
-override_inheritance_field_test/28: MissingCompileTimeError
-override_inheritance_field_test/30: MissingCompileTimeError
-override_inheritance_field_test/31: MissingCompileTimeError
-override_inheritance_field_test/32: MissingCompileTimeError
-override_inheritance_field_test/33: MissingCompileTimeError
-override_inheritance_field_test/33a: MissingCompileTimeError
-override_inheritance_field_test/34: MissingCompileTimeError
-override_inheritance_field_test/44: MissingCompileTimeError
-override_inheritance_field_test/47: MissingCompileTimeError
-override_inheritance_field_test/48: MissingCompileTimeError
-override_inheritance_field_test/53: MissingCompileTimeError
-override_inheritance_field_test/54: MissingCompileTimeError
-override_inheritance_generic_test/04: MissingCompileTimeError
-override_inheritance_generic_test/06: MissingCompileTimeError
-override_inheritance_generic_test/07: MissingCompileTimeError
-override_inheritance_generic_test/08: MissingCompileTimeError
-override_inheritance_generic_test/09: MissingCompileTimeError
-override_inheritance_generic_test/10: MissingCompileTimeError
-override_inheritance_method_test/04: MissingCompileTimeError
-override_inheritance_method_test/05: MissingCompileTimeError
-override_inheritance_method_test/06: MissingCompileTimeError
-override_inheritance_method_test/11: MissingCompileTimeError
-override_inheritance_method_test/12: MissingCompileTimeError
-override_inheritance_method_test/13: MissingCompileTimeError
-override_inheritance_method_test/14: MissingCompileTimeError
-override_inheritance_method_test/19: MissingCompileTimeError
-override_inheritance_method_test/20: MissingCompileTimeError
-override_inheritance_method_test/21: MissingCompileTimeError
-override_inheritance_method_test/27: MissingCompileTimeError
-override_inheritance_method_test/30: MissingCompileTimeError
-override_inheritance_method_test/31: MissingCompileTimeError
-override_inheritance_method_test/32: MissingCompileTimeError
-override_inheritance_method_test/33: MissingCompileTimeError
-override_inheritance_mixed_test/06: MissingCompileTimeError
-override_inheritance_mixed_test/07: MissingCompileTimeError
-override_inheritance_mixed_test/09: MissingCompileTimeError
-override_inheritance_no_such_method_test/01: MissingCompileTimeError
-override_inheritance_no_such_method_test/06: MissingCompileTimeError
-override_inheritance_no_such_method_test/07: MissingCompileTimeError
-override_inheritance_no_such_method_test/09: MissingCompileTimeError
-override_inheritance_no_such_method_test/10: MissingCompileTimeError
-override_inheritance_no_such_method_test/12: MissingCompileTimeError
-override_method_with_field_test/02: MissingCompileTimeError
-part2_test/01: MissingCompileTimeError
-positional_parameters_type_test/01: MissingCompileTimeError
-positional_parameters_type_test/02: MissingCompileTimeError
-prefix16_test/00: MissingCompileTimeError
-prefix16_test/01: MissingCompileTimeError
-prefix22_test/00: MissingCompileTimeError
-prefix23_test/00: MissingCompileTimeError
-prefix_import_collision_test/01: MissingCompileTimeError
-prefix_shadow_test/01: MissingCompileTimeError
-prefix_shadow_test/02: MissingCompileTimeError
-prefix_transitive_import_prefix_test/01: MissingCompileTimeError
-prefix_transitive_import_prefix_test/02: MissingCompileTimeError
-prefix_transitive_import_prefix_test/03: MissingCompileTimeError
-prefix_transitive_import_test/01: MissingCompileTimeError
-prefix_transitive_import_test/02: MissingCompileTimeError
-private_access_test/01: MissingCompileTimeError
-private_access_test/02: MissingCompileTimeError
-private_access_test/03: MissingCompileTimeError
-private_access_test/04: MissingCompileTimeError
-private_access_test/05: MissingCompileTimeError
-private_access_test/06: MissingCompileTimeError
-regress_12561_test: MissingCompileTimeError
-regress_13494_test: MissingCompileTimeError
-regress_17382_test: MissingCompileTimeError
-regress_19413_test: MissingCompileTimeError
-regress_19728_test: MissingCompileTimeError
-regress_21912_test/01: MissingCompileTimeError
-regress_21912_test/02: MissingCompileTimeError
-regress_22438_test: MissingCompileTimeError
-regress_22936_test: MissingCompileTimeError
-regress_23089_test: MissingCompileTimeError
-regress_23408_test: RuntimeError
-regress_26133_test: MissingCompileTimeError
-regress_27572_test: MissingCompileTimeError
-regress_31591_test: RuntimeError, OK # strong mode only
-return_type_test: MissingCompileTimeError
-rewrite_implicit_this_test/01: MissingCompileTimeError
-runtime_type_function_test: RuntimeError
-setter4_test: MissingCompileTimeError # Issue 14736
-setter_no_getter_call_test/01: MissingCompileTimeError
-setter_override_test/01: MissingCompileTimeError
-setter_override_test/02: MissingCompileTimeError
-static_field1_test/01: MissingCompileTimeError
-static_field1a_test/01: MissingCompileTimeError
-static_field3_test/01: MissingCompileTimeError
-static_field3_test/02: MissingCompileTimeError
-static_field3_test/03: MissingCompileTimeError
-static_field3_test/04: MissingCompileTimeError
-static_field_test/01: MissingCompileTimeError
-static_field_test/02: MissingCompileTimeError
-static_field_test/03: MissingCompileTimeError
-static_field_test/04: MissingCompileTimeError
-static_final_field2_test/01: MissingCompileTimeError
-static_getter_no_setter1_test/01: MissingCompileTimeError
-static_getter_no_setter2_test/01: MissingCompileTimeError
-static_initializer_type_error_test: MissingCompileTimeError
-static_setter_get_test/01: MissingCompileTimeError
-string_interpolation_test/01: MissingCompileTimeError
-string_no_operator_test/01: MissingCompileTimeError
-string_no_operator_test/02: MissingCompileTimeError
-string_no_operator_test/03: MissingCompileTimeError
-string_no_operator_test/04: MissingCompileTimeError
-string_no_operator_test/05: MissingCompileTimeError
-string_no_operator_test/06: MissingCompileTimeError
-string_no_operator_test/07: MissingCompileTimeError
-string_no_operator_test/08: MissingCompileTimeError
-string_no_operator_test/09: MissingCompileTimeError
-string_no_operator_test/10: MissingCompileTimeError
-string_no_operator_test/11: MissingCompileTimeError
-string_no_operator_test/12: MissingCompileTimeError
-string_no_operator_test/13: MissingCompileTimeError
-string_no_operator_test/14: MissingCompileTimeError
-string_no_operator_test/15: MissingCompileTimeError
-string_no_operator_test/16: MissingCompileTimeError
-string_test/01: MissingCompileTimeError
-substring_test/01: MissingCompileTimeError
-super_assign_test/01: MissingCompileTimeError
-super_bound_closure_test/01: MissingCompileTimeError
-super_call4_test/01: MissingCompileTimeError
-super_operator_index_test/01: MissingCompileTimeError
-super_operator_index_test/02: MissingCompileTimeError
-super_operator_index_test/03: MissingCompileTimeError
-super_operator_index_test/04: MissingCompileTimeError
-super_operator_index_test/05: MissingCompileTimeError
-super_operator_index_test/06: MissingCompileTimeError
-super_operator_index_test/07: MissingCompileTimeError
-switch_fallthru_test/01: MissingCompileTimeError
-symbol_literal_test/01: MissingCompileTimeError
-sync_generator1_test/01: MissingCompileTimeError
-syntax_test/59: MissingCompileTimeError, OK # Issue 30516.
-syntax_test/60: MissingCompileTimeError, OK # Issue 30516.
-syntax_test/61: MissingCompileTimeError, OK # Issue 30516.
-top_level_getter_no_setter1_test: MissingCompileTimeError
-top_level_getter_no_setter2_test: MissingCompileTimeError
-transitive_private_library_access_test: MissingCompileTimeError
-try_catch_on_syntax_test/07: MissingCompileTimeError
-try_catch_on_syntax_test/10: MissingCompileTimeError
-try_catch_on_syntax_test/11: MissingCompileTimeError
-try_catch_syntax_test/08: MissingCompileTimeError
-type_checks_in_factory_method_test/01: MissingCompileTimeError
-type_inference_accessor_ref_test/03: MissingCompileTimeError
-type_inference_accessor_ref_test/06: MissingCompileTimeError
-type_inference_circularity_test: MissingCompileTimeError
-type_inference_inconsistent_inheritance_test: MissingCompileTimeError
-type_promotion_functions_test/01: MissingCompileTimeError
-type_promotion_functions_test/05: MissingCompileTimeError
-type_promotion_functions_test/06: MissingCompileTimeError
-type_promotion_functions_test/07: MissingCompileTimeError
-type_promotion_functions_test/08: MissingCompileTimeError
-type_promotion_functions_test/10: MissingCompileTimeError
-type_promotion_parameter_test/01: MissingCompileTimeError
-type_promotion_parameter_test/02: MissingCompileTimeError
-type_promotion_parameter_test/03: MissingCompileTimeError
-type_promotion_parameter_test/04: MissingCompileTimeError
-type_promotion_parameter_test/05: MissingCompileTimeError
-type_promotion_parameter_test/06: MissingCompileTimeError
-type_promotion_parameter_test/07: MissingCompileTimeError
-type_promotion_parameter_test/08: MissingCompileTimeError
-type_promotion_parameter_test/09: MissingCompileTimeError
-type_promotion_parameter_test/10: MissingCompileTimeError
-type_promotion_parameter_test/11: MissingCompileTimeError
-type_promotion_parameter_test/12: MissingCompileTimeError
-type_promotion_parameter_test/13: MissingCompileTimeError
-type_promotion_parameter_test/14: MissingCompileTimeError
-type_promotion_parameter_test/15: MissingCompileTimeError
-type_promotion_parameter_test/16: MissingCompileTimeError
-type_promotion_parameter_test/17: MissingCompileTimeError
-type_promotion_parameter_test/18: MissingCompileTimeError
-type_promotion_parameter_test/19: MissingCompileTimeError
-type_promotion_parameter_test/20: MissingCompileTimeError
-type_promotion_parameter_test/21: MissingCompileTimeError
-type_promotion_parameter_test/22: MissingCompileTimeError
-type_promotion_parameter_test/23: MissingCompileTimeError
-type_promotion_parameter_test/24: MissingCompileTimeError
-type_promotion_parameter_test/25: MissingCompileTimeError
-type_promotion_parameter_test/26: MissingCompileTimeError
-type_promotion_parameter_test/27: MissingCompileTimeError
-type_promotion_parameter_test/28: MissingCompileTimeError
-type_promotion_parameter_test/29: MissingCompileTimeError
-type_promotion_parameter_test/30: MissingCompileTimeError
-type_promotion_parameter_test/31: MissingCompileTimeError
-type_promotion_parameter_test/32: MissingCompileTimeError
-type_promotion_parameter_test/33: MissingCompileTimeError
-type_promotion_parameter_test/34: MissingCompileTimeError
-type_promotion_parameter_test/35: MissingCompileTimeError
-type_promotion_parameter_test/36: MissingCompileTimeError
-type_promotion_parameter_test/37: MissingCompileTimeError
-type_promotion_parameter_test/38: MissingCompileTimeError
-type_promotion_parameter_test/39: MissingCompileTimeError
-type_promotion_parameter_test/40: MissingCompileTimeError
-type_promotion_parameter_test/41: MissingCompileTimeError
-type_promotion_parameter_test/42: MissingCompileTimeError
-type_promotion_parameter_test/43: MissingCompileTimeError
-type_promotion_parameter_test/44: MissingCompileTimeError
-type_promotion_parameter_test/45: MissingCompileTimeError
-type_promotion_parameter_test/46: MissingCompileTimeError
-type_promotion_parameter_test/47: MissingCompileTimeError
-type_promotion_parameter_test/48: MissingCompileTimeError
-type_promotion_parameter_test/49: MissingCompileTimeError
-type_promotion_parameter_test/50: MissingCompileTimeError
-type_promotion_parameter_test/51: MissingCompileTimeError
-type_promotion_parameter_test/52: MissingCompileTimeError
-type_promotion_parameter_test/54: MissingCompileTimeError
-type_promotion_parameter_test/55: MissingCompileTimeError
-type_promotion_parameter_test/56: MissingCompileTimeError
-type_variable_bounds2_test: MissingCompileTimeError
-type_variable_bounds3_test/00: MissingCompileTimeError
-type_variable_bounds4_test/01: MissingCompileTimeError
-type_variable_bounds_test/00: MissingCompileTimeError
-type_variable_bounds_test/01: MissingCompileTimeError
-type_variable_bounds_test/02: MissingCompileTimeError
-type_variable_bounds_test/03: MissingCompileTimeError
-type_variable_bounds_test/04: MissingCompileTimeError
-type_variable_bounds_test/05: MissingCompileTimeError
-type_variable_bounds_test/06: MissingCompileTimeError
-type_variable_bounds_test/07: MissingCompileTimeError
-type_variable_bounds_test/08: MissingCompileTimeError
-type_variable_bounds_test/09: MissingCompileTimeError
-type_variable_bounds_test/10: MissingCompileTimeError
-type_variable_bounds_test/11: MissingCompileTimeError
-type_variable_conflict2_test/01: MissingCompileTimeError
-type_variable_conflict2_test/03: MissingCompileTimeError
-type_variable_conflict2_test/04: MissingCompileTimeError
-type_variable_conflict2_test/05: MissingCompileTimeError
-type_variable_conflict2_test/07: MissingCompileTimeError
-type_variable_conflict2_test/09: MissingCompileTimeError
-type_variable_identifier_expression_test: MissingCompileTimeError
-type_variable_scope2_test: MissingCompileTimeError
-type_variable_scope_test/00: MissingCompileTimeError
-type_variable_scope_test/01: MissingCompileTimeError
-type_variable_scope_test/02: MissingCompileTimeError
-type_variable_scope_test/04: MissingCompileTimeError
-type_variable_scope_test/05: MissingCompileTimeError
-type_variable_static_context_test: MissingCompileTimeError
-typed_selector2_test: MissingCompileTimeError
-unbound_getter_test: MissingCompileTimeError
-unresolved_default_constructor_test/01: MissingCompileTimeError
-unresolved_in_factory_test: MissingCompileTimeError
-unresolved_top_level_method_test: MissingCompileTimeError
-unresolved_top_level_var_test: MissingCompileTimeError
-variable_shadow_class_test/01: MissingCompileTimeError
-
-[ $compiler != dartk && $runtime == vm && $checked ]
-call_method_as_cast_test/06: RuntimeError
-call_method_implicit_invoke_local_test/05: MissingCompileTimeError
-call_method_implicit_tear_off_implements_function_test/05: RuntimeError
-call_method_implicit_tear_off_implements_function_test/06: RuntimeError
-call_method_is_check_test/06: RuntimeError
-call_operator_test/01: RuntimeError
-call_operator_test/02: RuntimeError
-call_type_literal_test: RuntimeError
-call_with_no_such_method_test: RuntimeError
-class_literal_static_test/none: RuntimeError
-class_literal_test/none: RuntimeError
-constructor_call_as_function_test: RuntimeError
-constructor_call_as_function_test/01: MissingCompileTimeError
-covariance_type_parameter_test/01: RuntimeError
-covariance_type_parameter_test/02: RuntimeError
-covariance_type_parameter_test/03: RuntimeError
-covariance_type_parameter_test/none: RuntimeError
-covariant_subtyping_test: RuntimeError
-factory_implementation_test/00: Fail
-function_call_generic_test: RuntimeError # Type argument not inferred.
-function_type/function_type0_test: RuntimeError # Issue 30475
-function_type/function_type10_test: RuntimeError # Issue 30475
-function_type/function_type12_test: RuntimeError # Issue 30475
-function_type/function_type13_test: RuntimeError # Issue 30475
-function_type/function_type14_test: RuntimeError # Issue 30475
-function_type/function_type15_test: RuntimeError # Issue 30475
-function_type/function_type16_test: RuntimeError # Issue 30475
-function_type/function_type17_test: RuntimeError # Issue 30475
-function_type/function_type18_test: RuntimeError # Issue 30475
-function_type/function_type19_test: RuntimeError # Issue 30475
-function_type/function_type1_test: RuntimeError # Issue 30475
-function_type/function_type20_test: RuntimeError # Issue 30475
-function_type/function_type21_test: RuntimeError # Issue 30475
-function_type/function_type22_test: RuntimeError # Issue 30475
-function_type/function_type24_test: RuntimeError # Issue 30475
-function_type/function_type25_test: RuntimeError # Issue 30475
-function_type/function_type26_test: RuntimeError # Issue 30475
-function_type/function_type27_test: RuntimeError # Issue 30475
-function_type/function_type28_test: RuntimeError # Issue 30475
-function_type/function_type29_test: RuntimeError # Issue 30475
-function_type/function_type2_test: RuntimeError # Issue 30475
-function_type/function_type30_test: RuntimeError # Issue 30475
-function_type/function_type31_test: RuntimeError # Issue 30475
-function_type/function_type32_test: RuntimeError # Issue 30475
-function_type/function_type33_test: RuntimeError # Issue 30475
-function_type/function_type34_test: RuntimeError # Issue 30475
-function_type/function_type36_test: RuntimeError # Issue 30475
-function_type/function_type3_test: RuntimeError # Issue 30475
-function_type/function_type44_test: RuntimeError # Issue 30475
-function_type/function_type45_test: RuntimeError # Issue 30475
-function_type/function_type46_test: RuntimeError # Issue 30475
-function_type/function_type47_test: RuntimeError # Issue 30475
-function_type/function_type48_test: RuntimeError # Issue 30475
-function_type/function_type49_test: RuntimeError # Issue 30475
-function_type/function_type4_test: RuntimeError # Issue 30475
-function_type/function_type50_test: RuntimeError # Issue 30475
-function_type/function_type51_test: RuntimeError # Issue 30475
-function_type/function_type52_test: RuntimeError # Issue 30475
-function_type/function_type53_test: RuntimeError # Issue 30475
-function_type/function_type54_test: RuntimeError # Issue 30475
-function_type/function_type56_test: RuntimeError # Issue 30475
-function_type/function_type57_test: RuntimeError # Issue 30475
-function_type/function_type58_test: RuntimeError # Issue 30475
-function_type/function_type59_test: RuntimeError # Issue 30475
-function_type/function_type5_test: RuntimeError # Issue 30475
-function_type/function_type60_test: RuntimeError # Issue 30475
-function_type/function_type61_test: RuntimeError # Issue 30475
-function_type/function_type62_test: RuntimeError # Issue 30475
-function_type/function_type63_test: RuntimeError # Issue 30475
-function_type/function_type64_test: RuntimeError # Issue 30475
-function_type/function_type65_test: RuntimeError # Issue 30475
-function_type/function_type66_test: RuntimeError # Issue 30475
-function_type/function_type6_test: RuntimeError # Issue 30475
-function_type/function_type7_test: RuntimeError # Issue 30475
-function_type/function_type80_test: RuntimeError # Issue 30475
-function_type/function_type81_test: RuntimeError # Issue 30475
-function_type/function_type82_test: RuntimeError # Issue 30475
-function_type/function_type83_test: RuntimeError # Issue 30475
-function_type/function_type84_test: RuntimeError # Issue 30475
-function_type/function_type85_test: RuntimeError # Issue 30475
-function_type/function_type86_test: RuntimeError # Issue 30475
-function_type/function_type87_test: RuntimeError # Issue 30475
-function_type/function_type88_test: RuntimeError # Issue 30475
-function_type/function_type89_test: RuntimeError # Issue 30475
-function_type/function_type8_test: RuntimeError # Issue 30475
-function_type/function_type90_test: RuntimeError # Issue 30475
-function_type/function_type96_test: RuntimeError # Issue 30475
-function_type/function_type9_test: RuntimeError # Issue 30475
-function_type_alias2_test: RuntimeError
-function_type_alias6_test/none: RuntimeError
-invalid_override_in_mixin_test/01: MissingCompileTimeError
-type_literal_prefix_call_test: RuntimeError
-vm/regress_33040_instantiation_test: RuntimeError
-
-# The VM and does not implement the Dart 2.0 runtime checks yet unless
-# --checked is explicitly passed).
-[ $compiler != dartk && $runtime == vm && !$checked && !$strong ]
-bool_check_test: RuntimeError
-bool_condition_check_test: RuntimeError
-callable_test/none: RuntimeError
-cascaded_forwarding_stubs_generic_test: RuntimeError
-cascaded_forwarding_stubs_test: RuntimeError
-checked_setter2_test: RuntimeError
-checked_setter3_test: RuntimeError
-checked_setter_test: RuntimeError
-const_constructor2_test/13: MissingCompileTimeError
-const_constructor2_test/14: MissingCompileTimeError
-const_constructor2_test/15: MissingCompileTimeError
-const_constructor2_test/16: MissingCompileTimeError
-const_constructor2_test/17: MissingCompileTimeError
-const_constructor2_test/18: MissingCompileTimeError
-const_constructor2_test/20: MissingCompileTimeError
-const_constructor2_test/22: MissingCompileTimeError
-const_constructor2_test/24: MissingCompileTimeError
-const_constructor3_test/02: MissingCompileTimeError
-const_constructor3_test/04: MissingCompileTimeError
-const_init2_test/02: MissingCompileTimeError
-covariance_field_test/01: RuntimeError
-covariance_field_test/02: RuntimeError
-covariance_field_test/03: RuntimeError
-covariance_field_test/04: RuntimeError
-covariance_field_test/05: RuntimeError
-covariance_method_test/01: RuntimeError
-covariance_method_test/02: RuntimeError
-covariance_method_test/03: RuntimeError
-covariance_method_test/04: RuntimeError
-covariance_method_test/05: RuntimeError
-covariance_method_test/06: RuntimeError
-covariance_setter_test/01: RuntimeError
-covariance_setter_test/02: RuntimeError
-covariance_setter_test/03: RuntimeError
-covariance_setter_test/04: RuntimeError
-covariance_setter_test/05: RuntimeError
-covariance_setter_test/06: RuntimeError
-covariance_type_parameter_test/01: RuntimeError
-covariance_type_parameter_test/02: RuntimeError
-covariance_type_parameter_test/03: RuntimeError
-covariant_subtyping_tearoff1_test: RuntimeError
-covariant_subtyping_tearoff2_test: RuntimeError
-covariant_subtyping_tearoff3_test: RuntimeError
-covariant_subtyping_test: RuntimeError
-covariant_subtyping_unsafe_call1_test: RuntimeError
-covariant_subtyping_unsafe_call2_test: RuntimeError
-covariant_subtyping_unsafe_call3_test: RuntimeError
-field_override_optimization_test: RuntimeError
-field_type_check2_test/01: MissingRuntimeError
-forwarding_semi_stub_test: RuntimeError
-forwarding_stub_tearoff_generic_test: RuntimeError
-forwarding_stub_tearoff_test: RuntimeError
-function_subtype_checked0_test: RuntimeError
-function_subtype_closure0_test: RuntimeError
-function_subtype_closure1_test: RuntimeError
-function_subtype_factory1_test: RuntimeError
-function_subtype_inline1_test: RuntimeError
-function_subtype_inline2_test: RuntimeError
-function_subtype_regression_ddc_588_test: RuntimeError
-function_subtype_setter0_test: RuntimeError
-function_type2_test: RuntimeError
-function_type_alias2_test: RuntimeError
-function_type_call_getter2_test/none: RuntimeError
-function_type_test: RuntimeError
-generic_field_mixin6_test/none: RuntimeError
-generic_list_checked_test: RuntimeError
-getters_setters2_test/01: RuntimeError
-getters_setters2_test/none: RuntimeError
-if_null_precedence_test/none: RuntimeError
-implicit_downcast_during_assignment_test: RuntimeError
-implicit_downcast_during_combiner_test: RuntimeError
-implicit_downcast_during_compound_assignment_test: RuntimeError
-implicit_downcast_during_conditional_expression_test: RuntimeError
-implicit_downcast_during_constructor_initializer_test: RuntimeError
-implicit_downcast_during_constructor_invocation_test: RuntimeError
-implicit_downcast_during_do_test: RuntimeError
-implicit_downcast_during_factory_constructor_invocation_test: RuntimeError
-implicit_downcast_during_field_declaration_test: RuntimeError
-implicit_downcast_during_for_condition_test: RuntimeError
-implicit_downcast_during_for_in_element_test: RuntimeError
-implicit_downcast_during_for_initializer_expression_test: RuntimeError
-implicit_downcast_during_for_initializer_var_test: RuntimeError
-implicit_downcast_during_if_null_assignment_test: RuntimeError
-implicit_downcast_during_if_statement_test: RuntimeError
-implicit_downcast_during_indexed_assignment_test: RuntimeError
-implicit_downcast_during_indexed_compound_assignment_test: RuntimeError
-implicit_downcast_during_indexed_get_test: RuntimeError
-implicit_downcast_during_indexed_if_null_assignment_test: RuntimeError
-implicit_downcast_during_invocation_test: RuntimeError
-implicit_downcast_during_list_literal_test: RuntimeError
-implicit_downcast_during_logical_expression_test: RuntimeError
-implicit_downcast_during_map_literal_test: RuntimeError
-implicit_downcast_during_method_invocation_test: RuntimeError
-implicit_downcast_during_not_test: RuntimeError
-implicit_downcast_during_null_aware_method_invocation_test: RuntimeError
-implicit_downcast_during_redirecting_initializer_test: RuntimeError
-implicit_downcast_during_return_async_test: RuntimeError
-implicit_downcast_during_return_test: RuntimeError
-implicit_downcast_during_static_method_invocation_test: RuntimeError
-implicit_downcast_during_super_initializer_test: RuntimeError
-implicit_downcast_during_super_method_invocation_test: RuntimeError
-implicit_downcast_during_variable_declaration_test: RuntimeError
-implicit_downcast_during_while_statement_test: RuntimeError
-inferrer_synthesized_constructor_test: RuntimeError
-issue31596_implement_covariant_test: RuntimeError
-issue31596_test: RuntimeError
-list_is_test: RuntimeError
-list_literal1_test/01: MissingCompileTimeError
-malformed2_test/00: MissingCompileTimeError
-type_argument_in_super_type_test: RuntimeError
-type_check_const_function_typedef2_test: MissingCompileTimeError
-typevariable_substitution2_test/02: RuntimeError
-
-[ $compiler != dartk && $runtime == vm && !$strong ]
-covariant_subtyping_with_substitution_test: RuntimeError
-function_subtype_named1_test: RuntimeError
-function_subtype_named2_test: RuntimeError
-function_subtype_optional1_test: RuntimeError
-function_subtype_optional2_test: RuntimeError
-function_subtype_typearg2_test: RuntimeError
-function_subtype_typearg3_test: RuntimeError
-generic_function_typedef_test/01: RuntimeError
-generic_methods_named_parameters_test: RuntimeError
-generic_methods_optional_parameters_test: RuntimeError
-instanceof4_test/01: RuntimeError
-instanceof4_test/none: RuntimeError
-list_is_test: RuntimeError
-malbounded_type_cast_test/none: RuntimeError
-malbounded_type_test_test/none: RuntimeError
-map_literal8_test: RuntimeError
-mixin_type_parameters_mixin_extends_test: RuntimeError
-mixin_type_parameters_mixin_test: RuntimeError
-mixin_type_parameters_super_extends_test: RuntimeError
-mixin_type_parameters_super_test: RuntimeError
-no_such_method_mock_test: RuntimeError
-override_inheritance_mixed_test/08: MissingCompileTimeError
-regress_28341_test: Fail # Issue 28340
-type_variable_nested_test/01: RuntimeError
-type_variable_promotion_test: RuntimeError
-
-[ $compiler != dartkp && $mode == product && $runtime == dart_precompiled ]
-vm/type_vm_test/28: MissingRuntimeError
-vm/type_vm_test/29: MissingRuntimeError
-vm/type_vm_test/30: MissingRuntimeError
-vm/type_vm_test/31: MissingRuntimeError
-vm/type_vm_test/32: MissingRuntimeError
-vm/type_vm_test/33: MissingRuntimeError
-vm/type_vm_test/34: MissingRuntimeError
-vm/type_vm_test/35: MissingRuntimeError
-vm/type_vm_test/36: MissingRuntimeError
-
-[ $compiler == none && $mode != product && $runtime == vm ]
-vm/type_vm_test/none: RuntimeError
-
-[ $compiler == none && $runtime == vm ]
-async_star_cancel_while_paused_test: RuntimeError
-async_star_pause_test: Fail, OK
-async_star_regression_2238_test: CompileTimeError, RuntimeError
-class_keyword_test/02: MissingCompileTimeError # Issue 13627
-constructor3_test: Fail, OK, Pass
-cyclic_type2_test: Fail, OK
-cyclic_type_test/00: RuntimeError, OK # Not running in strong mode.
-cyclic_type_test/02: Fail, OK # Non-contractive types are not supported in the vm.
-cyclic_type_test/03: RuntimeError, OK # Not running in strong mode.
-cyclic_type_test/04: Fail, OK
-deferred_redirecting_factory_test: Fail, Crash # Issue 23408
-duplicate_export_negative_test: Fail # Issue 6134
-dynamic_prefix_core_test/01: RuntimeError # Issue 12478
-example_constructor_test: Fail, OK
-export_ambiguous_main_negative_test: Fail # Issue 14763
-f_bounded_quantification4_test: RuntimeError, OK # Not running in strong mode.
-field_initialization_order_test: Fail, OK
-generic_methods_bounds_test/02: MissingRuntimeError
-library_env_test/has_html_support: RuntimeError, OK
-library_env_test/has_no_io_support: RuntimeError, OK
-main_not_a_function_test: Skip
-mixin_illegal_super_use_test: Skip # Issues 24478 and 23773
-mixin_illegal_superclass_test: Skip # Issues 24478 and 23773
-mixin_mixin6_test: RuntimeError, OK # Not running in strong mode.
-multiline_strings_test: Fail # Issue 23020
-no_main_test/01: Skip
-regress_19413_test: MissingCompileTimeError
-regress_21793_test/01: MissingCompileTimeError
-super_test: Fail, OK
-type_variable_scope_test/03: MissingCompileTimeError
-unicode_bom_test: Fail # Issue 16067
-vm/debug_break_enabled_vm_test/01: Crash, OK # Expected to hit breakpoint.
-vm/regress_29145_test: Skip # Issue 29145
-vm/regress_33073_test: Skip # Issue 33073
-
-[ $compiler == none && $runtime == vm && $system == fuchsia ]
-async_await_test: RuntimeError
-async_star_test: RuntimeError
-closure_cycles_test: Pass, Crash
-vm/causal_async_exception_stack2_test: RuntimeError
-vm/causal_async_exception_stack_test: RuntimeError
-vm/math_vm_test: Crash
-
-[ $compiler == none && $runtime == vm && $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`.
-dynamic_test: RuntimeError
-generic_functions_test: Pass # Issue 25869
-generic_local_functions_test: Pass # Issue 25869
-generic_methods_function_type_test: Pass # Issue 25869
-generic_methods_generic_function_parameter_test: Pass # Issue 25869
-generic_methods_new_test: Pass # Issue 25869
-generic_methods_test: Pass # Issue 25869
-library_test/01: MissingCompileTimeError
-nosuchmethod_forwarding/nosuchmethod_forwarding_arguments_test: RuntimeError
-nosuchmethod_forwarding/nosuchmethod_forwarding_test/05: RuntimeError
-nosuchmethod_forwarding/nosuchmethod_forwarding_test/06: RuntimeError
-nsm5_test: MissingCompileTimeError
-override_inheritance_no_such_method_test/05: MissingCompileTimeError
-type_alias_equality_test/01: RuntimeError # Issue 32783
-type_alias_equality_test/02: RuntimeError # Issue 32783
-type_alias_equality_test/03: RuntimeError # Issue 32783
-type_alias_equality_test/04: RuntimeError # Issue 32783
-
-[ $compiler == none && $runtime == vm && !$checked ]
-assertion_initializer_const_error_test/01: MissingCompileTimeError
-assertion_initializer_const_function_error_test/01: MissingCompileTimeError
-generic_methods_dynamic_test/02: MissingRuntimeError
-generic_methods_dynamic_test/04: MissingRuntimeError
-type_parameter_test/05: MissingCompileTimeError
-
-[ ($compiler == app_jit || $compiler == none || $compiler == precompiler) && ($runtime == dart_precompiled || $runtime == vm) ]
-const_cast2_test/01: CompileTimeError
-
-[ $compiler != dartk && $runtime == vm || $compiler != dartkp && $runtime == dart_precompiled ]
-built_in_identifier_type_annotation_test/22: MissingCompileTimeError # Error only in strong mode
-int64_literal_test/*: Skip # This is testing Dart 2.0 int64 semantics.
-invalid_type_argument_count_test/01: MissingCompileTimeError # Error only in strong mode
-invalid_type_argument_count_test/02: MissingCompileTimeError # Error only in strong mode
-invalid_type_argument_count_test/03: MissingCompileTimeError # Error only in strong mode
-invalid_type_argument_count_test/04: MissingCompileTimeError # Error only in strong mode
-partial_tearoff_instantiation_test/none: CompileTimeError
+[ !$strong && ($runtime == dart_precompiled || $runtime == vm) ]
+*: SkipByDesign # tests/language has the non-strong mode versions of these tests.
diff --git a/tests/language_2/no_such_method_mock_test.dart b/tests/language_2/no_such_method_mock_test.dart
index 49d8f24..62f83bf 100644
--- a/tests/language_2/no_such_method_mock_test.dart
+++ b/tests/language_2/no_such_method_mock_test.dart
@@ -82,7 +82,7 @@
   var mock3 = new MockCat3();
   Expect.isTrue(mock3.eatFood("cat food", amount: 0.9));
   Expect.isFalse(mock3.eatFood("cat food", amount: 0.3));
-  Expect.equals("chair", mock3.scratch("chair"));
+  Expect.equals("chair,null", mock3.scratch("chair"));
   Expect.equals("chair,couch", mock3.scratch("chair", "couch"));
   Expect.equals("chair,null", mock3.scratch("chair", null));
   Expect.equals("chair,", mock3.scratch("chair", ""));
diff --git a/tests/language_2/nosuchmethod_forwarding/nosuchmethod_forwarding_arguments_test.dart b/tests/language_2/nosuchmethod_forwarding/nosuchmethod_forwarding_arguments_test.dart
index 126c2c0..01a59e7 100644
--- a/tests/language_2/nosuchmethod_forwarding/nosuchmethod_forwarding_arguments_test.dart
+++ b/tests/language_2/nosuchmethod_forwarding/nosuchmethod_forwarding_arguments_test.dart
@@ -14,10 +14,12 @@
       Expect.equals(invoke.positionalArguments[1], 2);
       return null;
     } else if (invoke.memberName == #test1) {
-      Expect.isTrue(invoke.namedArguments.isEmpty);
+      Expect.isTrue(invoke.namedArguments.length == 1);
+      Expect.equals(null, invoke.namedArguments[#x]);
       return null;
     } else if (invoke.memberName == #test2) {
-      Expect.isTrue(invoke.namedArguments.isEmpty);
+      Expect.isTrue(invoke.namedArguments.length == 1);
+      Expect.equals("w/e", invoke.namedArguments[#x]);
       return null;
     } else if (invoke.memberName == #test3) {
       Expect.equals(invoke.namedArguments[#x], "ok");
@@ -42,6 +44,9 @@
 
       Expect.equals(invoke.namedArguments.length, 1);
       Expect.equals(invoke.namedArguments[#foo], const <num>[3, 4]);
+    } else if (invoke.memberName == #test8) {
+      Expect.equals(1, invoke.positionalArguments.length);
+      Expect.equals(null, invoke.positionalArguments[0]);
     }
   }
 
@@ -56,6 +61,8 @@
   int get test7;
   void set test7(int x);
 
+  void test8([String x]);
+
   T allTogetherNow<T, S extends T>(S x1, {List<T> foo: const <Null>[]});
 }
 
@@ -89,4 +96,6 @@
   Expect.throwsTypeError(() => (a as dynamic).test7 = "hi");
 
   a.allTogetherNow<num, double>(2.0, foo: const <num>[3, 4]);
+
+  a.test8();
 }
diff --git a/tests/language_2/nosuchmethod_forwarding/nosuchmethod_forwarding_partial_instantiation_test.dart b/tests/language_2/nosuchmethod_forwarding/nosuchmethod_forwarding_partial_instantiation_test.dart
new file mode 100644
index 0000000..69a554f
--- /dev/null
+++ b/tests/language_2/nosuchmethod_forwarding/nosuchmethod_forwarding_partial_instantiation_test.dart
@@ -0,0 +1,25 @@
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Testing that `noSuchMethod` forwarders can be partially instantiated, and
+// that their delayed type arguments are transparently passed to `noSuchMethod`.
+
+import 'package:expect/expect.dart';
+
+class C {
+  T test1<T>(T x);
+
+  dynamic noSuchMethod(Invocation invoke) {
+    Expect.equals(invoke.typeArguments.length, 1);
+    Expect.equals(invoke.typeArguments[0].toString(), 'int');
+    Expect.equals(invoke.positionalArguments[0], 1);
+    return null;
+  }
+}
+
+void main() {
+  var c = new C();
+  int Function(int) k1 = c.test1;
+  k1(1);
+}
diff --git a/tests/language_2/vm/regress_31946_test.dart b/tests/language_2/vm/regress_31946_test.dart
new file mode 100644
index 0000000..19554a0
--- /dev/null
+++ b/tests/language_2/vm/regress_31946_test.dart
@@ -0,0 +1,32 @@
+// 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=--no_background_compilation --optimization_counter_threshold=10
+
+import 'dart:async';
+
+import 'package:expect/expect.dart';
+
+var root = [];
+var tests = <dynamic>[
+  () async {},
+  () async {
+    await new Future.value();
+    root.singleWhere((f) => f.name == 'optimizedFunction');
+  },
+];
+
+main(args) async {
+  for (int i = 0; i < 100; ++i) {
+    int exceptions = 0;
+    for (final test in tests) {
+      try {
+        await test();
+      } on StateError {
+        exceptions++;
+      }
+    }
+    Expect.isTrue(exceptions == 1);
+  }
+}
diff --git a/tests/language_2/vm/regress_33095_test.dart b/tests/language_2/vm/regress_33095_test.dart
new file mode 100644
index 0000000..9dd97c0
--- /dev/null
+++ b/tests/language_2/vm/regress_33095_test.dart
@@ -0,0 +1,19 @@
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+typedef String IntFunctionType(int _);
+
+class Box {
+  final IntFunctionType fun;
+  const Box(this.fun);
+}
+
+String genericFunction<T>(T v) => '$v';
+
+void main() {
+  const list = const [const Box(genericFunction)];
+  Expect.equals('42', list.first.fun(42));
+}
diff --git a/tests/lib_2/lib_2_dart2js.status b/tests/lib_2/lib_2_dart2js.status
index 092573e..9177102 100644
--- a/tests/lib_2/lib_2_dart2js.status
+++ b/tests/lib_2/lib_2_dart2js.status
@@ -700,8 +700,6 @@
 html/js_typed_interop_default_arg_test/explicit_argument: CompileTimeError
 html/js_typed_interop_side_cast_exp_test: Crash # 'file:*/pkg/compiler/lib/src/common_elements.dart': Failed assertion: line 405 pos 12: 'element.name == '=='': is not true.
 html/js_typed_interop_test: CompileTimeError
-typed_data/typed_data_list_test: Crash
-typed_data/typed_list_iterable_test: Crash
 
 [ $compiler == dart2js && $fasta && $minified ]
 html/audiobuffersourcenode_test/functional: RuntimeError
diff --git a/tests/lib_2/lib_2_kernel.status b/tests/lib_2/lib_2_kernel.status
index bf33435..65dbd6b 100644
--- a/tests/lib_2/lib_2_kernel.status
+++ b/tests/lib_2/lib_2_kernel.status
@@ -30,6 +30,9 @@
 mirrors/reflected_type_test/03: MissingCompileTimeError
 mirrors/variable_is_const_test/01: MissingCompileTimeError
 
+[ $arch == simdbc64 && $compiler == dartk && $mode == debug && $runtime == vm && $strong ]
+isolate/isolate_complex_messages_test: Crash # http://dartbug.com/33128
+
 [ $arch == x64 && $compiler == dartk && $mode == debug && $runtime == vm && $strong ]
 mirrors/invocation_fuzz_test: Skip # Because it times out, issue 29439.
 mirrors/variable_is_const_test/01: Crash
@@ -49,7 +52,6 @@
 isolate/browser/package_resolve_browser_test: CompileTimeError
 
 [ $compiler == dartk && $mode == debug && $runtime == vm && $strong ]
-isolate/isolate_complex_messages_test: Crash
 mirrors/other_declarations_location_test: Crash # assertion error, TypeParameter not having position.
 
 [ $compiler == dartk && $mode == debug && $strong ]
@@ -260,7 +262,6 @@
 *: SkipByDesign
 
 [ $compiler == dartkp && $mode == debug && $runtime == dart_precompiled && $strong ]
-isolate/isolate_complex_messages_test: Crash
 isolate/static_function_test: Skip # Flaky (https://github.com/dart-lang/sdk/issues/30063).
 
 # ===== dartkp + dart_precompiled status lines =====
diff --git a/tests/standalone/standalone.status b/tests/standalone/standalone.status
index 05c6d9c..22bb3c2 100644
--- a/tests/standalone/standalone.status
+++ b/tests/standalone/standalone.status
@@ -69,6 +69,9 @@
 io/socket_invalid_arguments_test: Fail, OK # These tests have type errors on purpose.
 io/stdout_bad_argument_test: Fail, OK # These tests have type errors on purpose.
 
+[ !$strong && ($compiler == dartk || $compiler == dartkp) ]
+*: Skip
+
 [ $compiler == app_jit || $compiler == precompiler ]
 io/compile_all_test: Skip # Incompatible flag --compile_all
 
diff --git a/tests/standalone_2/io/secure_client_server_test.dart b/tests/standalone_2/io/secure_client_server_test.dart
index ac76bbb..c8cb48e 100644
--- a/tests/standalone_2/io/secure_client_server_test.dart
+++ b/tests/standalone_2/io/secure_client_server_test.dart
@@ -41,10 +41,27 @@
   });
 }
 
+void checkServerCertificate(X509Certificate serverCert) {
+  String serverCertString = serverCert.pem;
+  String certFile =
+      new File(localFile('certificates/server_chain.pem')).readAsStringSync();
+  Expect.isTrue(certFile.contains(serverCertString));
+
+  // Computed with:
+  // openssl x509 -noout -sha1 -fingerprint -in certificates/server_chain.pem
+  List<int> serverSha1 = <int>[
+    0xB3, 0x01, 0xCB, 0x7E, 0x6F, 0xEF, 0xBE, 0xEF, //
+    0x75, 0x6D, 0xA8, 0x80, 0x60, 0xA8, 0x5D, 0x6F, //
+    0xC4, 0xED, 0xCD, 0x48, //
+  ];
+  Expect.listEquals(serverSha1, serverCert.sha1);
+}
+
 Future testClient(server) {
   return SecureSocket
       .connect(HOST, server.port, context: clientContext)
       .then((socket) {
+    checkServerCertificate(socket.peerCertificate);
     socket.write("Hello server.");
     socket.close();
     return socket.fold(<int>[], (message, data) => message..addAll(data)).then(
diff --git a/tests/standalone_2/standalone_2_precompiled.status b/tests/standalone_2/standalone_2_precompiled.status
index 99e6eb8..bbaa92a 100644
--- a/tests/standalone_2/standalone_2_precompiled.status
+++ b/tests/standalone_2/standalone_2_precompiled.status
@@ -19,6 +19,7 @@
 io/http_server_close_response_after_error_test: Skip
 io/https_unauthorized_test: Skip
 io/named_pipe_script_test: Skip
+io/namespace_test: Skip # Issue 33168
 io/platform_resolved_executable_test: Skip
 io/platform_test: RuntimeError # Expects to be running from 'dart' instead of 'dart_precompiled_runtime'
 io/print_sync_test: Skip
@@ -45,6 +46,7 @@
 io/stdio_nonblocking_test: Skip
 io/test_extension_fail_test: Skip
 io/test_extension_test: Skip
+io/test_runner_test: RuntimeError # Issue 33168
 io/windows_environment_test: Skip
 
 [ $arch == arm && $mode == release && $runtime == dart_precompiled && $system == android ]
diff --git a/tests/standalone_2/standalone_2_vm.status b/tests/standalone_2/standalone_2_vm.status
index 4b95f11..03479a7 100644
--- a/tests/standalone_2/standalone_2_vm.status
+++ b/tests/standalone_2/standalone_2_vm.status
@@ -9,9 +9,17 @@
 [ $compiler == app_jit ]
 full_coverage_test: Skip # Platform.executable
 io/code_collection_test: Skip # Platform.executable
+io/namespace_test: RuntimeError # Issue 33168
+io/platform_resolved_executable_test/00: RuntimeError # Issue 33168
+io/platform_resolved_executable_test/01: RuntimeError # Issue 33168
+io/platform_resolved_executable_test/02: RuntimeError # Issue 33168
+io/platform_resolved_executable_test/03: RuntimeError # Issue 33168
+io/platform_resolved_executable_test/04: RuntimeError # Issue 33168
+io/platform_resolved_executable_test/05: RuntimeError # Issue 33168
 io/platform_test: Skip # Platform.executable
 io/test_extension_fail_test: Skip # Platform.executable
 io/test_extension_test: Skip # Platform.executable
+io/test_runner_test: RuntimeError # Issue 33168
 regress_26031_test: Skip # Platform.resolvedExecutable
 
 [ $system == android ]
diff --git a/third_party/tcmalloc/BUILD.gn b/third_party/tcmalloc/BUILD.gn
index bea0427..9ab294d 100644
--- a/third_party/tcmalloc/BUILD.gn
+++ b/third_party/tcmalloc/BUILD.gn
@@ -31,6 +31,8 @@
     "-fno-builtin-posix_memalign",
     "-fno-builtin-valloc",
     "-fno-builtin-pvalloc",
+    "-fsized-deallocation",
+    "-faligned-new",
   ]
   if (is_clang) {
     cflags += [ "-Wno-unused-const-variable" ]
diff --git a/third_party/tcmalloc/include/config.h b/third_party/tcmalloc/include/config.h
index 2cd633a..16b2d7d 100644
--- a/third_party/tcmalloc/include/config.h
+++ b/third_party/tcmalloc/include/config.h
@@ -6,6 +6,9 @@
 #define GPERFTOOLS_CONFIG_H_
 
 
+/* Build new/delete operators for overaligned types */
+/* #undef ENABLE_ALIGNED_NEW_DELETE */
+
 /* Build runtime detection for sized delete */
 /* #undef ENABLE_DYNAMIC_SIZED_DELETE */
 
@@ -206,6 +209,9 @@
 /* define if your compiler has __attribute__ */
 #define HAVE___ATTRIBUTE__ 1
 
+/* define if your compiler supports alignment of functions */
+#define HAVE___ATTRIBUTE__ALIGNED_FN 1
+
 /* Define to 1 if compiler supports __environ */
 #if !defined(__ANDROID__)
 #define HAVE___ENVIRON 1
@@ -220,13 +226,9 @@
 /* Define to 1 if int32_t is equivalent to intptr_t */
 /* #undef INT32_EQUALS_INTPTR */
 
-/* Define to the sub-directory in which libtool stores uninstalled libraries.
-   */
+/* Define to the sub-directory where libtool stores uninstalled libraries. */
 #define LT_OBJDIR ".libs/"
 
-/* Define to 'volatile' if __malloc_hook is declared volatile */
-#define MALLOC_HOOK_MAYBE_VOLATILE volatile
-
 /* Name of package */
 #define PACKAGE "gperftools"
 
@@ -237,7 +239,7 @@
 #define PACKAGE_NAME "gperftools"
 
 /* Define to the full name and version of this package. */
-#define PACKAGE_STRING "gperftools 2.5"
+#define PACKAGE_STRING "gperftools 2.7"
 
 /* Define to the one symbol short name of this package. */
 #define PACKAGE_TARNAME "gperftools"
@@ -246,7 +248,7 @@
 #define PACKAGE_URL ""
 
 /* Define to the version of this package. */
-#define PACKAGE_VERSION "2.5"
+#define PACKAGE_VERSION "2.7"
 
 /* How to access the PC from a struct ucontext */
 /* #undef PC_FROM_UCONTEXT */
@@ -293,7 +295,7 @@
 /* #undef TCMALLOC_ALIGN_8BYTES */
 
 /* Version number of package */
-#define VERSION "2.5"
+#define VERSION "2.7"
 
 /* C99 says: define this to get the PRI... macros from stdint.h */
 #ifndef __STDC_FORMAT_MACROS
@@ -312,3 +314,4 @@
 #endif
 
 #endif  /* #ifndef GPERFTOOLS_CONFIG_H_ */
+
diff --git a/third_party/tcmalloc/include/gperftools/tcmalloc.h b/third_party/tcmalloc/include/gperftools/tcmalloc.h
index 138d1f9..7935081 100644
--- a/third_party/tcmalloc/include/gperftools/tcmalloc.h
+++ b/third_party/tcmalloc/include/gperftools/tcmalloc.h
@@ -37,30 +37,38 @@
 #define TCMALLOC_TCMALLOC_H_
 
 #include <stddef.h>                     /* for size_t */
+#ifdef __cplusplus
+#include <new>                          /* for std::nothrow_t, std::align_val_t */
+#endif
 
 /* Define the version number so folks can check against it */
 #define TC_VERSION_MAJOR  2
-#define TC_VERSION_MINOR  5
+#define TC_VERSION_MINOR  7
 #define TC_VERSION_PATCH  ""
-#define TC_VERSION_STRING "gperftools 2.5"
+#define TC_VERSION_STRING "gperftools 2.7"
 
 /* For struct mallinfo, if it's defined. */
 #if 1
 # include <malloc.h>
 #endif
 
-#ifdef __cplusplus
-#define PERFTOOLS_THROW throw()
+#ifndef PERFTOOLS_NOTHROW
+
+#if __cplusplus >= 201103L
+#define PERFTOOLS_NOTHROW noexcept
+#elif defined(__cplusplus)
+#define PERFTOOLS_NOTHROW throw()
 #else
 # ifdef __GNUC__
-#  define PERFTOOLS_THROW __attribute__((__nothrow__))
+#  define PERFTOOLS_NOTHROW __attribute__((__nothrow__))
 # else
-#  define PERFTOOLS_THROW
+#  define PERFTOOLS_NOTHROW
 # endif
 #endif
 
+#endif
+
 #ifndef PERFTOOLS_DLL_DECL
-#define PERFTOOLS_DLL_DECL_DEFINED
 # ifdef _WIN32
 #   define PERFTOOLS_DLL_DECL  __declspec(dllimport)
 # else
@@ -69,10 +77,6 @@
 #endif
 
 #ifdef __cplusplus
-namespace std {
-struct nothrow_t;
-}
-
 extern "C" {
 #endif
   /*
@@ -81,27 +85,27 @@
    * minor version, and patch-code (a string, usually "").
    */
   PERFTOOLS_DLL_DECL const char* tc_version(int* major, int* minor,
-                                            const char** patch) PERFTOOLS_THROW;
+                                            const char** patch) PERFTOOLS_NOTHROW;
 
-  PERFTOOLS_DLL_DECL void* tc_malloc(size_t size) PERFTOOLS_THROW;
-  PERFTOOLS_DLL_DECL void* tc_malloc_skip_new_handler(size_t size) PERFTOOLS_THROW;
-  PERFTOOLS_DLL_DECL void tc_free(void* ptr) PERFTOOLS_THROW;
-  PERFTOOLS_DLL_DECL void tc_free_sized(void *ptr, size_t size) PERFTOOLS_THROW;
-  PERFTOOLS_DLL_DECL void* tc_realloc(void* ptr, size_t size) PERFTOOLS_THROW;
-  PERFTOOLS_DLL_DECL void* tc_calloc(size_t nmemb, size_t size) PERFTOOLS_THROW;
-  PERFTOOLS_DLL_DECL void tc_cfree(void* ptr) PERFTOOLS_THROW;
+  PERFTOOLS_DLL_DECL void* tc_malloc(size_t size) PERFTOOLS_NOTHROW;
+  PERFTOOLS_DLL_DECL void* tc_malloc_skip_new_handler(size_t size) PERFTOOLS_NOTHROW;
+  PERFTOOLS_DLL_DECL void tc_free(void* ptr) PERFTOOLS_NOTHROW;
+  PERFTOOLS_DLL_DECL void tc_free_sized(void *ptr, size_t size) PERFTOOLS_NOTHROW;
+  PERFTOOLS_DLL_DECL void* tc_realloc(void* ptr, size_t size) PERFTOOLS_NOTHROW;
+  PERFTOOLS_DLL_DECL void* tc_calloc(size_t nmemb, size_t size) PERFTOOLS_NOTHROW;
+  PERFTOOLS_DLL_DECL void tc_cfree(void* ptr) PERFTOOLS_NOTHROW;
 
   PERFTOOLS_DLL_DECL void* tc_memalign(size_t __alignment,
-                                       size_t __size) PERFTOOLS_THROW;
+                                       size_t __size) PERFTOOLS_NOTHROW;
   PERFTOOLS_DLL_DECL int tc_posix_memalign(void** ptr,
-                                           size_t align, size_t size) PERFTOOLS_THROW;
-  PERFTOOLS_DLL_DECL void* tc_valloc(size_t __size) PERFTOOLS_THROW;
-  PERFTOOLS_DLL_DECL void* tc_pvalloc(size_t __size) PERFTOOLS_THROW;
+                                           size_t align, size_t size) PERFTOOLS_NOTHROW;
+  PERFTOOLS_DLL_DECL void* tc_valloc(size_t __size) PERFTOOLS_NOTHROW;
+  PERFTOOLS_DLL_DECL void* tc_pvalloc(size_t __size) PERFTOOLS_NOTHROW;
 
-  PERFTOOLS_DLL_DECL void tc_malloc_stats(void) PERFTOOLS_THROW;
-  PERFTOOLS_DLL_DECL int tc_mallopt(int cmd, int value) PERFTOOLS_THROW;
+  PERFTOOLS_DLL_DECL void tc_malloc_stats(void) PERFTOOLS_NOTHROW;
+  PERFTOOLS_DLL_DECL int tc_mallopt(int cmd, int value) PERFTOOLS_NOTHROW;
 #if 1
-  PERFTOOLS_DLL_DECL struct mallinfo tc_mallinfo(void) PERFTOOLS_THROW;
+  PERFTOOLS_DLL_DECL struct mallinfo tc_mallinfo(void) PERFTOOLS_NOTHROW;
 #endif
 
   /*
@@ -111,36 +115,48 @@
    *    glibc: malloc_usable_size()
    *    Windows: _msize()
    */
-  PERFTOOLS_DLL_DECL size_t tc_malloc_size(void* ptr) PERFTOOLS_THROW;
+  PERFTOOLS_DLL_DECL size_t tc_malloc_size(void* ptr) PERFTOOLS_NOTHROW;
 
 #ifdef __cplusplus
-  PERFTOOLS_DLL_DECL int tc_set_new_mode(int flag) PERFTOOLS_THROW;
+  PERFTOOLS_DLL_DECL int tc_set_new_mode(int flag) PERFTOOLS_NOTHROW;
   PERFTOOLS_DLL_DECL void* tc_new(size_t size);
   PERFTOOLS_DLL_DECL void* tc_new_nothrow(size_t size,
-                                          const std::nothrow_t&) PERFTOOLS_THROW;
-  PERFTOOLS_DLL_DECL void tc_delete(void* p) PERFTOOLS_THROW;
-  PERFTOOLS_DLL_DECL void tc_delete_sized(void* p, size_t size) throw();
+                                          const std::nothrow_t&) PERFTOOLS_NOTHROW;
+  PERFTOOLS_DLL_DECL void tc_delete(void* p) PERFTOOLS_NOTHROW;
+  PERFTOOLS_DLL_DECL void tc_delete_sized(void* p, size_t size) PERFTOOLS_NOTHROW;
   PERFTOOLS_DLL_DECL void tc_delete_nothrow(void* p,
-                                            const std::nothrow_t&) PERFTOOLS_THROW;
+                                            const std::nothrow_t&) PERFTOOLS_NOTHROW;
   PERFTOOLS_DLL_DECL void* tc_newarray(size_t size);
   PERFTOOLS_DLL_DECL void* tc_newarray_nothrow(size_t size,
-                                               const std::nothrow_t&) PERFTOOLS_THROW;
-  PERFTOOLS_DLL_DECL void tc_deletearray(void* p) PERFTOOLS_THROW;
-  PERFTOOLS_DLL_DECL void tc_deletearray_sized(void* p, size_t size) throw();
+                                               const std::nothrow_t&) PERFTOOLS_NOTHROW;
+  PERFTOOLS_DLL_DECL void tc_deletearray(void* p) PERFTOOLS_NOTHROW;
+  PERFTOOLS_DLL_DECL void tc_deletearray_sized(void* p, size_t size) PERFTOOLS_NOTHROW;
   PERFTOOLS_DLL_DECL void tc_deletearray_nothrow(void* p,
-                                                 const std::nothrow_t&) PERFTOOLS_THROW;
+                                                 const std::nothrow_t&) PERFTOOLS_NOTHROW;
+
+#if 1 && __cplusplus >= 201703L
+  PERFTOOLS_DLL_DECL void* tc_new_aligned(size_t size, std::align_val_t al);
+  PERFTOOLS_DLL_DECL void* tc_new_aligned_nothrow(size_t size, std::align_val_t al,
+                                          const std::nothrow_t&) PERFTOOLS_NOTHROW;
+  PERFTOOLS_DLL_DECL void tc_delete_aligned(void* p, std::align_val_t al) PERFTOOLS_NOTHROW;
+  PERFTOOLS_DLL_DECL void tc_delete_sized_aligned(void* p, size_t size, std::align_val_t al) PERFTOOLS_NOTHROW;
+  PERFTOOLS_DLL_DECL void tc_delete_aligned_nothrow(void* p, std::align_val_t al,
+                                            const std::nothrow_t&) PERFTOOLS_NOTHROW;
+  PERFTOOLS_DLL_DECL void* tc_newarray_aligned(size_t size, std::align_val_t al);
+  PERFTOOLS_DLL_DECL void* tc_newarray_aligned_nothrow(size_t size, std::align_val_t al,
+                                               const std::nothrow_t&) PERFTOOLS_NOTHROW;
+  PERFTOOLS_DLL_DECL void tc_deletearray_aligned(void* p, std::align_val_t al) PERFTOOLS_NOTHROW;
+  PERFTOOLS_DLL_DECL void tc_deletearray_sized_aligned(void* p, size_t size, std::align_val_t al) PERFTOOLS_NOTHROW;
+  PERFTOOLS_DLL_DECL void tc_deletearray_aligned_nothrow(void* p, std::align_val_t al,
+                                                 const std::nothrow_t&) PERFTOOLS_NOTHROW;
+#endif
 }
 #endif
 
-/* We're only un-defining those for public */
+/* We're only un-defining for public */
 #if !defined(GPERFTOOLS_CONFIG_H_)
 
-#undef PERFTOOLS_THROW
-
-#ifdef PERFTOOLS_DLL_DECL_DEFINED
-#undef PERFTOOLS_DLL_DECL
-#undef PERFTOOLS_DLL_DECL_DEFINED
-#endif
+#undef PERFTOOLS_NOTHROW
 
 #endif /* GPERFTOOLS_CONFIG_H_ */
 
diff --git a/tools/VERSION b/tools/VERSION
index b5da02e..b7ef033 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 0
 PATCH 0
-PRERELEASE 55
+PRERELEASE 56
 PRERELEASE_PATCH 0
diff --git a/tools/bots/dart2js_d8_hostchecked_tests.isolate b/tools/bots/dart2js_d8_hostchecked_tests.isolate
index 23c2346..1b53302 100644
--- a/tools/bots/dart2js_d8_hostchecked_tests.isolate
+++ b/tools/bots/dart2js_d8_hostchecked_tests.isolate
@@ -19,7 +19,23 @@
               'third_party/pkg/',
               'third_party/pkg_tested/',
               'third_party/d8/',
-              'tests/',
+              'tests/angular/',
+              'tests/co19/',
+              'tests/compiler/',
+              'tests/corelib/',
+              'tests/corelib_2/',
+              'tests/dart/',
+              'tests/html/',
+              'tests/isolate/',
+              'tests/kernel/',
+              'tests/language/',
+              'tests/language_2/',
+              'tests/lib/',
+              'tests/lib_2/',
+              'tests/light_unittest.dart',
+              'tests/search/',
+              'tests/standalone/',
+              'tests/standalone_2/',
               'pkg/async_helper/',
               'pkg/compiler/',
               'pkg/dart_internal/',
diff --git a/tools/bots/dart_tests.isolate b/tools/bots/dart_tests.isolate
index 74ac8b4..d2b7a74 100644
--- a/tools/bots/dart_tests.isolate
+++ b/tools/bots/dart_tests.isolate
@@ -12,7 +12,23 @@
               'third_party/d8/',
               'third_party/firefox_jsshell/',
               'third_party/observatory_pub_packages/packages/web_components/',
-              'tests/',
+              'tests/angular/',
+              'tests/co19/',
+              'tests/compiler/',
+              'tests/corelib/',
+              'tests/corelib_2/',
+              'tests/dart/',
+              'tests/html/',
+              'tests/isolate/',
+              'tests/kernel/',
+              'tests/language/',
+              'tests/language_2/',
+              'tests/lib/',
+              'tests/lib_2/',
+              'tests/light_unittest.dart',
+              'tests/search/',
+              'tests/standalone/',
+              'tests/standalone_2/',
               'pkg/async_helper/',
               'pkg/browser/',
               'pkg/compiler/',
diff --git a/tools/bots/pub_integration_test.py b/tools/bots/pub_integration_test.py
new file mode 100755
index 0000000..61168c2
--- /dev/null
+++ b/tools/bots/pub_integration_test.py
@@ -0,0 +1,44 @@
+#!/usr/bin/env python
+# 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 os
+import subprocess
+import sys
+import shutil
+import tempfile
+
+PUBSPEC = """name: pub_integration_test
+dependencies:
+  shelf:
+  test:
+"""
+
+def Main():
+  out_dir = 'xcodebuild' if sys.platform == 'darwin' else 'out'
+  extension = '' if not sys.platform == 'win32' else '.bat'
+  pub = os.path.abspath(
+    '%s/ReleaseX64/dart-sdk/bin/pub%s' % (out_dir, extension))
+
+  working_dir = tempfile.mkdtemp()
+  try:
+    pub_cache_dir = working_dir + '/pub_cache'
+    env = os.environ.copy()
+    env['PUB_CACHE'] = pub_cache_dir
+
+    with open(working_dir + '/pubspec.yaml', 'w') as pubspec_yaml:
+      pubspec_yaml.write(PUBSPEC)
+
+    exit_code = subprocess.call([pub, 'get'], cwd=working_dir, env=env)
+    if exit_code is not 0:
+      return exit_code
+
+    exit_code = subprocess.call([pub, 'upgrade'], cwd=working_dir, env=env)
+    if exit_code is not 0:
+      return exit_code
+  finally:
+    shutil.rmtree(working_dir);
+
+if __name__ == '__main__':
+  sys.exit(Main())
diff --git a/tools/bots/test_matrix.json b/tools/bots/test_matrix.json
index 585a075..8695c4c 100644
--- a/tools/bots/test_matrix.json
+++ b/tools/bots/test_matrix.json
@@ -18,7 +18,23 @@
       "runtime/tests/",
       "samples-dev/",
       "samples/",
-      "tests/",
+      "tests/angular/",
+      "tests/co19/",
+      "tests/compiler/",
+      "tests/corelib/",
+      "tests/corelib_2/",
+      "tests/dart/",
+      "tests/html/",
+      "tests/isolate/",
+      "tests/kernel/",
+      "tests/language/",
+      "tests/language_2/",
+      "tests/lib/",
+      "tests/lib_2/",
+      "tests/light_unittest.dart",
+      "tests/search/",
+      "tests/standalone/",
+      "tests/standalone_2/",
       "third_party/d8/",
       "third_party/observatory_pub_packages/packages/web_components/",
       "third_party/pkg/",
@@ -728,7 +744,7 @@
         {
           "name": "build dart",
           "script": "tools/build.py",
-          "arguments": ["dart2js_bot",  "compile_dart2js_platform"]
+          "arguments": ["dart2js_bot"]
         },
         {
           "name": "dart2js tests",
@@ -1613,14 +1629,8 @@
           "tests": ["pkg_tested"]
         },
         {
-          "name": "pub get dependencies",
-          "arguments": [
-            "--use-sdk",
-            "--compiler=none",
-            "--runtime=vm",
-            "--checked"
-          ],
-          "tests": ["pkgbuild"]
+          "name": "pub integration tests",
+          "script": "tools/bots/pub_integration_test.py"
         }
       ]
     },
diff --git a/tools/infra/config/cq.cfg b/tools/infra/config/cq.cfg
index 2bf13e2..508d716 100644
--- a/tools/infra/config/cq.cfg
+++ b/tools/infra/config/cq.cfg
@@ -31,8 +31,9 @@
       builders { name: "pkg-linux-release-try" }
       builders { name: "vm-canary-linux-debug-try" }
       builders { name: "vm-kernel-legacy-linux-release-x64-try" }
-      builders { name: "vm-kernel-mac-release-x64-try" experiment_percentage: 100 }
+      builders { name: "vm-kernel-linux-release-simdbc64-try" }
       builders { name: "vm-kernel-linux-release-x64-try" }
+      builders { name: "vm-kernel-mac-release-x64-try" experiment_percentage: 100 }
       builders { name: "vm-linux-product-x64-try" }
       builders { name: "vm-linux-release-x64-try" }
       builders { name: "vm-mac-release-x64-try" }
diff --git a/tools/sdks/linux/dart-sdk.tar.gz.sha1 b/tools/sdks/linux/dart-sdk.tar.gz.sha1
index d3e10bd..c32cb3c 100644
--- a/tools/sdks/linux/dart-sdk.tar.gz.sha1
+++ b/tools/sdks/linux/dart-sdk.tar.gz.sha1
@@ -1 +1 @@
-bcfe42edaebd8c1a13a78590aab6235769160858
\ No newline at end of file
+dbd141e72b88a1a30768af3acf75eba45963a896
\ No newline at end of file
diff --git a/tools/sdks/mac/dart-sdk.tar.gz.sha1 b/tools/sdks/mac/dart-sdk.tar.gz.sha1
index a34fc3f..cf501d1 100644
--- a/tools/sdks/mac/dart-sdk.tar.gz.sha1
+++ b/tools/sdks/mac/dart-sdk.tar.gz.sha1
@@ -1 +1 @@
-f1c33b5acdf0a3a4bd7838f98d71cf6199d38aa1
\ No newline at end of file
+6b686b5dd4a33806fc136cf01fa4bf3ac7f661b7
\ No newline at end of file
diff --git a/tools/sdks/win/dart-sdk.tar.gz.sha1 b/tools/sdks/win/dart-sdk.tar.gz.sha1
index cc0bdcf..902188f 100644
--- a/tools/sdks/win/dart-sdk.tar.gz.sha1
+++ b/tools/sdks/win/dart-sdk.tar.gz.sha1
@@ -1 +1 @@
-0a1a4fbd27281366e873ab5135260583286a2190
\ No newline at end of file
+898a3784afca3a8f0e8624fda56d243aadd1b95d
\ No newline at end of file
diff --git a/tools/testing/dart/compiler_configuration.dart b/tools/testing/dart/compiler_configuration.dart
index 4bc4061..5f930c6 100644
--- a/tools/testing/dart/compiler_configuration.dart
+++ b/tools/testing/dart/compiler_configuration.dart
@@ -498,7 +498,6 @@
       List<String> ddcOptions,
       List<String> args) {
     var result = sharedOptions.toList()..addAll(ddcOptions);
-
     // The file being compiled is the last argument.
     result.add(args.last);
 
@@ -1062,6 +1061,8 @@
   bool get _useSdk;
   bool get _isStrong;
   bool get _isAot;
+  bool get _isChecked;
+  bool get _useEnableAsserts;
 
   String get executableScriptSuffix;
 
@@ -1107,6 +1108,10 @@
     }
 
     args.add(arguments.where((name) => name.endsWith('.dart')).single);
+    args.addAll(arguments.where((name) => name.startsWith('-D')));
+    if (_isChecked || _useEnableAsserts) {
+      args.add('--enable_asserts');
+    }
 
     // Pass environment variable to the gen_kernel script as
     // arguments are not passed if gen_kernel runs in batch mode.
diff --git a/tools/testing/dart/test_suite.dart b/tools/testing/dart/test_suite.dart
index 8260858..52974f7 100644
--- a/tools/testing/dart/test_suite.dart
+++ b/tools/testing/dart/test_suite.dart
@@ -1053,13 +1053,14 @@
           '%TEST_SCRIPTS%', '<script src="$nameNoExt.js"></script>');
     } else {
       // Synthesize an HTML file for the test.
-      var scriptPath = _createUrlPathFromFile(new Path(jsWrapperFileName));
-
       if (configuration.compiler == Compiler.dart2js) {
+        var scriptPath = _createUrlPathFromFile(new Path(jsWrapperFileName));
         content = dart2jsHtml(fileName, scriptPath);
       } else {
         var jsDir =
             new Path(compilationTempDir).relativeTo(Repository.dir).toString();
+        jsWrapperFileName =
+            new Path('$compilationTempDir/$nameNoExt.js').toNativePath();
         // Always run with synchronous starts of `async` functions.
         // If we want to make this dependent on other parameters or flags,
         // this flag could be become conditional.
@@ -1095,50 +1096,36 @@
     // browser test. For running Dart in DRT, this will be noop commands.
     var commands = <Command>[];
 
-    switch (configuration.compiler) {
-      case Compiler.dart2js:
-        commands.add(_dart2jsCompileCommand(
-            fileName, jsWrapperFileName, tempDir, optionsFromFile));
-        break;
-
-      case Compiler.dartdevc:
-      case Compiler.dartdevk:
-        var toPath =
-            new Path('$compilationTempDir/$nameNoExt.js').toNativePath();
-        commands.add(configuration.compilerConfiguration.createCommand(
-            fileName,
-            toPath,
-            optionsFromFile["sharedOptions"] as List<String>,
-            environmentOverrides));
-        break;
-
-      default:
-        assert(false);
-    }
-
-    // Some tests require compiling multiple input scripts.
-    for (var name in optionsFromFile['otherScripts'] as List<String>) {
-      var namePath = new Path(name);
-      var fromPath = info.filePath.directoryPath.join(namePath);
-      var toPath = new Path('$tempDir/${namePath.filename}.js').toNativePath();
-
+    void addCompileCommand(String fileName, String toPath) {
       switch (configuration.compiler) {
         case Compiler.dart2js:
           commands.add(_dart2jsCompileCommand(
-              fromPath.toNativePath(), toPath, tempDir, optionsFromFile));
+              fileName, toPath, tempDir, optionsFromFile));
           break;
 
         case Compiler.dartdevc:
         case Compiler.dartdevk:
+          var ddcOptions = optionsFromFile["sharedOptions"] as List<String>;
+          ddcOptions.addAll(optionsFromFile["ddcOptions"] as List<String>);
           commands.add(configuration.compilerConfiguration.createCommand(
-              fromPath.toNativePath(),
-              toPath,
-              optionsFromFile["sharedOptions"] as List<String>,
-              environmentOverrides));
+              fileName, toPath, ddcOptions, environmentOverrides));
           break;
+
+        default:
+          assert(false);
       }
     }
 
+    addCompileCommand(fileName, jsWrapperFileName);
+
+    // Some tests require compiling multiple input scripts.
+    for (var name in optionsFromFile['otherScripts'] as List<String>) {
+      var namePath = new Path(name);
+      var fromPath = info.filePath.directoryPath.join(namePath).toNativePath();
+      var toPath = new Path('$tempDir/${namePath.filename}.js').toNativePath();
+      addCompileCommand(fromPath, toPath);
+    }
+
     if (info.optionsFromFile['isMultiHtmlTest'] as bool) {
       // Variables for browser multi-tests.
       var subtestNames = info.optionsFromFile['subtestNames'] as List<String>;
diff --git a/utils/compile_platform.gni b/utils/compile_platform.gni
index 8c933ce..5158a53 100644
--- a/utils/compile_platform.gni
+++ b/utils/compile_platform.gni
@@ -5,6 +5,12 @@
 import("../build/dart/dart_host_sdk_toolchain.gni")
 import("../build/dart/prebuilt_dart_sdk.gni")
 
+_is_fuchsia = defined(is_fuchsia_tree) && is_fuchsia_tree
+
+if (_is_fuchsia) {
+  import("//build/dart/dart.gni")
+}
+
 _dart_root = get_path_info("..", "abspath")
 
 template("compile_platform") {
@@ -35,7 +41,12 @@
 
     depfile = outputs[0] + ".d"
 
-    if (!prebuilt_dart_exe_works) {
+    if (_is_fuchsia) {
+      args += [
+        "--dart-executable",
+        rebase_path(prebuilt_dart),
+      ]
+    } else if (!prebuilt_dart_exe_works) {
       deps += [ "$_dart_root/runtime/bin:dart_bootstrap($dart_host_toolchain)" ]
       dart_out_dir = get_label_info(
               "$_dart_root/runtime/bin:dart_bootstrap($dart_host_toolchain)",
diff --git a/utils/dartdevc/BUILD.gn b/utils/dartdevc/BUILD.gn
index 0350464..0c5c4e2 100644
--- a/utils/dartdevc/BUILD.gn
+++ b/utils/dartdevc/BUILD.gn
@@ -11,6 +11,10 @@
 sdk_dill = "$target_gen_dir/kernel/ddc_sdk.dill"
 
 application_snapshot("dartdevc") {
+  vm_args = [
+    "--preview-dart-2",
+  ]
+
   main_dart = "../../pkg/dev_compiler/bin/dartdevc.dart"
 
   training_args = [
diff --git a/utils/pub/BUILD.gn b/utils/pub/BUILD.gn
index b2f724c..f34a69a 100644
--- a/utils/pub/BUILD.gn
+++ b/utils/pub/BUILD.gn
@@ -8,3 +8,11 @@
   main_dart = "../../third_party/pkg/pub/bin/pub.dart"
   training_args = [ "--help" ]
 }
+
+application_snapshot("pub2") {
+  main_dart = "../../third_party/pkg/pub/bin/pub.dart"
+  training_args = [ "--help" ]
+  vm_args = [
+    "--preview-dart-2",
+  ]
+}